Companion: double the mascot size + drop the sleepy-face nap

- Mascot badge 64→128px (Lottie 56→112, emoji fallback 32→64); zzz glyph
  scaled + repositioned to match. It read too small on screen.
- Awake companions (no sleeping clip, e.g. Happy Dog) no longer show a 😴
  face or drifting "z" when the engine naps them — they hold their idle pose
  via a renderMood redirect. Only the always-asleep cat (real sleep clip)
  keeps the zzz, preserving that gag.

Claude-Session: https://claude.ai/code/session_016Yr6jELuRc7hyzYLccQKZd
This commit is contained in:
prosolis
2026-06-25 22:35:38 -07:00
parent 660f00d452
commit a634994d25
3 changed files with 17 additions and 12 deletions

View File

@@ -17,7 +17,7 @@ const MOOD_EMOJI: Record<Mood, string> = {
happy: '😺', happy: '😺',
talking: '😸', talking: '😸',
celebrate: '😻', celebrate: '😻',
sleeping: '😴', sleeping: '🐾',
} }
const STORAGE_KEY = 'petal.companion' const STORAGE_KEY = 'petal.companion'
@@ -40,8 +40,13 @@ export function PetalCompanion({ wordCount, saveStatus, editTick, acceptTick }:
const [pickerOpen, setPickerOpen] = useState(false) const [pickerOpen, setPickerOpen] = useState(false)
const rootRef = useRef<HTMLDivElement>(null) const rootRef = useRef<HTMLDivElement>(null)
// Always-asleep mascots keep the calm sway + zzz whatever the engine's mood. // Awake companions (no sleeping clip) don't visibly nap — when the engine
const napping = companion.alwaysAsleep || mood === 'sleeping' // dozes them, keep their normal idle pose instead of a sleepy face. Only a
// mascot with a real sleep animation (the always-asleep cat) shows the zzz.
const hasSleepClip = Boolean(companion.animations.sleeping)
const renderMood: Mood =
mood === 'sleeping' && !companion.alwaysAsleep && !hasSleepClip ? 'idle' : mood
const napping = companion.alwaysAsleep || (mood === 'sleeping' && hasSleepClip)
function choose(id: string) { function choose(id: string) {
setCompanionId(id) setCompanionId(id)
@@ -148,8 +153,8 @@ export function PetalCompanion({ wordCount, saveStatus, editTick, acceptTick }:
aria-label="Choose a companion" aria-label="Choose a companion"
className={`petal-companion pointer-events-auto select-none ${napping ? 'petal-companion-sleep' : ''}`} className={`petal-companion pointer-events-auto select-none ${napping ? 'petal-companion-sleep' : ''}`}
style={{ style={{
width: 64, width: 128,
height: 64, height: 128,
padding: 0, padding: 0,
borderRadius: 'var(--radius-pill)', borderRadius: 'var(--radius-pill)',
background: 'var(--color-surface-alt)', background: 'var(--color-surface-alt)',
@@ -162,9 +167,9 @@ export function PetalCompanion({ wordCount, saveStatus, editTick, acceptTick }:
> >
<LottiePlayer <LottiePlayer
key={companion.id} key={companion.id}
animationData={companion.animations[mood]} animationData={companion.animations[renderMood]}
className="h-14 w-14" className="h-28 w-28"
fallback={<span style={{ fontSize: 32, lineHeight: 1 }}>{MOOD_EMOJI[mood]}</span>} fallback={<span style={{ fontSize: 64, lineHeight: 1 }}>{MOOD_EMOJI[renderMood]}</span>}
/> />
{napping && ( {napping && (
<span className="petal-zzz absolute" aria-hidden style={{ color: 'var(--color-muted)' }}> <span className="petal-zzz absolute" aria-hidden style={{ color: 'var(--color-muted)' }}>

View File

@@ -41,7 +41,7 @@ export const COMPANIONS: Companion[] = [
happy: happyDog, happy: happyDog,
talking: happyDog, talking: happyDog,
celebrate: happyDog, celebrate: happyDog,
// no sleeping clip → naps with the 😴 emoji fallback // no sleeping clip → stays in its idle pose instead of visibly napping
}, },
}, },
] ]

View File

@@ -227,10 +227,10 @@ button, a, input {
} }
.petal-zzz { .petal-zzz {
top: 2px; top: 6px;
right: 8px; right: 14px;
font-weight: 800; font-weight: 800;
font-size: 0.8rem; font-size: 1.1rem;
animation: petal-zzz 2.4s ease-in-out infinite; animation: petal-zzz 2.4s ease-in-out infinite;
} }
@keyframes petal-zzz { @keyframes petal-zzz {