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>
- Add simulateLegacyData option to SkillConfig interface
- When set, generateSlotResults omits helpLevelUsed field to simulate legacy data
- Update NaN Stress Test profile to test 3 skills with legacy data format
- This tests the actual production issue where old sessions lack helpLevelUsed
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
All 15 profiles now have correct category assignments:
- 5 BKT profiles (category: 'bkt')
- 4 Session profiles (category: 'session')
- 6 Edge case profiles (category: 'edge')
This enables CLI filtering when seeding specific profile types.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Root cause: Old production data (before Dec 2024) is missing the
`helpLevelUsed` field. The `helpLevelWeight` function had no default
case in its switch statement, returning `undefined` when called with
undefined, which caused `undefined * rtWeight = NaN` to propagate
through BKT calculations.
Changes:
- evidence-quality.ts: Add default case returning 1.0 for undefined/null
and add NaN guard to responseTimeWeight
- bkt-core.ts: Add NaN guards that surface invalid data with console.warn
- conjunctive-bkt.ts: Add NaN guards for multi-skill BKT updates
- compute-bkt.ts: Skip problem results that would produce NaN, preserving
prior state rather than corrupting skill estimates
- bkt-integration.ts: Add NaN guard to calculateBktMultiplier with
conservative fallback
- DashboardClient.tsx: Add UI error state for NaN pKnown values showing
"⚠️ Data Error" instead of displaying "~NaN%"
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Remove view mode toggle (Compact/Detailed) - confusing UX
- Add problem numbers (#1, #2...) to compact view for easy reference
- Make each problem tappable to open detail popover
- Popover shows: equation, student answer if wrong, response time,
pause threshold, help level, abacus usage, skills exercised
- Close popover with tap outside, X button, or Escape key
Users can now see all problems at a glance with numbers, and tap any
specific problem to get the full details without losing their place.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Replace horizontal rows in stale skills section with SkillCard grid
- Move "Mark Current" action into SkillDetailDrawer for stale skills
- Add staleness alert section in drawer with explanation and action
- Consistent visual presentation between practicing and stale skills
- User can now tap any stale skill to see details and mark as current
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Make StudentFilterBar fixed below nav with proper z-index layering
- Add sticky bucket headers (Today, This Week, etc.) and category headers
- Move bulk actions into filter bar (shown in edit mode in place of search)
- Create shared EmojiPicker component with emojibase-data integration
- Simplify AddStudentModal to use shared EmojiPicker (single way to pick emoji)
- Add z-index constants for filter bar and sticky headers
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The dashboard fetches skills from /api/curriculum/[playerId] which was
returning raw playerSkillMastery records with persisted attempts/correct
values (always 0 for seeded data).
Updated the API to compute skill stats from session results, consistent
with the recent single-source-of-truth refactor.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Previously, skill stats (attempts, correct, accuracy) were stored as
persisted aggregates in playerSkillMastery and updated incrementally.
This caused issues with seeded test data showing "0 correct".
Now:
- analyzeSkillPerformance() computes stats from session results on-the-fly
- findStrugglingSkills() computes accuracy from session results
- Seeder no longer needs to update aggregate columns
Benefits:
- Single source of truth (session results)
- No drift between aggregates and actual data
- Seeded data automatically works correctly
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Rename "⚖️ Balanced Mix" → "⚖️ Multi-Weak Remediation" to match actual output
- Update intention notes to reflect BKT's natural tendency to push skills to extremes
- Remove tuning criteria that fought against realistic behavior
- Focus profiles on app feature coverage rather than perfect BKT states
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
ProblemToReview component improvements:
- Use AnnotatedProblem for unified collapsed/expanded problem display
- Integrate BKT mastery data for weak skill detection and ordering
- Add smooth CSS Grid animations for expand/collapse transitions
- Make header row clickable (toggle moved from footer to header)
- Add purpose explanations and timing info in expanded mode
- Show up to 3 weak skills in collapsed mode with "+N more" indicator
React Query cache fix:
- Fix "Mark Current" button not updating UI (stale cache issue)
- Replace plain fetch + router.refresh() with useRefreshSkillRecency mutation
- Mutation properly invalidates curriculumKeys.detail(playerId)
Documentation:
- Add CLAUDE.md section on React Query mutation patterns
- Document the relationship between mutations and query cache invalidation
- Include checklist to prevent future cache invalidation bugs
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Major changes:
- Merge SessionSummary and SessionOverview into unified experience
- Add "Problems Worth Attention" section with expandable problem details
- Add "All Problems" collapsible section with compact/detailed toggle
- Keep auto-pause timing info in unified view
- Remove debug view toggle from SummaryClient
- Delete SessionOverview.tsx (replaced by new components)
New components:
- AllProblemsSection.tsx - collapsible all-problems view
- ProblemToReview.tsx - expandable problem row with reason badges
- sessionSummaryUtils.ts - filtering utilities for attention-worthy problems
Bug fix:
- Fix ROTATION_MULTIPLIERS import in DashboardClient (was undefined due to re-export chain)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Remove unimplemented features that didn't actually save data:
- Placement test: UI worked but results were never persisted
- Offline session recording: form collected data but just logged it
- View Progress button: was an empty callback
- Worksheet button: redirected but didn't integrate with practice
Add functional stale skills management:
- Add "Mark Current" refresh buttons to Skills tab stale skills section
- Show BKT status badges and staleness warnings
- Wire up refresh API to update skill recency
Clean up dead code:
- Delete SkillsClient.tsx (was unused, /skills redirects to dashboard)
- Remove onRefreshSkill from ManualSkillSelector modal
- Add BKT badges to ManualSkillSelector for skill status visibility
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Banner projects from content area to nav when scrolled under sticky header
- Uses IntersectionObserver to detect when content banner scrolls out of view
- FLIP animation smoothly transitions between slots with spring physics
- Preserves content slot space when projecting to prevent layout jump
- Uses react-use-measure for accurate dimension tracking
- Animates both position and size (width/height) between variants
- Nav slot collapses to height:0 when content slot is active
- Animation overlay uses higher z-index to appear above sticky nav
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Replace fixed-position ProjectingBanner with FLIP-based BannerSlots:
- Banners now render in document flow (relative positioning)
- Content flows naturally around banners
- FLIP animation only uses fixed positioning during ~400ms transition
- After animation, banner returns to document flow at target slot
Architecture:
- ContentBannerSlot/NavBannerSlot: Render content in-flow when active
- ProjectingBanner: Orchestrates FLIP animation during slot transitions
- Uses framer-motion springs for smooth position/size interpolation
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Consolidates two competing CTAs (resume button in dashboard vs practice
button in banner) into a single unified experience in the session banner.
When an active session exists, the projecting banner now shows:
- Session progress (X/Y problems completed)
- When started / last activity timestamps
- Focus description and skill changes since session start
- "Resume Session" button to continue where left off
- "Start Fresh" link to open modal (session only abandoned when new one starts)
Changes:
- Add ActiveSessionBanner component with dashboard and nav variants
- Add computeSkillChanges utility for tracking skill state changes
- Extend SessionModeBannerContext with activeSession state and handlers
- Modify ProjectingBanner to conditionally render ActiveSessionBanner
- Remove resume button and activeSession prop from ProgressDashboard
- Wire up active session data in DashboardClient
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Remove all "tall phone" media queries (@media max-width: 480px and min-height: 700px)
- Remove useEffect that auto-expanded settings on tall phones
- Use CSS order: 99 on session-config to always show CTAs first, settings last
- Remove redundant header section (🎯 Ready to practice?) - CTAs provide context
- Keep Dialog.Title/Description as sr-only for accessibility
- Simplify to just 2 layouts: default and landscape mode
- Format SessionProgressIndicator.stories.tsx
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Settings now expand automatically on tall phones (height >= 700px)
- Increased gap between sections (1rem -> 1.5rem)
- Restored normal padding and gaps inside expanded settings
- Larger labels and button gaps in settings on tall phones
This fills the empty space by showing all settings expanded,
making the layout feel intentional rather than sparse.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
On tall phones (width ≤ 480px AND height ≥ 700px):
- Reorder content: hero CTA banner first, settings second (CSS order)
- Hero CTA (tutorial/remediation/generic) is larger, centered, more prominent
- 2.5rem emoji, 1.125rem title, generous padding
- Centered vertical layout with skill badges
- Session settings appear below as secondary option
- Title and icon restored to full size
- Generous spacing creates intentional, designed appearance
- Content vertically centered with balanced whitespace
Fixes the "empty middle gap" issue where settings were at top
and CTA was pushed to bottom with marginTop: auto.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The modal was only going full-screen based on max-height: 700px,
which didn't trigger on iPhone 14 (844px height). Now also triggers
on max-width: 480px to cover all phone-sized screens.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Superseded by CelebrationProgressionBanner which is integrated
into SessionModeBanner and handles skill unlock celebrations.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
# [2.16.0](https://github.com/antialias/soroban-abacus-flashcards/compare/abacus-react-v2.15.0...abacus-react-v2.16.0) (2025-12-19)
### Bug Fixes
* **blog:** correct misleading claim about BKT feeding problem generation ([184cba0](184cba0ec8))
* **blog:** regenerate trajectory data from correct snapshot ([ce85565](ce85565f06))
* **dashboard:** make student dashboard responsive for small screens ([129907f](129907fcc6))
* **dashboard:** use React Query mutations instead of direct fetch ([ff7554b](ff7554b005))
* **migration:** add statement-breakpoint between CREATE and INSERT ([ba68cfc](ba68cfc75d))
* **practice:** add comprehensive logging and validation in recordSlotResult ([85d36c8](85d36c80a2))
* **practice:** add defensive checks in recordSlotResult ([a33e3e6](a33e3e6d2b))
* **practice:** add responsive styles to SessionModeBanner for small screens ([be08efe](be08efe06f))
* **practice:** check all later prefix sums for ambiguity, not just final answer ([43e7db4](43e7db4e88))
* **practice:** correct five complement skill detection for addition and subtraction ([1139c4d](1139c4d1a1))
* **practice:** correct pause phrase attribution ([cc5bb47](cc5bb479c6))
* **practice:** correct route path for resume session ([1a7945d](1a7945dd0b))
* **practice:** disable auto-scroll and add modern PWA meta tag ([8a9afa8](8a9afa86bc))
* **practice:** ensure badges are never taller than wide ([5730bd6](5730bd6112))
* **practice:** ensure keypad spans full screen width ([4b8cbdf](4b8cbdf83c))
* **practice:** ensure speed meter bar is always visible ([0c40dd5](0c40dd5c42))
* **practice:** fix circular import causing REINFORCEMENT_CONFIG.creditMultipliers to be undefined ([147974a](147974a9f0))
* **practice:** fix invisible resume button by using inline styles ([dd3dd45](dd3dd4507c))
* **practice:** handle paused state transitions and add complete phase ([36c9ec3](36c9ec3301))
* **practice:** improve dark mode contrast for sub-nav buttons ([59f574c](59f574c178))
* **practice:** improve mobile layout + floating abacus positioning ([3c9406a](3c9406afc5))
* **practice:** include endEarly.data in currentPlan priority chain ([28b3b30](28b3b30da6))
* **practice:** make session plan page self-sufficient for data loading ([7243502](7243502873))
* **practice:** move SessionPausedModal into ActiveSession for single pause state ([f0a9608](f0a9608a6b))
* **practice:** only show landscape keypad on phone-sized screens ([6c09976](6c09976d4b))
* **practice:** prevent keypad from covering nav and content ([839171c](839171c0ff))
* **practice:** prevent stray "0" rendering in problem area ([7a2390b](7a2390bd1b))
* **practice:** remove empty spacer button from keypad layout ([1058f41](1058f411c6))
* **practice:** remove fallback random problem generation ([f95456d](f95456dadc))
* **practice:** size answer boxes for intermediate prefix sums ([5cfbeeb](5cfbeeb8df))
* **practice:** state-aware complexity selection with graceful fallback ([6c88dcf](6c88dcfdc5))
* **practice:** update pun to "We pressed paws!" ([4800a48](4800a48128))
* **practice:** use inline styles for progress bar ([f45428e](f45428ed82))
* **practice:** use raw CSS media query for landscape keypad visibility ([31fbf80](31fbf80b8f))
* **practice:** use React Query cache for /resume page session data ([ae1a0a8](ae1a0a8e2d))
* **StartPracticeModal:** responsive improvements + integrated tutorial CTA ([56742c5](56742c511d))
* sync pause state between modal and ActiveSession ([55e5c12](55e5c121f1))
### Features
* **abacus:** add dockable abacus feature for practice sessions ([5fb4751](5fb4751728))
* **abacus:** add smooth animated transitions for dock/undock ([2c832c7](2c832c7944))
* **bkt:** add adaptive-bkt mode with unified BKT architecture ([7085a4b](7085a4b3df))
* **bkt:** implement adaptive skill targeting with validated convergence ([354ada5](354ada596d))
* **blog:** add Bayesian blame attribution validation and address reviewer feedback ([ceadd9d](ceadd9de67))
* **blog:** add interactive ECharts for BKT validation blog post ([6a4dd69](6a4dd694a2))
* **blog:** add layered skill trajectory visualization ([b227162](b227162da6))
* **blog:** add session 0, line thickness, and category averages to charts ([c40baee](c40baee43f))
* **blog:** show adaptive vs classic comparison on same chart ([b0c0f5c](b0c0f5c2da))
* **blog:** simplify All Skills chart to show average comparison ([6ef329d](6ef329dd60))
* **practice:** add "Press paws!" pun to auto-pause phrases ([8405f64](8405f64486))
* **practice:** add /resume route for "Welcome back" experience ([7b476e8](7b476e80c1))
* **practice:** add 30 and 45 minute session duration options ([e42766c](e42766c893))
* **practice:** add auto-pause and improve docked abacus sizing ([9c1fd85](9c1fd85ed5))
* **practice:** add browse mode navigation and improve SpeedMeter timing display ([3c52e60](3c52e607b3))
* **practice:** add cascading regrouping skills and improve help UX ([7cf689c](7cf689c3d9))
* **practice:** add celebration progression banner with smooth transitions ([bb9506b](bb9506b93e))
* **practice:** add complexity budget system and toggleable session parts ([5d61de4](5d61de4bf6))
* **practice:** add inline practice panel for browse mode debugging ([c0764cc](c0764ccd85))
* **practice:** add pause info with response time statistics to paused modal ([826c849](826c8490ba))
* **practice:** add play emoji to Keep Going button ([80a33bc](80a33bcae2))
* **practice:** add prefix sum disambiguation and debug panel ([46ff5f5](46ff5f528a))
* **practice:** add projecting SessionModeBanner with slot-based animation ([0f84ede](0f84edec0a))
* **practice:** add Remediation CTA for weak skill focus sessions ([7d8bb2f](7d8bb2f525))
* **practice:** add response time tracking and live timing display ([18ce1f4](18ce1f41af))
* **practice:** add SkillUnlockBanner + session summary improvements ([4daf7b7](4daf7b7433))
* **practice:** add student notes with animated modal + BKT improvements ([2702ec5](2702ec585f))
* **practice:** add subtraction support to problem generator ([4f7a9d7](4f7a9d76cd))
* **practice:** add unified SessionMode system for consistent skill targeting ([b345baf](b345baf3c4))
* **practice:** consolidate nav with transport dropdown and mood indicator ([8851be5](8851be5948))
* **practice:** improve docked abacus UX and submit button behavior ([60fc81b](60fc81bc2d))
* **practice:** improve help mode UX with crossfade and dismiss behaviors ([bcb1c7a](bcb1c7a173))
* **practice:** improve modal UI with problem counts and time estimation ([34d0232](34d0232451))
* **practice:** improve session summary UI ([a27fb0c](a27fb0c9a4))
* **practice:** inline emoji with random pause phrases ([c13fedd](c13feddfbb))
* **practice:** integrate timing display into sub-nav with mobile support ([2fca17a](2fca17a58b))
* **practice:** migrate mastery model to isPracticing + computed fluency ([b2e7268](b2e7268e7a))
* **practice:** redesign paused modal with kid-friendly statistics UX ([11ecb38](11ecb385ad))
* **practice:** reduce term count for visualization part ([9159608](9159608dcd))
* **practice:** refactor disambiguation into state machine with comprehensive tests ([ed277ef](ed277ef745))
* **practice:** responsive mobile keypad and unified skill detection ([ee8dccd](ee8dccd83a))
* **practice:** separate phrase sets for manual vs auto pause ([652519f](652519f219))
* **practice:** unify dashboard with session-aware progress display ([c40543a](c40543ac64))
* **practice:** use student's actual mastered skills for problem generation ([245cc26](245cc269fe))
* **session-planner:** integrate SessionMode for single source of truth targeting ([9851c01](9851c01026))
* **skills-modal:** add spring animations and UX improvements ([b94f533](b94f5338e5))
* **skills:** add Skills Dashboard with honest skill assessment framing ([bf4334b](bf4334b281))
* **test:** add journey simulator for BKT A/B testing ([86cd518](86cd518c39))
* **tutorial:** implement subtraction in unified step generator ([e5c697b](e5c697b7a8))
- Add bottomOffset/rightOffset to MyAbacusContext for virtual keyboard avoidance
- NumericKeypad sets offsets when mounted (48px bottom, 100px right)
- Floating abacus repositions above/beside keyboard in portrait/landscape
- PracticeSubNav: fix horizontal overflow with minWidth: 0 on flex children
- SessionProgressIndicator: allow proper flex shrinking
- ActiveSession: reduce padding/gaps, use flex layout to fill available space
- PracticeClient: use fixed positioning with proper insets for all orientations
- Portrait: bottom 48px for keypad
- Landscape: right 100px for keypad
- Desktop: no offsets needed
- Prevent viewport scrolling during practice sessions
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Implements a unified banner that seamlessly animates between positions:
- Full banner in content area (Dashboard, Summary pages)
- Compact banner in nav slot (other practice pages)
- Smooth React Spring animation when navigating between pages
New files:
- SessionModeBannerContext: manages slot registration and bounds tracking
- ProjectingBanner: animated portal banner using React Spring
- CompactBanner: condensed single-line variant for nav slot
- PracticeLayout: wrapper component with provider
- ProjectingBanner.stories: interactive demos showcasing transitions
Modified:
- PracticeSubNav: removed Start Practice button, added NavBannerSlot
- DashboardClient/SummaryClient: wrapped with provider, use ContentBannerSlot
- zIndex constants: added SESSION_MODE_BANNER layer
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit includes accumulated work from the SessionMode system:
- Add SkillUnlockBanner component for celebrating skill mastery
- Improve SessionSummary to show skill unlock celebrations
- Add session detail page at /practice/[studentId]/session/[sessionId]
- Update seedTestStudents script with more realistic test data
- Extend skill-tutorial-config with more skill mappings
- Improve BKT compute with better uncertainty handling
- Update progress-manager with skill completion tracking
- Remove legacy sessions API routes (replaced by session-plans)
- Add migration 0037 for practice_sessions schema cleanup
- Add plan documents for celebration wind-down and SessionMode
- Update gitignore to exclude db backups
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add @media (max-width: 400px) breakpoints to all three banner components:
- RemediationBanner: smaller padding, icon size, font sizes, button
- ProgressionBanner: smaller padding, icon size, font sizes, button
- MaintenanceBanner: smaller padding, icon size, font sizes, button
Also adds minWidth: 0 to text containers to prevent overflow on small screens.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Now that the Remediation CTA prominently displays weak skills,
the duplicate "Targeting:" and "Focusing on weak skills:" sections
in the config panel are no longer needed.
Removed:
- Target skills summary in collapsed view
- Target skills info in expanded config panel
- Unused targetSkillsInfo useMemo
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
When a student is in remediation mode (has weak skills to strengthen),
the StartPracticeModal now shows a special amber-themed CTA similar to
the tutorial CTA:
- 💪 "Time to build strength!" heading
- Lists weak skills with pKnown percentages
- "Start Focus Practice →" amber button
- Shows up to 4 skills with "+N more" overflow
Includes Storybook stories for:
- Single weak skill
- Multiple weak skills (2)
- Many weak skills (6, with overflow)
- Dark theme variant
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The session planner now accepts an optional sessionMode parameter that:
- Uses pre-computed weak skills from SessionMode (remediation mode)
- Eliminates duplicate BKT computation between UI and problem generation
- Ensures "no rug-pulling" - what the modal shows is what configures problems
Changes:
- session-planner.ts: Accept sessionMode, use getWeakSkillIds() when provided
- useSessionPlan.ts: Accept sessionMode in generateSessionPlan function
- plans/route.ts: Pass sessionMode from request body to planner
- StartPracticeModal.tsx: Pass sessionMode when generating plan
- index.ts: Export SessionMode types from curriculum module
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Creates a single source of truth for practice session decisions:
- SessionMode types: remediation, progression, maintenance
- getSessionMode() centralizes BKT computation
- SessionModeBanner component displays context-aware messaging
- useSessionMode() hook for React Query integration
Updates Dashboard, Summary, and StartPracticeModal to use SessionMode,
eliminating the "three-way messaging" problem where different parts of
the UI showed conflicting skill information.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Adds interpolation utilities and a celebration banner component that
smoothly morphs between celebration and normal states over 60 seconds.
🤫🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Full-screen mode at ≤700px height for iPhone SE support
- Two-column grid layout for settings in landscape mode
- Integrated tutorial CTA: combines unlock banner + start button
- Fixed collapsed mode clipping of target skills section
- Made "focusing on weak skills" visible on all screen sizes
- Fixed duplicate CSS media query breakpoints
- BKT: changed computeBktFromHistory to accept Partial<BktComputeExtendedOptions>
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Documents the critical requirement for --> statement-breakpoint markers
between multiple SQL statements in drizzle migrations. References the
2025-12-18 production outage caused by missing breakpoint.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Drizzle's better-sqlite3 driver requires --> statement-breakpoint
markers between SQL statements in migration files.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Tabs stack vertically on mobile (icon above label) instead of hiding labels
- Summary cards use 2x2 grid on mobile, 4x1 on tablet+
- Skill card grids use smaller min-width on mobile (120px vs 140px)
- Reduced padding throughout on mobile screens
- Section headers and buttons stack vertically on mobile
- History and Notes tabs use responsive padding and font sizes
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Student Notes Feature:
- Add notes column to players table with migration
- Create NotesModal component with zoom animation from student tile
- Add notes button on each student card in StudentSelector
- Support viewing and editing notes directly in modal
- Fix modal reopening bug with pointerEvents during animation
- Fix spring animation to start from clicked tile position
BKT & Curriculum Improvements:
- Add configurable BKT thresholds via admin settings
- Add skill anomaly detection API endpoint
- Add next-skill recommendation API endpoint
- Add problem history API endpoint
- Improve skills page with BKT classifications display
- Add skill tutorial integration infrastructure
Dashboard & Session Improvements:
- Enhanced dashboard with notes tab
- Improved session summary display
- Add StartPracticeModal stories
Test Infrastructure:
- Add seedTestStudents.ts script for BKT manual testing
- Add generateTrajectoryData.ts for simulation data
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add smooth spring-animated accordion expand/collapse using react-spring
- Add dynamic scroll indicators that show when content is scrolled
- Auto-scroll to show expanded category content optimally
- Replace ambiguous arrows with "Show/Hide" + rotating chevron
- Make modal full-screen on mobile, centered on desktop
- Add sticky category headers within scroll container
- Fix z-index layering using shared constants
- Add optimistic updates for skill mutations (instant UI feedback)
- Fix React Query cache sync for live skill updates
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Replace manual useLayoutEffect + resize listener with react-use-measure
hook for cleaner reactive measurement of takeover container bounds.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
DashboardClient had 3 direct fetch() calls that bypassed React Query:
- handleStartOver (abandon session)
- handleSaveManualSkills (set mastered skills)
- handleRefreshSkill (refresh skill recency)
These used router.refresh() to update data, which didn't reliably
update the React Query cache, causing stale UI state.
Fix:
- Add useSetMasteredSkills and useRefreshSkillRecency hooks
- Use useActiveSessionPlan with server props as initial data
- Replace direct fetch with mutation hooks
- Remove router.refresh() calls - React Query handles cache invalidation
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add session 0 data to show initial mastery state before practice
- Single Skill tab: line thickness based on skill tier, category average toggles
- All Skills tab: session 0 for ghost lines and averages
- Fix broken GitHub link (was placeholder "...")
- Add source code links to test files that generate chart data
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
New chart design with multiple visual encodings:
- Ghost lines (40% opacity) show individual skill trajectories
- Green spectrum for Adaptive, gray spectrum for Classic
- Darker shades = later in pedagogical sequence
- Line thickness encodes skill difficulty:
- 1px: basic skills
- 1.5px: five-complements
- 2px: ten-complements (friends of 10)
- 2.5px: cascading/multi-place regrouping
- 4px: average line (full opacity, on top)
- Clear legend showing Adaptive (avg) vs Classic (avg)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Replaced cluttered 12-line chart with clean 2-line comparison:
- Green line: Average mastery across all skills (Adaptive mode)
- Gray line: Average mastery across all skills (Classic mode)
- Clear legend with Adaptive/Classic labels
- Area fill for visual distinction
- Tooltip shows both values plus advantage in pp
Much easier to see that Adaptive consistently outpaces Classic.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Changed from heading-based injection to explicit marker comments:
- Markers like <!-- CHART: ValidationResults --> in markdown
- Charts now appear after explanatory text, not directly under headings
- Gives explicit control over chart placement in the document flow
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Changed "All Skills" tab to display both modes simultaneously:
- Solid lines = Adaptive mode (with circle markers)
- Dashed lines = Classic mode (no markers)
- Same color = same skill
- Tooltip shows both values with diff highlighted
This makes comparison much easier than toggling between modes.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The JSON was stale - regenerated from the correct 6-skill A/B test
snapshot showing adaptive wins 4-0 at 50% and 6-0 at 80%.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>