Add butterfly/parrot/wiggle-dog companions; scale mascot + tips

- Three new Lottie companions: Wiggle Dog (摇尾狗), Butterfly (蝴蝶),
  Parrot (鹦鹉). Parrot is mirrored via a new `flip` flag on Companion,
  threaded through LottiePlayer (scaleX(-1)) since the asset faces left.
- Mascot size now scales with the viewport: --petal-companion-size
  clamp(10rem, 17vw, 20rem); art, emoji fallback, and the sleep "z" all
  derive from it.
- Larger, more legible tip bubble (1.4rem zh / 1.15rem en, wider bubble).
- Bubbles linger longer for a bilingual ESL read: baseline 9s→14s,
  cheer 6s→9s, per-char 45→55ms, cap 20s→32s.

Claude-Session: https://claude.ai/code/session_016Yr6jELuRc7hyzYLccQKZd
This commit is contained in:
prosolis
2026-06-26 11:08:55 -07:00
parent 9d6698dcc6
commit adc0cdff1c
8 changed files with 91 additions and 16 deletions

View File

@@ -147,7 +147,7 @@ export function PetalCompanion({ wordCount, saveStatus, llmDown, editTick, accep
onClick={dismiss}
onMouseEnter={holdBubble}
onMouseLeave={releaseBubble}
className="petal-bubble pointer-events-auto max-w-[260px] cursor-pointer p-3 pr-3.5"
className="petal-bubble pointer-events-auto max-w-[420px] cursor-pointer p-4 pr-5"
style={{
background: 'var(--color-surface)',
border: '1px solid var(--color-border)',
@@ -158,10 +158,16 @@ export function PetalCompanion({ wordCount, saveStatus, llmDown, editTick, accep
}}
title="Click to dismiss"
>
<p className="text-sm font-bold leading-snug" style={{ color: 'var(--color-plum)' }}>
<p
className="font-bold leading-snug"
style={{ color: 'var(--color-plum)', fontSize: '1.4rem' }}
>
{bubble.zh}
</p>
<p className="mt-0.5 text-xs leading-snug" style={{ color: 'var(--color-muted)' }}>
<p
className="mt-0.5 leading-snug"
style={{ color: 'var(--color-muted)', fontSize: '1.15rem' }}
>
{bubble.en}
</p>
</div>
@@ -174,8 +180,9 @@ export function PetalCompanion({ wordCount, saveStatus, llmDown, editTick, accep
aria-label="Choose a companion"
className={`petal-companion pointer-events-auto select-none ${napping ? 'petal-companion-sleep' : ''}`}
style={{
width: 144,
height: 144,
// Size scales with the viewport — see --petal-companion-size in index.css.
width: 'var(--petal-companion-size)',
height: 'var(--petal-companion-size)',
padding: 0,
borderRadius: 'var(--radius-pill)',
background: 'var(--color-surface-alt)',
@@ -189,8 +196,13 @@ export function PetalCompanion({ wordCount, saveStatus, llmDown, editTick, accep
<LottiePlayer
key={companion.id}
animationData={animationData}
className="h-32 w-32"
fallback={<span style={{ fontSize: 72, lineHeight: 1 }}>{MOOD_EMOJI[renderMood]}</span>}
flip={companion.flip}
className="petal-companion-art"
fallback={
<span style={{ fontSize: 'calc(var(--petal-companion-size) * 0.5)', lineHeight: 1 }}>
{MOOD_EMOJI[renderMood]}
</span>
}
/>
{napping && (
<span className="petal-zzz absolute" aria-hidden style={{ color: 'var(--color-muted)' }}>