Problem:
- big.js precision was lost because clicks used browser's native SVG hit-testing
- Individual path onClick handlers rely on browser's 32-bit float precision
- Vatican City clicks were still limited to "one pixel works"
Solution:
- Add onClick handler to SVG container (when pointer locked)
- Use precise Big.js cursor position (cursorPositionRef) for click detection
- Convert to SVG coordinates and use isPointInFill() with precise point
- Choose smallest region when multiple regions contain the click point
- Disable pointerEvents on individual paths when pointer locked
This bypasses browser's limited SVG hit-testing and uses our precise
cursor tracking to determine what was clicked.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
The scaleX and scaleY variables were still needed for region bounding
box calculations later in the code. Added .toNumber() conversions from
the Big.js versions to regular numbers for these calculations.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Problem:
- JavaScript's 64-bit floats lose precision with ultra-small movements
- Vatican City (~0.05px) requires 0.03x dampened cursor (0.001px precision)
- At 1000x zoom with tiny deltas, floating-point rounding causes "one pixel works"
- Coordinate transformations compound precision loss
Solution:
- Install big.js for arbitrary-precision decimal arithmetic
- Use Big for cursor position tracking (cursorPositionRef stores Big values)
- Use Big for movement delta calculations (e.movementX * 0.03)
- Use Big for container → SVG coordinate transformations
- Use Big for zoom viewport calculations at extreme zoom levels (1000x)
- Convert to numbers only when interfacing with DOM/display
Technical details:
- cursorPositionRef: { x: Big; y: Big } instead of { x: number; y: number }
- Cursor deltas: new Big(e.movementX).times(currentMultiplier)
- SVG coordinates: cursorXBig.minus(offset).times(scale).plus(viewBoxX)
- Zoom viewport: new Big(viewBoxWidth).div(testZoom)
- Maintains full precision through entire calculation chain
This should allow Vatican City to be clickable from multiple cursor positions
instead of requiring exact pixel-perfect positioning.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
## [4.68.0](https://github.com/antialias/soroban-abacus-flashcards/compare/v4.67.1...v4.68.0) (2025-11-20)
### 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 'auto' option for scaffolding to defer to mastery progression ([a945a62](a945a620c4))
* add 3D printing support for abacus models ([dafdfdd](dafdfdd233))
* add adaptive zoom magnifier for Know Your World map ([1e8846c](1e8846cdb1))
* 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 auto scaffolding mode with visual feedback and override notices ([b62db5a](b62db5a323))
* 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 continent filtering to Know Your World game ([7bb03b8](7bb03b8409))
* 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 layout preview component for orientation selection ([8df62d6](8df62d6a45))
* add dynamic operator icon to tab navigation ([b6ff995](b6ff995a8c))
* add exponential zoom scaling for sub-pixel regions ([101213b](101213ba1c))
* add fancy QR codes with abacus logo throughout app ([ebcabf9](ebcabf9bb9))
* 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 interactive world map continent selector ([245005c](245005c8ec))
* add Know Your World geography quiz game ([25e24a7](25e24a7cbc))
* add mobile drawer and detailed summary for shared worksheets ([0a35e70](0a35e70e28))
* add ngrok tunnel to dev server for HTTPS testing ([ab2bfde](ab2bfde9c2))
* add per-country coloring and individual region clicks to continent selector ([2e9f409](2e9f409f26))
* add per-page worksheet generation API ([6398fbe](6398fbead9))
* add per-player stats tracking system ([613301c](613301cd13))
* add Pointer Lock API for precision mode to prevent edge issues ([4d5953d](4d5953d034))
* add precision controls for tiny regions in Know Your World ([3bf127f](3bf127f344))
* 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 responsive mobile drawer with draggable settings button ([fc1d7fc](fc1d7fcbd6))
* add responsive page button layout with dynamic dropdown ([3f33cd1](3f33cd1924))
* add shared worksheet viewer with open-in-editor functionality ([4b8b3ee](4b8b3ee532))
* add single-page worksheet preview API endpoint ([10e97db](10e97db78a))
* 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))
* calculate zoom based on region under cursor, target 15% area ([6736336](6736336317))
* **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))
* enhance scaffolding tab with live preview and resolved display rules ([9a5a0d4](9a5a0d4e3c))
* **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 binary search for optimal zoom level ([1a54f09](1a54f09814))
* 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 ([8b3d019](8b3d019652))
* 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 tab navigation layout and add pages to layout button ([926a029](926a029ff8))
* improve worksheet preview placeholder with cartoonish grid layout ([57fb99a](57fb99af63))
* increase max super zoom to 120x for ultra-tiny regions ([9b782be](9b782beabf))
* increase max zoom to 1000x with detailed debug logging ([a6be05f](a6be05f8c1))
* 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))
* make super zoom threshold configurable and increase to 3px ([d7ce474](d7ce474a51))
* make zoom transitions 4x slower for smoother experience ([ca752bd](ca752bd0aa))
* 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))
* show visual feedback for auto-resolved scaffolding values ([fbe776a](fbe776ac09))
* smooth cursor dampening transitions with react-spring ([66544dc](66544dc7dd))
* 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 'auto' to RuleMode type to prevent undefined display values ([a8636ca](a8636ca6a2))
* add comprehensive dark mode support to Smart Difficulty controls ([a65feb7](a65feb7344))
* add cooldown after quick-escape to prevent precision mode re-activation ([e885ae7](e885ae7ef4))
* add currentStepEstimate to required fields in JSON schema ([0d66c54](0d66c54991))
* add custom cursor when pointer lock is active ([5d6d6b4](5d6d6b4ddc))
* 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 missing openDeploymentInfo prop to MinimalNav ([30879d8](30879d8959))
* add missing selectedContinent to default config and fix ts-expect-error directives ([07e9224](07e92240e8))
* add mode descriptions and remove double borders ([6f2f6d4](6f2f6d444c))
* add seed and prngAlgorithm fields to all Zod schema versions (V1-V4) ([1782f42](1782f427f1))
* add shuffling to progressive difficulty mode & UI improvements ([38e9982](38e9982c3d))
* add xmlns to AbacusStatic for Typst SVG parsing ([98cd019](98cd019d4a))
* add zoom to selected continent and improve click detection ([6651979](6651979ea0))
* 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))
* center crosshairs and re-enable pointer lock after escape ([814bf94](814bf949f2))
* **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))
* eliminate cursor dampening lag when changing direction ([fc08b77](fc08b775db))
* enable page virtualization in worksheet creator ([b675f6c](b675f6c96e))
* enable vertical scrolling in layout controls ([a1b31f4](a1b31f454a))
* 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 draggable button constraints to avoid action button overlap ([00b0fb2](00b0fb297b))
* improve magnifier zoom calculation for multi-piece regions ([cb4114f](cb4114f344))
* 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))
* increase super zoom multiplier from 2.5x to 5.0x for Gibraltar ([138e6c0](138e6c071b))
* increase z-index of pointer lock prompt overlay ([5388441](5388441ebb))
* 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))
* lower quick-escape threshold to 15px/frame for easier triggering ([97b214d](97b214da12))
* 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))
* move pointer lock management to MapRenderer ([0ed4d13](0ed4d13db6))
* **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))
* pass correct parameter for borrow boxes in subtraction ([00d892a](00d892a05c))
* 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))
* preserve seed and prngAlgorithm in config migrations ([b18c412](b18c412736))
* preserve user's scaffolding settings when changing skills ([1eb04ce](1eb04ce0c4))
* 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))
* properly zoom to selected continent in game phases ([e900e44](e900e4465b))
* **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))
* refactor worksheet config persistence to blacklist approach + Storybook stories ([5b6db58](5b6db588a2))
* remove all scaffolding from final mastery skills ([d7bec42](d7bec423e0))
* remove distracting parallax and wobble 3D effects ([28a2d40](28a2d40996))
* remove duplicate containerRect declaration ([1a690e0](1a690e00b0))
* remove pages from visible set when they leave viewport ([9757449](9757449e21))
* remove redundant 'Teens minus singles' subtraction skill ([e156e87](e156e870df))
* remove unused velocity tracking and fix TypeScript errors ([0195a6d](0195a6dc6d))
* remove wobble physics and enhance wood grain visibility ([5d97673](5d97673406))
* replace deprecated path() with curve() in borrow arrows ([47d149c](47d149ca17))
* 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 borrow boxes display setting regardless of actual borrowing ([1aef0f2](1aef0f292f))
* respect operator-specific scaffolding in mastery+mixed mode ([a6472a2](a6472a231b))
* respect user's layout options (problemNumbers/cellBorders) in mastery mode ([e708add](e708add9f2))
* responsive page indicator and settings summary improvements ([93ddc28](93ddc28a3a))
* 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))
* scaffolding changes now apply in mastery+mixed mode ([510f052](510f052978))
* 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))
* track both SVG units and screen pixels for zoom and dampening ([d72f309](d72f309bad))
* **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))
* update AbacusQRCode for qrcode.react v4 compatibility ([0f0c3c6](0f0c3c65e8))
* update operator-specific display rules in mastery+mixed mode ([4174b6d](4174b6d2e7))
* use ± symbol for mixed operator icon consistently ([2695b50](2695b50abe))
* use absolute positioning for hero abacus to eliminate scroll lag ([096104b](096104b094))
* use ASCII characters for operator icons to support dark mode ([3bd5c00](3bd5c00d21))
* 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 screen pixels for zoom, abandon SVG path parsing ([912dc38](912dc385b3))
* use semantic tokens for nav bar transparent mode on hero ([d05c6a8](d05c6a8664))
* use subtle gray highlights for dropdown in dark mode ([8d6170a](8d6170a8c7))
* use SVG viewBox units instead of screen pixels for zoom ([0dcaabb](0dcaabb8a5))
* 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))
* eliminate props drilling for openDeploymentInfo ([24302d8](24302d8fc5))
* expand query key to include display settings ([7e3d84b](7e3d84b127))
* 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))
* remove debug logs for fixed issues ([5e42aab](5e42aabfa9))
* remove loadedPages and fetchingPages state ([90fb88b](90fb88b72a))
* reorganize Harmony and Victory guide sections ([fb629c4](fb629c44ea))
* replace two-query system with single all-pages query ([fbb035b](fbb035b12b))
* 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))
* simplify fetchWorksheetPreview to remove pagination ([200e394](200e394055))
* simplify pointer lock with movement delta multipliers ([749b16a](749b16ac27))
* start page dropdown at 4 and remove 'pages' suffix ([cf7eb57](cf7eb574d4))
* unify zoom modes into single adaptive zoom ([d1acdd9](d1acdd9e54))
* 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 comprehensive merge conflict resolution guide ([e4fc363](e4fc363a97))
* add comprehensive precision controls documentation for Know Your World ([8511998](8511998d0c))
* 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 merge conflict resolution section to CLAUDE.md ([a82d80b](a82d80b02c))
* add operator-specific settings architecture & refactoring plan ([e06de8e](e06de8ea47))
* 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))
* document compose-updater detection issue ([b37a960](b37a960d35))
* 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))
Changed zoom spring config to make transitions much more gradual:
- Reduced tension: 120 → 30 (slower response)
- Increased mass: 1 → 4 (more inertia, longer settling time)
- Kept friction at 30 for smooth easing
This creates a much less jarring zoom experience when moving between
regions of different sizes.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Problem:
- Movement multiplier (cursor dampening) changed instantly when crossing region boundaries
- This created jarring cursor behavior when moving from a large region to a tiny one
- Example: cursor speed jumping from 0.25x to 0.03x when moving from France to Gibraltar
Solution:
- Added movementMultiplier to magnifierSpring for smooth animated transitions
- Spring config: tension 180, friction 26 (faster than zoom, slower than position)
- Uses .get() to read current animated value in mouse handler
Benefits:
- Gradual cursor dampening changes feel natural and predictable
- No jarring speed changes when crossing region boundaries
- Maintains precision control while improving UX
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Problem:
- Portugal's bounding box includes distant Atlantic islands, causing mainland to be ignored
- Algorithm was selecting "largest piece by area" which picked island groups instead of mainland
- This caused Portugal to dominate zoom calculations and prevent Gibraltar from being prioritized
Solution:
- Changed pre-computation to use FIRST piece instead of largest (mainland is typically piece 1)
- Added showDebugBoundingBoxes prop to hide debug rectangles in production
- Improved zoom animation smoothness with gentler spring easing (tension: 120, friction: 30)
Technical details:
- Multi-piece SVG paths split by `z m` separator
- First piece is mainland, subsequent pieces are islands/territories
- Pre-computed sizes cached in useEffect for performance
- Only Portugal logs to console for debugging
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Replace area-based formula with binary search to find zoom where
regions occupy 10-20% of magnifier area.
Binary search algorithm:
1. Start with minZoom=1, maxZoom=1000
2. Test midpoint zoom level
3. Calculate how much of magnified view each region occupies
4. If no regions fit → zoom out (maxZoom = mid)
5. If regions < 10% → zoom in (minZoom = mid)
6. If regions > 20% → zoom out (maxZoom = mid)
7. If 10-20% → perfect, done!
8. Iterate max 20 times or until range < 0.1
This handles all regions in the detection box, not just the one
under cursor, giving better overall framing.
For Gibraltar area:
- Binary search will find zoom ~800-1000x where Gibraltar occupies
10-20% of magnifier
- Converges in ~10-15 iterations
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
TypeScript error: containerRect was declared twice in the same scope.
The variable is already declared at the top of handleMouseMove, no
need to redeclare it when calculating magnifier position.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Previous approach used smallest region in detection box for zoom, which
caused Spain to zoom to 1000x just because Gibraltar was nearby.
New approach:
- Use region UNDER CURSOR for zoom calculation (not smallest in box)
- Calculate zoom so region occupies 15% of magnifier area
- Formula: zoom = sqrt((magnifierArea × 0.15) / regionArea)
For Gibraltar (0.018px² area) in ~200,000px² magnifier:
- Target: 200,000 × 0.15 = 30,000px² in magnifier
- zoom = sqrt(30,000 / 0.018) ≈ 1,291x → capped at 1000x
- Result: Gibraltar occupies ~14% of magnifier (close to target)
For Spain (5,000px² area):
- Target: 200,000 × 0.15 = 30,000px² in magnifier
- zoom = sqrt(30,000 / 5,000) ≈ 2.4x
- Result: Spain occupies 15% of magnifier
This gives predictable, proportional zoom levels based on what
you're actually hovering over, not what's nearby.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
The calculateBoundingBox function doesn't handle relative SVG path
commands correctly. Gibraltar's path uses 'm' (relative move) followed
by tiny relative offsets like -0.009, 0.047, but the function treated
them as absolute coordinates, giving width of 460 units instead of 0.08.
Proper SVG path parsing requires:
- Tracking current position as you iterate through commands
- Handling both absolute (M,L,H,V,C,S,Q,T,A) and relative (m,l,h,v,c,s,q,t,a)
- Curves need Bezier math to find actual bounds
- Too complex for this use case
Solution: Use screen pixels (getBoundingClientRect) for everything.
Screen pixel measurements work correctly for tiny regions:
- Gibraltar: 0.08px (accurate)
- Jersey: 0.82px (accurate)
New zoom formula for screen pixels:
- Sub-pixel (< 1px): 1000/(size+0.05)
- Gibraltar (0.08px): ~7692x → capped at 1000x
- Tiny (1-10px): 500/(size+0.5)
- 1px: ~333x
- 5px: ~91x
- Small (10-50px): Linear up to +50x
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
The previous commit broke cursor dampening and magnifier triggers by
using SVG units for everything. We need both measurements:
- **SVG units** (0-1010): Accurate zoom calculation
- **Screen pixels**: Cursor dampening and magnifier triggers
Changes:
- Track detectedSmallestSize (SVG units) for zoom calculation
- Track detectedSmallestScreenSize (screen pixels) for dampening
- Use screen pixels for getMovementMultiplier() (expects <1px, <5px, <15px)
- Use screen pixels for hasSmallRegion trigger (<15px)
- Debug logging now shows both values
Example for Gibraltar:
- SVG size: 0.08 units → 1000x zoom
- Screen size: 0.08px → 3% cursor speed (ultra precision)
This restores cursor dampening behavior while keeping accurate
SVG-based zoom calculations.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
The previous implementation used getBoundingClientRect() which returns
axis-aligned bounding boxes in screen pixels. This has two problems:
1. **Inaccurate sizing**: Bounding boxes for irregular/rotated shapes
are much larger than the actual visible area
2. **Floating-point precision**: Sub-pixel screen measurements lose
precision and cause most regions to trigger max zoom
Solution: Use SVG path bounding box from viewBox coordinates
The world map viewBox is 1010 × 666 SVG units:
- Gibraltar: ~0.08 SVG units (extremely tiny!)
- Jersey: ~0.5 SVG units
- Most countries: 10-100 SVG units
New zoom formula for SVG units:
- Tiny regions (< 5 units): 200 / (size + 0.1)
- Gibraltar (0.08): 200/0.18 ≈ 1111x → capped at 1000x
- 1 unit: 200/1.1 ≈ 182x
- 5 units: 200/5.1 ≈ 39x
- Small regions (5-100 units): Linear scaling up to +50x
- Large regions (>100 units): Minimal size-based zoom
This avoids floating-point precision issues and gives accurate
zoom levels based on the region's true SVG path dimensions.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Increase MAX_ZOOM from 500x to 1000x and double the exponential
scaling formula to handle Gibraltar's extreme size.
New zoom calculation for sub-pixel regions:
- Formula: 1000 / (size + 0.05)
- Gibraltar (0.08px): ~770x size zoom → ~800x total (capped at 1000x)
- Jersey (0.82px): ~115x size zoom → ~145x total
- 1px: ~95x size zoom → ~125x total
Added detailed debug logging for Gibraltar to diagnose:
- Exact region size (4 decimal places)
- Breakdown: base (10) + density + size zoom
- Total before/after clamping
- Whether we're hitting max zoom limit
This will help determine if we're hitting floating-point precision
limits or if Gibraltar needs even more magnification.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Gibraltar at 0.08px needs extreme magnification to be clickable.
Increased max zoom from 120x to 500x and added exponential scaling
for sub-pixel regions.
New zoom calculation:
- Base: 10x
- Density: up to +20x
- Size-based (exponential for <1px): 500 / (size + 0.05)
- Gibraltar (0.08px): ~385x + base/density = ~415x total
- Jersey (0.82px): ~57x + base/density = ~87x total
- 1px regions: ~50x + base/density = ~80x total
- Size-based (linear for >=1px): up to +150x
Gold border threshold increased to 100x to indicate extreme zoom.
This exponential scaling ensures the tiniest regions get massive
magnification while regular small regions get reasonable zoom.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Remove leftover velocity calculation code that was used for quick-escape
logic (no longer needed with unified zoom).
Fix TypeScript errors:
- Remove lastMoveTimeRef reference (not needed)
- Fix detectedRegions type - it's string[], not MapRegion[]
- Use .includes('gi') instead of .some(r => r.id === 'gi')
- Log detectedRegionIds instead of trying to map to names
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Simplify precision controls by removing dual zoom modes (normal + super).
Now uses a single unified adaptive zoom that immediately calculates the
right magnification based on region size.
Changes:
- Remove hover delay timer (HOVER_DELAY_MS)
- Remove super zoom state (superZoomActive)
- Remove quick-escape velocity threshold
- Unify zoom calculation: 8x base + up to 16x density + up to 96x size
- Gold border now shows for any zoom >60x (not just "super zoom")
Zoom calculation for Gibraltar (0.08px):
- Base: 8x
- Density (4 regions): +6x
- Size factor (0.996): +92x
- Total: ~106x (immediately, no delay)
Benefits:
- Simpler UX - no waiting for super zoom to activate
- More responsive - zoom adjusts immediately to region size
- Less code complexity - no timer management or state tracking
- Predictable behavior - zoom level purely based on what's visible
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Gibraltar is only 0.08px wide and needs extreme magnification.
Previous multiplier of 2.5x only achieved ~48x zoom, which was
insufficient to make Gibraltar visible and clickable.
New calculation:
- Base adaptive zoom: ~19x (based on size + density)
- Super zoom multiplier: 5.0x
- Result: ~95-120x zoom for Gibraltar
This should make Gibraltar clearly visible in the magnifier at
maximum super zoom.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Add console logging to help debug why Gibraltar isn't visible:
1. Map filtering: Log whether Gibraltar is included or excluded
2. Region sizing: Log Gibraltar's actual pixel dimensions
3. Magnifier detection: Log when Gibraltar is detected in hover area
4. Zoom levels: Log final zoom when Gibraltar is in view
Logs are targeted to avoid excessive output:
- Only log Gibraltar specifically (id='gi')
- Only log ultra-tiny regions (< 1-2px)
- Skip logging for normal-sized regions
This will help diagnose if Gibraltar is:
- Being filtered out by difficulty
- Too small to render on screen
- Not being detected by precision controls
- Not receiving sufficient zoom magnification
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Increase MAX_ZOOM_SUPER from 60x to 120x to handle extremely small
regions like Gibraltar (0.08px). The previous 60x zoom was still
insufficient for clicking such tiny regions.
Changes:
- Add MAX_ZOOM_NORMAL constant (24x)
- Add MAX_ZOOM_SUPER constant (120x)
- Use constants instead of hardcoded values in zoom calculations
- Super zoom now reaches up to 120x magnification for sub-pixel regions
This should make Gibraltar and other extremely tiny territories
clickable with the pointer lock precision controls.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Add SUPER_ZOOM_SIZE_THRESHOLD constant (default: 3px)
- Previously hardcoded at < 1px (only sub-pixel regions)
- Now activates for regions < 3px (more helpful range)
- Easy to tune for different preferences
Update logging to reference the configurable threshold.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
**Crosshair positioning:**
- Fix vertical line: left: 50%, top: 0 (was top: 50%)
- Fix horizontal line: left: 0, top: 50% (was left: 50%)
- Both now properly centered in the circle
**Re-enable pointer lock:**
- Show prompt overlay again when pointer lock is released
- User can press Escape to exit, then click to re-enter
- Handles both user-initiated unlock (Escape) and errors
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
**Problem:** Pointer lock was activating on MapRenderer's container,
but PlayingPhase was trying to manage it, so state never updated.
**Solution:** Move all pointer lock management into MapRenderer:
- Add pointerLocked state in MapRenderer
- Add pointer lock event listeners in MapRenderer
- Add click handler to request lock on MapRenderer container
- Add "Enable Precision Controls" overlay in MapRenderer
- Remove all pointer lock code from PlayingPhase
Now pointer lock state tracks correctly and custom cursor will render.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Increase z-index from 1000 to 10000 to ensure the overlay
appears above all other content.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Add extensive console logging to debug cursor visibility:
**PlayingPhase:**
- Log when pointer lock listeners attach/detach
- Log pointer lock state changes with element details
- Log container click events with conditions
- Log pointerLocked state changes
**MapRenderer:**
- Log custom cursor render conditions on every render
- Log when cursor should be visible
- Log cursor position when rendering
This will help diagnose why custom cursor isn't visible.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
When pointer lock is active, the browser hides the native cursor.
Add a custom crosshair cursor that follows the tracked position:
- 20px circle with crosshair lines
- Blue color (matches theme)
- Positioned at tracked cursor coordinates
- Only visible when pointerLocked is true
This ensures users can always see where they're pointing.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Major refactoring of precision controls for Know Your World game:
**New Flow:**
- Pointer lock requested once when PlayingPhase mounts (user click)
- Active for entire game session until unmount
- Simpler: use movementX/movementY with adaptive multiplier
**PlayingPhase.tsx:**
- Add pointer lock management with event listeners
- Show "Enable Precision Controls" overlay on mount
- Request pointer lock on first click (user gesture)
- Release on unmount (game ends)
- Pass pointerLocked prop to MapRenderer
**MapRenderer.tsx:**
- Accept pointerLocked as prop (don't manage internally)
- Remove complex cursor dampening (dual refs: raw vs dampened)
- Simplified: apply multiplier to movementX/movementY based on region size
- Sub-pixel regions (<1px): 3% speed
- Tiny regions (1-5px): 10% speed
- Small regions (5-15px): 25% speed
- Larger regions: 100% speed
- Remove precision mode state (not needed)
- Remove cooldown logic (not needed)
- Remove click capture handler (not needed)
- Update cursor style and mouse handlers to use pointerLocked
**Benefits:**
- Much simpler code (removed ~100 lines of complexity)
- No lag when changing direction (no interpolation)
- Pointer lock active entire session (can't drift off map)
- Movement multiplier clearer than dampening
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Remove verbose console logging that was used to debug issues that are now fixed:
- Velocity logging (quick-escape threshold is now correct)
- Dampening state logs (dampening lag is fixed)
- Region detection logs (crosshair accuracy is fixed)
- Per-frame precision mode state checks (too verbose)
Keep only important logs:
- Quick escape triggers
- Precision mode state changes
- Pointer lock debugging (current issue)
- Magnifier state changes
This reduces console noise while keeping useful feedback.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Add detailed logging to debug pointer lock activation:
- Log useEffect triggers with all conditions
- Log pointer lock request attempts and results
- Log pointer lock state in precision mode checks
- Add try/catch around requestPointerLock
- Warn if container ref is missing
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
When cursor dampening is active, the real mouse can drift off the map while the dampened cursor is still on it, causing magnifier to disappear. Pointer Lock solves this.
Changes:
- Add pointerLocked state and event listeners
- Request pointer lock when precision mode activates
- Use movementX/Y deltas instead of absolute position when locked
- Clamp calculated position to container bounds
- Update SVG bounds check for both locked and normal modes
- Ignore mouse leave events when pointer is locked
- Release pointer lock when precision mode deactivates
Benefits:
- No more hitting viewport edges during precision mode
- Real cursor disappears, only dampened cursor visible
- Smooth movement tracking without boundary issues
- Magnifier stays active even if real mouse would leave container
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Console logs showed user reaching 22px/frame when trying to escape, but 30px threshold was too high. This required an unrealistically aggressive mouse flick.
Changes:
- Lower QUICK_MOVE_THRESHOLD from 30px to 15px/frame (2x easier to trigger)
- Increase PRECISION_MODE_COOLDOWN from 800ms to 1200ms (more time to escape area)
With these values, moderate-speed mouse movements will trigger escape, and users have more time to move away before precision mode can re-activate.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Add detailed console logging to debug quick-escape issues:
- Log velocity every frame when in precision mode or moving
- Show velocity vs threshold and whether escape will trigger
- Log when quick-escape actually triggers
- Log precision mode state check every frame:
- shouldShow, cooldownActive, time remaining
- current vs target precision mode state
- smallest region size
- Log when precision mode state actually changes
This will help identify why quick-escape isn't working as expected.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
After quick-escape, precision mode was immediately re-enabling because the user was still hovering over small regions. This made it feel impossible to escape dampening.
Changes:
- Add precisionModeCooldownRef to track cooldown expiration time
- Lower QUICK_MOVE_THRESHOLD from 50px to 30px (easier to trigger)
- Add PRECISION_MODE_COOLDOWN_MS = 800ms grace period after escape
- Precision mode won't re-activate during cooldown even if over small regions
- Cooldown resets on mouse leave
Result: Users can now easily escape precision mode with a quick mouse flick, and it won't immediately re-engage. After 800ms cooldown, precision mode can auto-activate again if still over small regions.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Fix cursor dampening feedback loop that caused lag when reversing mouse direction. The previous implementation tracked the dampened position, creating momentum/lag when changing direction.
Changes:
- Split lastCursorRef into two separate refs:
- lastRawCursorRef: tracks actual raw mouse position
- dampenedCursorRef: tracks current dampened position
- Calculate delta from raw-to-raw (not dampened-to-raw)
- Direction changes now respond instantly, just at reduced speed
- No more "continuation" effect when reversing direction
Technical details:
- Velocity calculation now uses raw positions for accuracy
- First frame of precision mode initializes dampened cursor at raw position
- Both refs reset on mouse leave
- Debug logging updated to show both raw and dampened positions
Result: Cursor dampening feels responsive and precise, no lag when changing direction.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Add detailed documentation for the advanced precision control system that makes sub-pixel regions (Gibraltar 0.08px, Jersey 0.82px) clickable:
- PRECISION_CONTROLS.md: Complete technical deep-dive
- Automatic cursor dampening (3-25% speed based on region size)
- Auto super-zoom (up to 60x) after 500ms hover on sub-pixel regions
- Quick-escape mechanism (>50px/frame cancels all precision features)
- Crosshair accuracy fix ensuring dampened cursor matches hover highlighting
- Configuration constants, debug logging, performance considerations
- know-your-world/README.md: Game overview and feature documentation
- Game modes, maps, difficulty levels, study mode
- Visual features, technical architecture, component structure
- Development guide, troubleshooting, configuration
- Updated documentation graph:
- Main README → Arcade Games → Know Your World → Precision Controls
- All documentation now reachable from root README
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Implement automatic cursor dampening, super zoom on hover, and quick-escape to make sub-pixel regions (Gibraltar 0.08px, Jersey 0.82px) clickable. Fix crosshair accuracy to match dampened cursor position, add excluded region visualization (gray pre-labeled), and increase unfound region contrast (0.3→0.7 opacity).
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
## [4.68.0](https://github.com/antialias/soroban-abacus-flashcards/compare/v4.67.1...v4.68.0) (2025-11-19)
### 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 'auto' option for scaffolding to defer to mastery progression ([a945a62](a945a620c4))
* add 3D printing support for abacus models ([dafdfdd](dafdfdd233))
* add adaptive zoom magnifier for Know Your World map ([1e8846c](1e8846cdb1))
* 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 auto scaffolding mode with visual feedback and override notices ([b62db5a](b62db5a323))
* 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 continent filtering to Know Your World game ([7bb03b8](7bb03b8409))
* 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 layout preview component for orientation selection ([8df62d6](8df62d6a45))
* add dynamic operator icon to tab navigation ([b6ff995](b6ff995a8c))
* add fancy QR codes with abacus logo throughout app ([ebcabf9](ebcabf9bb9))
* 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 interactive world map continent selector ([245005c](245005c8ec))
* add Know Your World geography quiz game ([25e24a7](25e24a7cbc))
* add mobile drawer and detailed summary for shared worksheets ([0a35e70](0a35e70e28))
* add ngrok tunnel to dev server for HTTPS testing ([ab2bfde](ab2bfde9c2))
* add per-country coloring and individual region clicks to continent selector ([2e9f409](2e9f409f26))
* 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 responsive mobile drawer with draggable settings button ([fc1d7fc](fc1d7fcbd6))
* add responsive page button layout with dynamic dropdown ([3f33cd1](3f33cd1924))
* add shared worksheet viewer with open-in-editor functionality ([4b8b3ee](4b8b3ee532))
* add single-page worksheet preview API endpoint ([10e97db](10e97db78a))
* 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))
* enhance scaffolding tab with live preview and resolved display rules ([9a5a0d4](9a5a0d4e3c))
* **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 ([8b3d019](8b3d019652))
* 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 tab navigation layout and add pages to layout button ([926a029](926a029ff8))
* 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))
* show visual feedback for auto-resolved scaffolding values ([fbe776a](fbe776ac09))
* 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 'auto' to RuleMode type to prevent undefined display values ([a8636ca](a8636ca6a2))
* 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 missing openDeploymentInfo prop to MinimalNav ([30879d8](30879d8959))
* add missing selectedContinent to default config and fix ts-expect-error directives ([07e9224](07e92240e8))
* add mode descriptions and remove double borders ([6f2f6d4](6f2f6d444c))
* add seed and prngAlgorithm fields to all Zod schema versions (V1-V4) ([1782f42](1782f427f1))
* add shuffling to progressive difficulty mode & UI improvements ([38e9982](38e9982c3d))
* add xmlns to AbacusStatic for Typst SVG parsing ([98cd019](98cd019d4a))
* add zoom to selected continent and improve click detection ([6651979](6651979ea0))
* 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 vertical scrolling in layout controls ([a1b31f4](a1b31f454a))
* 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 draggable button constraints to avoid action button overlap ([00b0fb2](00b0fb297b))
* 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))
* pass correct parameter for borrow boxes in subtraction ([00d892a](00d892a05c))
* 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))
* preserve seed and prngAlgorithm in config migrations ([b18c412](b18c412736))
* preserve user's scaffolding settings when changing skills ([1eb04ce](1eb04ce0c4))
* 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))
* properly zoom to selected continent in game phases ([e900e44](e900e4465b))
* **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))
* refactor worksheet config persistence to blacklist approach + Storybook stories ([5b6db58](5b6db588a2))
* 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 deprecated path() with curve() in borrow arrows ([47d149c](47d149ca17))
* 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 borrow boxes display setting regardless of actual borrowing ([1aef0f2](1aef0f292f))
* respect operator-specific scaffolding in mastery+mixed mode ([a6472a2](a6472a231b))
* respect user's layout options (problemNumbers/cellBorders) in mastery mode ([e708add](e708add9f2))
* responsive page indicator and settings summary improvements ([93ddc28](93ddc28a3a))
* 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))
* scaffolding changes now apply in mastery+mixed mode ([510f052](510f052978))
* 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))
* update AbacusQRCode for qrcode.react v4 compatibility ([0f0c3c6](0f0c3c65e8))
* update operator-specific display rules in mastery+mixed mode ([4174b6d](4174b6d2e7))
* use ± symbol for mixed operator icon consistently ([2695b50](2695b50abe))
* use absolute positioning for hero abacus to eliminate scroll lag ([096104b](096104b094))
* use ASCII characters for operator icons to support dark mode ([3bd5c00](3bd5c00d21))
* 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))
* eliminate props drilling for openDeploymentInfo ([24302d8](24302d8fc5))
* expand query key to include display settings ([7e3d84b](7e3d84b127))
* 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))
* remove loadedPages and fetchingPages state ([90fb88b](90fb88b72a))
* reorganize Harmony and Victory guide sections ([fb629c4](fb629c44ea))
* replace two-query system with single all-pages query ([fbb035b](fbb035b12b))
* 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))
* simplify fetchWorksheetPreview to remove pagination ([200e394](200e394055))
* 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 comprehensive merge conflict resolution guide ([e4fc363](e4fc363a97))
* 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 merge conflict resolution section to CLAUDE.md ([a82d80b](a82d80b02c))
* add operator-specific settings architecture & refactoring plan ([e06de8e](e06de8ea47))
* 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))
* document compose-updater detection issue ([b37a960](b37a960d35))
* 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))
Add intelligent magnifying glass feature with smooth animations:
Magnifier Features:
- Appears when 7+ regions overlap in 50×50px box OR region <8px
- Adaptive zoom (8×-24×) based on region density and size
- Smooth zoom/opacity animations using react-spring
- Dynamic positioning to avoid covering cursor
- Visual indicator box on main map shows magnified area
- Crosshair shows exact cursor position in magnified view
Implementation Details:
- Uses react-spring for smooth zoom and fade transitions
- Position calculated per quadrant (opposite corner from cursor)
- Zoom formula: base 8× + density factor + size factor
- Animated SVG viewBox for seamless zooming
- Dashed blue indicator rectangle tracks magnified region
UI/UX Improvements:
- Remove duplicate turn indicator (use player avatar dock)
- Hide arrow labels feature behind flag (disabled by default)
- Add Storybook stories for map renderer with tuning controls
This makes clicking tiny island nations and crowded regions much easier!
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Fix continent zoom to work in Study and Playing phases (not setup):
Fixed Bounding Box Calculation:
- Rewrite calculateBoundingBox() to properly parse SVG path commands
- Handle both absolute (M, L, H, V, C, Q) and relative (m, l, h, v, c, q) commands
- Track current position for accurate relative coordinate conversion
- Include all control points for Bezier curves in bounding box
- Now correctly calculates continent boundaries
Reverted Setup Screen Changes:
- Remove zoom from ContinentSelector (keep full world visible)
- Setup screen shows complete world map for easy continent selection
- Zoom only happens in game phases (Study, Playing, Results)
Game Phase Zoom:
- Study and Playing phases now properly zoom to selected continent
- Uses accurate bounding box from fixed calculateBoundingBox()
- 10% padding around continent for optimal visibility
- Filtered regions AND adjusted viewBox work together
How It Works:
1. User selects continent in setup (sees full world map)
2. Clicks "Start Study & Play" or "Start Game"
3. Study/Playing phases automatically zoom to show only that continent
4. Countries fill the available space for easier clicking
5. Geographic details much more visible
Technical Fix:
- Previous implementation naively extracted numbers from SVG paths
- Didn't account for relative vs absolute coordinates
- Resulted in incorrect bounding boxes
- New implementation mirrors calculatePathCenter() logic
- Properly handles all SVG path command types
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Fix two critical UX issues in the continent selector:
Auto-Zoom to Selected Continent:
- Calculate dynamic viewBox based on selected continent
- Use calculateContinentViewBox() to crop map to continent bounds
- Add 10% padding around continent for better visibility
- Smooth transition when switching between continents
- Shows full world when "All" is selected
- Selected continent fills the available space efficiently
Improved Click Detection:
- Add explicit pointerEvents: 'all' to all path elements
- Add stopPropagation() to prevent event bubbling conflicts
- Ensure all individual countries are clickable
- Better event handling for reliable click registration
Technical Changes:
- Import useMemo and calculateContinentViewBox from maps.ts
- Calculate viewBox dynamically based on selectedContinent
- Update SVG viewBox prop to use calculated value
- Add pointer-events style and stopPropagation to onClick handlers
User Experience:
- Clicking any country now reliably selects its continent
- Selected continent automatically zooms to fill the space
- Much easier to see and click individual countries
- Geographic details more visible when continent is selected
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Enhance the continent selector with colorful individual regions:
Per-Country Coloring:
- Each country/region now has its own distinct color using the game's color algorithm
- Same 8-color deterministic palette as the main game
- Unselected continents shown at 20% opacity for subtle visibility
- Selected continent regions shown at full color intensity
- Hovered regions get enhanced borders and highlighting
Individual Region Interaction:
- Click any individual country to select its continent
- Hover over any country highlights that specific region
- Smooth transitions between states (0.15s)
- Thicker stroke on hover (1.5px) for clear feedback
- Visual feedback shows exactly which country you're pointing at
Benefits:
- Much more visually appealing and educational
- Users can see individual countries within each continent
- Clearer geographic boundaries and relationships
- More engaging interaction model
- Same visual language as the main game map
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Replace continent button grid with interactive world map selector:
Interactive Map Features:
- Visual world map showing all continents with color-coded regions
- Click any continent on the map to select it
- Hover effects show which continent you're pointing at
- Selected continent highlighted in solid blue
- Unselected continents shown in subtle gray
Visual Feedback:
- Selected: Solid blue fill with blue stroke
- Hovered: Semi-transparent blue overlay
- Unselected: Light gray with subtle borders
- Smooth transitions between states
Legend Buttons:
- Small buttons below map for quick access
- All 7 continents + "All" option
- Synchronized with map selection
- Hover on button also highlights continent on map
UX Improvements:
- More intuitive than button grid
- Visual context of where continents are located
- Easier to understand geographic relationships
- Better use of screen space
- Instructions text: "Click a continent to focus on it, or select 'All' for the whole world"
Technical Implementation:
- Create ContinentSelector component with interactive SVG
- Group world map regions by continent
- Bidirectional hover state (map ↔ buttons)
- Reuse existing continent grouping logic
- Maintain all existing functionality (persistence, filtering, etc.)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Add continent-based filtering for the world map to make the game more playable by reducing visual clutter:
Continent Selection:
- Add continent selector to setup screen (only for world map)
- 7 continents + "All" option: Africa, Asia, Europe, North America, South America, Oceania, Antarctica
- Each continent button shows emoji and name
Map Filtering:
- Filter world map regions by selected continent using ISO 3166-1 country codes
- Calculate bounding box for filtered regions
- Automatically crop and scale viewBox to show only selected continent
- Add 10% padding around continent bounding box for better visibility
Technical Implementation:
- Create continents.ts with comprehensive country-to-continent mappings (256 countries)
- Add getFilteredMapData() function to filter regions and adjust viewBox
- Add calculateBoundingBox() to compute min/max coordinates from SVG paths
- Add selectedContinent field to game state and config (persisted to database)
- Add SET_CONTINENT move type and validator
- Update all map rendering components (StudyPhase, PlayingPhase, MapRenderer)
Benefits:
- Solves "too many small countries" problem on world map
- Allows focused study of specific geographic regions
- Dynamic viewBox adjustment provides optimal zoom level
- Maintains full world map option for comprehensive play
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Add new arcade game for testing geography knowledge:
Game Features:
- 4 phases: Setup, Study, Playing, Results
- 3 multiplayer modes: Cooperative, Race, Turn-Based
- 2 maps: World countries, USA states
- Configurable study mode (0, 30, 60, or 120 seconds)
- Return to Setup and New Game options in game menu
- Small region labels with arrows for improved visibility
Map Rendering:
- 8-color deterministic palette with hash-based assignment
- Opacity-based states (20-27% unfound, 100% found)
- Enhanced label visibility with text shadows
- Smart bounding box calculation for small regions
- Supports both easy (outlines always visible) and hard (outlines on hover/found) difficulty
Game Modes:
- Cooperative: All players work together to find all regions
- Race: First to click gets the point
- Turn-Based: Players take turns finding regions
Study Phase:
- Optional timed study period before quiz starts
- Shows all region labels for memorization
- Countdown timer with skip option
Dependencies:
- Add @svg-maps/world and @svg-maps/usa packages
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
## [4.68.0](https://github.com/antialias/soroban-abacus-flashcards/compare/v4.67.1...v4.68.0) (2025-11-18)
### 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 'auto' option for scaffolding to defer to mastery progression ([a945a62](a945a620c4))
* 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 auto scaffolding mode with visual feedback and override notices ([b62db5a](b62db5a323))
* 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 layout preview component for orientation selection ([8df62d6](8df62d6a45))
* add dynamic operator icon to tab navigation ([b6ff995](b6ff995a8c))
* add fancy QR codes with abacus logo throughout app ([ebcabf9](ebcabf9bb9))
* 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 mobile drawer and detailed summary for shared worksheets ([0a35e70](0a35e70e28))
* 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 responsive mobile drawer with draggable settings button ([fc1d7fc](fc1d7fcbd6))
* add responsive page button layout with dynamic dropdown ([3f33cd1](3f33cd1924))
* add shared worksheet viewer with open-in-editor functionality ([4b8b3ee](4b8b3ee532))
* add single-page worksheet preview API endpoint ([10e97db](10e97db78a))
* 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))
* enhance scaffolding tab with live preview and resolved display rules ([9a5a0d4](9a5a0d4e3c))
* **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 ([8b3d019](8b3d019652))
* 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 tab navigation layout and add pages to layout button ([926a029](926a029ff8))
* 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))
* show visual feedback for auto-resolved scaffolding values ([fbe776a](fbe776ac09))
* 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 'auto' to RuleMode type to prevent undefined display values ([a8636ca](a8636ca6a2))
* 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 missing openDeploymentInfo prop to MinimalNav ([30879d8](30879d8959))
* add mode descriptions and remove double borders ([6f2f6d4](6f2f6d444c))
* add seed and prngAlgorithm fields to all Zod schema versions (V1-V4) ([1782f42](1782f427f1))
* add shuffling to progressive difficulty mode & UI improvements ([38e9982](38e9982c3d))
* 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 vertical scrolling in layout controls ([a1b31f4](a1b31f454a))
* 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 draggable button constraints to avoid action button overlap ([00b0fb2](00b0fb297b))
* 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))
* pass correct parameter for borrow boxes in subtraction ([00d892a](00d892a05c))
* 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))
* preserve seed and prngAlgorithm in config migrations ([b18c412](b18c412736))
* preserve user's scaffolding settings when changing skills ([1eb04ce](1eb04ce0c4))
* 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))
* refactor worksheet config persistence to blacklist approach + Storybook stories ([5b6db58](5b6db588a2))
* 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 deprecated path() with curve() in borrow arrows ([47d149c](47d149ca17))
* 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 borrow boxes display setting regardless of actual borrowing ([1aef0f2](1aef0f292f))
* respect operator-specific scaffolding in mastery+mixed mode ([a6472a2](a6472a231b))
* respect user's layout options (problemNumbers/cellBorders) in mastery mode ([e708add](e708add9f2))
* responsive page indicator and settings summary improvements ([93ddc28](93ddc28a3a))
* 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))
* scaffolding changes now apply in mastery+mixed mode ([510f052](510f052978))
* 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))
* update AbacusQRCode for qrcode.react v4 compatibility ([0f0c3c6](0f0c3c65e8))
* update operator-specific display rules in mastery+mixed mode ([4174b6d](4174b6d2e7))
* use ± symbol for mixed operator icon consistently ([2695b50](2695b50abe))
* use absolute positioning for hero abacus to eliminate scroll lag ([096104b](096104b094))
* use ASCII characters for operator icons to support dark mode ([3bd5c00](3bd5c00d21))
* 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))
* eliminate props drilling for openDeploymentInfo ([24302d8](24302d8fc5))
* expand query key to include display settings ([7e3d84b](7e3d84b127))
* 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))
* remove loadedPages and fetchingPages state ([90fb88b](90fb88b72a))
* reorganize Harmony and Victory guide sections ([fb629c4](fb629c44ea))
* replace two-query system with single all-pages query ([fbb035b](fbb035b12b))
* 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))
* simplify fetchWorksheetPreview to remove pagination ([200e394](200e394055))
* 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 comprehensive merge conflict resolution guide ([e4fc363](e4fc363a97))
* 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 merge conflict resolution section to CLAUDE.md ([a82d80b](a82d80b02c))
* add operator-specific settings architecture & refactoring plan ([e06de8e](e06de8ea47))
* 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))
* document compose-updater detection issue ([b37a960](b37a960d35))
* 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))
Changed overflow from 'hidden' to 'overflowX: hidden, overflowY: auto'
to allow vertical scrolling when content is clipped while preventing
horizontal scroll.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>