'use client' /** * AnimatedNumber — flashes green/red when its value changes, the way a live * trading terminal ticks. Pure presentational: it renders `display` (already * formatted) but watches `value` (the raw number) to decide flash direction. * * The flash is a CSS class toggled for ~600ms via a keyframe (`tick-flash-up` / * `tick-flash-down` in globals.css). Respects prefers-reduced-motion (the CSS * keyframes are disabled there, so this degrades to a plain number). */ import { useEffect, useRef, useState } from 'react' interface Props { /** Raw numeric value — drives the flash direction when it changes. */ value: number | null | undefined /** Pre-formatted string to actually show (e.g. "$72,140"). */ display: string /** Extra className(s) for the wrapper. */ className?: string style?: React.CSSProperties } export default function AnimatedNumber({ value, display, className = '', style }: Props) { const prev = useRef(value) const [dir, setDir] = useState<'up' | 'down' | null>(null) useEffect(() => { const p = prev.current if (value != null && p != null && value !== p) { setDir(value > p ? 'up' : 'down') const id = setTimeout(() => setDir(null), 600) prev.current = value return () => clearTimeout(id) } prev.current = value }, [value]) return ( {display} ) }