diff --git a/src/blobbi/rooms/components/BlobbiRoomHero.tsx b/src/blobbi/rooms/components/BlobbiRoomHero.tsx index fc850546..e5430899 100644 --- a/src/blobbi/rooms/components/BlobbiRoomHero.tsx +++ b/src/blobbi/rooms/components/BlobbiRoomHero.tsx @@ -79,7 +79,7 @@ export interface BlobbiRoomHeroProps { roomId: BlobbiRoomId; /** Room order for dot indicators */ roomOrder?: BlobbiRoomId[]; - /** Called when the user taps a low-status stat icon to start the guide. */ + /** Called when the user taps any stat icon to start the guide. */ onGuide?: (stat: keyof BlobbiStats) => void; className?: string; } @@ -144,12 +144,12 @@ export function BlobbiRoomHero({
-
+
-arcHalf + (arcSpread / (count - 1)) * i); return ( -
+
{allStats.map((s, i) => { const angleDeg = angles[i]; const angleRad = (angleDeg * Math.PI) / 180; @@ -243,13 +243,13 @@ function StatsCrown({ return (
onGuide(s.stat as keyof BlobbiStats) : undefined} + onClick={onGuide ? () => onGuide(s.stat as keyof BlobbiStats) : undefined} >
diff --git a/src/blobbi/rooms/lib/stat-guide-config.ts b/src/blobbi/rooms/lib/stat-guide-config.ts index 28ded6fc..dcb68ca4 100644 --- a/src/blobbi/rooms/lib/stat-guide-config.ts +++ b/src/blobbi/rooms/lib/stat-guide-config.ts @@ -1,5 +1,5 @@ /** - * Stat Guide Configuration — mappings and helpers for the low-status guided UX. + * Stat Guide Configuration — mappings and helpers for the stat-guided UX. * * Centralises: * stat → target room @@ -57,15 +57,6 @@ export const STAT_GUIDE_ACTION: Partial> = { energy: 'sleep', }; -/** Contextual help text shown in the stat popover. */ -export const STAT_HELP_TEXT: Record = { - hunger: { title: 'Blobbi is hungry!', description: 'Head to the Kitchen and pick some food.' }, - happiness: { title: 'Blobbi is feeling sad…', description: 'Go Home and play with a toy!' }, - health: { title: 'Blobbi needs care!', description: 'Visit the Care Room for medicine.' }, - hygiene: { title: 'Blobbi needs a bath!', description: 'Go to the Care Room for hygiene items.' }, - energy: { title: 'Blobbi is tired!', description: 'Head to the Bedroom and put Blobbi to sleep.' }, -}; - // ─── Room carousel item constraints ─────────────────────────────────────────── /** @@ -117,7 +108,7 @@ export function findGuideItemForStat(stat: keyof BlobbiStats): string | null { // ─── Guide target builder ───────────────────────────────────────────────────── /** - * Build a `GuideTarget` for a low stat, automatically resolving the correct + * Build a `GuideTarget` for a stat, automatically resolving the correct * room, target type, item/action, and initial step. * * `currentRoom` determines whether the guide starts at the 'room' step diff --git a/src/index.css b/src/index.css index e3a33fab..611c0680 100644 --- a/src/index.css +++ b/src/index.css @@ -745,8 +745,8 @@ } /* Guide-target glow — quick blink + pause for nav arrows & carousel. - 1.4 s cycle, linear: rise (0→8%), brief peak (8→18%), fall (18→28%), - idle (28→100% ≈ 1 s pause). */ + Applied at 1.1s linear: rise (0→8%), brief peak (8→18%), fall (18→28%), + idle (28→100% ≈ 0.8 s pause). */ @keyframes guide-glow-slow { 0%, 28%, 100% { box-shadow: 0 0 0 0 transparent; } 8%, 18% { box-shadow: 0 0 4px 1.5px currentColor; } diff --git a/src/pages/BlobbiPage.tsx b/src/pages/BlobbiPage.tsx index 8fa4db44..8aed6bc3 100644 --- a/src/pages/BlobbiPage.tsx +++ b/src/pages/BlobbiPage.tsx @@ -45,8 +45,7 @@ import { type StorageItem, } from '@/blobbi/core/lib/blobbi'; -import { applyBlobbiDecay, getStatStatus } from '@/blobbi/core/lib/blobbi-decay'; -import { calculateProjectedDecay } from '@/blobbi/core/hooks/useProjectedBlobbiState'; +import { applyBlobbiDecay } from '@/blobbi/core/lib/blobbi-decay'; import type { BlobbiStats } from '@/blobbi/core/types/blobbi'; import { useSeedIdentitySync } from '@/blobbi/core/hooks/useSeedIdentitySync'; @@ -128,17 +127,16 @@ const DEBUG_BLOBBI = import.meta.env.DEV; const CARE_THRESHOLD = 40; /** - * Check if a companion needs care based on projected (decay-applied) stats. - * Uses the same projection as the main UI so the badge is consistent with - * what the user sees on the Blobbi page. + * Check if a companion needs care based on stat thresholds. + * A Blobbi needs care if any stat is below CARE_THRESHOLD. */ function companionNeedsCare(companion: BlobbiCompanion): boolean { - const { stats } = calculateProjectedDecay(companion); + const { stats } = companion; return ( - stats.hunger < CARE_THRESHOLD || - stats.happiness < CARE_THRESHOLD || - stats.hygiene < CARE_THRESHOLD || - stats.health < CARE_THRESHOLD + (stats.hunger !== undefined && stats.hunger < CARE_THRESHOLD) || + (stats.happiness !== undefined && stats.happiness < CARE_THRESHOLD) || + (stats.hygiene !== undefined && stats.hygiene < CARE_THRESHOLD) || + (stats.health !== undefined && stats.health < CARE_THRESHOLD) ); } @@ -944,7 +942,7 @@ function BlobbiDashboard({ } }, [isSleeping]); - // ─── Low-Status Guide Flow ─── + // ─── Stat Guide Flow ─── const [guideTarget, setGuideTarget] = useState(null); // Start a guide: build the target and set state @@ -972,11 +970,6 @@ function BlobbiDashboard({ // Derived: action glow (only when in correct room + on 'action' step) const guideActionGlow = guideTarget?.step === 'action' ? guideTarget.targetAction : null; - // Wrap onRest — guide cleanup is handled by the isSleeping effect below - const handleRestWithGuide = useCallback(() => { - onRest(); - }, [onRest]); - // Toggle drawer: tapping same tab closes it, tapping another opens that one const toggleDrawer = useCallback((drawer: DashboardDrawer) => { setActiveDrawer(prev => prev === drawer ? 'none' : drawer); @@ -1013,14 +1006,8 @@ function BlobbiDashboard({ } }, [isSleeping, guideTarget]); - // Clear guide when the guided stat recovers above warning threshold - useEffect(() => { - if (!guideTarget || !projectedState) return; - const val = projectedState.stats[guideTarget.stat] ?? 100; - if (getStatStatus(companion.stage, guideTarget.stat, val) === 'normal') { - setGuideTarget(null); - } - }, [guideTarget, projectedState, companion.stage]); + // Guide is cleared by completion events (item used, sleep started, + // or a different stat clicked), not by the stat recovering to normal. // Measure hero container width for responsive stat arc radius const heroRef = useRef(null); @@ -1602,7 +1589,7 @@ function BlobbiDashboard({ handleUseItemFromTab={handleUseItemFromTab} handleDirectAction={handleDirectAction} onUseItem={onUseItem} - onRest={handleRestWithGuide} + onRest={onRest} setShowPhotoModal={setShowPhotoModal} poopStateRef={poopStateRef} guideHighlightId={guideHighlightId}