Commit Graph

3188 Commits

Author SHA1 Message Date
Thomas Hallock f95456dadc fix(practice): remove fallback random problem generation
Remove the fallback that was silently generating random problems when
skill-based generation failed. Instead, throw ProblemGenerationError
with detailed constraint information so issues can be addressed.

The analyzeRequiredSkills function should only be used for tests or
stories, not in production where we need accurate skill tracking.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-10 20:56:48 -06:00
Thomas Hallock 5d61de4bf6 feat(practice): add complexity budget system and toggleable session parts
- Add skill complexity budget system with base costs per skill type:
  - Basic skills: 0 (trivial bead movements)
  - Five complements: 1 (single mental substitution)
  - Ten complements: 2 (cross-column operations)
  - Cascading operations: 3 (multi-column)

- Add per-term complexity debug overlay in VerticalProblem (toggle via visual debug mode)
  - Shows total cost per term and individual skill costs
  - Highlights over-budget terms in red

- Make session structure parts toggleable in configure page:
  - Can enable/disable abacus, visualization, and linear parts
  - Time estimates, problem counts adjust dynamically
  - At least one part must remain enabled

- Fix max terms per problem not being respected:
  - generateSingleProblem was hardcoding 3-5 terms
  - Now properly uses minTerms/maxTerms from constraints

- Set visualization complexity budget to 3 (more restrictive)
- Hide complexity badges for zero-cost (basic) skills in ManualSkillSelector

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-10 20:18:20 -06:00
Thomas Hallock 9159608dcd feat(practice): reduce term count for visualization part
Visualization problems now use 2-4 terms (75% of abacus's 3-6 terms)
to make them easier since students don't have the physical abacus
to help track their mental calculations.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-10 11:32:19 -06:00
Thomas Hallock 7cf689c3d9 feat(practice): add cascading regrouping skills and improve help UX
- Add advanced.cascadingCarry and advanced.cascadingBorrow skills for
  detecting when carry/borrow propagates across 2+ consecutive columns
  (e.g., 999 + 1 = 1000 or 1000 - 1 = 999)
- Update VerticalProblem help UX: replace answer boxes with help abacus
  instead of floating above terms (less confusing for kids)
- Dim terms already in prefix sum at 40% opacity when in help mode
- Enlarge current-help arrow indicator to 1.75rem
- Add "Advanced Multi-Column Operations" category to ManualSkillSelector
  so teachers can manually enable these skills
- Add unit tests for cascading regrouping detection (21 tests)

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-10 11:19:09 -06:00
Thomas Hallock 5cfbeeb8df fix(practice): size answer boxes for intermediate prefix sums
- Calculate prefix sums (intermediate values) when determining maxDigits
- Ensures kids can enter step-by-step solutions that may be larger than final answer
- Example: 100-99=1 now has 3 answer boxes to accommodate entering "100" first

Also adds Playground story for testing any term sequence with:
- Textarea input with smart parsing of negatives
- Display of all prefix sums and max digits needed
- Interactive answer input

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-10 10:24:20 -06:00
Thomas Hallock e5c697b7a8 feat(tutorial): implement subtraction in unified step generator
Add complete subtraction support to the decomposition system:

- Direct subtraction: remove beads when sufficient
- Five's complement subtraction: -d = -5 + (5-d)
- Ten's complement subtraction (borrow): -d = +(10-d) - 10
- Multi-digit subtraction with left-to-right processing
- Cascade borrow through consecutive zeros

Also adds:
- Comprehensive architecture documentation
- Subtraction implementation plan with design decisions
- Decomposition audit story for testing all operation types
- Skill extraction functions for subtraction skills

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-10 09:31:13 -06:00
Thomas Hallock 4f7a9d76cd feat(practice): add subtraction support to problem generator
- Add subtraction problem generation alongside addition
- Generator now uses signed terms (negative = subtraction)
- Update analyzeRequiredSkills to handle mixed operations
- Remove dead generateSkillTrace function (replaced by provenance)
- Add ProblemGeneratorAudit story for debugging skill analysis
- Display subtraction terms in red with proper +/- signs in audit UI

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-10 08:06:34 -06:00
Thomas Hallock a3e79dac74 chore: sync lockfile with package.json
Regenerate pnpm-lock.yaml to fix CI deployment failure.
The lockfile was out of sync causing "ERR_PNPM_OUTDATED_LOCKFILE"
in GitHub Actions when running with frozen-lockfile.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-10 07:06:29 -06:00
Thomas Hallock e42766c893 feat(practice): add 30 and 45 minute session duration options
Extends session duration choices from [5, 10, 15, 20] to [5, 10, 15, 20, 30, 45] minutes, allowing for longer practice sessions with more problems.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-09 21:01:13 -06:00
Thomas Hallock c40543ac64 feat(practice): unify dashboard with session-aware progress display
- Make ProgressDashboard session-aware with single primary CTA
  - No session: "Start Practice →" (blue)
  - Active session: "Resume Practice →" (green) with progress count
  - Single "Start over" link replaces redundant Abandon/Regenerate buttons
- Add skill mismatch warning inline in level card
- Add masteredSkillIds to session_plans for mismatch detection
- Fix getActiveSessionPlan to check completedAt IS NULL (fixes loop bug)
- Remove separate Active Session Card from dashboard (now integrated)

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-09 20:59:53 -06:00
Thomas Hallock 245cc269fe feat(practice): use student's actual mastered skills for problem generation
Major fix: Session planner now uses the student's actual mastered skills
from the database instead of hardcoded phase-based constraints.

Changes:
- Add buildConstraintsFromMasteredSkills() to convert student skill records
  to problem generator constraints
- Session planner fetches mastered skills and passes them to problem generator
- Skills set via ManualSkillSelector now actually affect generated problems
- Remove unused buildChallengeConstraints() function
- Fix findStrugglingSkills() signature (remove unused param)

Also includes supporting changes from previous session:
- Add setMasteredSkills() to progress-manager for persisting skills
- Add PUT endpoint to skills/route.ts for saving mastered skills
- Display mastered skills in session configure preview
- Add "View All Planned Problems" section to SessionSummary
- Sync ManualSkillSelector state when modal opens

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-09 19:18:48 -06:00
Thomas Hallock c19109758a refactor(practice): remove unnecessary route guards
Routes are now independent views, not exclusive states:
- /dashboard: always accessible (view stats during session)
- /configure: always accessible (prep next session during session)
- /summary: always accessible (shows in-progress partial results,
  completed session, or empty state)

Only /practice/[studentId] retains guards since it requires an
active in-progress session to render a problem.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-09 15:10:54 -06:00
Thomas Hallock 5ebc743b43 refactor(practice): unify configure page with live session preview
- Restructure practice routes so each route represents valid state
- /practice/[studentId] now ONLY shows the current problem
- New /dashboard route for progress view
- New /summary route with guards (can't view mid-session)
- Combine configure + plan review into single unified page with:
  - Duration selector that updates preview in real-time
  - Live problem count and session structure preview
  - Single "Let's Go!" button that generates + starts session
- Replace two-stage flow with instant feedback UX
- Delete StudentPracticeClient (replaced by simpler PracticeClient)
- Add getMostRecentCompletedSession for summary page

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-09 14:13:54 -06:00
Thomas Hallock 9c646acc16 style: format practice session files
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-09 12:48:36 -06:00
Thomas Hallock f74db216da chore: remove abandoned 3d-printing feature
Remove dead code from abandoned 3D printing initiative:
- Delete jobManager.ts (had unbounded memory growth)
- Delete openscad.worker.ts (unused)
- Delete 3D model files from public/
- Remove openscad-wasm-prebuilt dependency
- Clean up doc references

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-09 12:48:13 -06:00
Thomas Hallock ae1a0a8e2d fix(practice): use React Query cache for /resume page session data
The /resume page was showing stale session data when navigating mid-session.
Now uses useActiveSessionPlan with server props as initialData, so cached
session data from the active practice session takes priority.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-09 12:48:05 -06:00
Thomas Hallock 28b3b30da6 fix(practice): include endEarly.data in currentPlan priority chain
The stop button wasn't working because endEarly.data was not included
in the currentPlan derivation chain. When the mutation completed with
the updated plan (completedAt set), the view didn't update to 'summary'.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-09 12:22:15 -06:00
Thomas Hallock 7b476e80c1 feat(practice): add /resume route for "Welcome back" experience
- Create /practice/[studentId]/resume route for returning students
- Student selector navigates to /resume instead of main practice page
- /resume shows "Welcome back" card with session progress
- Clicking "Continue" navigates to /practice/[studentId] (goes straight to practice)
- Clicking "Start Fresh" abandons session and goes to /configure
- Main practice page no longer shows welcome card (goes straight to practicing)
- Reloading mid-session stays in practice (no welcome card)

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-09 12:00:01 -06:00
Thomas Hallock 7243502873 fix(practice): make session plan page self-sufficient for data loading
- Update useActiveSessionPlan to accept initialData from server props
- Page now fetches its own data if cache is empty (no abstraction hole)
- Three loading scenarios handled:
  1. Cache populated (from ConfigureClient mutation): instant display
  2. Cache miss: fetches from API with loading state
  3. Direct page load: uses server props as initialData
- Add loading view while fetching session plan

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-09 11:52:52 -06:00
Thomas Hallock 8a9afa86bc fix(practice): disable auto-scroll and add modern PWA meta tag
- Add scroll: false to all router.push() calls in practice pages
- Add scroll={false} to Link component in not-found page
- Fixes Next.js warning about auto-scroll with fixed position header
- Add mobile-web-app-capable meta tag alongside deprecated apple-mobile-web-app-capable

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-09 11:25:53 -06:00
Thomas Hallock 43e7db4e88 fix(practice): check all later prefix sums for ambiguity, not just final answer
Previously, typing "3" for problem [2, 1, 30, 10, 1] with prefix sums
[2, 3, 33, 43, 44] would immediately show help for prefix sum 3 because
the code only checked if "3" was a digit-prefix of the final answer (44).

Now it correctly checks if "3" could be a digit-prefix of ANY later prefix
sum (33 in this case), making it ambiguous and allowing the user to continue
typing "33" to get help for that prefix instead.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-09 10:48:38 -06:00
Thomas Hallock ed277ef745 feat(practice): refactor disambiguation into state machine with comprehensive tests
- Complete migration of disambiguation state into the state machine
- Remove backward compatibility code (no legacy concerns in new app)
- Eliminate dual-state patterns in ActiveSession.tsx
- Export derived state from hook (attempt, helpContext, outgoingAttempt)
- Export boolean predicates (isTransitioning, isPaused, isSubmitting)
- Add comprehensive tests for awaitingDisambiguation phase
- Fix tests to match actual unambiguous prefix sum behavior
- Add SSR support with proper hydration for practice pages

The state machine is now the single source of truth for all UI state.
Unambiguous prefix matches immediately trigger helpMode, while ambiguous
matches enter awaitingDisambiguation with a 4-second timer.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-09 10:19:14 -06:00
Thomas Hallock 46ff5f528a feat(practice): add prefix sum disambiguation and debug panel
- Add ProblemDebugPanel component for viewing current problem details
  when visual debug mode is enabled (fixed position, collapsible, copy JSON)

- Fix false positive help mode triggers when typing multi-digit answers
  - "3" when answer is "33" now shows "need help?" prompt instead of
    immediately triggering help mode
  - 4 second timer before auto-triggering help in ambiguous cases

- Add leading zero disambiguation for requesting help
  - Typing "03" explicitly requests help for prefix sum 3
  - isDigitConsistent now allows leading zeros
  - findMatchedPrefixIndex treats leading zeros as unambiguous help request

- Add "need help?" styled pill prompt on ambiguous prefix matches
  - Yellow pill badge with arrow pointing to the term
  - Pulse animation for visibility

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-09 09:32:27 -06:00
Thomas Hallock 36c9ec3301 fix(practice): handle paused state transitions and add complete phase
Fix edge cases in the state machine:
- completeSubmit now works while paused (updates resumePhase)
- completeTransition now works while paused (updates resumePhase)
- Add 'complete' phase for session completion
- Allow enterHelpMode from helpMode (navigate between terms)
- Add transformActivePhase helper for paused state handling
- Add markComplete action and isComplete predicate
- Prevent pausing from complete phase

Add 5 new tests for these edge cases.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-08 15:47:47 -06:00
Thomas Hallock 1ce448eb0b refactor(practice): clean up props for state machine compatibility
- NumericKeypad: add showSubmitButton prop to hide submit during auto-submit
- VerticalProblem: remove autoSubmitPending prop (state machine handles this)
- Add usePracticeSoundEffects hook for centralized sound effect management

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-08 15:28:03 -06:00
Thomas Hallock 4d41c9c54a refactor(practice): replace boolean flags with state machine
Replace scattered boolean state flags (isPaused, isSubmitting, isTransitioning,
feedback, helpTermIndex) with a single discriminated union state machine.

- Add useInteractionPhase hook with 7 explicit phases:
  loading, inputting, helpMode, submitting, showingFeedback, transitioning, paused
- Derive all UI predicates from phase state (canAcceptInput, showHelpOverlay, etc.)
- Delete useProblemAttempt hook (superseded by state machine)
- Add 62 comprehensive tests for phase transitions and derived state

Benefits:
- Single source of truth for all interaction state
- Impossible states eliminated (can't be paused AND submitting)
- Explicit phase transitions instead of scattered boolean flipping
- Type safety ensures phase-appropriate data access

Both vertical and linear problem formats use the same state machine.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-08 15:28:03 -06:00
semantic-release-bot fd7e317151 chore(abacus-react): release v2.15.0 [skip ci]
# [2.15.0](https://github.com/antialias/soroban-abacus-flashcards/compare/abacus-react-v2.14.0...abacus-react-v2.15.0) (2025-12-08)

### Bug Fixes

* **404:** reset easter egg config on page reload/close ([d6f1c13](d6f1c13317))
* account for SVG preserveAspectRatio in coordinate transforms ([e4e0925](e4e09256c2))
* 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 missing openDeploymentInfo prop to MinimalNav ([30879d8](30879d8959))
* add missing scaleX and scaleY number conversions ([ae6cc5e](ae6cc5e326))
* add missing selectedContinent to default config and fix ts-expect-error directives ([07e9224](07e92240e8))
* add mode descriptions and remove double borders ([6f2f6d4](6f2f6d444c))
* add quotes around unquoted keys when parsing customCrops.ts ([0add49c](0add49c599))
* 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 zoom to selected continent and improve click detection ([6651979](6651979ea0))
* align share persistence with user session logic ([72c72fc](72c72fc218))
* calculate total problems correctly in preview API ([25dfb71](25dfb71b3e))
* cancel previous give-up animation when new give-up starts ([c01cb7f](c01cb7f384))
* cap zoom when releasing pointer lock (escape key) ([2331f10](2331f1038c))
* center crosshairs and re-enable pointer lock after escape ([814bf94](814bf949f2))
* change zoom capping to create pause effect instead of slow easing ([f2ca9d1](f2ca9d1ebe))
* combine fast easing with smooth precision mode transition ([cab1fbf](cab1fbff95))
* configure Next.js to transpile [@svg-maps](https://github.com/svg-maps) ES modules ([ebf2b66](ebf2b66910))
* consolidate worksheet validation constants and increase MAX_PAGES to 100 ([0f3ec36](0f3ec369bf))
* correct GPT-5 API parameters and surface actual grading errors ([2d33f35](2d33f35c4d))
* **create:** use inline styles for dynamic gradient backgrounds ([ed25b32](ed25b323e8))
* DevCropTool key quoting and magnifier label positioning ([2e4f22a](2e4f22a522))
* don't show labels for excluded/filtered regions ([a83fbb1](a83fbb1070))
* eagerly load map caches in browser and use Suspense pattern ([db6be73](db6be73a1c))
* 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))
* ensure entire region path is clickable with pointerEvents: all ([eb94191](eb94191b2e))
* export worksheet schema tables from index ([6a16674](6a1667404f))
* hide abacus on /arcade and /arcade-rooms routes ([77033f0](77033f0b22))
* implement manual click detection using precise cursor position ([156f63f](156f63faaf))
* 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 magnifier zoom smoothness and debug panel ([639e662](639e662d76))
* improve socket server error messages for better debugging ([5d1ea7d](5d1ea7db2d))
* improve text contrast for selected dropdown items in dark mode ([8d03452](8d0345287f))
* improve zoom easing to threshold by deferring capping ([b355a3f](b355a3fc8f))
* increase sampling density for tiny region detection and show all detected regions ([2c9f760](2c9f760ae9))
* increase super zoom multiplier from 2.5x to 5.0x for Gibraltar ([138e6c0](138e6c071b))
* increase z-index of pointer lock prompt overlay ([5388441](5388441ebb))
* **know-your-world:** actually change magnifier element dimensions to 1/3 ([31a06d6](31a06d6fef))
* **know-your-world:** allow space in name confirmation input ([285b128](285b128bb8))
* **know-your-world:** center setup settings panel horizontally ([5f69fab](5f69fab859))
* **know-your-world:** correctly identify local player for cursor sharing ([7aafe8c](7aafe8c92e))
* **know-your-world:** enable hot/cold only for current player in turn mode ([f5ce53e](f5ce53efc0))
* **know-your-world:** fix celebration timer restart and mobile magnifier dismissal bugs ([0558132](055813205a))
* **know-your-world:** fix hot/cold visual feedback delay ([a6352ec](a6352ec624))
* **know-your-world:** fix pointer lock escape for all edges and add smooth release animation ([a7fa858](a7fa858a29))
* **know-your-world:** fix server/client filter mismatch for USA map ([98e74ba](98e74bae3a))
* **know-your-world:** fix TypeScript build errors ([f622bfa](f622bfab54))
* **know-your-world:** guard against undefined state during session init ([ea8965b](ea8965bc95))
* **know-your-world:** improve crosshair UX and fix mobile Select button ([0584863](0584863bdd))
* **know-your-world:** improve mobile layout for setup screen ([81b44a6](81b44a6422))
* **know-your-world:** improve mobile magnifier positioning and sizing ([9a254e2](9a254e2933))
* **know-your-world:** improve mobile magnifier touch controls ([aee5f21](aee5f21ecc))
* **know-your-world:** make game settings visible in right panel ([11d2d56](11d2d5693c))
* **know-your-world:** move Start button to top-right settings panel ([cc51de3](cc51de35e3))
* **know-your-world:** normalize accented letters for keyboard input ([b27856e](b27856e9fc))
* **know-your-world:** prevent hint bubble closing when toggling settings ([a67c11a](a67c11ae04))
* **know-your-world:** raise auto-zoom thresholds for tiny regions ([17c113e](17c113e68b))
* **know-your-world:** reduce magnifier size to 1/3 of pane dimensions ([61a438d](61a438dd31))
* **know-your-world:** remove confidence gate from hot/cold visual emoji ([7f6b9dd](7f6b9dd558))
* **know-your-world:** remove hovered region label from setup screen ([5bb2288](5bb228883d))
* **know-your-world:** Remove redundant preventDefault calls in touch handlers ([021a75f](021a75f583))
* **know-your-world:** remove tips section from setup screen ([c9e9190](c9e9190937))
* **know-your-world:** replace react-spring with CSS animation for crosshair rotation ([af5e7b5](af5e7b59dc))
* **know-your-world:** restore no-music celebration sounds ([f6d1295](f6d1295c6f))
* **know-your-world:** restore Start button character ([7013a7b](7013a7b068))
* **know-your-world:** stabilize mobile magnifier 1:1 touch tracking ([ab30add](ab30adda25))
* **know-your-world:** suppress hot/cold hints during takeover and give-up ([9f6b425](9f6b425daf))
* **know-your-world:** use getBBox() for consistent takeover positioning ([f8acc4a](f8acc4aa6a))
* **know-your-world:** use localPlayerId for cursor updates in all modes ([5e8c37b](5e8c37b68e))
* **know-your-world:** use shared MAX_ZOOM constant for mobile magnifier ([e4c35e9](e4c35e9425))
* **know-your-world:** use spring-for-speed pattern for smooth crosshair rotation ([b7fe2af](b7fe2af369))
* **know-your-world:** use viewport-based maxHeight for right panel ([a4f9db6](a4f9db6d3f))
* lazy-load map data in know-your-world validator ([07c25a2](07c25a2296))
* lower quick-escape threshold to 15px/frame for easier triggering ([97b214d](97b214da12))
* make map-renderer fill parent container for fit-crop-with-fill ([18b1476](18b14766b2))
* make placeholder pages match actual page dimensions ([4003c5c](4003c5ceb7))
* make useArcadeSocket work without ArcadeErrorProvider ([01740af](01740afcb7))
* merge duplicate style attributes on magnifier SVG ([3eda493](3eda493051))
* move pointer lock management to MapRenderer ([0ed4d13](0ed4d13db6))
* 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))
* position debug panel opposite from magnifier ([aa80a73](aa80a73664))
* position shared worksheet banner below app nav ([fb3412c](fb3412c9a5))
* **practice:** add 80px top padding to account for app nav height ([a50b268](a50b268d35))
* **practice:** allow vertical overflow for help overlays ([1ddf9fc](1ddf9fc94f))
* **practice:** prevent decomposition math from wrapping ([52ea3f1](52ea3f10fa))
* **practice:** remove overflow clipping to allow help overlays ([e9b123a](e9b123a7b3))
* **practice:** remove redundant 'already at target' message ([e9ccfb9](e9ccfb9186))
* **practice:** use explicit padding to prevent shorthand override ([4c00d92](4c00d92ccb))
* 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 zoom jump on precision mode activation by resetting spring target ([33d9f15](33d9f15897))
* prevent zoom jump when activating precision mode ([9cb3c89](9cb3c898ec))
* 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))
* reduce font size for mini skill card titles to prevent wrapping ([833b481](833b481ebb))
* refactor worksheet config persistence to blacklist approach + Storybook stories ([5b6db58](5b6db588a2))
* regenerate lockfile to remove big.js dependencies ([05fc5cf](05fc5cfe49))
* remove all scaffolding from final mastery skills ([d7bec42](d7bec423e0))
* remove background rect from main map SVG ([7d3c5c3](7d3c5c304b))
* remove duplicate containerRect declaration ([1a690e0](1a690e00b0))
* remove magnifierSpring.zoom from effect dependencies ([5eb2eed](5eb2eeda32))
* remove mispositioned background rect from magnifier SVG ([5815cbe](5815cbee15))
* remove pages from visible set when they leave viewport ([9757449](9757449e21))
* remove redundant 'Teens minus singles' subtraction skill ([e156e87](e156e870df))
* remove regex lookbehind for Safari compatibility ([4d77f1f](4d77f1ffd3))
* remove unused velocity tracking and fix TypeScript errors ([0195a6d](0195a6dc6d))
* replace deprecated path() with curve() in borrow arrows ([47d149c](47d149ca17))
* replace ES module imports with JSON data files ([fb735be](fb735be014))
* resolve auto zoom freeze and stuck zoom issues ([0aee60d](0aee60d8d1))
* 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))
* resume zoom animation immediately when precision mode activates ([7ba7e03](7ba7e03661))
* resume zoom animation immediately when precision mode activates ([7c1f2e5](7c1f2e54c9))
* resume zoom animation when target drops below threshold ([e73b59d](e73b59d510))
* scaffolding changes now apply in mastery+mixed mode ([510f052](510f052978))
* **server:** lazy-load game validators to avoid ES module errors ([a88bd58](a88bd5844c))
* show hot/cold button on iPad with mouse attached ([1333818](1333818bae))
* skip pointer lock request on unsupported devices (iPad) ([d6eb997](d6eb997445))
* stabilize mini skill card height and fix preview updates ([4a52943](4a5294353e))
* take all measurements inside animation callback for label sync ([2191e07](2191e0732b))
* track both SVG units and screen pixels for zoom and dampening ([d72f309](d72f309bad))
* transform screen coordinates to SVG space for isPointInFill() ([4c933be](4c933be48a))
* transmit hovered region ID with network cursor to avoid hit-testing discrepancies ([6c3f860](6c3f860efc))
* **tutorial:** expose activeGroupTargetColumn state to context ([69f759a](69f759a178))
* update AbacusQRCode for qrcode.react v4 compatibility ([0f0c3c6](0f0c3c65e8))
* update operator-specific display rules in mastery+mixed mode ([4174b6d](4174b6d2e7))
* upgrade to Node.js 20 to resolve ES module import issues ([192de5c](192de5c6b5))
* use ± symbol for mixed operator icon consistently ([2695b50](2695b50abe))
* use actual SVG path geometry for region detection instead of bounding boxes ([e255ce2](e255ce2c6f))
* use animated spring for magnifier label positioning ([94d1cdf](94d1cdfcb5))
* use ASCII characters for operator icons to support dark mode ([3bd5c00](3bd5c00d21))
* use correct Unicode minus sign (−) for subtraction operator checks ([0dd9e45](0dd9e45952))
* use dynamic ES module imports for [@svg-maps](https://github.com/svg-maps) packages in know-your-world ([ab94fd3](ab94fd350f))
* use LAN IP instead of localhost for QR code camera uploads ([00b400a](00b400ae8a))
* use screen pixels for zoom, abandon SVG path parsing ([912dc38](912dc385b3))
* 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))
* **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:** correct Typst array membership syntax for ten-frames rendering ([14b3594](14b359462f))
* **worksheets:** enable borrowNotation and borrowingHints in smart difficulty mode ([8020ee8](8020ee835e))
* **worksheets:** prevent infinite loop when problem space is empty ([02463df](02463df8e5))
* **worksheets:** render operators last for proper layering ([cdd0de7](cdd0de797f))
* **worksheets:** sync preview and download problem generation ([822ef78](822ef78e58))
* **worksheets:** ten-frames not rendering in mastery mode ([b36df3a](b36df3a40c))
* **worksheets:** validation function was converting mastery mode to manual ([4ad687d](4ad687df73))

### Features

* **abacus-react:** add defaultValue prop for uncontrolled mode ([3ce12c5](3ce12c59fc))
* add 'auto' option for scaffolding to defer to mastery progression ([a945a62](a945a620c4))
* add adaptive zoom magnifier for Know Your World map ([1e8846c](1e8846cdb1))
* add AI-powered worksheet grading with GPT-5 vision ([6e95732](6e9573288f))
* add auto scaffolding mode with visual feedback and override notices ([b62db5a](b62db5a323))
* add auto-submit on correct answer + Newton poem blog post ([2f7cb03](2f7cb03c3f))
* add comprehensive error handling for arcade games ([e8c5256](e8c52561a2))
* add continent filtering to Know Your World game ([7bb03b8](7bb03b8409))
* add custom error boundaries with navigation ([73cc418](73cc4185c3))
* add database schema for custom skills and skill customizations ([906fa63](906fa63f24))
* add debug bounding boxes to magnifier view ([9c7d2fa](9c7d2fab5f))
* add debug indicator for custom crop region (dev only) ([9c89aad](9c89aadb17))
* add detailed zoom decision debug panel ([cb57f15](cb57f1585a))
* add dev-only crop tool for custom map region cropping ([855e5df](855e5df2c0))
* 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 give up with zoom animation for Know Your World ([94cff43](94cff4374f))
* add gold scrim overlay and improve precision mode messaging ([4b20d07](4b20d0753f))
* 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 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 precision mode system with pixel grid visualization ([53e9041](53e90414a3))
* 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 fade-in animation for 404 message text changes ([e88380a](e88380a48d))
* add split-action share button with copy shortcut ([085d200](085d200da4))
* add themed backgrounds and enhanced styling to 404 page ([dd14062](dd14062112))
* add visible grab tab to worksheet panel resize handle ([288e6ed](288e6ed878))
* add visual debugging for zoom importance scoring ([e60a2c0](e60a2c09c0))
* 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))
* **blog:** add subtraction and multi-digit worksheet blog posts ([dd9587f](dd9587f8cd))
* calculate zoom based on region under cursor, target 15% area ([6736336](6736336317))
* convert operator selection to checkboxes with required validation ([c997c4a](c997c4a7ba))
* create unified difficulty interface with 2-tab selector ([0b7382f](0b7382f1b6))
* enable production source maps for easier debugging ([d992e98](d992e98d77))
* enhance scaffolding tab with live preview and resolved display rules ([9a5a0d4](9a5a0d4e3c))
* **help-system:** add focus areas for skills needing reinforcement ([871390d](871390d8e1))
* **help-system:** add schema for progressive help and feedback loop ([41c4603](41c46038d8))
* **help-system:** add usePracticeHelp hook and skill extraction ([0b1ad1f](0b1ad1f896))
* **help-system:** integrate PracticeHelpPanel into ActiveSession ([373ec34](373ec34e46))
* hide easter egg hint until first discovery ([c2c7153](c2c71531ae))
* implement binary search for optimal zoom level ([1a54f09](1a54f09814))
* implement fit-crop-with-fill for custom map crops ([b6569ed](b6569ed4e1))
* implement lazy loading for worksheet preview with cursor pagination ([8b3d019](8b3d019652))
* implement lazy loading for worksheet preview with cursor pagination ([2a7d67d](2a7d67db58))
* 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))
* **know-your-world:** add 'H' keyboard shortcut for hint ([cdc9451](cdc94514d9))
* **know-your-world:** add adaptive hint cycling for struggling users ([5440250](54402501e5))
* **know-your-world:** add celebration animations for found regions ([3b9d6b0](3b9d6b0fdf))
* **know-your-world:** add device capability hooks and improve mobile support ([c502a4f](c502a4fa92))
* **know-your-world:** add drill-down map selector and improve setup UI ([a6f8dbe](a6f8dbe474))
* **know-your-world:** add filter tabs for size, importance, and population ([6c3c0ac](6c3c0ac70e))
* **know-your-world:** add fire tracer animation for learning mode takeover ([1e6153e](1e6153ee8b))
* **know-your-world:** add hint system, pointer lock buttons, and mobile magnifier support ([55e480c](55e480c03b))
* **know-your-world:** add hints for Europe and Africa regions ([46e5c6b](46e5c6b99b))
* **know-your-world:** add hot/cold audio feedback for cursor proximity ([69813e9](69813e92a2))
* **know-your-world:** add hot/cold debug panel and production debug mode ([493313a](493313a3bb))
* **know-your-world:** add hot/cold feedback for mobile magnifier ([824325b](824325b843))
* **know-your-world:** add interaction state machine foundation ([e4d6748](e4d6748d70))
* **know-your-world:** add Learning mode and fix hints before name unlock ([fc87808](fc87808b40))
* **know-your-world:** add learning mode takeover animation and fix give-up sequence ([3fd8472](3fd8472e68))
* **know-your-world:** add map zoom preview, remove study time feature ([57dd61b](57dd61b994))
* **know-your-world:** add missing island hints and revise all hints ([8b13b5a](8b13b5a455))
* **know-your-world:** add mobile cursor sharing and fix multi-device coop mode ([2ce5e18](2ce5e180b7))
* **know-your-world:** add mobile virtual keyboard and space-skipping ([5318d0d](5318d0dd89))
* **know-your-world:** add multiplayer cursor sharing and fix map viewport ([c3b94be](c3b94bea3d))
* **know-your-world:** add puzzle piece fly-to-map animation for learning mode ([7c49652](7c496525e9))
* **know-your-world:** add range thermometer for region size selection ([c7c4e7c](c7c4e7cef3))
* **know-your-world:** add region shape silhouette to learning takeover ([ebe07e3](ebe07e358f))
* **know-your-world:** add session-based give-up voting and fix cursor emojis ([bb2d6fc](bb2d6fc7d8))
* **know-your-world:** add speech announcements and compass-style crosshairs ([e0b762e](e0b762e3ee))
* **know-your-world:** add speech synthesis for hints with auto-hint/auto-speak ([cd841ff](cd841ff7dc))
* **know-your-world:** add Strudel-based music system ([7dab07b](7dab07b3a7))
* **know-your-world:** add SVG path geometry helpers for future use ([ea141f0](ea141f04f6))
* **know-your-world:** add turn-based restrictions for letter typing ([45730bb](45730bb4db))
* **know-your-world:** align guidance UI with assistance levels ([7e7a8dc](7e7a8dc1e8))
* **know-your-world:** auto-enable hot/cold for learning mode ([dcc32c2](dcc32c288f))
* **know-your-world:** enhance hint audio and region name display ([e6f58bf](e6f58bfd93))
* **know-your-world:** fix magnifier outline aspect ratio and add visual debug toggle ([ac915f2](ac915f2065))
* **know-your-world:** full-screen layout with squish-through pointer lock escape ([1729418](1729418dc5))
* **know-your-world:** implement empirical scale measurement for 1:1 magnifier tracking ([39886e8](39886e859c))
* **know-your-world:** improve magnifier UX and hide abacus on games ([fa1514d](fa1514d351))
* **know-your-world:** improve mobile magnifier controls and animations ([4449fb1](4449fb19b4))
* **know-your-world:** improve mobile magnifier with adaptive zoom and select button ([60cf98e](60cf98e77a))
* **know-your-world:** improve region size filter layout ([558d369](558d369ba0))
* **know-your-world:** improve setup screen UX ([dc4d621](dc4d62195b))
* **know-your-world:** improve takeover UI and fix celebration sound bug ([a8c6b84](a8c6b84855))
* **know-your-world:** live crop updates and safe zone improvements ([3f4691e](3f4691e8a3))
* **know-your-world:** make magnifier lazy - only move when cursor obscured ([ac82564](ac82564eac))
* **know-your-world:** make magnifier size responsive to aspect ratio ([5920cb4](5920cb4dc3))
* **know-your-world:** match setup phase map positioning with gameplay ([b030558](b0305581f9))
* **know-your-world:** move region size filters inside map preview ([81301ab](81301ab148))
* **know-your-world:** move start button below settings controls ([a05c4ca](a05c4ca5bf))
* **know-your-world:** Phase 2 - integrate useMagnifierZoom hook ([8ce878d](8ce878d03e))
* **know-your-world:** responsive setup + travel-themed start button ([02762fa](02762fad81))
* **know-your-world:** separate region filtering from assistance level ([9499e4e](9499e4e8b5))
* **know-your-world:** show magnifier on mobile drag gesture ([a02a710](a02a7108e9))
* **know-your-world:** speak country names in user's locale ([426a1e6](426a1e6868))
* **know-your-world:** sync letter confirmation across multiplayer sessions ([655660f](655660f7cf))
* **know-your-world:** unified region selector with inline list on desktop ([d329d80](d329d80399))
* **know-your-world:** unify setup and gameplay UI positions ([141a506](141a506739))
* **know-your-world:** unify setup UI positions with gameplay ([c1a0485](c1a0485b1d))
* **know-your-world:** wire interaction state machine to MapRenderer ([7e55953](7e55953eee))
* make 404 page abacus hero-sized and responsive ([41de252](41de25238f))
* 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 problem generation and add duplicate warning system ([11c46c1](11c46c1b44))
* pause zoom animation at precision mode threshold ([c4989b3](c4989b3ab0))
* pause/resume zoom animation at precision mode threshold ([bdf59e5](bdf59e571d))
* pause/resume zoom animation at precision mode threshold ([4687820](4687820d8a))
* persist seed and prngAlgorithm for exact problem reproducibility ([8cb2209](8cb2209d84))
* **practice:** add dark mode support and fix doubled answer digits ([026993c](026993cb05))
* **practice:** add progressive help overlay with proper positioning ([9a4ab82](9a4ab8296e))
* **practice:** add session HUD with tape-deck controls and PageWithNav ([b19c6d0](b19c6d0eca))
* **practice:** add smooth problem transition animation ([b12112e](b12112e8da))
* **practice:** add student onboarding and offline sync features ([b52f054](b52f0547af))
* **practice:** add three-part daily practice session system ([5855438](585543809a))
* **practice:** improve help UX with coach hints and simplified UI ([19169ad](19169ad9fe))
* **practice:** integrate progressive help with decomposition display ([804d937](804d937dd9))
* redesign shared worksheet viewer with read-only studio and proper error handling ([23dccc0](23dccc0ef3))
* remove all easter egg hints from 404 page ([1756182](17561829ef))
* remove redundant navigation buttons from 404 page ([e5262e5](e5262e5007))
* show magnifier only when current target region needs magnification ([996c973](996c973774))
* show magnifier only when target region needs it ([c6997ac](c6997ac9a7))
* show visual feedback for auto-resolved scaffolding values ([fbe776a](fbe776ac09))
* smooth cursor dampening transitions with react-spring ([66544dc](66544dc7dd))
* **thermometer:** add "only" buttons to quickly select single category ([623f882](623f882075))
* **worksheets:** add 3x scale effect to thrown dice ([920a855](920a855eb5))
* **worksheets:** add draggable dice easter egg with physics ([b8e66df](b8e66dfc17))
* **worksheets:** add duplicate risk warnings to page selector UI ([1d8dceb](1d8dceb55b))
* **worksheets:** add foundational steps to progression path ([7e6f99b](7e6f99b78c))
* **worksheets:** add QR codes with share codes for easy worksheet sharing ([a0e73d9](a0e73d971b))
* **worksheets:** add shuffle button with animated dice icon ([f97efb5](f97efb5c94))
* **worksheets:** add viewport edge ricochet to dice physics ([c6db7dc](c6db7dcfa2))
* **worksheets:** enhance dice throw physics for natural feel ([047a960](047a960567))
* **worksheets:** restore mastery progression UI with 3-way mode selector ([26a0885](26a08859d7))
* **worksheets:** smooth dice rotation settle to final face ([d00c707](d00c70750e))
* **worksheets:** upgrade to 3D dice with random rotation animation ([3cd5e49](3cd5e4992b))

### Performance Improvements

* add spatial filtering to skip distant regions ([8cb4c88](8cb4c88bef))
* cache polygon conversions to fix performance regression ([348ce8f](348ce8f314))
* **know-your-world:** memoize state machine return value and remove debug logging ([d85b976](d85b976f8b))
* reduce retry limit from 3000 to 100 in problem generators ([08fef59](08fef59cc5))

### Reverts

* **know-your-world:** undo premature extractions, restore working state ([f0bf205](f0bf2050d3))
* remove ngrok and LAN IP detection ([0040b57](0040b57829))
2025-12-08 17:50:10 +00:00
Thomas Hallock e937c05323 chore: miscellaneous updates and documentation
- Update know-your-world implementation docs
- Update decomposition CSS styles
- Update AbacusReact component
- Update gallery template
- Update dependencies (pnpm-lock.yaml)
- Update biome config

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-08 11:40:59 -06:00
Thomas Hallock b56c8f439b refactor(practice): add centralized style system for practice components
Add new style utilities to reduce duplication and improve maintainability:
- practiceTheme.ts: Color definitions with light/dark variants and themed() helper
- practiceStyles.ts: Reusable style functions (cards, buttons, badges, progress bars)
- practiceMixins.ts: Layout primitives (centerStack, row, gap/padding presets)
- index.ts: Central export for all utilities

Migrate NumericKeypad and StudentSelector as proof of concept.
Also fix StudentSelector.stories.tsx invalid isGuest property.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-08 11:29:25 -06:00
Thomas Hallock 4c00d92ccb fix(practice): use explicit padding to prevent shorthand override
Replace padding shorthand with explicit paddingTop/Right/Bottom/Left
values to ensure the extra 4rem top padding for help overlays is
applied correctly. CSS shorthand properties can override specific
properties depending on declaration order.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-08 11:14:02 -06:00
Thomas Hallock e9b123a7b3 fix(practice): remove overflow clipping to allow help overlays
Remove overflow-x/overflow-y clipping as CSS doesn't allow mixing
visible and hidden on different axes. The outgoing problem fades
to opacity 0 anyway so clipping isn't needed.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-08 11:07:05 -06:00
Thomas Hallock 1ddf9fc94f fix(practice): allow vertical overflow for help overlays
Change overflow: hidden to overflowX: hidden + overflowY: visible
so help elements above the problem are not clipped while still
hiding horizontal transition animation overflow.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-08 09:57:58 -06:00
Thomas Hallock b12112e8da feat(practice): add smooth problem transition animation
- Add react-spring animation for transitioning between problems
- New problem fades in to the right, then track slides left to center it
- Outgoing problem fades out during the slide
- Use useLayoutEffect to prevent layout jank from flexbox recentering
- Use flushSync for smooth cleanup when removing outgoing problem
- Hide decomposition section when not meaningful (e.g., "5 = 5")
- Add DecompositionSection component for self-contained display
- Simplify HelpAbacus visibility with opacity + pointer-events

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-08 09:56:51 -06:00
Thomas Hallock 52ea3f10fa fix(practice): prevent decomposition math from wrapping
Add whiteSpace: 'nowrap' to keep the step-by-step math on one line.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-08 06:41:46 -06:00
Thomas Hallock 88a2b82f55 refactor(practice): remove usePracticeHelp hook and progressive help levels
We no longer use progressive help levels - help shows all at once when
a prefix sum is detected. Removed:
- usePracticeHelp hook and all helpState/helpActions usage
- helpSettings and isBeginnerMode props
- currentTermIndex state (unused after help system removal)
- handleDismissHelp callback (unused)
- Help tracking fields from result (helpLevelUsed, helpTrigger)

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-08 06:37:20 -06:00
Thomas Hallock 10c210c3b1 refactor(practice): simplify submit button, remove unused help button state
Since help auto-triggers when a prefix sum is detected, the "Get Help"
button state was never actually usable. Simplified to just Submit/disabled.

- Replace buttonState ('help'|'submit'|'disabled') with canSubmit boolean
- Remove handleGetHelp callback (auto-help useEffect handles it)
- Button now always shows "Submit" or "Enter Total"

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-08 06:26:39 -06:00
Thomas Hallock b46a99a3a1 refactor(practice): remove part instruction banner
The part type is already shown in the HUD - redundant banner removed.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-07 21:05:56 -06:00
Thomas Hallock e9ccfb9186 fix(practice): remove redundant 'already at target' message
Return null instead of showing message when target is reached -
the success feedback is already shown elsewhere in the component.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-07 20:59:01 -06:00
Thomas Hallock 19169ad9fe feat(practice): improve help UX with coach hints and simplified UI
- Add coach hint generator using same hints as tutorial (segment.readable.summary)
- Hide abacus numerals in help mode for cleaner display
- Restructure layout: abacus centered, coaching panel on right side
- Exit help mode completely when student finishes adding term to abacus
- Remove checkmarks from term indicators, keep only arrow for current term
- Clean up unused props (confirmedTermCount, detectedPrefixIndex, countdownElement)
- Add HelpCountdown component (pie chart timer, not currently used)

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-07 20:41:33 -06:00
Thomas Hallock 9a4ab8296e feat(practice): add progressive help overlay with proper positioning
- Create PracticeHelpOverlay component showing interactive abacus with
  bead arrows and tooltips (uses same system as TutorialPlayer)
- Extract BeadTooltipContent to shared component for consistency
- Add helpOverlay prop to VerticalProblem for proper positioning
- Position help abacus directly above the term being helped using
  bottom: 100% on the term row (overflow visible)
- Dynamically size abacus columns based on max(currentValue, targetValue)
- Add timing configuration in helpTiming.ts (debug vs production)
- Add beadTooltipUtils.ts for tooltip positioning calculations

The help overlay now correctly covers the confirmed terms in the
vertical problem, with the "Adding: +X" badge and interactive abacus
positioned above the term being worked on.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-07 15:38:17 -06:00
Thomas Hallock 804d937dd9 feat(practice): integrate progressive help with decomposition display
- Extract standalone DecompositionContext from TutorialContext
- Create reusable DecompositionDisplay and ReasonTooltip components
- Wire prefix-sum "Get Help" button to progressive help system (L1→L2→L3)
- Sync abacus interactions with decomposition step highlighting
- Add currentStepIndex tracking in PracticeHelpPanel
- Make HelpAbacus interactive at L3 to update decomposition display
- Update documentation linking decomposition components

The progressive help system now:
- L1: Shows coach hint when user clicks "Get Help" after typing prefix sum
- L2: Shows interactive decomposition with hoverable explanations
- L3: Shows visual abacus with arrows, synced with decomposition highlighting

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-07 08:56:35 -06:00
Thomas Hallock 2f7cb03c3f feat: add auto-submit on correct answer + Newton poem blog post
Practice session improvements:
- Auto-submit when correct answer entered with ≤2 corrections
- Show celebration animation ("Perfect!") before auto-submit
- Display prefix sum checkmarks/arrows before clicking "Get Help"

New blog post: "The Fluxion of Fortune"
- Poem about Newton losing money in the South Sea Bubble
- Hero image of Newton with his calculations and sinking ships
- Custom CSS for properly centered x-bar notation

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-07 06:46:12 -06:00
github-actions[bot] 4f25e1fd52 🎨 Update template examples and crop mark gallery
Auto-generated fresh SVG examples and unified gallery from latest templates.
Includes comprehensive crop mark demonstrations with before/after comparisons.

Files updated:
- packages/templates/gallery-unified.html

🤖 Generated with GitHub Actions

Co-Authored-By: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-12-07 02:40:16 +00:00
Thomas Hallock 026993cb05 feat(practice): add dark mode support and fix doubled answer digits
- Add dark mode support to all practice components:
  - ActiveSession, VerticalProblem, NumericKeypad, HelpAbacus
  - StudentSelector, ProgressDashboard, PlanReview, SessionSummary
  - OfflineSessionForm, ManualSkillSelector, PlacementTest, PracticeHelpPanel
- Fix doubled answer digit cells in VerticalProblem by consolidating
  two separate cell-rendering loops into a single unified loop

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-06 19:59:23 -06:00
Thomas Hallock a50b268d35 fix(practice): add 80px top padding to account for app nav height
Push main content down below the fixed app navigation bar.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-06 19:20:47 -06:00
Thomas Hallock b19c6d0eca feat(practice): add session HUD with tape-deck controls and PageWithNav
Major UI improvements to the practice session:
- Add dark control bar at top with session info and transport controls
- Replace pause/end buttons with tape-deck style buttons (⏸️/▶ and ⏹️)
- Move part type, problem count, and progress info into compact HUD
- Add overall progress counter (X/Y total) and health indicator
- Wrap practice page with PageWithNav for consistent app navigation
- Begin dark mode support with isDark prop from useTheme

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-06 19:16:13 -06:00
Thomas Hallock 871390d8e1 feat(help-system): add focus areas for skills needing reinforcement
Add tracking and display of skills that need extra practice:
- Add needsReinforcement, lastHelpLevel, reinforcementStreak to SkillProgress
- Add Focus Areas section to ProgressDashboard
- Add teacher controls to clear reinforcement flags
- Simplify helpSettings schema (remove default value from schema)

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-06 19:12:13 -06:00
Thomas Hallock 3ce12c59fc feat(abacus-react): add defaultValue prop for uncontrolled mode
Add standard React controlled/uncontrolled component pattern to AbacusReact:
- Add `defaultValue` prop to support uncontrolled mode (component owns state)
- When `value` is provided, component operates in controlled mode (syncs to prop)
- When only `defaultValue` is provided, component operates in uncontrolled mode
- Update HelpAbacus to use defaultValue for interactive help

This enables interactive abacus in help mode where the component tracks its own
state while parent monitors via onValueChange callback.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-06 19:11:43 -06:00
Thomas Hallock 373ec34e46 feat(help-system): integrate PracticeHelpPanel into ActiveSession
Phase 3 of help system implementation:

New component:
- PracticeHelpPanel.tsx: Progressive help display for practice sessions
  - L0: "Need Help?" button
  - L1: Coach hint with verbal guidance
  - L2: Mathematical decomposition with segment explanations
  - L3: Bead movement steps with instructions
  - Help level indicator dots
  - "More Help" escalation button
  - Max help level tracking display

ActiveSession integration:
- Added usePracticeHelp hook for help state management
- Track running total and current term for help context
- Reset help context when advancing to new term
- Record help usage in SlotResult (helpLevelUsed, incorrectAttempts, helpTrigger)
- Display PracticeHelpPanel after problem, before input area
- Pass isAbacusPart to enable bead-specific help messaging

Props added:
- helpSettings: StudentHelpSettings for configurable help behavior
- isBeginnerMode: Enable free help without mastery penalty

Stories updated:
- Fixed Date timestamp types
- Added default help tracking fields in interactive demo

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-06 15:27:51 -06:00
Thomas Hallock 0b1ad1f896 feat(help-system): add usePracticeHelp hook and skill extraction
Phase 2 of help system implementation:

New utilities:
- skillExtraction.ts: Maps pedagogical rules to SkillSet identifiers
  - extractSkillsFromSequence(): Extract skills from instruction sequence
  - extractSkillsFromProblem(): Extract skills for multi-term problems
  - getUniqueSkillIds(): Get deduplicated skill list
  - Helper functions for skill ID parsing

New hooks:
- usePracticeHelp.ts: Manages progressive help during practice
  - L0-L3 help levels (none → hint → decomposition → bead arrows)
  - Timer-based auto-escalation in 'auto' mode
  - Error-based auto-escalation (2+ errors triggers help)
  - Manual help request in 'manual' mode
  - Teacher-approved mode placeholder for L2+ help
  - Generates help content from UnifiedInstructionSequence
  - Tracks maxLevelUsed for feedback loop

Test coverage:
- 18 tests for skill extraction covering:
  - Direct addition, heaven bead, simple combinations
  - Five's complement patterns (4=5-1, 3=5-2, 2=5-3, 1=5-4)
  - Ten's complement patterns (9=10-1 through 5=10-5)
  - Multi-digit additions with multiple skills
  - Multi-term problem skill extraction

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-06 15:21:22 -06:00