Soroban abacus flashcards and learning tools
Go to file
semantic-release-bot a40fa809ef chore(release): 4.68.0 [skip ci]
## [4.68.0](https://github.com/antialias/soroban-abacus-flashcards/compare/v4.67.1...v4.68.0) (2025-11-12)

### Features

* **3d-abacus:** change default columns from 13 to 4 ([cd15c70](cd15c70a25))
* **abacus-react:** add AbacusStatic for React Server Components ([3b8e864](3b8e864cfa))
* **abacus-react:** add automatic theme detection for numeral colors ([cbfd861](cbfd8618a9))
* **abacus-react:** add comprehensive Storybook stories for automatic theme detection ([8ef57cc](8ef57ccec5))
* **abacus-react:** add core utility functions for state management ([e65541c](e65541c100))
* **abacus-react:** add layout and educational props ([35bbcec](35bbcecb9e))
* **abacus-react:** add pre-defined theme presets ([cf1f950](cf1f950c7c))
* **abacus-react:** add React hooks for abacus calculations ([de038d2](de038d2afc))
* **abacus-react:** add separate /static export path for React Server Components ([ed69f6b](ed69f6b917))
* **abacus-react:** add shared dimension calculator for consistent sizing ([e5ba772](e5ba772fde))
* **abacus-react:** export new utilities, hooks, and themes ([ce4e44d](ce4e44d630))
* **abacus:** add nativeAbacusNumbers setting to schema and UI ([79f7347](79f7347d48))
* add 3D printing support for abacus models ([dafdfdd](dafdfdd233))
* add AI-powered worksheet grading with GPT-5 vision ([6e95732](6e9573288f))
* add API endpoint for live worksheet preview examples ([bef3a21](bef3a21442))
* add arrow from '1' in borrow hint pointing right ([b718994](b718994dab))
* add client-side OpenSCAD WASM support for 3D preview ([eaaf17c](eaaf17cd4c))
* add close button and theme support to mobile menu ([ea41b32](ea41b323d0))
* add comprehensive metadata, SEO, and make AbacusReact SSR-compatible ([0922ea1](0922ea10b7))
* add comprehensive Storybook coverage and migration guide ([7a4a37e](7a4a37ec6d))
* add cropToActiveBeads prop to AbacusStatic and AbacusReact ([35b0824](35b0824fc4))
* add database schema for custom skills and skill customizations ([906fa63](906fa63f24))
* add diagonal arrow from '1' to borrowed 10s box ([a9319c3](a9319c3bd8))
* add DisplayOptionsPreview component with debouncing ([6502da7](6502da7e37))
* add download and share buttons to shared worksheet viewer ([9b8947a](9b8947a198))
* add dynamic operator icon to tab navigation ([b6ff995](b6ff995a8c))
* add function-based custom bead rendering and HTTP status code easter eggs ([fde5ae9](fde5ae9164))
* add game preview system with mock arcade environment ([25880cc](25880cc7e4))
* add infrastructure for borrowing hints toggle ([74c6756](74c67566d2))
* add ngrok tunnel to dev server for HTTPS testing ([ab2bfde](ab2bfde9c2))
* add per-page worksheet generation API ([6398fbe](6398fbead9))
* add per-player stats tracking system ([613301c](613301cd13))
* add prev/next navigation buttons to mixed mode mini skill panes ([498df2c](498df2ca5a))
* add problem space validation to warn about duplicate risk ([0b8c180](0b8c1803ff))
* add shared worksheet viewer with open-in-editor functionality ([4b8b3ee](4b8b3ee532))
* add skill configuration system with interactive 2D difficulty plot ([7fbc743](7fbc743c4c)), closes [#9333](https://github.com/antialias/soroban-abacus-flashcards/issues/9333) [#10b981](https://github.com/antialias/soroban-abacus-flashcards/issues/10b981)
* add smooth curved arrow for borrowing hints ([112745c](112745ce16))
* add smooth fade-in animation for 404 message text changes ([e88380a](e88380a48d))
* add split-action share button with copy shortcut ([085d200](085d200da4))
* add Strategy & Tactics section to Rithmomachia guide ([81ead65](81ead65680))
* add theme support to abacus style dropdown ([2e294ee](2e294ee820))
* add theme support to config panel components ([c868421](c8684213fa))
* add theme support to desktop hamburger menu ([ab9272b](ab9272bee6))
* add theme support to MyAbacus button ([702c1c9](702c1c9af2))
* add theme support to orientation and generate panels ([e38775b](e38775b991))
* add theme support to worksheet page container ([5c14925](5c14925d7d))
* add theme support to worksheet preview ([693b679](693b679965))
* add themed backgrounds and enhanced styling to 404 page ([dd14062](dd14062112))
* add unified trophy abacus with hero mode integration ([6620418](6620418a70))
* add visible grab tab to worksheet panel resize handle ([288e6ed](288e6ed878))
* add visual grab tab to resize handle with rounded corners ([6e55d5a](6e55d5add7))
* add visual warnings to page selector buttons ([5a87799](5a8779969c))
* add worksheet generation core logic and helpers ([163517d](163517db7d))
* add worksheet sharing infrastructure with database persistence ([7b4c7c3](7b4c7c3fb6))
* add worksheet studio with comprehensive features ([d5672bd](d5672bdddf))
* apply skill-specific scaffolding and fix mini card heights ([ee90182](ee90182ff2))
* **arcade:** add ability to deactivate remote players without kicking user ([3628426](3628426a56))
* **arcade:** add native abacus numbers support to pressure gauge ([1d525c7](1d525c7b53))
* **arcade:** add Rithmomachia (Battle of Numbers) game ([2fc0a05](2fc0a05f7f))
* **arcade:** add yjs-demo collaborative game and Yjs persistence layer ([d568955](d568955d6a))
* **arcade:** auto-create room when user has none ([ff88c3a](ff88c3a1b8))
* **blog:** add "The Calculator Won" post on abacus education history ([8e04867](8e0486765a))
* **blog:** add blog pages and API endpoints ([1886ea0](1886ea0e73))
* **blog:** add navigation bar to blog pages ([6b4ed5d](6b4ed5d9dc))
* **blog:** add subtraction and multi-digit worksheet blog posts ([dd9587f](dd9587f8cd))
* **blog:** generate worksheet examples showing scaffolding progression ([b628a34](b628a34605))
* **calendar:** add beautiful daily calendar with locale-based paper size detection ([bdca315](bdca3154f8))
* **calendar:** add i18n support and cropped abacus day numbers ([5242f89](5242f890f7))
* **card-sorting:** add activity feed notifications for collaborative mode ([1461414](1461414ef4))
* **card-sorting:** add auto-submit countdown for perfect sequences ([780a716](780a7161bc))
* **card-sorting:** add bezier curves to connecting arrows ([4d8e873](4d8e873358))
* **card-sorting:** add CardPosition type and position syncing ([656f5a7](656f5a7838))
* **card-sorting:** add collapsible stats sidebar for spectators ([6527c26](6527c26a81))
* **card-sorting:** add game mode selector UI to setup phase ([d25b888](d25b888ffb))
* **card-sorting:** add GameMode type system for multiplayer support ([fd76533](fd765335ef))
* **card-sorting:** add green border to correctly positioned cards ([16fca86](16fca86b76)), closes [#22c55](https://github.com/antialias/soroban-abacus-flashcards/issues/22c55)
* **card-sorting:** add player emoji indicators on moving cards ([3a82099](3a82099757))
* **card-sorting:** add react-spring animations for real-time sync ([c367e0c](c367e0ceec))
* **card-sorting:** add smooth transition to drop shadow ([b0b93d0](b0b93d0175))
* **card-sorting:** add spectator mode UI enhancements ([ee7345d](ee7345d641)), closes [#6366f1](https://github.com/antialias/soroban-abacus-flashcards/issues/6366f1) [#8b5cf6](https://github.com/antialias/soroban-abacus-flashcards/issues/8b5cf6)
* **card-sorting:** add team scoring UI for collaborative mode ([ed6f177](ed6f177914)), closes [#a78](https://github.com/antialias/soroban-abacus-flashcards/issues/a78) [#8b5cf6](https://github.com/antialias/soroban-abacus-flashcards/issues/8b5cf6)
* **card-sorting:** add updateCardPositions action to Provider ([f6ed4a2](f6ed4a27a2))
* **card-sorting:** auto-arrange prefix/suffix cards in corners ([4ba7f24](4ba7f24717))
* **card-sorting:** fade correctly positioned cards to 50% opacity ([7028cfc](7028cfc511))
* **card-sorting:** gentler spring animation for locked cards ([47189cb](47189cb6e7))
* **card-sorting:** implement continuous bezier curve paths ([2d93024](2d9302410f))
* **card-sorting:** improve card distribution for natural scattered look ([0b0503f](0b0503f035))
* **card-sorting:** make player emoji fill entire card background ([2e7a02c](2e7a02c9e4))
* **card-sorting:** optimize results screen for mobile ([d188789](d188789069))
* **card-sorting:** redesign setup screen with modern UI ([73cf967](73cf967492))
* **card-sorting:** scale correctly positioned cards to 50% ([222dc55](222dc555fa))
* **card-sorting:** shrink/fade cards in correct suffix as well ([8f6feec](8f6feec4f2))
* **card-sorting:** smooth spring transition from game table to results grid ([c5f39d5](c5f39d51eb))
* **card-sorting:** wrap prefix/suffix cards to multiple rows ([e3184dd](e3184dd0d4))
* complete 3D enhancement integration for all three proposals ([5ac55cc](5ac55cc149))
* convert operator selection to checkboxes with required validation ([c997c4a](c997c4a7ba))
* create unified difficulty interface with 2-tab selector ([0b7382f](0b7382f1b6))
* **create-room:** replace hardcoded game grid with dynamic Radix Select dropdown ([83d0ba2](83d0ba26f5))
* **create:** add worksheet creator card to hub page ([c84d712](c84d7122f3))
* dynamic day-of-month favicon using subprocess pattern ([4d0795a](4d0795a9df))
* dynamically crop favicon to active beads for maximum size ([5670322](567032296a))
* enable 3D enhancement on hero/open MyAbacus modes ([37e330f](37e330f26e))
* enable production source maps for easier debugging ([d992e98](d992e98d77))
* **flashcards:** add live preview functionality ([b38bec8](b38bec814b))
* **games:** add autoplay and improve carousel layout ([9f51edf](9f51edfaa9))
* **games:** add horizontal scroll support to carousels ([a224abb](a224abb6f6))
* **games:** add rotating games hero carousel ([24231e6](24231e6b2e))
* handle cascading borrows in borrowing hints ([3e1b51b](3e1b51bd84))
* hide easter egg hint until first discovery ([c2c7153](c2c71531ae))
* **homepage:** responsive 2-column layout with data attributes ([ad33056](ad33056b12))
* **i18n:** add dynamic locale switching without page reload ([fe9bfea](fe9bfeabf9))
* **i18n:** add global language selector to navigation ([0506360](0506360117))
* **i18n:** add homepage translations for all supported languages ([8c9d35a](8c9d35a3b4))
* **i18n:** add internationalization for all create pages ([b080970](b080970d76))
* **i18n:** add Old High German (goh) language support ([b334a15](b334a15255))
* **i18n:** add translations for addition worksheet creator ([2bf645a](2bf645a30c))
* **i18n:** add worksheet translations for all languages ([6acd15a](6acd15aab8))
* **i18n:** complete Old High German translations for all locales ([0b06a1c](0b06a1ce00))
* **i18n:** internationalize games page and tutorial content ([4253964](4253964af1))
* **i18n:** internationalize homepage with English translations ([40cff14](40cff143c7))
* **i18n:** migrate from react-i18next to next-intl ([9016b76](9016b76024))
* **i18n:** update games page hero section copy ([6333c60](6333c60352))
* implement borrowing hints arrow visualization ([b2f875c](b2f875c5a5))
* implement borrowing hints visual guidance ([89b8f98](89b8f98662))
* implement full-screen mobile hamburger menu with portal ([615cd28](615cd28829))
* implement lazy loading for worksheet preview with cursor pagination ([2a7d67d](2a7d67db58))
* implement light/dark theme system with semantic tokens ([210a014](210a014699))
* implement two-column landscape layout with smart viewport-based flexbox ([b57458b](b57458b039))
* improve shared worksheet viewer UX and multi-page support ([1c10a82](1c10a82c78))
* improve worksheet preview placeholder with cartoonish grid layout ([57fb99a](57fb99af63))
* install embla-carousel-autoplay for games carousel ([946e5d1](946e5d1910))
* install embla-carousel-react for player profile carousel ([642ae95](642ae95738))
* internationalize guide page with 6 languages ([e9c320b](e9c320bb10))
* internationalize tutorial player ([26d41cf](26d41cfd05))
* make 404 page abacus hero-sized and responsive ([41de252](41de25238f))
* make mobile menu more responsive with larger touch targets ([3ad244f](3ad244f2d3))
* make resize handle grab tab fully draggable with rounded corners ([be40f70](be40f70bc6))
* make scaffolding and preview collapsible ([804fb1a](804fb1a2f6))
* move difficulty parameters into Smart mode ([4b66758](4b667587f8))
* move layout controls to OrientationPanel with toggles ([995966f](995966ffbc))
* operator-specific scaffolding for mixed mastery mode ([4d7d000](4d7d000046))
* optimize card sorting for mobile displays ([b443ee9](b443ee9cdc))
* optimize problem generation and add duplicate warning system ([11c46c1](11c46c1b44))
* optimize ten-frame blog examples for dark theme ([904701d](904701da2b))
* persist seed and prngAlgorithm for exact problem reproducibility ([8cb2209](8cb2209d84))
* Redesign Rithmomachia setup page with dramatic medieval theme ([6ae4d13](6ae4d13dc7))
* redesign shared worksheet viewer with read-only studio and proper error handling ([23dccc0](23dccc0ef3))
* refactor borrow scaffolding into unified UI with column alignment ([41b5c05](41b5c057ed))
* remove all easter egg hints from 404 page ([1756182](17561829ef))
* remove redundant navigation buttons from 404 page ([e5262e5](e5262e5007))
* replace static examples with live preview in display options ([4361ad3](4361ad3005))
* **rithmomachia:** add 80% opacity to guide modal when not hovered ([4a78485](4a78485d2e))
* **rithmomachia:** add CaptureContext for capture dialog state management ([d7eb957](d7eb957a8d))
* **rithmomachia:** add ghost panel preview for guide docking ([c0d6526](c0d6526d30))
* **rithmomachia:** add guide docking with resizable panels ([f457f1a](f457f1a1c2))
* **rithmomachia:** add helper piece selection for mathematical captures ([cae3359](cae3359587))
* **rithmomachia:** add helpful error messages for failed captures ([b172440](b172440a41))
* **rithmomachia:** add initial board visual to guide Overview section ([d42bcff](d42bcff0d9))
* **rithmomachia:** Add interactive playing guide modal ([3121d82](3121d8240a))
* **rithmomachia:** add number bond visualization and helper placeholders ([82d8913](82d89131f0))
* **rithmomachia:** add ratio capture example to guide ([9150b0c](9150b0c678))
* **rithmomachia:** add standalone guide page route ([3fcc79f](3fcc79fe9e))
* **rithmomachia:** add useBoardLayout hook for centralized layout calculations ([27f1c98](27f1c989d5))
* **rithmomachia:** add usePieceSelection hook for selection state management ([275f401](275f401e3c))
* **rithmomachia:** add visual board examples to Capture section ([74bc3c0](74bc3c0dcf))
* **rithmomachia:** add visual board examples to Harmony section ([1d5f01c](1d5f01c966))
* **rithmomachia:** add visual winning example to Victory section ([b7fac78](b7fac78829))
* **rithmomachia:** auto-size tab labels with react-textfit ([9fd5406](9fd54067ce))
* **rithmomachia:** cycle through valid helpers with dynamic number tooltips ([4829e41](4829e41ea1))
* **rithmomachia:** enhance capture relation UI with smooth animations ([0a30801](0a308016e9))
* **rithmomachia:** enhance Harmony section with comprehensive content ([f555856](f5558563ea))
* **rithmomachia:** enhance Pieces section with visual examples and pyramid details ([55aff82](55aff829f4))
* **rithmomachia:** enhance Pyramid section with comprehensive details ([9fde1ef](9fde1ef9e7))
* **rithmomachia:** guide defaults to docked right on open ([11f674d](11f674d542))
* **rithmomachia:** improve guide pieces section layout ([a270bfc](a270bfc0cc))
* **rithmomachia:** improve guide UX and add persistence ([b314740](b314740697))
* **rithmomachia:** improve roster status notice UX ([e27df45](e27df45256))
* **rithmomachia:** integrate roster warning into game nav ([8a11594](8a11594203))
* **rithmomachia:** make guide modal ultra-responsive down to 150px width ([0474197](04741971b2))
* **rithmomachia:** recreate original guide modal header layout ([2489695](24896957d0))
* **rithmomachia:** show capture error on hover instead of click ([339b678](339b6780f6))
* **rithmomachia:** show pyramid face numbers on hover instead of selection ([b0c4523](b0c4523c0b))
* **rithmomachia:** show pyramid face numbers when selected ([5c186f3](5c186f3947))
* **rithmomachia:** show pyramid face numbers when selected with subtle animation ([5c2ddbe](5c2ddbef05))
* **rithmomachia:** show real preview layout when dragging guide to dock ([17d2460](17d2460a87))
* **rithmomachia:** simplify guide language for clarity ([85cb630](85cb630add))
* **rithmomachia:** skip helper selection UI and auto-select first valid helper ([be2a00e](be2a00e8b3))
* **rithmomachia:** Update harmony system to classical three-piece proportions ([08c9762](08c97620f5))
* **rithmomachia:** Update to traditional board setup with 25 pieces per side ([0769eaa](0769eaaa1d))
* **rithmomachia:** use actual piece SVGs in number bond with 2.5s rotation animation ([976a7de](976a7de949))
* **room-share:** add QR code button for easy mobile joining ([349290a](349290ac6a))
* show rithmomachia turn in nav ([7c89bfe](7c89bfef9c))
* switch to royal color theme with transparent background ([944ad65](944ad6574e)), closes [#fbbf24](https://github.com/antialias/soroban-abacus-flashcards/issues/fbbf24) [#f59e0](https://github.com/antialias/soroban-abacus-flashcards/issues/f59e0) [#a855f7](https://github.com/antialias/soroban-abacus-flashcards/issues/a855f7) [#7e22](https://github.com/antialias/soroban-abacus-flashcards/issues/7e22)
* **web:** add test page for AbacusStatic RSC compatibility ([903dea2](903dea2584))
* **web:** add test page for AbacusStatic Server Component ([3588d5a](3588d5acde))
* **web:** add Typst-based preview endpoint with React Suspense ([599a758](599a758471))
* **web:** add year abacus to calendar header and make grid bolder ([867c7ee](867c7ee172)), closes [#333](https://github.com/antialias/soroban-abacus-flashcards/issues/333)
* **web:** improve calendar abacus preview styling ([8439727](8439727b15))
* **web:** optimize monthly calendar for single-page layout ([b277a89](b277a89415))
* **web:** redesign monthly calendar as single composite SVG ([8ce8038](8ce8038bae))
* **worksheets:** Add borrow notation scaffolding for subtraction ([ff161d4](ff161d4e30))
* **worksheets:** add color-coding to difficulty presets with interpolation ([b1201b8](b1201b83c0))
* **worksheets:** add customizable operands to preview ([21cda18](21cda181e4))
* **worksheets:** add diagonal-split pattern to carry boxes ([5b91809](5b9180916e))
* **worksheets:** add difficulty preset dropdown for Smart mode ([49f6c02](49f6c029f6))
* **worksheets:** add double-digit addition worksheet creator ([1a75213](1a75213df0))
* **worksheets:** add duplicate risk warnings to page selector UI ([1d8dceb](1d8dceb55b))
* **worksheets:** add foundational steps to progression path ([7e6f99b](7e6f99b78c))
* **worksheets:** add interactive 2D difficulty map with hover preview ([b92b702](b92b702223))
* **worksheets:** add ModeSelector component for Smart/Manual mode switching ([4ffd47a](4ffd47a6b6))
* **worksheets:** add operator selection and subtraction problem generation ([ab87c6e](ab87c6ebe7))
* **worksheets:** add regrouping frequency controls to Manual mode ([f060692](f06069241f))
* **worksheets:** add subtraction problem analysis and implementation plan ([a7b48a2](a7b48a2879))
* **worksheets:** add type-safe config persistence with schema versioning ([0406adc](0406adc9da))
* **worksheets:** add V3 config schema with Smart/Manual mode discrimination ([cd1b3ed](cd1b3edc15))
* **worksheets:** add visual mode badges to scaffolding summary ([eaeeae4](eaeeae4ce8))
* **worksheets:** display scaffolding attributes on separate lines with fixed button height ([cc9fff7](cc9fff7733))
* **worksheets:** enhance addition worksheets with ten-frames and refinements ([71ad300](71ad300c23))
* **worksheets:** filter operator-specific scaffolds from difficulty change descriptions ([cace1c7](cace1c75c6))
* **worksheets:** filter operator-specific scaffolds from preset summaries ([8407b07](8407b070f9))
* **worksheets:** generate discrete pages with precise sizing ([56c0227](56c0227e9f))
* **worksheets:** implement auto-save and load for worksheet settings ([186fa81](186fa81b08))
* **worksheets:** implement constrained 2D difficulty system with pedagogical zones ([c39b7f6](c39b7f6d3a))
* **worksheets:** implement true RGB color interpolation for custom difficulty ([952cffa](952cffa2d1))
* **worksheets:** implement unique place value colors for 1-6 digit problems ([65e272c](65e272c570))
* **worksheets:** improve difficulty controls and problem sizing ([aedeb45](aedeb456f1))
* **worksheets:** improve preset dropdown with descriptions and remove duplicate buttons ([852504a](852504a4fd))
* **worksheets:** improve preview error reporting ([d8b4951](d8b4951d63))
* **worksheets:** integrate subtraction scaffolding into smart difficulty mode ([15bded1](15bded1ab8))
* **worksheets:** make progressive difficulty available in both Smart and Manual modes ([54abd5d](54abd5de09))
* **worksheets:** Phase 10 - Add operator validation ([d93dfac](d93dfac461))
* **worksheets:** Phase 5 - Update typstGenerator for operator support ([b191bb9](b191bb9a82))
* **worksheets:** Phase 7 - Add operator to auto-save persistence ([01d0959](01d095942d))
* **worksheets:** Phase 8 - Update preview and example routes for operator ([0106068](010606848d))
* **worksheets:** Phase 9 - Update DisplayOptionsPreview for operator ([d5bbd78](d5bbd783b3))
* **worksheets:** pre-generate preview on server to eliminate loading flash ([02c9187](02c918713d))
* **worksheets:** redesign display options as toggle buttons ([ac3b749](ac3b749605))
* **worksheets:** reorganize orientation panel with Radix dropdown and compact layout ([f37960a](f37960aa94))
* **worksheets:** replace digit selector with Radix double-thumbed slider ([c0298cf](c0298cf65d))
* **worksheets:** restore mastery progression UI with 3-way mode selector ([26a0885](26a08859d7))
* **worksheets:** show enabled scaffolding aids instead of numeric level ([0b8b0d2](0b8b0d21c5))
* **worksheets:** show nearest presets for custom difficulty configurations ([0e3f0ae](0e3f0aed94))
* **worksheets:** simplify difficulty controls with collapsible regrouping pane ([bb363c0](bb363c0837))
* **worksheets:** update ConfigPanel with accurate page calculations ([2c0fbd9](2c0fbd9074))
* **worksheets:** update validation and generation for V3 mode-aware schema ([ada9600](ada96005f5))
* **worksheets:** use more vibrant and distinct difficulty colors ([984b75c](984b75cb94))
* **worksheets:** use scaffolding summary for all preset descriptions ([23f0f1d](23f0f1dc21))

### Bug Fixes

* **404:** reset easter egg config on page reload/close ([d6f1c13](d6f1c13317))
* **abacus-react:** add data-testid attributes back to beads for testing ([23ae1b0](23ae1b0c6f))
* **abacus-react:** correct column highlighting offset in AbacusStatic ([0641eb7](0641eb719e))
* **abacus-react:** fix animations by preventing component remounting ([be7d4c4](be7d4c4713))
* **abacus-react:** include space for numbers in viewBox calculation ([1da3358](1da3358db1))
* **abacus-react:** remove duplicate numeral rendering and fix dark mode colors ([fcbf0f5](fcbf0f5421))
* **abacus-react:** restore original AbacusReact measurements and positioning ([88c0baa](88c0baaad9))
* **abacus-react:** showNumbers prop was hardcoded to false, breaking numeral display ([de89dcd](de89dcddb3))
* add comprehensive dark mode support to Smart Difficulty controls ([a65feb7](a65feb7344))
* add currentStepEstimate to required fields in JSON schema ([0d66c54](0d66c54991))
* add light/dark mode support to tutorial tooltips and decomposition UI ([ea10249](ea10249e94))
* add missing blog dependencies to package.json ([ceefb2f](ceefb2f1bd))
* add missing color definitions to example route ([bc7ca12](bc7ca12158))
* add mode descriptions and remove double borders ([6f2f6d4](6f2f6d444c))
* add seed and prngAlgorithm fields to all Zod schema versions (V1-V4) ([1782f42](1782f427f1))
* add xmlns to AbacusStatic for Typst SVG parsing ([98cd019](98cd019d4a))
* adjust hero abacus position to avoid covering subtitle ([f03d341](f03d341314))
* align share persistence with user session logic ([72c72fc](72c72fc218))
* **arcade:** add automatic retry for version conflict rejections ([fbcde25](fbcde2505f))
* **arcade:** allow deactivating players from users who left the room ([7c1c2d7](7c1c2d7beb))
* **arcade:** implement optimistic locking in session manager ([71fd66d](71fd66d96a))
* arrow direction - go RIGHT to borrowed 10s box, not left ([fab1fb1](fab1fb10b7))
* board rotation now properly fills height in portrait mode ([b5a96ea](b5a96eaeb1))
* calculate total problems correctly in preview API ([25dfb71](25dfb71b3e))
* **card-sorting:** add border radius to outer card container ([a922eba](a922eba73c))
* **card-sorting:** add debug logging for spring animations ([d42947e](d42947eb8d))
* **card-sorting:** add missing gameMode support after hard reset ([a832325](a832325deb))
* **card-sorting:** add missing useMemo import ([949d76d](949d76d844))
* **card-sorting:** add overflow hidden to clip rounded corners ([84c66fe](84c66feec6))
* **card-sorting:** adjust connecting paths for scaled cards ([829c741](829c741e55))
* **card-sorting:** adjust game board for spectator panels ([fc5cf12](fc5cf1216f))
* **card-sorting:** adjust viewport dimensions for spectator panels ([4dce16c](4dce16cca4))
* **card-sorting:** animate cards from game board to results grid ([17d45fe](17d45fe88c))
* **card-sorting:** correct suffix card detection in auto-arrange ([d02ab59](d02ab5922c))
* **card-sorting:** enable card scaling for spectators ([6b095c3](6b095c3383))
* **card-sorting:** enable New Game button during active gameplay ([f3f6eca](f3f6eca1db))
* **card-sorting:** end drag immediately when card becomes locked ([ae45298](ae45298ec4))
* **card-sorting:** filter local player from emoji overlays on dragged cards ([dc2d94a](dc2d94aaa5))
* **card-sorting:** fix results panel layout to not cover cards ([4b4fbfe](4b4fbfef32))
* **card-sorting:** hide activity notifications in spectator mode ([5cca279](5cca279687))
* **card-sorting:** keep arrow sequence numbers upright ([79c9469](79c94699fa))
* **card-sorting:** lock correctly positioned prefix/suffix cards ([170abed](170abed231))
* **card-sorting:** lock spring positions after initial animation completes ([275cc62](275cc62a52))
* **card-sorting:** New Game now restarts with same settings instantly ([f3687ed](f3687ed236))
* **card-sorting:** only shrink/fade cards in correct prefix ([51368c6](51368c6ec5))
* **card-sorting:** preserve card positions on pause/resume ([0d8af09](0d8af09517))
* **card-sorting:** preserve rotation when starting drag ([3364144](3364144fb6))
* **card-sorting:** prevent duplicate START_GAME moves on Play Again ([a0b14f8](a0b14f87e9))
* **card-sorting:** prevent ghost movements with proper optimistic updates ([bd014be](bd014bec4f))
* **card-sorting:** prevent infinite loop when all cards are correct ([34785f4](34785f466f))
* **card-sorting:** prevent infinite loop with tolerance-based position comparison ([627b873](627b873382))
* **card-sorting:** prevent position jump when clicking rotated cards ([564a00f](564a00f82b))
* **card-sorting:** prevent replaying own movements from server ([308168a](308168a7fb))
* **card-sorting:** prevent springs from reinitializing on window resize ([30953b8](30953b8c4a))
* **card-sorting:** prevent springs from resetting after animation ([8aff60c](8aff60ce3f))
* **card-sorting:** remove hasAnimatedRef logic causing backwards animation ([a44aa5a](a44aa5a4c2))
* **card-sorting:** remove remaining reveal numbers references ([15c53ea](15c53ea4eb))
* **card-sorting:** restore prefix/suffix card shrinking visual feedback ([f5fb4d7](f5fb4d7b76))
* **card-sorting:** show only active players in team members section ([fa9f1a5](fa9f1a568f))
* **card-sorting:** smooth scale animation while dragging cards ([0eefc33](0eefc332ac))
* **card-sorting:** stabilize inferred sequence for locked cards during drag ([b0cd194](b0cd194838))
* **card-sorting:** use empty deps array for useSprings to prevent recreation ([cee399e](cee399ed15))
* **card-sorting:** use ref to track initialized state and prevent re-animation ([f389afa](f389afa831))
* **card-sorting:** use same coordinate system for game board and results ([6972fdf](6972fdf110))
* **complement-race:** prevent delivery move thrashing in steam sprint mode ([e1258ee](e1258ee041))
* configure favicon metadata and improve bead visibility ([e1369fa](e1369fa275))
* consolidate worksheet validation constants and increase MAX_PAGES to 100 ([0f3ec36](0f3ec369bf))
* copy entire packages/core and packages/templates ([0ccada0](0ccada0ca7))
* correct GPT-5 API parameters and surface actual grading errors ([2d33f35](2d33f35c4d))
* correct hero abacus scroll direction to flow with page content ([4232746](423274657c))
* correct Typst template path in Dockerfile ([4c518de](4c518decb7))
* **db:** add statement-breakpoint to worksheet_settings migration ([42e1a71](42e1a71292))
* delete existing user sessions before creating new ones ([0cced47](0cced47a0f))
* disable place value colors in subtraction borrow boxes to fix arrow layering ([b4586ba](b4586bac8e))
* **docker:** add libfuse2 and APPIMAGE_EXTRACT_AND_RUN for OpenSCAD extraction ([12490a7](12490a7083))
* **docker:** add scripts, abacus-react, and tsx for production calendar generation ([33eb90e](33eb90e316))
* **docker:** upgrade OpenSCAD to 2024.11 to fix CGAL intersection bug ([e1bcd24](e1bcd24169))
* enable page virtualization in worksheet creator ([b675f6c](b675f6c96e))
* enable virtualization for worksheet preview by limiting SSR to 3 pages ([f409e3c](f409e3c2ed))
* export worksheet schema tables from index ([6a16674](6a1667404f))
* extract pure SVG content from AbacusReact renders ([b07f1c4](b07f1c4216))
* **games:** prevent horizontal page scroll from carousel overflow ([5a8c98f](5a8c98fc10))
* **games:** smooth scroll feel for carousel wheel navigation ([f80a73b](f80a73b35c))
* **games:** use specific transition properties for smooth carousel loop ([187271e](187271e515))
* **guide:** increase abacus sizes - they were too small ([1074624](1074624b2f))
* **guide:** make abacus sizes consistent and add nav spacing ([bea4842](bea4842a29))
* **guide:** remove inner containers and tighten margins ([7e54c6f](7e54c6f4fc))
* **i18n:** add nav bar to 3D abacus creator page ([827a949](827a949216))
* **i18n:** eliminate FOUC by loading messages server-side ([4d4d930](4d4d930bd3))
* **i18n:** use useMessages() for tutorial translations ([95b0105](95b0105ca3))
* improve dark mode contrast in OrientationPanel dropdown ([f9e2343](f9e2343ffb))
* improve dark mode for orientation and page buttons ([fe9b9f9](fe9b9f9ffa))
* improve text contrast for selected dropdown items in dark mode ([8d03452](8d0345287f))
* include column posts in favicon bounding box ([0b2f481](0b2f48106a))
* increase server update debounce to 2000ms for low bandwidth ([633ff12](633ff12750))
* Integrate threshold input into Point Victory card ([b29bbee](b29bbeefca))
* **layout:** add systematic spacing for fixed nav bar ([4559fb1](4559fb121d))
* **layout:** remove wrapper, use utility class for nav spacing ([247c3d9](247c3d9874))
* make borrow notation destination boxes full height ([17307f7](17307f7e82))
* make placeholder pages match actual page dimensions ([4003c5c](4003c5ceb7))
* mark dynamic routes as force-dynamic to prevent static generation errors ([d7b35d9](d7b35d9544))
* **nav:** restrict transparent hero styling to home page only ([fab227d](fab227d686))
* **nav:** show full navigation on /games page ([d3fe6ac](d3fe6acbb0))
* page indicator not tracking scroll when showing all pages ([3d157e3](3d157e32ed))
* page indicator stuck on page 1 due to stale closure ([952ebc7](952ebc7756))
* PDF generation now respects operator and digitRange settings ([8b8dfee](8b8dfeefbd))
* position arrowhead at endpoint and increase size ([bdf28b2](bdf28b21b2))
* position shared worksheet banner below app nav ([fb3412c](fb3412c9a5))
* preserve saved seed on page reload ([64ce64b](64ce64bd35))
* prevent duplicate API calls in React StrictMode ([0d59676](0d59676b38))
* prevent modal closure when clicking tabs in AllSkillsModal ([4746e1f](4746e1f8fe))
* prevent regrouping problems in no-regrouping skills and enable progressive difficulty toggle ([59712e1](59712e1021))
* prevent skill name wrapping in mini cards with single-line ellipsis ([a463d08](a463d088d7))
* prevent undefined displayRules error in worksheet generator ([7c33d02](7c33d0246f))
* properly apply dark mode hover states in dropdown ([34553ce](34553cebf7))
* properly cycle through problem sets when exceeding unique problem space ([55d4920](55d4920167))
* **qr-button:** improve layout and z-index ([646a422](646a4228d0))
* **qr-button:** increase mini QR code size to 80px ([61ac737](61ac7378bd))
* **qr-button:** increase mini QR code to 84px ([3fae5ea](3fae5ea6fa))
* **qr-button:** make button square and increase QR size ([dc2d466](dc2d46663b))
* **qr-button:** match height of stacked buttons ([81f202d](81f202d215))
* reduce borrowing hint font size from 0.5x to 0.25x ([f5d3de2](f5d3de2309))
* reduce font size for mini skill card titles to prevent wrapping ([833b481](833b481ebb))
* reduce padding to minimize gap below last bead ([0e529be](0e529be789))
* remove all scaffolding from final mastery skills ([d7bec42](d7bec423e0))
* remove distracting parallax and wobble 3D effects ([28a2d40](28a2d40996))
* remove pages from visible set when they leave viewport ([9757449](9757449e21))
* remove redundant 'Teens minus singles' subtraction skill ([e156e87](e156e870df))
* remove wobble physics and enhance wood grain visibility ([5d97673](5d97673406))
* replace hardcoded colors with semantic tokens in HomeBlogSection ([e124096](e124096914))
* replace regex HTML parsing with deterministic bead position calculations in icon generation ([41a3707](41a3707841))
* resolve TypeScript errors blocking Docker build ([a195338](a195338ba1))
* resolve z-index layering and hero abacus visibility issues ([ed9a050](ed9a050d64))
* respect user's layout options (problemNumbers/cellBorders) in mastery mode ([e708add](e708add9f2))
* rewrite 3D stories to use props instead of CSS wrappers ([26bdb11](26bdb11237))
* **rithmomachia:** add missing i18next dependencies ([91154d9](91154d9364))
* **rithmomachia:** add missing pyramid section keys to Japanese (ja.json) ([dae615e](dae615ee72))
* **rithmomachia:** adjust error dialog sizing to prevent text clipping ([cda1126](cda1126cb0))
* **rithmomachia:** adjust roster notice position to not overlap nav ([7093223](709322373a))
* **rithmomachia:** change undock icon to pop-out arrow ([2a91748](2a91748493))
* **rithmomachia:** correct board dimensions to 16x8 and restore original layout values ([cfac277](cfac277505))
* **rithmomachia:** Correct board setup to match reference image exactly ([618e563](618e56358d))
* **rithmomachia:** correct makeMove parameter types for capture handling ([aafb64f](aafb64f3e3))
* **rithmomachia:** fix guide modal resize drift by calculating from initial state ([1bcd99c](1bcd99c949))
* **rithmomachia:** fix harmony section translation structure for hi/ja/es ([14259a1](14259a19a9))
* **rithmomachia:** fix modal resizing zoom issue ([4fa20f4](4fa20f44cb))
* **rithmomachia:** Fix TypeScript errors in playing guide modal ([4834ece](4834ece98e))
* **rithmomachia:** handle pyramid pieces in hover error tooltip ([56f3164](56f3164155))
* **rithmomachia:** implement proper board cropping and highlighting in guide ([d0a8fcd](d0a8fcdea6))
* **rithmomachia:** improve guide modal tab navigation at narrow widths ([a673177](a673177bec))
* **rithmomachia:** reconnect player assignment UI and fix setup layout ([a1a0374](a1a0374fac))
* **rithmomachia:** render guide as docked in preview panel ([190f8cf](190f8cf302))
* **rithmomachia:** show actual values in tooltips for non-helper relations ([774c6b0](774c6b0ce7))
* **rithmomachia:** show guest-friendly message when they can't fix too many players ([54bfd2f](54bfd2fac8))
* **rithmomachia:** smooth guide dragging from docked state without jump ([8f4a79c](8f4a79c9b0))
* **rithmomachia:** validate move path before showing capture error on hover ([bd49964](bd49964186))
* **room-info:** hide Leave Room button when user is alone ([5927f61](5927f61c3c))
* separate horizontal and vertical bounding box logic ([83090df](83090df4df))
* stabilize mini skill card height and fix preview updates ([4a52943](4a5294353e))
* **syntax:** correct div nesting and indentation in abacus page ([3c9ecca](3c9eccab78))
* **syntax:** remove emoji variation selector causing build error ([00aabd8](00aabd8e6b))
* tolerate OpenSCAD CGAL warnings if output file is created ([88993f3](88993f3662))
* **tutorial:** correct column validation for bead highlights ([9ba1824](9ba1824226))
* **tutorial:** expose activeGroupTargetColumn state to context ([69f759a](69f759a178))
* **tutorial:** fix overlay rendering, arrow indicators, and bead visibility ([a804316](a80431608d))
* **ui:** add wrapper div to prevent content from appearing under nav ([99f4dd5](99f4dd51e3))
* use absolute positioning for hero abacus to eliminate scroll lag ([096104b](096104b094))
* use correct Unicode minus sign (−) for subtraction operator checks ([0dd9e45](0dd9e45952))
* use curved Bezier path for borrow arrow ([9b4eb14](9b4eb14aaa))
* use dark gray for borrowing hints on colored backgrounds ([5cb346d](5cb346deee))
* use Debian base for deps stage to match runner for binary compatibility ([f8fe6e4](f8fe6e4a41))
* use default BOSL2 branch instead of non-existent v2.0.0 tag ([f4ffc5b](f4ffc5b027))
* use LAN IP instead of localhost for QR code camera uploads ([00b400a](00b400ae8a))
* use nested SVG viewBox for actual cropping, not just scaling ([440b492](440b492e85))
* use numeric cellSize for borrow box sizing in hints ([cc54176](cc54176cb1))
* use semantic tokens for nav bar transparent mode on hero ([d05c6a8](d05c6a8664))
* use subtle gray highlights for dropdown in dark mode ([8d6170a](8d6170a8c7))
* use white text for selected dropdown items in dark mode ([e1a7375](e1a73758d6))
* various game improvements and UI enhancements ([b67cf61](b67cf610c5))
* **web,docker:** add --format flag for Typst and upgrade to v0.13.0 ([19b9d7a](19b9d7a74f))
* **web:** add dynamic export to rithmomachia page ([329e623](329e623212))
* **web:** fix Typst PDF generation path resolution ([7ce1287](7ce1287525))
* **web:** generate styled-system artifacts during build ([293390a](293390ae35))
* **web:** move react-dom/server import to API route to satisfy Next.js ([00a8bc3](00a8bc3e5e))
* **web:** move tsx to production dependencies for calendar generation ([ffae9c1](ffae9c1bdb))
* **web:** prevent abacus overlap in composite calendar ([448f93c](448f93c1e2)), closes [#f0f0f0](https://github.com/antialias/soroban-abacus-flashcards/issues/f0f0f0)
* **web:** use AbacusStatic for calendar SVG generation ([08c6a41](08c6a419e2))
* **web:** use dynamic import for react-dom/server in API route ([4f93c7d](4f93c7d996))
* **web:** use nested SVG elements to prevent coordinate space conflicts ([f9cbee8](f9cbee8fcd))
* **worksheets:** actually fix dropdown button height by constraining description area ([aa9052a](aa9052a49e))
* **worksheets:** Add "Practice" difficulty profile for scaffolded regrouping mastery ([d23b606](d23b606642))
* **worksheets:** add backward compatibility for displayRules in SmartModeControls ([b956e2d](b956e2d605))
* **worksheets:** add borrowNotation and borrowingHints to DisplayRules interfaces ([3b908ac](3b908ac453))
* **worksheets:** add borrowNotation and borrowingHints to validation fallback ([3f700af](3f700af643))
* **worksheets:** add mastery mode to Zod schema validation ([003f1d1](003f1d11cc))
* **worksheets:** Add operator to preview query key and update UI labels ([97ddc7e](97ddc7ee67))
* **worksheets:** add V4 fields to preview query key for cache invalidation ([d9b54a7](d9b54a736c))
* **worksheets:** align makeEasier fallback with spec priorities ([3e56e1d](3e56e1d6b6))
* **worksheets:** align makeHarder fallback with spec priorities ([a170209](a170209b2f))
* **worksheets:** correct findNearestPreset direction logic ([878cf02](878cf02511))
* **worksheets:** correct scaffolding summary to include all conditional modes ([2797038](2797038502))
* **worksheets:** correct Typst array membership syntax for ten-frames rendering ([14b3594](14b359462f))
* **worksheets:** dynamically size grid based on actual problem digits ([130bbd4](130bbd49dd))
* **worksheets:** enable borrowNotation and borrowingHints in smart difficulty mode ([8020ee8](8020ee835e))
* **worksheets:** Fix subtraction regrouping frequency bug ([8d8e55d](8d8e55d5c4))
* **worksheets:** increase color visibility for difficulty presets ([a7412ad](a7412adbee))
* **worksheets:** increase dropdown button height to fit all content lines ([3a43149](3a43149995))
* **worksheets:** Make destination borrow box more visible ([a01fa81](a01fa818b4))
* **worksheets:** only show ten-frames row for problems that need regrouping ([8f92f5a](8f92f5a57b))
* **worksheets:** persist digitRange and manualPreset in auto-save ([c874995](c87499535a))
* **worksheets:** prevent wrong preset showing as active at custom positions ([88e929e](88e929ed63))
* **worksheets:** remove foreign key constraint to support guest users ([e6e9ec3](e6e9ec3e4f))
* **worksheets:** resolve SSR URL error and guest user foreign key constraint ([42ea8d5](42ea8d561e))
* **worksheets:** Set showBorrowNotation to false for smart mode ([e9d52ba](e9d52bab49))
* **worksheets:** show ten-frames in smart mode when rule is 'always' ([0bc8272](0bc8272830))
* **worksheets:** ten-frames not rendering in mastery mode ([b36df3a](b36df3a40c))
* **worksheets:** update display options preview to use new problem-stack signature ([258b9ac](258b9ac1b4))
* **worksheets:** use fixed height instead of min-height for dropdown button ([fe1ef8a](fe1ef8a7fc))
* **worksheets:** use imperative voice for difficulty adjustment button labels ([d991512](d99151239d))
* **worksheets:** use white text on colored backgrounds for readability ([2b7b8ec](2b7b8ecc87))
* **worksheets:** validation function was converting mastery mode to manual ([4ad687d](4ad687df73))

### Performance Improvements

* optimize Docker image size to reduce build failures ([9ca3106](9ca3106361))
* reduce retry limit from 3000 to 100 in problem generators ([08fef59](08fef59cc5))

### Code Refactoring

* begin modularizing typstHelpers.ts - extract shared components ([b42daf9](b42daf9a4b))
* **card-sorting:** remove reveal numbers feature ([ea5e3e8](ea5e3e838b))
* **card-sorting:** send complete card sequence instead of individual moves ([e4df843](e4df8432b9))
* change operator values from Unicode to alphanumeric strings ([f06a6f2](f06a6f2dcd))
* complete subtraction modularization - 793 lines → modular structure ([a769fe1](a769fe1e20))
* convert LanguageSelector to Radix UI with theme support ([515e4c4](515e4c4f98))
* convert mode selector to large tab-style interface ([8910f6a](8910f6a197))
* decouple virtualization from config source ([95f61c6](95f61c6e70))
* eliminate prop drilling with WorksheetConfigContext ([a2ab826](a2ab82620a))
* extract DifficultyPresetDropdown and MakeEasierHarderButtons ([4d1c2c1](4d1c2c1e79))
* extract OverallDifficultySlider and integrate DifficultyPresetDropdown ([783f269](783f269a2f))
* extract shared Typst problem rendering function ([d150955](d150955815))
* **games:** implement carousel, fix victories bug, add conditional stats ([82c133f](82c133f742))
* **games:** move page title to nav bar ([712ee58](712ee58e59))
* **games:** remove redundant subtitle below nav ([ad5bb87](ad5bb87325))
* **games:** remove wheel scrolling, enable overflow visible carousel ([876513c](876513c9cc))
* **layout:** make nav height truly self-referential ([9886302](98863026b7))
* move 3D abacus creator feature to separate branch ([c8aa602](c8aa602e1c))
* move large page counts to dropdown menu ([4ea4ead](4ea4ead834))
* move progressive difficulty toggle below operator section ([0425033](0425033080))
* place 'n − 1 →' text inside borrow box at top ([232e1a2](232e1a2221))
* redesign tabs to look like traditional tabs ([8f1ddf4](8f1ddf4b34))
* remove debug console.log statements ([32f51ae](32f51ae739))
* reorganize Harmony and Victory guide sections ([fb629c4](fb629c44ea))
* restructure /create page into hub with sub-pages ([b91b23d](b91b23d95f))
* **rithmomachia:** extract board and capture components (phase 2+3) ([a0a867b](a0a867b271))
* **rithmomachia:** extract CaptureErrorDialog component (Phase 2 partial) ([f0a066d](f0a066d8f0))
* **rithmomachia:** extract constants and coordinate utilities (Phase 1) ([eace0ed](eace0ed529))
* **rithmomachia:** extract guide sections into separate files ([765525d](765525dc45))
* **rithmomachia:** extract hooks (phase 5) ([324a659](324a65992f))
* **rithmomachia:** extract phase components (phase 4) ([11364f6](11364f6394))
* **rithmomachia:** extract reusable components from SetupPhase ([3abc325](3abc325ea2))
* **rithmomachia:** make setup phase UI more compact ([e55f848](e55f848a26))
* **rithmomachia:** redesign error notification with modern UI ([dfeeb0e](dfeeb0e0db)), closes [#1e293](https://github.com/antialias/soroban-abacus-flashcards/issues/1e293) [#0f172](https://github.com/antialias/soroban-abacus-flashcards/issues/0f172) [#f1f5f9](https://github.com/antialias/soroban-abacus-flashcards/issues/f1f5f9)
* **rithmomachia:** simplify capture error dialog to one-liner ([82a5eb2](82a5eb2e4b))
* **rithmomachia:** Update board setup to authoritative CSV layout ([0471da5](0471da598d))
* **rithmomachia:** update capture components to use CaptureContext ([2ab6ab5](2ab6ab5799))
* **rithmomachia:** use useBoardLayout and usePieceSelection in BoardDisplay ([0ab7a1d](0ab7a1df32))
* simplify borrowed 10s box UI and add place value colors ([42c9c9d](42c9c9dd7e))
* start page dropdown at 4 and remove 'pages' suffix ([cf7eb57](cf7eb574d4))
* use AbacusReact for dynamic Open Graph image ([9c20f12](9c20f12bac))
* use package-level cropToActiveBeads in generateDayIcon script ([b6c3d6b](b6c3d6bda4))
* use server-side loading for shared worksheets ([c9a9146](c9a9146820))
* **web:** import utility functions from abacus-react ([7228bbc](7228bbc2eb))
* **web:** move calendar generators to src/utils for proper compilation ([379698f](379698fea3))
* **web:** return calendar SVG preview with PDF generation ([14a5de0](14a5de0dfa))
* **web:** use ABACUS_THEMES instead of manual style definitions ([9f7f001](9f7f001d74))
* **web:** use client-side React rendering for live calendar preview ([f880cbe](f880cbe4bf))
* **web:** use compact prop for inline mini-abacus ([ff1d60a](ff1d60a233))
* **web:** use direct function imports instead of execSync for calendar generation ([9f1715f](9f1715f085))
* **web:** use stdin/stdout for Typst compilation ([06f68cc](06f68cc74c))
* **worksheets:** constrain display preview width ([507a39d](507a39da19))
* **worksheets:** extract client component and add debug logging ([f7e4c52](f7e4c5241e))
* **worksheets:** extract ConfigPanel helper components (Phase 1) ([3656800](3656800534))
* **worksheets:** extract shared ConfigPanel sections (Phase 2 complete) ([d27e2c0](d27e2c03bd))
* **worksheets:** extract Smart Mode controls (Phase 3 complete) ([76a6168](76a6168b00))
* **worksheets:** extract StudentNameInput component (Phase 2 - partial) ([cbe29d5](cbe29d5c54))
* **worksheets:** extract utility functions ([2e0f99f](2e0f99f98a))
* **worksheets:** Phase 4 - Extract Manual Mode controls ([4cf6fca](4cf6fcab15))
* **worksheets:** Phase 5 - Final ConfigPanel cleanup ([85db052](85db052f07))
* **worksheets:** simplify scaffolding summary with grouped frequency ([3541b79](3541b792d5))
* **worksheets:** use distance-guided discrete progression for difficulty ([bd6fadf](bd6fadf0db))

### Documentation

* **abacus-react:** add Storybook stories for AbacusStatic ([4f9dc46](4f9dc4666d))
* **abacus-react:** add Storybook stories for new features ([6a1cec0](6a1cec06a7))
* **abacus-react:** export AbacusStatic and update README ([74f2d97](74f2d97434))
* **abacus-react:** update documentation for new features ([35d8734](35d8734a3a))
* **abacus-react:** update README with /static import path for RSC ([72a4c2b](72a4c2b80c))
* add 3D enhancement documentation to README ([cc96802](cc96802df8))
* add code factoring guidelines to prevent copy-paste ([71a8ab5](71a8ab5c93))
* add critical section on never adding tsx to production dependencies ([770cfc3](770cfc3aca))
* add database migration guide and playing guide modal spec ([5a29af7](5a29af78e2))
* add deployment verification guidelines to prevent false positives ([3d8da23](3d8da2348b))
* add Storybook stories demonstrating cropToActiveBeads feature ([104f3e6](104f3e65d4))
* **blog:** update difficulty post with scaffolding examples ([191231f](191231f8ff))
* **card-sorting:** add comprehensive multiplayer plan ([008ccea](008ccead0f))
* clarify dev server management in Claude Code instructions ([e08fdfd](e08fdfd676))
* comprehensive problem generation documentation ([5304e4d](5304e4da4e))
* link problem generation docs to README graph ([1a7e81c](1a7e81c4e2))
* **rithmomachia:** Add concise one-page playing guide ([e3c1f10](e3c1f10233))
* update workflow to require manual testing before commits ([0991796](0991796f1e))
* **worksheets:** add academic publication plan for 2D difficulty system ([ca8d774](ca8d774370))
* **worksheets:** add comprehensive refactoring plan for AdditionWorksheetClient ([f2e48bb](f2e48bb8ab))
* **worksheets:** add constrained 2D difficulty system specification ([7d72865](7d72865d4d))
* **worksheets:** add two-mode system planning docs and update API route ([369b7f2](369b7f263d))

### Styles

* **abacus:** fix indentation ([847c503](847c50346f))
* fix formatting and add approved bash commands ([0c4b0c2](0c4b0c2fac))
* **rithmomachia:** improve divider styling and make tabs responsive ([88ca35e](88ca35e044)), closes [#e5e7](https://github.com/antialias/soroban-abacus-flashcards/issues/e5e7) [#9ca3](https://github.com/antialias/soroban-abacus-flashcards/issues/9ca3)
* **rithmomachia:** improve pyramid face numbers visibility and contrast ([94e5e6a](94e5e6a268)), closes [#fbbf24](https://github.com/antialias/soroban-abacus-flashcards/issues/fbbf24) [#b45309](https://github.com/antialias/soroban-abacus-flashcards/issues/b45309)
* **rithmomachia:** increase pyramid face numbers size and boldness ([7bf2d73](7bf2d730d3))

### Tests

* trigger compose-updater deployment test ([2b06aae](2b06aae394))
* verify compose-updater automatic deployment cycle ([af0552c](af0552ccd9))
2025-11-12 19:01:47 +00:00
.claude
.github/workflows
apps/web feat: add visible grab tab to worksheet panel resize handle 2025-11-12 12:52:48 -06:00
docs
nas-deployment
out
packages chore: restore stashed work from previous session 2025-11-08 14:59:40 -06:00
scripts
test_svg_inactive_beads.svg
test_svg_smaller_gaps.svg
tests
.dockerignore fix: prevent undefined displayRules error in worksheet generator 2025-11-07 13:01:54 -06:00
.gitignore
.mcp.json
.releaserc.json
ARCADE_CHARACTER_INTEGRATION_PLAN.md
ARITHMETIC_CHALLENGES_PLAN.md
CHANGELOG.md chore(release): 4.68.0 [skip ci] 2025-11-12 19:01:47 +00:00
CONTRIBUTING.md
DEPLOYMENT.md
DESIGN.md
DEVELOPMENT.md
Dockerfile fix(worksheets): ten-frames not rendering in mastery mode 2025-11-10 10:06:27 -06:00
INSTALL.md
Makefile
PLACE_VALUE_REFACTOR_PLAN.md
PRACTICE_PROBLEM_SYSTEM.md
PROGRESSIVE_INSTRUCTION_PLAN.md
README.md docs: link problem generation docs to README graph 2025-11-12 09:32:37 -06:00
REBUILD_CHECKLIST.md
demo_heaven_bead_fix.html
demo_heaven_bead_gap_fixed.html
demo_heaven_bead_gap_fixed.pdf
demo_heaven_bead_gap_fixed_linear.pdf
generate_complete_games_website.py
generate_samples.sh
guest-auth-plan.md
hero_showcase.html
package.json
pnpm-lock.yaml chore: regenerate pnpm-lock.yaml 2025-11-11 11:34:17 -06:00
pnpm-workspace.yaml
pyproject.toml
pytest.ini
requirements-api.txt
requirements.txt
server-persistence-plan.md
setup-dev.sh
test-templates-integration.js
test_active_bead_gaps.html
test_active_bead_gaps_fixed.html
test_active_heaven_beads.html
test_adjacent_fixed.html
test_adjacent_spacing.html
test_adjacent_spacing.pdf
test_adjacent_spacing_linear.pdf
test_all_adjacent_spacing.html
test_all_digits_physical.html
test_all_digits_physical.pdf
test_all_digits_physical_linear.pdf
test_alternating_colors.html
test_alternating_colors_fixed.html
test_animations.html
test_arithmetic_complete.html
test_arithmetic_complete.pdf
test_balanced_gaps.html
test_beautiful_ui.html
test_beautiful_ui.pdf
test_better_spacing.html
test_better_spacing.pdf
test_better_spacing_linear.pdf
test_borderless_input.html
test_clean.html
test_closer_gaps.html
test_colorblind.html
test_companion.pdf
test_complete_guide.html
test_complete_guide.pdf
test_debug_prefix.html
test_debug_prefix.pdf
test_equal_gaps.html
test_equal_gaps.pdf
test_equal_gaps_final.html
test_equal_gaps_linear.pdf
test_expanded_heaven_gap.html
test_final_input_and_cards.html
test_final_larger_abacus.html
test_fixed_syntax.html
test_heaven_above_bar.html
test_heaven_above_bar.pdf
test_heaven_above_bar_linear.pdf
test_heaven_beads.html
test_heaven_beads.pdf
test_heaven_beads_active.html
test_heaven_beads_fixed.html
test_heaven_beads_fixed.pdf
test_heaven_beads_fixed_linear.pdf
test_heaven_beads_linear.pdf
test_heaven_earth_colors.html
test_heaven_earth_spans.html
test_heaven_way_up_top.html
test_higher_heaven_beads.html
test_improved_print.html
test_improved_print.pdf
test_inactive_separation.html
test_individual_digit_colors.html
test_large_cards_fixed_input.html
test_larger_abacus.html
test_larger_sorting_game.html
test_long_number_colors.html
test_maximum_heaven_gap.html
test_maximum_heaven_gap.pdf
test_maximum_heaven_gap_linear.pdf
test_memory_fix.html
test_memory_fix.pdf
test_memory_grid_hiding.html
test_memory_grid_hiding.pdf
test_memory_partial_hiding.html
test_memory_partial_hiding.pdf
test_mnemonic_colors.html
test_monochrome_no_spans.html
test_multiple_place_values.html
test_new_challenge_layout.html
test_pdf_bead_gaps.pdf
test_pdf_bead_gaps_fixed.pdf
test_pdf_bead_gaps_fixed_linear.pdf
test_pdf_bead_gaps_linear.pdf
test_pdf_direct.html
test_pdf_direct.pdf
test_pdf_inactive_beads.pdf
test_pdf_inactive_beads_linear.pdf
test_pdf_smaller_gaps.pdf
test_pdf_smaller_gaps_linear.pdf
test_penalty_scoring.html
test_physical_abacus_logic.html
test_place_value_colors.html
test_place_value_colors_fixed.html
test_prefix_conflicts.html
test_prefix_conflicts.pdf
test_print_fix.html
test_print_fix.pdf
test_print_fixed.html
test_print_fixed.pdf
test_relative_to_reckoning_bar.html
test_rod_bounds.html
test_rod_bounds.pdf
test_rod_bounds_hidden.html
test_rod_bounds_linear.pdf
test_scaling.html
test_sectioned_layout.html
test_sectioned_layout.pdf
test_simple_equal_gaps.html
test_smart_input.html
test_sorting_buttons_fix.html
test_tutorial_complete.html
test_tutorial_complete.pdf
test_viewport_aware_cards.html
test_welcome_intro.html
test_welcome_intro.pdf
test_zero_hidden.html
turbo.json

README.md

🧮 Soroban Flashcard Generator

Master the Ancient Art of Mental Math

Colorful Soroban showing 987,654,321
Transform numbers into beautiful, interactive learning experiences

The ultimate toolkit for learning soroban (Japanese abacus) calculation
🎯 Perfect for students, teachers, and mental math enthusiasts
🚀 From zero to calculation ninja in record time
🎨 Stunning visuals meet ancient wisdom


Create gorgeous flashcards, interactive web games, and immersive quizzes that make learning soroban addictive. Whether you're teaching a classroom or mastering mental math yourself, this generator transforms traditional number learning into a vibrant, engaging adventure.

🔥 What makes this special:

  • Visual perfection: Crystal-clear soroban representations with authentic bead positioning
  • Game-changing interactivity: Memory challenges, sorting games, and smart input systems
  • Universal compatibility: Generate PDFs, web apps, PNGs, SVGs - whatever you need
  • Colorblind-friendly: Thoughtfully designed palettes ensure everyone can learn
  • Instant deployment: One command creates complete learning environments

Experience the Beauty of Mathematical Precision

Nature palette soroban
🌿 Nature Palette
Earth tones for focused learning
Colorblind-friendly soroban
👁️ Universal Access
Colorblind-friendly brilliance
Mnemonic color soroban
🧠 Memory Master
Colors that stick in your mind

Each bead precisely positioned, every color carefully chosen, all interactions thoughtfully designed.


Examples

Soroban showing 123
Soroban (Front)
Numeral 123
Numeral (Back)
Place-value colored 456
Place-Value Colors
Colored numeral 456
Colored Numerals

Bead Shapes

Diamond beads
Diamond (Realistic)
Circle beads
Circle (Traditional)
Square beads
Square

Layouts and Options

6 cards per page
6 Cards Per Page
12 cards per page
12 Cards Per Page
Counting by 5s
Skip Counting by 5s
Hidden inactive beads
Hidden Inactive Beads

Printing Features

Cutting guides
Cutting Guides
Full-page guides for accurate card separation
Cutting and registration marks
With Registration Marks
Alignment marks for duplex printing verification

Output Formats

📱 Interactive Web Flashcards (--format web)

Generate self-contained HTML files with advanced interactive features:

# Generate interactive web flashcards
python3 src/generate.py --format web --range 0-99 --output flashcards.html

# Try the quiz mode
python3 src/generate.py --format web --range 0-50 --shuffle

Web Features:

  • 🃏 Digital Flashcards: Hover to reveal numbers, click to flip cards
  • 🧠 Timed Quiz Mode: Configurable display times (0.5-10 seconds), multiple card counts (5, 10, 15, 25, All)
  • 📊 Smart Scoring: Fair scoring algorithm, progress tracking, detailed results
  • 🎯 Sorting Challenge: Drag-and-drop number sorting with gap-filling logic
  • 🎮 Matching Pairs: Memory game matching abacus patterns with numerals
    • Single & two-player modes with competitive scoring
    • Multiple grid sizes (3×4, 4×4, 4×6, 5×6) for different skill levels
    • Turn-based timers and player indicators for multiplayer games
    • Efficiency-based medal system (Gold/Silver/Bronze achievements)
  • 📱 Responsive Design: Works on desktop, tablet, and mobile
  • 🖨️ PDF Integration: Automatically suggests high-quality PDF format when printing is attempted
  • Accessible: Keyboard navigation, semantic HTML, ARIA labels
  • 🎨 Full Customization: All color schemes, bead shapes, and display options supported

📄 Vector PDF (--format pdf)

High-quality vector PDFs optimized for duplex printing:

# Standard PDF with cut marks
python3 src/generate.py --format pdf --range 0-99 --cut-marks --registration

PDF Features:

  • Pure vector graphics for crisp output at any scale
  • Duplex printing alignment with registration marks
  • Cutting guides for precise card separation
  • Embedded fonts ensure consistent output

🖼️ PNG/SVG Images (--format png, --format svg)

Individual card images for digital use or custom layouts:

# Generate PNG cards at high resolution
python3 src/generate.py --format png --range 1-10 --dpi 300 --transparent

# Generate SVG cards for web use
python3 src/generate.py --format svg --range 0-99 --separate

Image Features:

  • High-resolution PNG (configurable DPI)
  • Scalable SVG with embedded CSS
  • Transparent backgrounds supported
  • Separate front/back organization

Features

🎓 Learning & Teaching Tools

  • 🧠 Interactive Quiz Mode: Timed flashcard quizzes with configurable display times and scoring
  • 🎯 Sorting Challenges: Drag-and-drop number sorting games with intelligent gap-filling
  • 🎮 Matching Pairs Game: Memory challenges matching soroban patterns with numerals
    • Single Player: Focus mode with efficiency scoring and medal achievements
    • Two Player: Competitive multiplayer with turn timers and player tracking
    • Adaptive Difficulty: 4 grid sizes (6-30 pairs) scaling with skill level
    • Smart Validation: Prevents invalid moves, guides learning progression
  • 📊 Progress Tracking: Real-time feedback, scoring, and performance analytics
  • 📱 Multi-Device Support: Responsive design works on desktop, tablet, and mobile

🎨 Visual Customization

  • 🎯 Pure vector graphics - Crisp output at any scale, all formats
  • 🎨 Color schemes - Educational colors for place-value, heaven-earth, alternating
  • 🌈 Colored numerals - Match numeral colors to bead colors for reinforcement
  • 🔷 Customizable beads - Diamond (realistic), circle, or square shapes
  • 🔀 Minimalist mode - Hide inactive beads for cleaner displays

📋 Flexible Content

  • 🔢 Flexible ranges - Any range (0-9999+) or custom lists (1,2,5,10,20,50,100)
  • 📈 Skip counting - Count by 2s, 5s, 10s, or any increment
  • 🎲 Shuffling - Randomize with optional seeds for reproducible builds
  • 📊 Smart scaling - Automatic column management and font sizing

🖨️ Print & Production

  • 📏 Configurable layouts - 1 to 30+ cards per page with automatic scaling
  • 🖨️ Duplex printing ready - Automatic front/back alignment for double-sided printing
  • ✂️ Cutting guides - Full-page guides and registration marks for accurate separation
  • 🔤 Embedded fonts - Bundled DejaVu Sans for consistent cross-platform output

🔧 Integration & Formats

  • 📱 Web HTML - Self-contained interactive flashcards with quiz modes
  • 📄 Vector PDF - High-quality print-ready documents
  • 🖼️ PNG/SVG - Individual card images for digital use
  • 📦 Node.js/TypeScript - Clean API for web applications
  • 🌐 REST API - FastAPI server for web services
  • ⚙️ CLI Interface - Powerful command-line tool with extensive options

Quick Start

Prerequisites

  • macOS (tested on latest versions)
  • Python 3 (included with macOS)
  • Typst (PDF generation engine)
  • qpdf (optional, for linearization)

Installation

# Install dependencies
make install

# Or manually:
brew install typst qpdf
pip3 install pyyaml

Generate Flashcards

# Generate default set (0-9)
make

# Generate from config file
python3 src/generate.py --config config/0-99.yaml

# Custom range
python3 src/generate.py --range 0-99

# Custom list of numbers
python3 src/generate.py --range "1,2,5,10,20,50,100"

# With shuffle
python3 src/generate.py --range 0-99 --shuffle --seed 42

📚 Component Documentation

Explore our comprehensive component documentation and interactive examples:

🎮 Interactive Learning Games

The web format includes three immersive learning experiences designed to make soroban mastery engaging and fun:

🧠 Memory Quiz Challenge

Test your number recognition skills with timed flashcard quizzes:

  • Adaptive Timing: 0.5-10 second display windows
  • Flexible Difficulty: 5, 10, 15, 25 cards or full deck
  • Smart Scoring: Accounts for difficulty and accuracy
  • Progress Tracking: Real-time feedback and performance analytics

🎯 Sorting Master

Develop number sense through drag-and-drop sorting challenges:

  • Intelligent Gap-Filling: Place cards in the correct sequence
  • Visual Feedback: Immediate validation and hints
  • Scalable Difficulty: Choose your challenge level
  • Educational Design: Reinforces number relationships

🎮 Matching Pairs Arena

Memory game combining visual pattern recognition with numerical understanding:

Single Player Mode:

  • 🏆 Medal System: Gold (≤1.5× pairs), Silver (≤2× pairs), Bronze (≤3× pairs)
  • 📏 Four Grid Sizes: 3×4 (6 pairs), 4×4 (8 pairs), 4×6 (12 pairs), 5×6 (15 pairs)
  • Efficiency Scoring: Rewards optimal play and quick thinking
  • 🎯 Smart Validation: Only allows valid matches (abacus ↔ numeral)

Two Player Mode:

  • 👥 Competitive Multiplayer: Turn-based gameplay with score tracking
  • ⏱️ Turn Timers: Optional 15s/30s/60s time limits with visual countdown
  • 🏆 Player Indicators: Color-coded badges show who found each match
  • 🚀 First Move Grace: Timer waits for first card flip to begin counting
  • 🎨 Visual Clarity: De-emphasized matched cards guide continued play

Technical Features:

  • 📱 Responsive Design: Scales perfectly on all devices without scrolling
  • 🔄 One-Click Start: Integrated mode and grid selection
  • 🎨 Kid-Friendly UX: Clear visual feedback prevents confusion
  • Accessible: Keyboard navigation and semantic HTML

Configuration

Using Configuration Files

Create a YAML or JSON file with your preferences:

range: "0-99"
cards_per_page: 6
paper_size: "us-letter"
orientation: "portrait"
margins:
  top: "0.5in"
  bottom: "0.5in"
  left: "0.5in"
  right: "0.5in"
gutter: "5mm"
show_cut_marks: true
show_registration: true
font_family: "DejaVu Sans"
font_size: "48pt"
columns: auto
show_empty_columns: false
shuffle: false
seed: 42 # For deterministic shuffling

Command-Line Options

python3 src/generate.py [OPTIONS]

Options:
  --config, -c FILE           Configuration file (JSON or YAML)
  --range, -r RANGE          Number range (e.g., "0-99") or list (e.g., "1,2,5")
  --step, -s N               Step/increment for ranges (e.g., 2 for even numbers)
  --cards-per-page N         Cards per page (default: 6, supports 1-30+)
  --paper-size SIZE          Paper size (default: us-letter)
  --orientation ORIENT       Page orientation (portrait/landscape)
  --margins T,R,B,L          Margins (e.g., "0.5in,0.5in,0.5in,0.5in")
  --gutter SIZE              Space between cards (default: 5mm)
  --shuffle                  Shuffle the numbers
  --seed N                   Random seed for deterministic shuffle
  --cut-marks                Show cut marks
  --registration             Show registration marks for alignment
  --font-family FONT         Font family (default: DejaVu Sans)
  --font-size SIZE           Font size (default: 48pt, auto-scales)
  --columns N                Soroban columns (auto or number)
  --show-empty-columns       Show leading empty columns
  --hide-inactive-beads      Hide inactive beads (show only active)
  --bead-shape SHAPE         Bead shape (diamond/circle/square)
  --color-scheme SCHEME      Color scheme (monochrome/place-value/heaven-earth/alternating)
  --colored-numerals         Color numerals to match bead colors
  --scale-factor N           Manual scale adjustment (0.1-1.0, default: 0.9)
  --output, -o FILE          Output PDF path (default: out/flashcards.pdf)
  --linearize                Create linearized PDF (default: true)

Soroban Representation

The soroban is rendered with:

  • 1 heaven bead (worth 5) per column
  • 4 earth beads (worth 1 each) per column
  • Active beads shown in black, moved toward the reckoning bar
  • Inactive beads shown in light gray, away from the bar
  • Columns represent place values (ones, tens, hundreds, etc.)

Column Display Options

  • columns: auto - Shows minimal columns needed
  • columns: 3 - Always shows 3 columns (e.g., for 0-999)
  • show_empty_columns: true - Shows leading zeros
  • show_empty_columns: false - Suppresses leading zeros

Print Settings

For Best Results

  1. Paper: US Letter (8.5" × 11") or A4
  2. Margins: Default 0.5" works with most printers
  3. Duplex: Long-edge binding, automatic duplex
  4. Cut marks: Enable with --cut-marks for easier cutting
  5. Registration: Enable with --registration for alignment verification

Duplex Printing

The PDFs are specifically formatted for double-sided printing:

  • Odd pages (1, 3, 5...): Soroban bead diagrams (front of cards)
  • Even pages (2, 4, 6...): Arabic numerals (back of cards)
  • Pages are properly ordered for long-edge binding (standard duplex)
  • Back sides are horizontally mirrored to align correctly when flipped

To print double-sided:

  1. Open the PDF in your viewer
  2. Select Print → Two-Sided → Long-Edge Binding
  3. The printer will automatically place numerals on the back of each soroban diagram

Sample Configurations

  • config/default.yaml - Basic 0-9 set
  • config/0-99.yaml - Two-digit numbers with cut marks
  • config/3-column-fixed.yaml - Three-digit numbers, fixed width
  • config/minimal-beads.yaml - Hide inactive beads for clarity
  • config/circle-beads.yaml - Traditional circular beads
  • config/place-value-colors.yaml - Place value color coding
  • config/colored-numerals.yaml - Colored numerals matching beads
  • config/count-by-5s.yaml - Skip counting by 5s

Project Structure

soroban-abacus-flashcards/
├── src/
│   ├── generate.py            # Main CLI tool (all formats)
│   ├── web_generator.py       # Interactive web flashcards with quiz modes
│   ├── bridge.py              # Node.js integration bridge
│   ├── api.py                 # FastAPI REST server
│   └── generate_examples.py   # Example generation utilities
├── templates/
│   └── flashcards.typ         # Typst template with soroban rendering
├── config/                    # Preset configurations
│   ├── default.yaml           # Basic 0-9 set
│   ├── 0-99.yaml             # Two-digit numbers with cut marks
│   ├── place-value-colors.yaml # Educational color coding
│   ├── colored-numerals.yaml  # Matching numeral colors
│   ├── minimal-beads.yaml     # Hide inactive beads
│   ├── circle-beads.yaml      # Traditional circular beads
│   ├── count-by-5s.yaml       # Skip counting by 5s
│   └── 3-column-fixed.yaml    # Fixed-width three-digit display
├── tests/
│   ├── test_generation.py     # Core generation tests
│   ├── test_web_generation.py # Web format tests
│   ├── test_quiz_functionality.py # Interactive quiz tests
│   ├── test_config.py         # Configuration parsing tests
│   └── test_visual.py         # Visual output validation
├── client/                    # Integration libraries
│   ├── node/                  # Node.js/TypeScript wrapper
│   ├── typescript/            # Browser TypeScript client
│   └── browser/               # Browser-based implementation
├── fonts/
│   ├── DejaVuSans.ttf        # Bundled font
│   └── DejaVuSans-Bold.ttf   # Bold variant
├── docs/
│   └── images/               # Example images for README
├── out/                      # Generated outputs (created on first run)
│   ├── *.pdf                # PDF flashcards
│   ├── *.html               # Interactive web flashcards
│   ├── png/                 # PNG card images
│   └── svg/                 # SVG card images
├── Makefile                  # Build automation
└── README.md                # This file

Design Notes

Soroban Number Mapping

Numbers are decomposed into heaven (5s) and earth (1s) beads:

  • 7 = 1 heaven bead (5) + 2 earth beads (2×1)
  • 23 = Tens: 4 earth beads (4×1), Ones: 3 earth beads (3×1)
  • 156 = Hundreds: 1 heaven + 0 earth, Tens: 1 heaven + 0 earth, Ones: 1 heaven + 1 earth

Duplex Alignment

  • Front cards are laid out left-to-right, top-to-bottom
  • Back cards are mirrored horizontally for long-edge binding
  • Registration marks (optional) help verify alignment
  • Safe margins ensure content isn't lost when cutting

Vector Graphics

All elements are rendered as vectors using Typst's drawing primitives:

  • Beads are vector circles with stroke
  • Rods and reckoning bar are vector rectangles
  • No rasterization ensures crisp output at any scale

Troubleshooting

"typst command not found"

Run make install or brew install typst

"qpdf command not found"

PDF will generate but won't be linearized. Install with brew install qpdf

Fonts not embedding

Ensure the fonts/ directory contains the DejaVu TTF files

Misaligned duplex printing

  • Check printer duplex settings (should be long-edge)
  • Enable registration marks with --registration
  • Verify margins match your printer's capabilities

Examples

Quick Start Examples

# Generate interactive web flashcards (try the quiz!)
python3 src/generate.py --format web --range 0-20 --shuffle

# Generate print-ready PDF with cutting guides
python3 src/generate.py --format pdf --range 0-99 --cut-marks --registration

# Generate high-res PNG cards for digital use
python3 src/generate.py --format png --range 1-10 --dpi 300 --transparent

# Generate place-value colored cards for teaching
python3 src/generate.py --format web --range 0-50 \
  --color-scheme place-value --colored-numerals

# Generate minimal-style cards (hide inactive beads)
python3 src/generate.py --format web --range 0-25 --hide-inactive-beads

# Generate skip-counting practice (count by 5s)
python3 src/generate.py --format web --range 0-100 --step 5

Development & Testing

# Generate samples
make samples

# Quick test
make test

# Clean all outputs
make clean

# Show help
make help

Node.js/TypeScript Integration

Installation

cd client/node
npm install

Usage Example

import { SorobanGenerator } from "./soroban-generator-bridge";

async function generateFlashcards() {
  const generator = new SorobanGenerator();

  // Generate with clean function interface - no CLI args!
  const result = await generator.generate({
    range: "0-99",
    cardsPerPage: 6,
    colorScheme: "place-value",
    coloredNumerals: true,
    showCutMarks: true,
  });

  // Get PDF as Buffer
  const pdfBuffer = Buffer.from(result.pdf, "base64");

  // Save to file or send to client
  await fs.writeFile("flashcards.pdf", pdfBuffer);
}

Express.js Integration

import express from "express";
import { SorobanGenerator } from "./soroban-generator-bridge";

const app = express();
const generator = new SorobanGenerator();

app.post("/api/flashcards", async (req, res) => {
  // Direct function call - no shell commands!
  const result = await generator.generate(req.body);
  const pdfBuffer = Buffer.from(result.pdf, "base64");

  res.contentType("application/pdf");
  res.send(pdfBuffer);
});

API Reference

The SorobanGenerator class provides:

  • generate(config) - Returns { pdf: string, count: number, numbers: number[] }
  • generateBuffer(config) - Returns PDF as Node.js Buffer
  • initialize() - Start persistent Python process for better performance
  • close() - Clean up Python process

All methods use clean TypeScript interfaces with proper types - no shell command building required!

REST API Server

For web services and remote generation:

Start the API Server

# Install FastAPI dependencies
pip3 install fastapi uvicorn

# Start the development server
python3 src/api.py
# or
uvicorn src.api:app --reload --host 0.0.0.0 --port 8000

API Endpoints

# Generate flashcards via POST
curl -X POST "http://localhost:8000/generate" \
  -H "Content-Type: application/json" \
  -d '{
    "range": "0-99",
    "format": "web",
    "color_scheme": "place-value",
    "cards_per_page": 6
  }'

# Health check
curl http://localhost:8000/health

# OpenAPI documentation available at:
# http://localhost:8000/docs (Swagger UI)
# http://localhost:8000/redoc (ReDoc)

API Features

  • 🔄 All formats supported: PDF, PNG, SVG, and interactive web HTML
  • 📊 JSON responses: Base64-encoded files with metadata
  • 🛡️ CORS enabled: Ready for web app integration
  • 📚 Auto documentation: OpenAPI/Swagger specs included
  • High performance: Optimized for production workloads

Development

📦 NPM Package Publishing

The @soroban/abacus-react package is automatically published to both npm and GitHub Packages using semantic versioning. To trigger a release:

# For new features (minor version bump)
git commit -m "feat(abacus-react): add new bead animation system"

# For bug fixes (patch version bump)
git commit -m "fix(abacus-react): resolve gesture detection issue"

# For breaking changes (major version bump)
git commit -m "feat(abacus-react)!: change callback signature"

Important: Use the (abacus-react) scope in commit messages to trigger package releases. Regular commits without this scope only affect the monorepo versioning.

📖 Full details: See CONTRIBUTING.md for complete workflow documentation.

Updating Example Images

If you make changes that affect the visual output, please update the example images:

# Regenerate all example images
make examples

# Or use the update script
./scripts/update-examples.sh

# Verify examples are up to date (CI will also check this)
make verify-examples

The CI pipeline will automatically verify that example images are up to date with the code.

Running Tests

The project includes comprehensive test coverage for all functionality:

# Run all tests
python3 -m pytest tests/ -v

# Test specific functionality
python3 -m pytest tests/test_quiz_functionality.py -v  # Interactive quiz features
python3 -m pytest tests/test_web_generation.py -v     # Web format generation
python3 -m pytest tests/test_generation.py -v         # Core generation logic
python3 -m pytest tests/test_config.py -v             # Configuration parsing
python3 -m pytest tests/test_visual.py -v             # Visual output validation

# Quick test build
make test

# Generate all samples
make samples

# Full CI verification (ensures examples are up to date)
make verify-examples

Test Coverage

  • 🧠 Quiz Functionality: Interactive quiz modes, scoring algorithms, progress tracking
  • 🎯 Sorting Challenges: Drag-and-drop mechanics, gap-filling logic, user interactions
  • 🌐 Web Generation: HTML output, CSS styling, JavaScript functionality
  • 📄 PDF Generation: Vector rendering, duplex alignment, cutting guides
  • 🖼️ Image Output: PNG/SVG generation, transparency, resolution scaling
  • ⚙️ Configuration: YAML/JSON parsing, validation, command-line interface
  • 🎨 Visual Output: Color schemes, bead shapes, layout consistency

License

MIT License - see LICENSE file for details.

This project uses DejaVu Sans font (included), which is released under a free license.

📚 Additional Documentation

Worksheet Generator

Location: apps/web/src/app/create/worksheets/ Overview: apps/web/src/app/create/worksheets/README.md

Create customizable math worksheets with progressive difficulty, problem space validation, and Typst-powered PDF generation.

Key Documentation:

Abacus React Component

Package: @soroban/abacus-react Documentation: packages/abacus-react/README.md Storybook: Interactive Examples

React component library for rendering interactive and static abacus visualizations.

🚀 Active Development Projects

Speed Complement Race Port (In Progress)

Status: Planning Complete, Ready to Implement Plan Document: apps/web/COMPLEMENT_RACE_PORT_PLAN.md Source: packages/core/src/web_generator.py (lines 10956-15113) Target: apps/web/src/app/games/complement-race/

A comprehensive port of the sophisticated Speed Complement Race game from standalone HTML to Next.js. Features 3 game modes, 2 AI personalities with 82 unique commentary messages, adaptive difficulty, and multiple visualization systems.