feat(know-your-world): enhance hint audio and region name display

Audio hints now include the region name:
- Speak "France. Located in Western Europe" instead of just "Located in Western Europe"
- Applies to all hint speech triggers (manual, auto-speak, region change)

Region name display is now more prominent:
- Larger font size (2xl)
- Pop-in animation when region changes
- Subtle glow pulse animation on the prompt box
- Target emoji (🎯) added to "Find" label
- Improved styling with rounded corners and thicker border

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

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Thomas Hallock 2025-11-26 21:19:48 -06:00
parent 81301ab148
commit e6f58bfd93
2 changed files with 53 additions and 18 deletions

View File

@ -170,31 +170,48 @@ export function GameInfoPanel({
className={css({
flex: 1,
textAlign: 'center',
padding: '2',
padding: '3',
bg: isDark ? 'blue.900' : 'blue.50',
rounded: 'md',
border: '2px solid',
rounded: 'xl',
border: '3px solid',
borderColor: 'blue.500',
minWidth: 0, // Allow shrinking
display: 'flex',
flexDirection: 'column',
gap: '1',
})}
style={{
animation: 'glowPulse 2s ease-in-out infinite',
}}
>
<style>{`
@keyframes glowPulse {
0%, 100% { box-shadow: 0 0 10px rgba(59, 130, 246, 0.3); }
50% { box-shadow: 0 0 20px rgba(59, 130, 246, 0.6), 0 0 30px rgba(59, 130, 246, 0.3); }
}
@keyframes popIn {
0% { transform: scale(0.8); opacity: 0; }
50% { transform: scale(1.1); }
100% { transform: scale(1); opacity: 1; }
}
`}</style>
<div
className={css({
fontSize: '2xs',
fontSize: 'xs',
color: isDark ? 'blue.300' : 'blue.700',
fontWeight: 'semibold',
fontWeight: 'bold',
textTransform: 'uppercase',
letterSpacing: 'wide',
})}
>
Find:
🎯 Find
</div>
<div
key={currentRegionId || 'empty'} // Re-trigger animation on change
className={css({
fontSize: 'lg',
fontSize: '2xl',
fontWeight: 'bold',
color: isDark ? 'blue.100' : 'blue.900',
color: isDark ? 'white' : 'blue.900',
overflow: 'hidden',
textOverflow: 'ellipsis',
whiteSpace: 'nowrap',
@ -203,8 +220,12 @@ export function GameInfoPanel({
justifyContent: 'center',
gap: '2',
})}
style={{
animation: 'popIn 0.4s ease-out',
textShadow: isDark ? '0 2px 4px rgba(0,0,0,0.3)' : 'none',
}}
>
{flagEmoji && <span className={css({ fontSize: 'xl' })}>{flagEmoji}</span>}
{flagEmoji && <span className={css({ fontSize: '2xl' })}>{flagEmoji}</span>}
<span>{currentRegionName || '...'}</span>
</div>
</div>

View File

@ -494,6 +494,20 @@ export function MapRenderer({
const hintText = useRegionHint(hintMapKey, currentPrompt)
const hasHint = useHasRegionHint(hintMapKey, currentPrompt)
// Get the current region name for audio hints
const currentRegionName = useMemo(() => {
if (!currentPrompt) return null
const region = mapData.regions.find((r) => r.id === currentPrompt)
return region?.name ?? null
}, [currentPrompt, mapData.regions])
// Create full hint text with region name prefix for speech
const fullHintText = useMemo(() => {
if (!hintText) return null
if (!currentRegionName) return hintText
return `${currentRegionName}. ${hintText}`
}, [currentRegionName, hintText])
// Speech synthesis for reading hints aloud
const {
speak: speakHint,
@ -585,10 +599,10 @@ export function MapRenderer({
const handleSpeakClick = useCallback(() => {
if (isSpeaking) {
stopSpeaking()
} else if (hintText) {
speakHint(hintText, withAccent)
} else if (fullHintText) {
speakHint(fullHintText, withAccent)
}
}, [isSpeaking, stopSpeaking, hintText, speakHint, withAccent])
}, [isSpeaking, stopSpeaking, fullHintText, speakHint, withAccent])
const speakButton = usePointerLockButton({
id: 'speak-hint',
@ -712,10 +726,10 @@ export function MapRenderer({
const justOpened = showHintBubble && !prevShowHintBubbleRef.current
prevShowHintBubbleRef.current = showHintBubble
if (justOpened && autoSpeak && hintText && isSpeechSupported) {
speakHint(hintText, withAccent)
if (justOpened && autoSpeak && fullHintText && isSpeechSupported) {
speakHint(fullHintText, withAccent)
}
}, [showHintBubble, autoSpeak, hintText, isSpeechSupported, speakHint, withAccent])
}, [showHintBubble, autoSpeak, fullHintText, isSpeechSupported, speakHint, withAccent])
// Track previous prompt to detect region changes
const prevPromptRef = useRef<string | null>(null)
@ -741,13 +755,13 @@ export function MapRenderer({
setShowHintBubble(true)
// If region changed and both auto-hint and auto-speak are enabled, speak immediately
// This handles the case where the bubble was already open
if (isNewRegion && autoSpeakRef.current && hintText && isSpeechSupported) {
speakHint(hintText, withAccentRef.current)
if (isNewRegion && autoSpeakRef.current && fullHintText && isSpeechSupported) {
speakHint(fullHintText, withAccentRef.current)
}
} else {
setShowHintBubble(false)
}
}, [currentPrompt, hasHint, hintText, isSpeechSupported, speakHint])
}, [currentPrompt, hasHint, fullHintText, isSpeechSupported, speakHint])
// Hot/cold audio feedback hook
// Only enabled if: 1) assistance level allows it, 2) user toggle is on, 3) not touch device