"use client"; /** * Hand-rolled inline-SVG charts for the cockpit — no charting library in the * Mini App bundle. Both are theme-driven (stroke/fill ride `currentColor`, * so the caller sets the hue via a text color) and degrade to a flat * baseline for an all-zero series rather than dividing by zero. */ const SPARK_W = 300; const SPARK_H = 72; /** Smooth-ish area sparkline with a gradient fill and an emphasized last * point — the hero's spend trend. `values` oldest → newest. */ export function Sparkline({ values }: { values: number[] }) { const n = values.length; const max = Math.max(...values, 0); const min = Math.min(...values, 0); const span = max - min || 1; const gradId = "tg-spark-grad"; const x = (i: number) => (n <= 1 ? 0 : (i / (n - 1)) * SPARK_W); // Leave 6px headroom top/bottom so the stroke + endpoint dot never clip. const y = (v: number) => SPARK_H - 6 - ((v - min) / span) * (SPARK_H - 12); const points = values.map((v, i) => [x(i), y(v)] as const); const line = points.map(([px, py]) => `${px},${py}`).join(" "); const area = `M0,${SPARK_H} L${line.replace(/ /g, " L")} L${SPARK_W},${SPARK_H} Z`; const [lastX, lastY] = points[points.length - 1] ?? [SPARK_W, SPARK_H / 2]; return ( ); } /** Compact day bars — the last bar (today) emphasized in the accent, the * rest muted. `values` oldest → newest. */ export function DayBars({ values, labels, }: { values: number[]; labels?: string[]; }) { const max = Math.max(...values, 1); return (