import type { ReactNode } from 'react'; import './kpiCard.css'; /** * A KPI tile — the console's headline figure. * * ── There were two of these, and neither worked ───────────────────────────── * * This component put an icon inline with the label and CENTRED the value * underneath it, which is why a row of tiles never lined up: a centred number * sits in a different place in every tile depending on how long it is. * `console.css` had a second, unrelated implementation — `.kpi` — with a * brand-tinted icon tile on the left and the text stacked beside it. The two * appeared on the same screen. The second was the better design and this is * now that design, for both. * * ── `note` is rendered again, and that is the real change ─────────────────── * * The line under the figure — "142 app · 38 counter", "12% of app orders" — * was removed from the tile at some point but never removed from the CALLERS: * 86 of them still compute and pass it, and it was being thrown away. That is * the half of a KPI that carries the meaning. A bare `0` under "Unsynced * bills" reads as "no data" when it means everything is in the books, and `42` * under "Total orders" says nothing about which channel they came through. * * ── `tone` does something now ─────────────────────────────────────────────── * * All five tones used to map to `var(--color-brand)`, so the prop was * decorative — every tile was purple whether it reported takings or a failure. * The tone now colours the icon tile only: the figure itself stays in ink, * because a number that changes colour with its own value is hard to compare * against the tile beside it. Brand remains the default, so a tile that is * merely reporting is not shouting. */ export type KpiTone = 'accent' | 'success' | 'warning' | 'error' | 'neutral'; export interface KpiCardProps { /** Small-caps label. Say what it is, not what it means. */ label: string; value: string; /** * The line under the figure — what the number is made of, or what it is a * share of. This is where a KPI gets its meaning; see the note above. */ note?: string; /** * Colours the icon tile. `neutral` and `accent` are both the brand — a tile * reports by default and only says more when something is actually wrong. */ tone?: KpiTone; icon?: ReactNode; /** * Accepted and ignored. * * The 2px underline bar this drove was removed from the tile deliberately — * a proportion bar under five tiles turned the strip into a chart. Six call * sites still pass it, so the prop stays declared to keep them compiling. * Drop it from those callers and this can go. */ fill?: number; } export function KpiCard({ label, value, note, tone = 'neutral', icon }: KpiCardProps) { return (