Commit Graph

1841 Commits

Author SHA1 Message Date
Thomas Hallock a8c6b84855 feat(know-your-world): improve takeover UI and fix celebration sound bug
UI Improvements:
- Add frosted glass backdrop + enhanced text shadow for region name contrast
- Heat effect on region outline: blue → purple → orange → gold as letters typed
- Puzzle piece now uses gold styling to match map celebration
- Consistent gold styling from takeover through to map celebration

Bug Fix:
- Fix celebration sound playing 30+ times layered on top of each other
- Remove duplicate sound trigger from CelebrationOverlay (MusicContext handles it)
- Use celebration.startTime as stable identifier to prevent re-triggers
- Track last played celebration in ref to ensure single playback

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-01 10:14:16 -06:00
Thomas Hallock 1e6153ee8b feat(know-your-world): add fire tracer animation for learning mode takeover
Add animated fire/sparkle tracer effect around region outlines in learning mode:
- Tracer follows simplified path (using simplify-js) for smooth coastlines
- Supports multiple islands with simultaneous animations
- Progressive intensity as letters are typed:
  - Speed increases exponentially (15s → 0.075s, 200x faster)
  - Opacity fades in (25% → 100%)
  - Sparkle count grows exponentially (1 → 48)
- 750ms laser effect delay after final letter before dismissing
- Uses react-spring for smooth transitions
- Performance optimized: removed filters from particles

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-01 09:44:03 -06:00
Thomas Hallock f8acc4aa6a fix(know-your-world): use getBBox() for consistent takeover positioning
- Add hidden SVG to measure accurate bounding box via getBBox() for part 1
- Both takeover parts now use getBBox() instead of different calculation methods
- Add vectorEffect="non-scaling-stroke" to takeover region shapes
- Add stroke to takeover region shape for visual consistency
- Add vectorEffect to label pointer lines in MapRenderer
- Document failure pattern in CLAUDE.md: verify agreed approach is
  implemented everywhere, not just obvious cases

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-01 08:32:47 -06:00
Thomas Hallock 7c496525e9 feat(know-your-world): add puzzle piece fly-to-map animation for learning mode
Add animated region silhouette that flies from takeover screen to map position
when user correctly identifies a region in learning mode:

- Add PuzzlePieceTarget interface with sourceRect for animation positioning
- Capture takeover region position with ref and getBoundingClientRect
- Use react-spring to animate from takeover to map position
- Preserve aspect ratio during takeover display
- Fix flash at animation end by checking isInTakeoverLocal
- Add debug logging for accent normalization

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-01 07:49:42 -06:00
Thomas Hallock dcc32c288f feat(know-your-world): auto-enable hot/cold for learning mode
When a game starts with the "learning" assistance level, automatically
enable hot/cold audio feedback for all players. This ensures the full
learning experience is available without requiring manual toggle.

The setting is also persisted to localStorage so it remains enabled
if the player navigates away and returns.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-30 20:35:38 -06:00
Thomas Hallock 45730bb4db feat(know-your-world): add turn-based restrictions for letter typing
In turn-based learning mode:
- Show current player's emoji next to typing instruction
- Only allow the current player to type letters
- Show "Waiting for [player] to type..." when it's not your turn
- Display "Not your turn!" notice when attempting to type during another player's turn

This makes it clear whose turn it is and prevents confusion in multiplayer games.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-30 20:34:51 -06:00
Thomas Hallock f5ce53efc0 fix(know-your-world): enable hot/cold only for current player in turn mode
In turn-based multiplayer, hot/cold feedback should only be active for
the player whose turn it is. Previously, all players with fine pointers
would get hot/cold feedback regardless of turn, which could be confusing.

Added turn check: (gameMode !== 'turn-based' || currentPlayer === localPlayerId)

This matches the pattern used elsewhere in the component for cursor
broadcasting and other turn-based restrictions.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-30 20:27:55 -06:00
Thomas Hallock c0f50c53dc test(know-your-world): add storybook stories for accented characters
Added stories to test the normalizeToBaseLetter function:
- Côte d'Ivoire (ô → o)
- São Tomé and Príncipe (ã → a)
- Curaçao (ç → c)
- Réunion (é → e)
- México (é → e)
- Perú (ú → u)
- Saint Barthélemy (space + accent)

Also updated the demo component to use the same normalization
logic as the actual game.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-30 20:24:23 -06:00
Thomas Hallock b27856e9fc fix(know-your-world): normalize accented letters for keyboard input
Added normalizeToBaseLetter() function that converts accented characters
to their base ASCII equivalents (e.g., 'é' → 'e', 'ñ' → 'n', 'ç' → 'c').

This allows users to type region names like "Côte d'Ivoire" or "São Tomé"
using a regular keyboard without needing to input accented characters.

Applied to both physical keyboard and virtual keyboard handlers.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-30 19:26:48 -06:00
Thomas Hallock 77033f0b22 fix: hide abacus on /arcade and /arcade-rooms routes
The previous check for `/arcade/` (with trailing slash) missed:
- /arcade (the arcade landing page)
- /arcade-rooms/* (actual game rooms)

Changed to `/arcade` prefix check which catches all arcade routes.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-30 18:39:29 -06:00
Thomas Hallock fa1514d351 feat(know-your-world): improve magnifier UX and hide abacus on games
Magnifier improvements:
- Add auto-zoom when dragging on magnifier (mobile)
- Add desktop click-and-drag to show magnifier (like shift key)
- Add fullscreen expand button (mobile only, top-right corner)
- Add Select button inside magnifier (mobile only, bottom-right)
- Add Full Map button to exit fullscreen (mobile only, bottom-left)
- Select button disabled when crosshair is over ocean or found region
- All magnifier buttons only appear on touch devices
- Click-drag magnifier works in pointer lock mode

Abacus visibility:
- Hide floating abacus on all /arcade/* routes by default
- Games can opt-in via setShowInGame(true) context

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-30 17:49:25 -06:00
Thomas Hallock c502a4fa92 feat(know-your-world): add device capability hooks and improve mobile support
- Create useDeviceCapabilities.ts with three hooks:
  - useIsTouchDevice(): detect touch-only devices
  - useCanUsePrecisionMode(): check pointer lock + fine pointer support
  - useHasAnyFinePointer(): detect any fine pointer (for hybrid devices)
- Update usePointerLock to accept canUsePrecisionMode option:
  - Prevents pointer lock on unsupported devices
  - Auto-exits pointer lock when switching to mobile mode (DevTools)
- Update MapRenderer to use new hooks:
  - Replace manual isTouchDevice detection with hooks
  - Use canUsePrecisionMode for precision mode UI visibility
  - Use hasAnyFinePointer for hot/cold feedback
- Add pinch-to-zoom magnifier expansion:
  - Magnifier expands to fill leftover area during pinch gesture
  - Tap outside dismisses and resets size
- Update SimpleLetterKeyboard to import from shared hooks file

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-30 16:55:23 -06:00
Thomas Hallock ea8965bc95 fix(know-your-world): guard against undefined state during session init
Add loading guard in GameComponent to prevent crash when state is
undefined during session initialization.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-30 15:04:37 -06:00
Thomas Hallock 60cf98e77a feat(know-your-world): improve mobile magnifier with adaptive zoom and select button
- Use findOptimalZoom for mobile (same algorithm as desktop) instead of hardcoded 2.5-4x
- Keep magnifier visible after drag ends so user can confirm selection
- Add green "Select ✓" button below magnifier for confirming region selection
- Tap elsewhere on map to dismiss magnifier without selecting
- Disable pull-to-refresh with touchAction: none and overscrollBehavior: none
- Add defensive check for undefined includeSizes in filterRegionsBySizes

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-30 15:01:51 -06:00
Thomas Hallock 9a254e2933 fix(know-your-world): improve mobile magnifier positioning and sizing
- Add mobile drag gesture detection to show magnifier when dragging on map
- Constrain magnifier to leftover rectangle (below nav/floating UI)
- Size magnifier based on leftover area dimensions, not full viewport
- Use leftover rectangle center for positioning decisions
- Prevent text selection during drag with CSS and preventDefault()
- Fix runtime error in filterRegionsBySizes with undefined check

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-30 14:10:37 -06:00
Thomas Hallock a02a7108e9 feat(know-your-world): show magnifier on mobile drag gesture
Detect touch drag gestures on the map to show the magnifier on mobile:
- Track touch start position and detect drag when moved past threshold
- Show magnifier when user drags on the map (not just on the magnifier)
- Position magnifier in opposite corner from touch point
- Use adaptive zoom based on region detection
- Hide magnifier when touch ends

This makes the magnifier discoverable on mobile by appearing automatically
when the user starts dragging on the map to search for regions.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-30 13:46:44 -06:00
Thomas Hallock 7dab07b3a7 feat(know-your-world): add Strudel-based music system
Add procedurally generated background music using Strudel.cc:
- MusicContext/MusicProvider for global music state
- useMusicEngine hook with Strudel.cc integration
- Regional music presets (continental themes + hyper-local variations)
- MusicControls and MusicControlPanel for user control
- MusicDebugPanel for development testing
- Region-to-music mapping system for adaptive soundtrack
- Integration with CelebrationOverlay and PlayingPhase

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-30 13:25:37 -06:00
Thomas Hallock 5318d0dd89 feat(know-your-world): add mobile virtual keyboard and space-skipping
- Add SimpleLetterKeyboard component for touch devices (react-simple-keyboard)
- Skip spaces when counting letters for name confirmation
  (e.g., "US Virgin Islands" → type U, S, V)
- Hide MyAbacus floating button when virtual keyboard is shown
- Add Storybook stories for testing letter confirmation flow

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-30 13:08:39 -06:00
Thomas Hallock 655660f7cf feat(know-your-world): sync letter confirmation across multiplayer sessions
Add shared state for learning mode name confirmation:
- Add nameConfirmationProgress to KnowYourWorldState
- Add CONFIRM_LETTER move type for validating letter entry
- Implement validateConfirmLetter in Validator (looks up region name from ID)
- Add confirmLetter action to Provider context
- Update GameInfoPanel to use shared state with optimistic updates

Fixes race condition when typing fast by using an optimistic ref that
updates immediately before server responds, then syncs with server state.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-30 11:46:01 -06:00
Thomas Hallock 285b128bb8 fix(know-your-world): allow space in name confirmation input
The name confirmation feature (type first 3 letters) was rejecting
space characters, making it impossible to confirm names like
"New York" or "Sri Lanka".

Updated regex from /[a-z]/i to /[a-z ]/i to allow spaces.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-30 11:46:01 -06:00
Thomas Hallock ea141f04f6 feat(know-your-world): add SVG path geometry helpers for future use
Add helper functions for SVG path analysis:
- parsePathToSubpaths: Parse SVG path into separate subpaths
- calculatePolygonArea: Shoelace formula for polygon area
- calculatePolygonCentroid: Shoelace formula for centroid
- getLargestSubpathCentroid: Find center of largest subpath

These will be useful for region centering improvements later.

Also adds celebration feature planning document.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-29 18:18:10 -06:00
Thomas Hallock 7f6b9dd558 fix(know-your-world): remove confidence gate from hot/cold visual emoji
The confidence threshold was gating both audio AND visual feedback,
causing noticeable lag in the emoji updates under the cursor. Now:
- Visual emoji updates immediately on every sample (100ms)
- Confidence threshold only gates audio speech

This makes the hot/cold feedback feel much more responsive.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-29 17:50:03 -06:00
Thomas Hallock 3b9d6b0fdf feat(know-your-world): add celebration animations for found regions
Add celebratory feedback when kids find regions:
- Gold flash effect on the found region (main map + magnifier)
- Confetti burst from region center
- Sound effects using Web Audio API (no audio files)
- Three celebration types based on search behavior:
  - Lightning: Fast direct find (< 3 sec) - quick sparkle
  - Standard: Normal discovery - two-note chime
  - Hard-earned: Perseverance (> 20 sec, wandering) - triumphant arpeggio + encouraging message

Uses search metrics from hot/cold feedback (path distance, direction reversals, near-misses) to classify celebration type.

Game waits for celebration to complete before advancing to next region.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-29 17:45:49 -06:00
Thomas Hallock 9f6b425daf fix(know-your-world): suppress hot/cold hints during takeover and give-up
Add isInTakeover state to context so MapRenderer knows when GameInfoPanel
has a scrim covering the map. Suppress hot/cold audio feedback when:
- Learning mode takeover is active (user can't see the map)
- Give-up animation is playing

This prevents confusing audio hints when the user can't interact with the map.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-29 17:19:36 -06:00
Thomas Hallock ac915f2065 feat(know-your-world): fix magnifier outline aspect ratio and add visual debug toggle
Magnifier outline fix:
- Create shared magnifierDimensions.ts utility for responsive magnifier sizing
- Adjust magnifier viewBox to match container aspect ratio (eliminates letterboxing)
- Fix dotted outline dimensions to match magnifier's actual visible region
- Fix zoom lines to connect to correct corners matching the adjusted aspect ratio
- Fix useMagnifierZoom.ts to use actual magnifier dimensions instead of hardcoded 0.5

Visual debug toggle:
- Add VisualDebugContext for global debug flag control (dev mode only)
- Add Developer section to hamburger menu with visual debug toggle
- Wire up all debug visualizations (bounding boxes, safe zones, magnifier info)
- Persist preference to localStorage

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-29 17:13:23 -06:00
Thomas Hallock ebe07e358f feat(know-your-world): add region shape silhouette to learning takeover
- Display SVG silhouette of target region during takeover animation
- Use CSS centering for takeover text (more robust than position animation)
- Restructure takeover overlay as parent container to fix stacking context
- Region shape shows between scrim and text with semi-transparent blue fill

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-29 16:47:02 -06:00
Thomas Hallock 3fd8472e68 feat(know-your-world): add learning mode takeover animation and fix give-up sequence
- Add react-spring powered takeover animation in learning mode
  - Region name scales up and centers on screen
  - Progress-based transition (letters typed / letters needed)
  - Blurry backdrop scrim with smooth CSS transitions
  - Nav bar remains accessible above scrim
- Fix give-up sequence timing
  - Show given-up region name during animation instead of next region
  - Hide type-to-unlock instruction during give-up
  - Suppress takeover animation during give-up to avoid conflict
- Add remaining count display at top of prompt pane
- Add progress gradient background to prompt pane

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-29 16:21:10 -06:00
Thomas Hallock 7e7a8dc1e8 feat(know-your-world): align guidance UI with assistance levels
Guidance dropdown improvements:
- Hide dropdown entirely in "No Assistance" mode (no options to configure)
- Hide Auto-Show Hints toggle when hints unavailable (hintsMode: none)
- Hide Auto Speak toggle when hints unavailable
- Rename "Show Hints" to "Auto-Show Hints" for clarity

Setup screen badges:
- Add "⌨️ Type to unlock" badge for Learning mode
- Add "👁️ Shows names" badge when wrong clicks reveal region name
- Extract getFeatureBadges to shared utility for testability

Cursor hot/cold emoji:
- Only show emoji when effectiveHotColdEnabled (respects both
  assistance level AND user toggle setting)

Code cleanup:
- Remove pointer lock button code and documentation
- Add guidanceVisibility utility with pure functions
- Add 30 unit tests for guidance visibility logic

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-29 14:27:17 -06:00
Thomas Hallock 7013a7b068 fix(know-your-world): restore Start button character
Bring back the travel-themed design:
- Decorative flag strip at top
- Stacked travel icons (✈️🌍 etc)
- "Start {Region}" text with context
- Region count subtitle
- Gradient background with hover effects

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-29 06:40:03 -06:00
Thomas Hallock 5f69fab859 fix(know-your-world): center setup settings panel horizontally
Move Mode/Guidance/Start panel to top-center for better visual balance
and prominence, matching the position of the gameplay prompt.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-29 06:38:59 -06:00
Thomas Hallock cc51de35e3 fix(know-your-world): move Start button to top-right settings panel
All setup controls (Mode, Guidance, Start) now in a single top-right panel,
matching the position of gameplay controls for seamless transition.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-29 06:38:28 -06:00
Thomas Hallock c1a0485b1d feat(know-your-world): unify setup UI positions with gameplay
Move setup controls to match gameplay UI positions for minimal transition:
- Move Mode/Guidance selectors to top-right (same position as gameplay controls)
- Keep Start button at bottom-center (prominent, no conflict)
- Adjust selector sizes for vertical stack on mobile, horizontal on desktop

This minimizes map movement when transitioning from setup to gameplay
since both phases now use the same safe zone margins effectively.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-29 06:06:49 -06:00
Thomas Hallock a4f9db6d3f fix(know-your-world): use viewport-based maxHeight for right panel
- Change from fixed 550px to calc(100vh - 200px) for maxHeight
- Ensures assistance level selector is visible on all screen sizes
- The inline region list on larger screens was pushing content out of view

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-29 05:25:29 -06:00
Thomas Hallock 11d2d5693c fix(know-your-world): make game settings visible in right panel
- Increase maxHeight from 450px to 550px to accommodate game settings
- Change overflow from 'hidden' to 'auto' for scrollable content
- Game mode and assistance level selectors were being cut off

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-29 05:19:33 -06:00
Thomas Hallock 141a506739 feat(know-your-world): unify setup and gameplay UI positions
- Move game mode and assistance level selectors to right panel in DrillDownMapSelector
- Remove redundant selectors from SetupPhase bottom bar (now just Start button)
- Setup and gameplay now use same safe zone margins for consistent map positioning
- Selectors integrate with existing region filter panel in unified right-side controls

This reduces visual transition when starting game - controls are already positioned
where gameplay controls will appear.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-28 20:56:11 -06:00
Thomas Hallock b0305581f9 feat(know-your-world): match setup phase map positioning with gameplay
- Update DrillDownMapSelector to use same safe zone calculation as MapRenderer
- When fillContainer is true, use custom crop (or full map bounds) with SAFE_ZONE_MARGINS
- Setup and gameplay phases now show maps positioned identically
- Non-fillContainer mode keeps expanded viewBox for browsing context

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-28 19:49:53 -06:00
Thomas Hallock 3f4691e8a3 feat(know-your-world): live crop updates and safe zone improvements
- Add runtime crop override system for live DevCropTool updates without page reload
- Fix SVG letterboxing in DevCropTool coordinate conversion (screenToSvg/svgToScreen)
- Hide all UI (nav, GameInfoPanel) during crop mode for unobstructed drawing
- Show debug overlay (leftover/crop rectangles) even when no custom crop defined
- Use full map bounds as implicit crop when no custom crop exists
- Ensure map always fits within leftover area (not under UI elements)

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-28 19:46:23 -06:00
Thomas Hallock eb94191b2e fix: ensure entire region path is clickable with pointerEvents: all
Add explicit pointerEvents: 'all' to region paths so the entire filled
area is clickable, not just the visible stroke/fill. This may fix click
detection issues on certain states (like Oregon) on older Safari/iPad.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-27 21:55:58 -06:00
Thomas Hallock d6eb997445 fix: skip pointer lock request on unsupported devices (iPad)
On devices where pointer lock isn't supported (like iPad), clicking
the map would try to request pointer lock on every click and return
early, preventing region clicks from being processed. Now we check
if pointer lock is supported before trying to request it.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-27 21:37:37 -06:00
Thomas Hallock 1333818bae fix: show hot/cold button on iPad with mouse attached
Replace isTouchDevice detection with hasFinePointer using
(any-pointer: fine) media query. This properly detects if a mouse
is connected, so iPads with attached mice will show the hot/cold
button, but pure touch devices won't.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-27 20:52:39 -06:00
Thomas Hallock a83fbb1070 fix: don't show labels for excluded/filtered regions
Excluded regions (filtered out by size/importance/population) were
showing labels, causing hundreds of labels to clutter the world map.
Now excluded regions are just grayed out without labels.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-27 20:27:01 -06:00
Thomas Hallock 4d77f1ffd3 fix: remove regex lookbehind for Safari compatibility
Safari/WebKit doesn't support lookbehind assertions (?<=). Replace with
a simple replace + split pattern that works in all browsers.

Fixes "Invalid regular expression: invalid group specifier name" error
on iPad/Safari.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-27 20:16:43 -06:00
Thomas Hallock 623f882075 feat(thermometer): add "only" buttons to quickly select single category
- Appears on hover for each category option
- Shows green highlight when that category is the only one selected
- Click to set both min and max to that value

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-27 19:01:10 -06:00
Thomas Hallock 6c3c0ac70e feat(know-your-world): add filter tabs for size, importance, and population
Add tabbed region selector with three filter criteria:
- Size: Filter by geographic size (huge → tiny)
- Importance: Filter by geopolitical importance (G7/UNSC superpowers → minor territories)
- Population: Filter by population (100M+ → <1M)

Includes:
- New category data for ~200 countries by importance and population
- Utility functions for all filter criteria types
- Compact tab UI with Radix tooltips
- Fixed 205px panel width with proper alignment

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-27 19:00:10 -06:00
Thomas Hallock fc87808b40 feat(know-your-world): add Learning mode and fix hints before name unlock
- Add new "Learning" assistance level (📚) that requires typing first 3 letters
  before hints are shown - best for memorizing region names
- Remove 3-letter requirement from "Guided" mode (now just has auto-hints)
- Fix bug where auto-hints bypassed the name confirmation requirement
- Add hintsLocked prop to MapRenderer to properly suppress hints
- Share hint unlock state between GameInfoPanel and MapRenderer via PlayingPhase

The Learning mode is now the easiest option, designed specifically for
learning region names by requiring active recall before showing hints.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-27 16:21:12 -06:00
Thomas Hallock a17e951e7c refactor(know-your-world): extract reusable utilities and components
- Extract regionSizeUtils.ts with size/range conversion functions
- Extract RegionListPanel component for scrollable region lists
- Add responsiveStyles.ts with breakpoint utilities and preventFlexExpansion
- Add comprehensive unit tests for all extracted modules (65 tests)

This improves code organization and reusability for the region selector.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-27 15:55:01 -06:00
Thomas Hallock cc317d2bdd docs: add region selector refactoring proposals
Document 7 refactoring opportunities for DrillDownMapSelector and RangeThermometer:
- Extract utility functions to separate module
- Create useRegionFiltering hook
- Simplify RangeThermometer props
- Extract RegionListPanel component
- Consolidate responsive breakpoint logic
- Add discriminated union for SelectionPath
- Add caching layer for filtered regions

Includes priority recommendations and testing considerations.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-27 15:37:26 -06:00
Thomas Hallock e3b898bec6 test: add unit tests for RangeThermometer and DrillDownMapSelector utils
- Add 19 tests for RangeThermometer component
  - Rendering options, labels, descriptions
  - Count badges and total count calculation
  - hideCountOnMd responsive behavior
  - onChange handler for option clicks
  - Hover preview calculations
  - Selected region names popover

- Add 34 tests for DrillDownMapSelector utilities
  - sizesToRange and rangeToSizes conversion functions
  - Roundtrip conversion consistency
  - SelectionPath type behavior
  - Excluded regions calculation logic
  - Preview add/remove regions calculation

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-27 15:28:03 -06:00
Thomas Hallock d329d80399 feat(know-your-world): unified region selector with inline list on desktop
- Combine region size selector and region list into one unified panel on desktop
- Hide "N regions" count on md+ screens, show inline scrollable list instead
- Keep "N regions" as clickable popover menu on mobile screens
- Add hideCountOnMd prop to RangeThermometer for responsive count display
- Constrain region list width to match thermometer (no panel expansion)
- Region names wrap within available width using CSS width:0 + minWidth:100% trick

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-27 15:21:15 -06:00
Thomas Hallock dc4d62195b feat(know-your-world): improve setup screen UX
- Add inline region list panel on larger screens (md+)
- Fix mobile double-tap issue with touch-action: manipulation
- Sync map navigation state across network for multiplayer

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-27 15:05:07 -06:00