Commit Graph

2667 Commits

Author SHA1 Message Date
Thomas Hallock 05fc5cfe49 fix: regenerate lockfile to remove big.js dependencies 2025-11-19 19:31:59 -06:00
Thomas Hallock 68cef7c0d0 chore: update lockfile after big.js revert 2025-11-19 19:26:02 -06:00
Thomas Hallock 9ad4517f2a Revert "feat: use big.js for arbitrary precision in cursor and zoom math"
This reverts commit 8e9c0548c8.
2025-11-19 19:24:07 -06:00
Thomas Hallock 156f63faaf fix: implement manual click detection using precise cursor position
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>
2025-11-19 19:21:11 -06:00
Thomas Hallock ae6cc5e326 fix: add missing scaleX and scaleY number conversions
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>
2025-11-19 19:12:06 -06:00
Thomas Hallock 8e9c0548c8 feat: use big.js for arbitrary precision in cursor and zoom math
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>
2025-11-19 18:45:38 -06:00
semantic-release-bot d85450a4cd chore(release): 4.68.0 [skip ci]
## [4.68.0](https://github.com/antialias/soroban-abacus-flashcards/compare/v4.67.1...v4.68.0) (2025-11-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))
2025-11-20 00:20:03 +00:00
Thomas Hallock ca752bd0aa feat: make zoom transitions 4x slower for smoother experience
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>
2025-11-19 18:09:47 -06:00
Thomas Hallock 66544dc7dd feat: smooth cursor dampening transitions with react-spring
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>
2025-11-19 18:08:09 -06:00
Thomas Hallock cb4114f344 fix: improve magnifier zoom calculation for multi-piece regions
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>
2025-11-19 18:06:35 -06:00
Thomas Hallock 1a54f09814 feat: implement binary search for optimal zoom level
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>
2025-11-19 18:06:35 -06:00
Thomas Hallock 1a690e00b0 fix: remove duplicate containerRect declaration
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>
2025-11-19 18:06:35 -06:00
Thomas Hallock 6736336317 feat: calculate zoom based on region under cursor, target 15% area
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>
2025-11-19 18:06:35 -06:00
Thomas Hallock 912dc385b3 fix: use screen pixels for zoom, abandon SVG path parsing
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>
2025-11-19 18:06:35 -06:00
Thomas Hallock d72f309bad fix: track both SVG units and screen pixels for zoom and dampening
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>
2025-11-19 18:06:35 -06:00
Thomas Hallock 0dcaabb8a5 fix: use SVG viewBox units instead of screen pixels for zoom
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>
2025-11-19 18:06:35 -06:00
Thomas Hallock a6be05f8c1 feat: increase max zoom to 1000x with detailed debug logging
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>
2025-11-19 18:06:35 -06:00
Thomas Hallock 101213ba1c feat: add exponential zoom scaling for sub-pixel regions
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>
2025-11-19 18:06:35 -06:00
Thomas Hallock 0195a6dc6d fix: remove unused velocity tracking and fix TypeScript errors
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>
2025-11-19 18:06:34 -06:00
Thomas Hallock d1acdd9e54 refactor: unify zoom modes into single adaptive zoom
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>
2025-11-19 18:06:34 -06:00
Thomas Hallock 138e6c071b fix: increase super zoom multiplier from 2.5x to 5.0x for Gibraltar
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>
2025-11-19 18:06:34 -06:00
Thomas Hallock 07fe9e882c debug: add targeted logging for Gibraltar tracking
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>
2025-11-19 18:06:34 -06:00
Thomas Hallock 9b782beabf feat: increase max super zoom to 120x for ultra-tiny regions
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>
2025-11-19 18:06:34 -06:00
Thomas Hallock d7ce474a51 feat: make super zoom threshold configurable and increase to 3px
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>
2025-11-19 18:06:34 -06:00
Thomas Hallock 814bf949f2 fix: center crosshairs and re-enable pointer lock after escape
**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>
2025-11-19 18:06:34 -06:00
Thomas Hallock 0ed4d13db6 fix: move pointer lock management to MapRenderer
**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>
2025-11-19 18:06:34 -06:00
Thomas Hallock 5388441ebb fix: increase z-index of pointer lock prompt overlay
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>
2025-11-19 18:06:34 -06:00
Thomas Hallock 0dbb2eb83c debug: add logging for pointer lock and custom cursor
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>
2025-11-19 18:06:34 -06:00
Thomas Hallock 5d6d6b4ddc fix: add custom cursor when pointer lock is active
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>
2025-11-19 18:06:34 -06:00
Thomas Hallock 749b16ac27 refactor: simplify pointer lock with movement delta multipliers
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>
2025-11-19 18:06:34 -06:00
Thomas Hallock 5e42aabfa9 refactor: remove debug logs for fixed issues
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>
2025-11-19 18:06:34 -06:00
Thomas Hallock cf2d63f5e6 debug: add verbose pointer lock logging
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>
2025-11-19 18:06:34 -06:00
Thomas Hallock 4d5953d034 feat: add Pointer Lock API for precision mode to prevent edge issues
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>
2025-11-19 18:06:34 -06:00
Thomas Hallock 97b214da12 fix: lower quick-escape threshold to 15px/frame for easier triggering
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>
2025-11-19 18:06:34 -06:00
Thomas Hallock e712bcd66d debug: add verbose logging for quick-escape and precision mode state
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>
2025-11-19 18:06:34 -06:00
Thomas Hallock e885ae7ef4 fix: add cooldown after quick-escape to prevent precision mode re-activation
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>
2025-11-19 18:06:34 -06:00
Thomas Hallock fc08b775db fix: eliminate cursor dampening lag when changing direction
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>
2025-11-19 18:06:34 -06:00
Thomas Hallock 8511998d0c docs: add comprehensive precision controls documentation for Know Your World
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>
2025-11-19 18:06:34 -06:00
Thomas Hallock 3bf127f344 feat: add precision controls for tiny regions in Know Your World
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>
2025-11-19 18:06:34 -06:00
semantic-release-bot bf849143b3 chore(release): 4.68.0 [skip ci]
## [4.68.0](https://github.com/antialias/soroban-abacus-flashcards/compare/v4.67.1...v4.68.0) (2025-11-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))
2025-11-19 02:14:07 +00:00
Thomas Hallock 1e8846cdb1 feat: add adaptive zoom magnifier for Know Your World map
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>
2025-11-18 20:04:52 -06:00
Thomas Hallock e900e4465b fix: properly zoom to selected continent in game phases
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>
2025-11-18 20:04:52 -06:00
Thomas Hallock 6651979ea0 fix: add zoom to selected continent and improve click detection
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>
2025-11-18 20:04:52 -06:00
Thomas Hallock 2e9f409f26 feat: add per-country coloring and individual region clicks to continent selector
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>
2025-11-18 20:04:52 -06:00
Thomas Hallock 07e92240e8 fix: add missing selectedContinent to default config and fix ts-expect-error directives 2025-11-18 20:04:52 -06:00
Thomas Hallock 245005c8ec feat: add interactive world map continent selector
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>
2025-11-18 20:04:52 -06:00
Thomas Hallock 7bb03b8409 feat: add continent filtering to Know Your World game
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>
2025-11-18 20:04:52 -06:00
Thomas Hallock 25e24a7cbc feat: add Know Your World geography quiz game
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>
2025-11-18 20:04:52 -06:00
semantic-release-bot ff04312232 chore(release): 4.68.0 [skip ci]
## [4.68.0](https://github.com/antialias/soroban-abacus-flashcards/compare/v4.67.1...v4.68.0) (2025-11-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))
2025-11-18 17:31:29 +00:00
Thomas Hallock a1b31f454a fix: enable vertical scrolling in layout controls
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>
2025-11-18 11:21:32 -06:00