Antigravity AI
UI improvements and HUD refinements for deployment
8ceb96d
"use client";
interface BlendshapeBarProps {
name: string;
value: number;
color?: string;
}
function BlendshapeBar({ name, value, color = "#63b3ed" }: BlendshapeBarProps) {
return (
<div className="flex flex-col gap-1.5">
<div className="flex items-center justify-between px-0.5">
<span className="text-[10px] text-white/40 uppercase tracking-wider font-medium">{name}</span>
<span className="text-[10px] text-white/30 font-mono">
{Math.round(value * 100)}%
</span>
</div>
<div className="h-1.5 bg-white/5 rounded-full overflow-hidden border border-white/5 shadow-inner">
<div
className="h-full rounded-full transition-all duration-300 ease-out"
style={{
width: `${Math.round(value * 100)}%`,
background: `linear-gradient(90deg, ${color}cc, ${color})`,
boxShadow: `0 0 10px ${color}40`,
}}
/>
</div>
</div>
);
}
interface StatsPanel {
fps: number;
faceDetected: boolean;
blendshapes: Record<string, number>;
}
const KEY_BLENDSHAPES: Array<{ key: string; label: string; color: string }> = [
{ key: "mouthSmileLeft", label: "Smile L", color: "#68d391" },
{ key: "mouthSmileRight", label: "Smile R", color: "#68d391" },
{ key: "browInnerUp", label: "Brow Up", color: "#f6ad55" },
{ key: "jawOpen", label: "Jaw Open", color: "#63b3ed" },
{ key: "browDownLeft", label: "Brow ↓L", color: "#fc8181" },
{ key: "browDownRight", label: "Brow ↓R", color: "#fc8181" },
{ key: "mouthFrownLeft", label: "Frown L", color: "#76e4f7" },
{ key: "mouthFrownRight", label: "Frown R", color: "#76e4f7" },
];
export default function StatsPanel({ fps, faceDetected, blendshapes }: StatsPanel) {
return (
<div className="glass rounded-2xl p-5 space-y-6 animate-scale-up">
<div className="flex items-center justify-between">
<div className="flex items-center gap-2">
<div className="p-1.5 rounded-lg bg-blue-500/10 border border-blue-500/20">
<svg className="w-3.5 h-3.5 text-blue-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 19v-6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2a2 2 0 002-2zm0 0V9a2 2 0 012-2h2a2 2 0 012 2v10m-6 0a2 2 0 002 2h2a2 2 0 002-2m0 0V5a2 2 0 012-2h2a2 2 0 012 2v14a2 2 0 01-2 2h-2a2 2 0 01-2-2z" />
</svg>
</div>
<h3
style={{ fontFamily: "Outfit, sans-serif" }}
className="text-xs font-bold text-white/70 uppercase tracking-widest"
>
Analytics
</h3>
</div>
<div className={`px-2 py-0.5 rounded-full text-[10px] font-bold uppercase tracking-tighter border transition-colors ${
faceDetected ? "bg-green-500/10 border-green-500/30 text-green-400" : "bg-red-500/10 border-red-500/30 text-red-400"
}`}>
{faceDetected ? "Active" : "Idle"}
</div>
</div>
{/* Stats Grid */}
<div className="grid grid-cols-2 gap-3">
<div className="glass-strong rounded-xl p-3 border border-white/5 group hover:border-white/10 transition-colors">
<p className="text-xs text-white/30 mb-1">Performance</p>
<div className="flex items-baseline gap-1">
<span className="text-2xl font-bold text-white tracking-tight" style={{ fontFamily: "Outfit, sans-serif" }}>
{fps}
</span>
<span className="text-[10px] text-white/20 font-bold uppercase">fps</span>
</div>
</div>
<div className="glass-strong rounded-xl p-3 border border-white/5 group hover:border-white/10 transition-colors">
<p className="text-xs text-white/30 mb-1">Detection</p>
<div className="flex items-baseline gap-1">
<span className="text-2xl font-bold text-white tracking-tight" style={{ fontFamily: "Outfit, sans-serif" }}>
{faceDetected ? "1" : "0"}
</span>
<span className="text-[10px] text-white/20 font-bold uppercase">face</span>
</div>
</div>
</div>
{/* Blendshapes */}
{faceDetected && (
<div className="space-y-4 pt-2">
<div className="flex items-center gap-2">
<div className="h-px flex-1 bg-gradient-to-r from-transparent via-white/10 to-transparent" />
<span className="text-[10px] text-white/20 uppercase tracking-widest font-bold">Signals</span>
<div className="h-px flex-1 bg-gradient-to-r from-transparent via-white/10 to-transparent" />
</div>
<div className="grid grid-cols-1 gap-4">
{KEY_BLENDSHAPES.map(({ key, label, color }) => (
<BlendshapeBar
key={key}
name={label}
value={blendshapes[key] ?? 0}
color={color}
/>
))}
</div>
</div>
)}
</div>
);
}