Kitten yields to cards: fade, shrink, click-through; plus UX review doc
When a suggestion card drifts into the mascot's corner, the kitten turns translucent (15%), steps back 10% (standalone `scale` so it composes with the bob animation), and lets clicks pass through to the card. It wakes while its bubble or the picker is open, or once the corner clears. Also adds UX_REVIEW_2026-07-27.md — the hands-on review of the live deploy turned into implementation-ready items (repro, location, fix, acceptance). Claude-Session: https://claude.ai/code/session_016y6gyuHkQXPiEuW8RGQyua
This commit is contained in:
@@ -3,6 +3,7 @@ import type { SaveStatus } from '../../hooks/useAutoSave'
|
||||
import { useCompanion, type Mood } from './useCompanion'
|
||||
import { LottiePlayer } from './LottiePlayer'
|
||||
import { COMPANIONS, DEFAULT_COMPANION } from './companions'
|
||||
import { useCardOverlap } from './useCardOverlap'
|
||||
import { onPrefsScopeChange, readPref, writePref } from '../../lib/prefs'
|
||||
import { usePack } from '../../i18n'
|
||||
|
||||
@@ -86,6 +87,14 @@ export function PetalCompanion({
|
||||
const companion = COMPANIONS.find((c) => c.id === companionId) ?? COMPANIONS[0]
|
||||
const [pickerOpen, setPickerOpen] = useState(false)
|
||||
const rootRef = useRef<HTMLDivElement>(null)
|
||||
const badgeRef = useRef<HTMLButtonElement>(null)
|
||||
|
||||
// When suggestion cards stack down into the corner, the kitten fades to
|
||||
// translucent and shrinks a step so the card stays readable and clickable.
|
||||
// It wakes back up whenever it has something to say (bubble) or is being
|
||||
// interacted with (picker open).
|
||||
const crowded = useCardOverlap(badgeRef)
|
||||
const faded = crowded && !pickerOpen && !bubble
|
||||
|
||||
// Awake companions (no sleeping clip) don't visibly nap — when the engine
|
||||
// dozes them, keep their normal idle pose instead of a sleepy face. Only a
|
||||
@@ -239,11 +248,14 @@ export function PetalCompanion({
|
||||
)}
|
||||
|
||||
<button
|
||||
ref={badgeRef}
|
||||
type="button"
|
||||
onClick={() => setPickerOpen((o) => !o)}
|
||||
title="Choose a companion"
|
||||
aria-label="Choose a companion"
|
||||
className={`petal-companion pointer-events-auto select-none ${napping ? 'petal-companion-sleep' : ''}`}
|
||||
className={`petal-companion select-none ${faded ? 'petal-companion-faded' : 'pointer-events-auto'}${
|
||||
napping ? ' petal-companion-sleep' : ''
|
||||
}`}
|
||||
style={{
|
||||
// Size scales with the viewport — see --petal-companion-size in index.css.
|
||||
width: 'var(--petal-companion-size)',
|
||||
|
||||
Reference in New Issue
Block a user