Commit Graph

11 Commits

Author SHA1 Message Date
Thomas Hallock
53e90414a3 feat: add precision mode system with pixel grid visualization
Add precision mode threshold system for know-your-world magnifier:

**Precision Mode Threshold System:**
- Constant PRECISION_MODE_THRESHOLD = 20 px/px
- Caps zoom when not in pointer lock to prevent exceeding threshold
- Shows clickable notice when threshold reached
- Activates pointer lock for precision control

**Pixel Grid Visualization:**
- Shows gold grid overlay aligned with crosshair
- Each grid cell = 1 screen pixel of mouse movement on main map
- Fades in from 70% to 100% of threshold (14-20 px/px)
- Fades out from 100% to 130% of threshold (20-26 px/px)
- Visible in both normal and precision modes

**Visual "Disabled" State:**
- Magnifier dims (60% brightness, 50% saturation) when at threshold
- Indicates zoom is capped until precision mode activated
- Returns to normal appearance in precision mode

**User Experience:**
- Below 14 px/px: Normal magnifier
- 14-20 px/px: Grid fades in as warning
- At 20 px/px: Full grid, dimmed magnifier, "Click here (not map) for precision mode"
- Click magnifier label (not map) to activate pointer lock
- In precision mode: Grid fades out (20-26 px/px), magnifier returns to normal
- e.stopPropagation() prevents accidental region clicks

**Debug Mode:**
- SHOW_MAGNIFIER_DEBUG_INFO flag (dev only)
- Shows technical info: zoom level and px/px ratio

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-23 14:00:43 -06:00
Thomas Hallock
1729418dc5 feat(know-your-world): full-screen layout with squish-through pointer lock escape
Implement full-screen, no-scrolling layout for Know Your World game with seamless
pointer lock UX:

## Layout Changes
- Add react-resizable-panels for vertical panel layout (info top, map bottom)
- Wrap playing phase with StandardGameLayout for 100vh no-scroll behavior
- Extract game info (prompt, progress, error) into compact GameInfoPanel
- Map panel fills remaining space with ResizeObserver for dynamic scaling
- SVG uses aspect-ratio to prevent distortion during panel resize

## Pointer Lock UX
- Remove obtrusive "Enable Precision Controls" prompt entirely
- First click silently enables pointer lock (seamless gameplay)
- Cursor squish-through escape at boundaries:
  - 40px dampen zone: movement slows quadratically near edges
  - 20px squish zone: cursor visually compresses (50%) and stretches (140%)
  - 2px escape threshold: pointer lock releases when squished through
- Custom cursor distortion provides visual feedback for escape progress

## Testing
- Unit tests: GameInfoPanel (20+ tests), PlayingPhase (15+ tests)
- E2E tests: Layout, panel resizing, magnifier behavior
- Update vitest config with Panda CSS aliases

## Technical Details
- ResizeObserver replaces window resize listeners for panel-aware updates
- Labels and magnifier recalculate on panel resize
- All magnifier math preserved (zoom, region indicator, coordinate transforms)
- Boundary dampening uses quadratic easing for natural feel
- Squish effect animates with 0.1s ease-out transition

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-22 21:50:13 -06:00
Thomas Hallock
b36df3a40c fix(worksheets): ten-frames not rendering in mastery mode
Fixed two critical bugs preventing ten-frames from rendering:

1. **Mastery mode not handled** (typstGenerator.ts:61)
   - Code only checked for 'smart' | 'manual' modes
   - Mastery mode fell into manual path, tried to use boolean flags that don't exist
   - Resulted in all display options being `undefined`
   - Fix: Check for both 'smart' OR 'mastery' modes (both use displayRules)

2. **Typst array membership syntax** (already fixed in previous commit)
   - Used `(i in array)` which doesn't work in Typst
   - Changed to `array.contains(i)`

Added comprehensive unit tests (tenFrames.test.ts):
- Problem analysis tests (regrouping detection)
- Display rule evaluation tests
- Full Typst template generation tests
- Mastery mode specific tests
- All 14 tests now passing

Added debug logging to trace display rules resolution:
- displayRules.ts: Shows rule evaluation per problem
- typstGenerator.ts: Shows enriched problems and Typst data
- Helps diagnose future issues

The issue was that mastery mode (which uses displayRules like smart mode)
was being treated as manual mode (which uses boolean flags), resulting in
undefined display options.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-10 10:06:27 -06:00
Thomas Hallock
cd75df7221 chore: restore stashed work from previous session
Recover all changes from stash including:
- Linter/formatter updates across codebase
- Settings permission updates for git checkout

This commit captures the complete state of work that was
stashed during the previous session's git operations.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-08 14:59:40 -06:00
Thomas Hallock
7f95032253 feat: add room creation and join flow UI
Add comprehensive room management UI:
- CreateRoomModal: Modal for creating new multiplayer rooms
- JoinRoomModal: Modal for joining rooms via code
- JoinRoomInput: Reusable input component for room codes
- PlayOnlineTab: Tab component for arcade lobby
- RecentRoomsList: List of user's recent rooms
- /join/[code] page: Direct join link page
- E2E test for join flow

Includes shareable room links, clipboard integration,
and user-friendly error handling.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-13 11:23:28 -05:00
Thomas Hallock
f9af0f169e chore: biome formatting fixes 2025-10-11 07:17:38 -05:00
Thomas Hallock
bda5bc6c0e fix: prevent database imports from being bundled into client code
**Problem:**
- player-ownership.ts imported drizzle-orm and @/db at top level
- When RoomMemoryPairsProvider imported client-safe utilities, Webpack bundled ALL imports including database code
- This caused hydration error: "The 'original' argument must be of type Function"
- Node.js util.promisify was being called in browser context

**Solution:**
1. Created player-ownership.client.ts with ONLY client-safe utilities
   - No database imports
   - Safe to import from 'use client' components
   - Contains: buildPlayerOwnershipFromRoomData(), buildPlayerMetadata(), helper functions

2. Updated player-ownership.ts to re-export client utilities and add server-only functions
   - Re-exports everything from .client.ts
   - Adds buildPlayerOwnershipMap() (async, database-backed)
   - Safe to import from server components/API routes

3. Updated RoomMemoryPairsProvider to import from .client.ts

**Result:**
- No more hydration errors on /arcade/room
- Client bundle doesn't include database code
- Server code can still use both client and server utilities

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-10 11:40:46 -05:00
Thomas Hallock
60d70cd2f2 style: apply Biome formatting to entire codebase
Run Biome formatter on all files to ensure consistent code style:
- Single quotes for JS/TS
- Double quotes for JSX
- 2-space indentation
- 100 character line width
- Semicolons as needed
- ES5 trailing commas

This is the result of running: npx @biomejs/biome format . --write

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-07 12:48:26 -05:00
Thomas Hallock
619be9859c test: add E2E tests for arcade modal session behavior
Added comprehensive Playwright tests for arcade modal session system:
- Session redirects and persistence
- Player modification blocking during games
- "Return to Arcade" button functionality
- Session lifecycle from creation to end

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-06 12:21:42 -05:00
Thomas Hallock
d58053fad3 feat: add comprehensive E2E testing with Playwright
- Add Playwright configuration for cross-browser testing
- Implement navigation slot persistence tests
- Add sound settings persistence E2E tests
- Ensure robust testing of navigation state management
- Cover edge cases for mini-nav behavior across routes

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-29 09:44:36 -05:00
Thomas Hallock
3fa314aaa5 fix: resolve mini navigation game name persistence across all routes
Add @nav parallel route slots for all major routes to prevent game names
from persisting when navigating between different sections of the app.

- Add @nav/page.tsx (home)
- Add @nav/create/page.tsx (create page)
- Add @nav/guide/page.tsx (guide page)
- Add @nav/games/page.tsx (games listing)
- Keep @nav/games/matching/page.tsx (Memory Pairs game)
- Keep @nav/games/memory-quiz/page.tsx (Memory Lightning game)
- Add comprehensive e2e test covering navigation persistence scenarios

All non-game routes return null (no game name in mini nav).
Only game routes show their specific game names.

Fixes issue where navigating Game → Guide → Games would show stale game name.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-29 09:22:33 -05:00