import type { AgentStatus } from '@page-agent/core' import { Motion } from 'ai-motion' import { BookOpen, Globe } from 'lucide-react' import { useEffect, useRef } from 'react' import { siGithub } from 'simple-icons' import { TypingAnimation } from '@/components/ui/typing-animation' import { cn } from '@/lib/utils' // Status dot indicator export function StatusDot({ status }: { status: AgentStatus }) { const colorClass = { idle: 'bg-muted-foreground', running: 'bg-blue-500', completed: 'bg-green-500', error: 'bg-destructive', }[status] const label = { idle: 'Ready', running: 'Running', completed: 'Done', error: 'Error', }[status] return (
{label}
) } export function Logo({ className }: { className?: string }) { return Page Agent } // Full-screen ai-motion glow overlay, shown only while running export function MotionOverlay({ active }: { active: boolean }) { const containerRef = useRef(null) const motionRef = useRef(null) useEffect(() => { try { const mode = document.documentElement.classList.contains('dark') ? 'dark' : 'light' const motion = new Motion({ mode, borderWidth: 4, borderRadius: 14, glowWidth: mode === 'dark' ? 120 : 60, styles: { position: 'absolute', inset: '0' }, }) motionRef.current = motion containerRef.current!.appendChild(motion.element) motion.autoResize(containerRef.current!) } catch (e) { console.warn('[MotionOverlay] Motion unavailable:', e) } return () => { motionRef.current?.dispose() motionRef.current = null } }, []) useEffect(() => { const motion = motionRef.current if (!motion) return let disposed = false if (active) { motion.start() motion.fadeIn() } else { motion.fadeOut().then(() => !disposed && motion.pause()) } return () => { disposed = true } }, [active]) return (
) } // Empty state with logo and breathing glow export function EmptyState() { return (

Page Agent Ext

) }