Dashboard Overview
Original · freecompact dashboard overview grid
Copy prompt gives Claude Code, Cursor or v0 a ready-to-paste prompt that recreates this exact component.
npx shadcn@latest add https://webinnoventix.com/r/dash-overview.json"use client";
import { useCallback, useId, useMemo, useRef, useState } from "react";
import type { KeyboardEvent as ReactKeyboardEvent } from "react";
import { motion, useReducedMotion } from "motion/react";
type RangeId = "7d" | "30d" | "90d";
type KpiId = "devs" | "requests" | "latency" | "errors";
type RangeMeta = {
id: RangeId;
short: string;
label: string;
compare: string;
};
type KpiMeta = {
id: KpiId;
label: string;
suffix: string;
goodWhen: "up" | "down";
text: string;
stroke: string;
};
type KpiPoint = {
value: number;
prev: number;
series: number[];
};
type ClientRow = {
id: string;
name: string;
detail: string;
bar: string;
dot: string;
};
type RunbookItem = {
id: string;
title: string;
meta: string;
done: boolean;
};
const RANGES: RangeMeta[] = [
{ id: "7d", short: "7d", label: "Last 7 days", compare: "vs. prior 7 days" },
{ id: "30d", short: "30d", label: "Last 30 days", compare: "vs. prior 30 days" },
{ id: "90d", short: "90d", label: "Last 90 days", compare: "vs. prior 90 days" },
];
const KPIS: KpiMeta[] = [
{
id: "devs",
label: "Active developers",
suffix: "",
goodWhen: "up",
text: "text-indigo-600 dark:text-indigo-400",
stroke: "text-indigo-500 dark:text-indigo-400",
},
{
id: "requests",
label: "API requests",
suffix: "",
goodWhen: "up",
text: "text-violet-600 dark:text-violet-400",
stroke: "text-violet-500 dark:text-violet-400",
},
{
id: "latency",
label: "p95 latency",
suffix: "ms",
goodWhen: "down",
text: "text-sky-600 dark:text-sky-400",
stroke: "text-sky-500 dark:text-sky-400",
},
{
id: "errors",
label: "Error rate",
suffix: "%",
goodWhen: "down",
text: "text-amber-600 dark:text-amber-500",
stroke: "text-amber-500 dark:text-amber-500",
},
];
const KPI_DATA: Record<RangeId, Record<KpiId, KpiPoint>> = {
"7d": {
devs: {
value: 1284,
prev: 1197,
series: [1102, 1150, 1128, 1196, 1240, 1219, 1284],
},
requests: {
value: 4_820_000,
prev: 4_310_000,
series: [612000, 668000, 701000, 655000, 724000, 748000, 712000],
},
latency: { value: 214, prev: 236, series: [236, 231, 240, 224, 219, 226, 214] },
errors: {
value: 0.42,
prev: 0.61,
series: [0.61, 0.58, 0.66, 0.52, 0.47, 0.5, 0.42],
},
},
"30d": {
devs: {
value: 4936,
prev: 4402,
series: [4402, 4488, 4515, 4602, 4574, 4688, 4731, 4802, 4869, 4936],
},
requests: {
value: 19_640_000,
prev: 17_250_000,
series: [
17250000, 17540000, 17980000, 18120000, 18460000, 18790000, 19010000,
19230000, 19440000, 19640000,
],
},
latency: {
value: 227,
prev: 241,
series: [241, 244, 238, 235, 239, 232, 230, 233, 229, 227],
},
errors: {
value: 0.51,
prev: 0.58,
series: [0.58, 0.6, 0.57, 0.55, 0.56, 0.53, 0.54, 0.52, 0.53, 0.51],
},
},
"90d": {
devs: {
value: 11208,
prev: 9865,
series: [
9865, 10020, 10190, 10310, 10480, 10620, 10740, 10880, 10990, 11080,
11150, 11208,
],
},
requests: {
value: 56_310_000,
prev: 48_720_000,
series: [
48720000, 49600000, 50410000, 51280000, 52040000, 52880000, 53610000,
54320000, 54980000, 55510000, 55940000, 56310000,
],
},
latency: {
value: 238,
prev: 268,
series: [268, 264, 259, 256, 252, 249, 247, 244, 242, 241, 239, 238],
},
errors: {
value: 0.63,
prev: 0.77,
series: [0.77, 0.75, 0.73, 0.72, 0.7, 0.69, 0.68, 0.67, 0.66, 0.65, 0.64, 0.63],
},
},
};
const CLIENTS: ClientRow[] = [
{
id: "node",
name: "Node SDK",
detail: "v2.8.4 and newer",
bar: "bg-indigo-500",
dot: "bg-indigo-500",
},
{
id: "python",
name: "Python SDK",
detail: "v2.7.0 and newer",
bar: "bg-violet-500",
dot: "bg-violet-500",
},
{
id: "rest",
name: "REST (raw)",
detail: "No SDK, direct HTTP",
bar: "bg-sky-500",
dot: "bg-sky-500",
},
{
id: "cli",
name: "CLI",
detail: "Local + CI runners",
bar: "bg-emerald-500",
dot: "bg-emerald-500",
},
{
id: "browser",
name: "Browser",
detail: "Edge-signed tokens",
bar: "bg-amber-500",
dot: "bg-amber-500",
},
];
const CLIENT_DATA: Record<RangeId, Record<string, number>> = {
"7d": {
node: 2_060_000,
python: 1_240_000,
rest: 830_000,
cli: 410_000,
browser: 280_000,
},
"30d": {
node: 8_420_000,
python: 5_010_000,
rest: 3_390_000,
cli: 1_680_000,
browser: 1_140_000,
},
"90d": {
node: 24_100_000,
python: 14_380_000,
rest: 9_720_000,
cli: 4_820_000,
browser: 3_290_000,
},
};
const RUNBOOK: RunbookItem[] = [
{ id: "keys", title: "Rotate staging API keys", meta: "Due 16:00 UTC", done: true },
{
id: "webhooks",
title: "Review 3 flagged webhook retries",
meta: "acct_9f21, acct_4b07",
done: true,
},
{
id: "pr",
title: "Merge rate-limit header PR",
meta: "#4821 · 2 approvals",
done: false,
},
{
id: "changelog",
title: "Publish v2.9 changelog",
meta: "Draft ready",
done: false,
},
{
id: "backfill",
title: "Backfill eu-west latency metrics",
meta: "Blocked on ingest",
done: false,
},
];
const KEYFRAMES = `
@keyframes dov-ping {
0% { transform: scale(1); opacity: .55; }
70% { transform: scale(2.6); opacity: 0; }
100% { transform: scale(2.6); opacity: 0; }
}
@keyframes dov-rise {
from { opacity: 0; transform: translateY(7px); }
to { opacity: 1; transform: none; }
}
.dov-ping { animation: dov-ping 2.4s cubic-bezier(0, 0, .2, 1) infinite; }
.dov-rise { animation: dov-rise .5s cubic-bezier(.16, 1, .3, 1) both; }
@media (prefers-reduced-motion: reduce) {
.dov-ping, .dov-rise { animation: none !important; }
}
`;
const SPARK_W = 100;
const SPARK_H = 32;
const SPARK_PAD = 4;
function fmtInt(n: number): string {
return Math.round(n).toLocaleString("en-US");
}
function fmtCompact(n: number): string {
if (n >= 1_000_000) return `${(n / 1_000_000).toFixed(2)}M`;
if (n >= 1_000) return `${(n / 1_000).toFixed(1)}k`;
return fmtInt(n);
}
function fmtKpi(id: KpiId, v: number): string {
if (id === "requests") return fmtCompact(v);
if (id === "errors") return v.toFixed(2);
return fmtInt(v);
}
function sparkPaths(series: number[]): { line: string; area: string } {
const n = series.length;
const min = Math.min(...series);
const max = Math.max(...series);
const span = max - min || 1;
const inner = SPARK_H - SPARK_PAD * 2;
const pts = series.map((v, i) => {
const x = n === 1 ? SPARK_W / 2 : (i / (n - 1)) * SPARK_W;
const y = SPARK_PAD + (1 - (v - min) / span) * inner;
return { x, y };
});
const line = pts
.map((p, i) => `${i === 0 ? "M" : "L"}${p.x.toFixed(2)},${p.y.toFixed(2)}`)
.join(" ");
const area = `M${pts[0].x.toFixed(2)},${SPARK_H} ${pts
.map((p) => `L${p.x.toFixed(2)},${p.y.toFixed(2)}`)
.join(" ")} L${pts[n - 1].x.toFixed(2)},${SPARK_H} Z`;
return { line, area };
}
const RING_R = 18;
const RING_C = 2 * Math.PI * RING_R;
export default function DashOverview() {
const reduce = useReducedMotion();
const uid = useId();
const [range, setRange] = useState<RangeId>("30d");
const [compact, setCompact] = useState<boolean>(false);
const [muted, setMuted] = useState<string[]>([]);
const [done, setDone] = useState<Record<string, boolean>>(() =>
Object.fromEntries(RUNBOOK.map((r) => [r.id, r.done])),
);
const radioRefs = useRef<Array<HTMLButtonElement | null>>([]);
const rangeMeta = useMemo<RangeMeta>(
() => RANGES.find((r) => r.id === range) ?? RANGES[1],
[range],
);
const clientValues = CLIENT_DATA[range];
const clientTotals = useMemo(() => {
const all = CLIENTS.reduce((sum, c) => sum + clientValues[c.id], 0);
const selected = CLIENTS.filter((c) => !muted.includes(c.id)).reduce(
(sum, c) => sum + clientValues[c.id],
0,
);
const max = Math.max(...CLIENTS.map((c) => clientValues[c.id]));
return { all, selected, max };
}, [clientValues, muted]);
const doneCount = useMemo(
() => RUNBOOK.filter((r) => done[r.id]).length,
[done],
);
const ringPct = doneCount / RUNBOOK.length;
const toggleClient = useCallback((id: string): void => {
setMuted((prev) =>
prev.includes(id) ? prev.filter((x) => x !== id) : [...prev, id],
);
}, []);
const onRangeKey = useCallback(
(e: ReactKeyboardEvent<HTMLDivElement>): void => {
const i = RANGES.findIndex((r) => r.id === range);
let next = i;
switch (e.key) {
case "ArrowRight":
case "ArrowDown":
next = (i + 1) % RANGES.length;
break;
case "ArrowLeft":
case "ArrowUp":
next = (i - 1 + RANGES.length) % RANGES.length;
break;
case "Home":
next = 0;
break;
case "End":
next = RANGES.length - 1;
break;
default:
return;
}
e.preventDefault();
setRange(RANGES[next].id);
radioRefs.current[next]?.focus();
},
[range],
);
const cardPad = compact ? "p-3.5" : "p-5";
const gridGap = compact ? "gap-2.5" : "gap-4";
const sparkH = compact ? "h-6" : "h-9";
const valueSize = compact ? "text-xl" : "text-2xl";
return (
<section className="relative w-full bg-slate-50 px-4 py-16 dark:bg-slate-950 sm:px-6 sm:py-20">
<style>{KEYFRAMES}</style>
<div className="mx-auto w-full max-w-5xl">
{/* Header */}
<div className="flex flex-col gap-5 sm:flex-row sm:items-end sm:justify-between">
<div>
<span className="inline-flex items-center gap-2 rounded-full border border-slate-200 bg-white px-2.5 py-1 text-[11px] font-semibold uppercase tracking-widest text-slate-500 dark:border-slate-800 dark:bg-slate-900 dark:text-slate-400">
<span className="relative flex h-1.5 w-1.5" aria-hidden="true">
<span className="dov-ping absolute inline-flex h-full w-full rounded-full bg-emerald-500" />
<span className="relative inline-flex h-1.5 w-1.5 rounded-full bg-emerald-500" />
</span>
Live
</span>
<h2 className="mt-2.5 text-2xl font-semibold tracking-tight text-slate-900 dark:text-white">
Platform overview
</h2>
<p className="mt-1 text-sm text-slate-500 dark:text-slate-400">
Ingest API · {rangeMeta.label}, {rangeMeta.compare}
</p>
</div>
<div className="flex flex-wrap items-center gap-3">
{/* Range radiogroup */}
<div
role="radiogroup"
aria-label="Reporting window"
onKeyDown={onRangeKey}
className="inline-flex rounded-xl border border-slate-200 bg-white p-1 dark:border-slate-800 dark:bg-slate-900"
>
{RANGES.map((r, i) => {
const on = r.id === range;
return (
<button
key={r.id}
ref={(el) => {
radioRefs.current[i] = el;
}}
type="button"
role="radio"
aria-checked={on}
tabIndex={on ? 0 : -1}
onClick={() => setRange(r.id)}
className={`rounded-lg px-3 py-1.5 text-sm font-medium tabular-nums transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-indigo-500 focus-visible:ring-offset-2 focus-visible:ring-offset-white dark:focus-visible:ring-offset-slate-900 ${
on
? "bg-slate-900 text-white shadow-sm dark:bg-white dark:text-slate-900"
: "text-slate-500 hover:text-slate-900 dark:text-slate-400 dark:hover:text-slate-100"
}`}
>
{r.short}
<span className="sr-only"> — {r.label}</span>
</button>
);
})}
</div>
{/* Density switch */}
<button
type="button"
role="switch"
aria-checked={compact}
onClick={() => setCompact((v) => !v)}
className="inline-flex items-center gap-2 rounded-xl border border-slate-200 bg-white py-2 pl-3 pr-2.5 text-sm font-medium text-slate-600 transition-colors hover:text-slate-900 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-indigo-500 focus-visible:ring-offset-2 focus-visible:ring-offset-slate-50 dark:border-slate-800 dark:bg-slate-900 dark:text-slate-300 dark:hover:text-white dark:focus-visible:ring-offset-slate-950"
>
Compact
<span
aria-hidden="true"
className={`relative h-5 w-9 shrink-0 rounded-full transition-colors ${
compact
? "bg-indigo-600"
: "bg-slate-200 dark:bg-slate-700"
}`}
>
<span
className="absolute left-0 top-0.5 h-4 w-4 rounded-full bg-white shadow-sm transition-transform duration-200"
style={{ transform: compact ? "translateX(18px)" : "translateX(2px)" }}
/>
</span>
</button>
</div>
</div>
<p className="sr-only" aria-live="polite">
Showing {rangeMeta.label}. {doneCount} of {RUNBOOK.length} runbook tasks
complete.
</p>
{/* KPI tiles */}
<div className={`mt-6 grid grid-cols-2 ${gridGap} lg:grid-cols-4`}>
{KPIS.map((kpi, i) => {
const point = KPI_DATA[range][kpi.id];
const pct = ((point.value - point.prev) / point.prev) * 100;
const up = pct >= 0;
const good = kpi.goodWhen === "up" ? up : !up;
const paths = sparkPaths(point.series);
const gradId = `${uid}-${kpi.id}`;
return (
<div
key={kpi.id}
className={`dov-rise rounded-2xl border border-slate-200 bg-white ${cardPad} shadow-sm transition-[padding] duration-200 dark:border-slate-800 dark:bg-slate-900`}
style={{ animationDelay: `${i * 70}ms` }}
>
<p className="truncate text-xs font-medium text-slate-500 dark:text-slate-400">
{kpi.label}
</p>
<div className="mt-1.5 flex items-baseline gap-1">
<span
className={`${valueSize} font-semibold tracking-tight tabular-nums text-slate-900 transition-[font-size] duration-200 dark:text-white`}
>
{fmtKpi(kpi.id, point.value)}
</span>
{kpi.suffix ? (
<span className="text-sm font-medium text-slate-400 dark:text-slate-500">
{kpi.suffix}
</span>
) : null}
</div>
<div className="mt-2 flex items-center gap-1.5">
<span
className={`inline-flex items-center gap-0.5 rounded-md px-1.5 py-0.5 text-[11px] font-semibold tabular-nums ${
good
? "bg-emerald-50 text-emerald-700 dark:bg-emerald-500/10 dark:text-emerald-400"
: "bg-rose-50 text-rose-700 dark:bg-rose-500/10 dark:text-rose-400"
}`}
>
<svg
viewBox="0 0 12 12"
className={`h-2.5 w-2.5 ${up ? "" : "rotate-180"}`}
fill="none"
aria-hidden="true"
>
<path
d="M6 9.5V2.5M6 2.5 3 5.5M6 2.5l3 3"
stroke="currentColor"
strokeWidth="1.6"
strokeLinecap="round"
strokeLinejoin="round"
/>
</svg>
{up ? "+" : "−"}
{Math.abs(pct).toFixed(1)}%
</span>
<span className="truncate text-[11px] text-slate-400 dark:text-slate-500">
{rangeMeta.compare}
</span>
</div>
<svg
key={`${kpi.id}-${range}`}
viewBox={`0 0 ${SPARK_W} ${SPARK_H}`}
preserveAspectRatio="none"
className={`mt-3 w-full ${sparkH} transition-[height] duration-200 ${kpi.stroke}`}
role="img"
aria-label={`${kpi.label} trend over the ${rangeMeta.label.toLowerCase()}: ${fmtKpi(
kpi.id,
point.series[0],
)}${kpi.suffix} rising to ${fmtKpi(kpi.id, point.value)}${kpi.suffix}.`}
>
<defs>
<linearGradient id={gradId} x1="0" y1="0" x2="0" y2="1">
<stop offset="0%" stopColor="currentColor" stopOpacity="0.28" />
<stop offset="100%" stopColor="currentColor" stopOpacity="0" />
</linearGradient>
</defs>
<motion.path
d={paths.area}
fill={`url(#${gradId})`}
initial={reduce ? false : { opacity: 0 }}
animate={reduce ? undefined : { opacity: 1 }}
transition={{ duration: 0.6, ease: "easeOut" }}
/>
<motion.path
d={paths.line}
fill="none"
stroke="currentColor"
strokeWidth={1.75}
strokeLinecap="round"
strokeLinejoin="round"
vectorEffect="non-scaling-stroke"
initial={reduce ? false : { pathLength: 0 }}
animate={reduce ? undefined : { pathLength: 1 }}
transition={{ duration: 0.85, ease: "easeInOut" }}
/>
</svg>
</div>
);
})}
</div>
{/* Bento row */}
<div className={`mt-4 grid ${gridGap} lg:grid-cols-3`}>
{/* Clients breakdown */}
<div
className={`dov-rise rounded-2xl border border-slate-200 bg-white ${cardPad} shadow-sm transition-[padding] duration-200 dark:border-slate-800 dark:bg-slate-900 lg:col-span-2`}
style={{ animationDelay: "300ms" }}
>
<div className="flex flex-wrap items-start justify-between gap-3">
<div>
<h3 className="text-sm font-semibold text-slate-900 dark:text-white">
Requests by client
</h3>
<p className="mt-0.5 text-xs text-slate-500 dark:text-slate-400">
Toggle a client to include or exclude it from the total
</p>
</div>
<div className="text-right">
<p className="text-lg font-semibold tabular-nums text-slate-900 dark:text-white">
{fmtCompact(clientTotals.selected)}
</p>
<p className="text-[11px] tabular-nums text-slate-400 dark:text-slate-500">
of {fmtCompact(clientTotals.all)} selected
</p>
</div>
</div>
<ul className={`mt-4 space-y-1 ${compact ? "" : "sm:space-y-1.5"}`}>
{CLIENTS.map((c) => {
const v = clientValues[c.id];
const off = muted.includes(c.id);
const barPct = (v / clientTotals.max) * 100;
const share = (v / clientTotals.all) * 100;
return (
<li key={c.id}>
<button
type="button"
aria-pressed={!off}
onClick={() => toggleClient(c.id)}
className="group flex w-full items-center gap-3 rounded-lg px-2 py-1.5 text-left transition-colors hover:bg-slate-50 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-indigo-500 focus-visible:ring-offset-1 focus-visible:ring-offset-white dark:hover:bg-slate-800/60 dark:focus-visible:ring-offset-slate-900"
>
<span
aria-hidden="true"
className={`h-2 w-2 shrink-0 rounded-full ${c.dot} ${
off ? "opacity-25" : ""
}`}
/>
<span className="w-24 shrink-0 sm:w-28">
<span
className={`block truncate text-xs font-medium ${
off
? "text-slate-400 dark:text-slate-600"
: "text-slate-800 dark:text-slate-100"
}`}
>
{c.name}
</span>
{!compact ? (
<span className="block truncate text-[10px] text-slate-400 dark:text-slate-500">
{c.detail}
</span>
) : null}
</span>
<span className="relative h-2 flex-1 overflow-hidden rounded-full bg-slate-100 dark:bg-slate-800">
<motion.span
className={`absolute inset-y-0 left-0 rounded-full ${c.bar} ${
off ? "opacity-20" : ""
}`}
initial={reduce ? false : { width: 0 }}
animate={{ width: `${barPct}%` }}
transition={
reduce
? { duration: 0 }
: { duration: 0.7, ease: [0.16, 1, 0.3, 1] }
}
/>
</span>
<span
className={`w-14 shrink-0 text-right text-xs font-semibold tabular-nums ${
off
? "text-slate-300 dark:text-slate-600"
: "text-slate-700 dark:text-slate-200"
}`}
>
{fmtCompact(v)}
</span>
<span className="hidden w-11 shrink-0 text-right text-[11px] tabular-nums text-slate-400 dark:text-slate-500 sm:block">
{share.toFixed(1)}%
</span>
</button>
</li>
);
})}
</ul>
</div>
{/* Runbook */}
<div
className={`dov-rise rounded-2xl border border-slate-200 bg-white ${cardPad} shadow-sm transition-[padding] duration-200 dark:border-slate-800 dark:bg-slate-900`}
style={{ animationDelay: "370ms" }}
>
<div className="flex items-center justify-between gap-3">
<div>
<h3 className="text-sm font-semibold text-slate-900 dark:text-white">
Today’s runbook
</h3>
<p className="mt-0.5 text-xs text-slate-500 dark:text-slate-400">
{doneCount} of {RUNBOOK.length} complete
</p>
</div>
<svg viewBox="0 0 44 44" className="h-11 w-11 shrink-0 -rotate-90" aria-hidden="true">
<circle
cx="22"
cy="22"
r={RING_R}
fill="none"
strokeWidth="4"
className="stroke-slate-100 dark:stroke-slate-800"
/>
<motion.circle
cx="22"
cy="22"
r={RING_R}
fill="none"
strokeWidth="4"
strokeLinecap="round"
strokeDasharray={RING_C}
className="stroke-emerald-500"
initial={false}
animate={{ strokeDashoffset: RING_C * (1 - ringPct) }}
transition={
reduce ? { duration: 0 } : { duration: 0.45, ease: "easeOut" }
}
/>
</svg>
</div>
<ul className="mt-3 space-y-0.5">
{RUNBOOK.map((item) => {
const checked = done[item.id];
return (
<li key={item.id}>
<label className="flex cursor-pointer items-start gap-2.5 rounded-lg px-2 py-2 transition-colors hover:bg-slate-50 dark:hover:bg-slate-800/60">
<input
type="checkbox"
checked={checked}
onChange={() =>
setDone((prev) => ({ ...prev, [item.id]: !prev[item.id] }))
}
className="peer sr-only"
/>
<span
aria-hidden="true"
className={`mt-px grid h-4 w-4 shrink-0 place-items-center rounded border transition-colors peer-focus-visible:ring-2 peer-focus-visible:ring-indigo-500 peer-focus-visible:ring-offset-2 peer-focus-visible:ring-offset-white dark:peer-focus-visible:ring-offset-slate-900 ${
checked
? "border-emerald-500 bg-emerald-500"
: "border-slate-300 bg-white dark:border-slate-600 dark:bg-slate-900"
}`}
>
{checked ? (
<svg viewBox="0 0 12 12" className="h-2.5 w-2.5" fill="none">
<path
d="M2.5 6.2 4.7 8.4 9.5 3.6"
stroke="white"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
/>
</svg>
) : null}
</span>
<span className="min-w-0">
<span
className={`block text-xs font-medium leading-snug ${
checked
? "text-slate-400 line-through dark:text-slate-600"
: "text-slate-800 dark:text-slate-100"
}`}
>
{item.title}
</span>
{!compact ? (
<span className="mt-0.5 block truncate text-[10px] text-slate-400 dark:text-slate-500">
{item.meta}
</span>
) : null}
</span>
</label>
</li>
);
})}
</ul>
</div>
</div>
{/* Footer strip */}
<div
className="dov-rise mt-4 flex flex-wrap items-center justify-between gap-3 rounded-2xl border border-slate-200 bg-white px-5 py-3 text-xs shadow-sm dark:border-slate-800 dark:bg-slate-900"
style={{ animationDelay: "440ms" }}
>
<p className="flex items-center gap-2 font-medium text-slate-600 dark:text-slate-300">
<svg
viewBox="0 0 16 16"
className="h-3.5 w-3.5 text-emerald-500"
fill="none"
aria-hidden="true"
>
<circle cx="8" cy="8" r="6.5" stroke="currentColor" strokeWidth="1.5" />
<path
d="M5 8.2 7 10.2l4-4.4"
stroke="currentColor"
strokeWidth="1.7"
strokeLinecap="round"
strokeLinejoin="round"
/>
</svg>
All four regions healthy
</p>
<p className="tabular-nums text-slate-400 dark:text-slate-500">
us-east 187ms · eu-west 226ms · ap-south 341ms ·
sa-east 298ms
</p>
<p className="text-slate-400 dark:text-slate-500">Synced 2 min ago</p>
</div>
</div>
</section>
);
}Dependencies
Licence
Built by Web Innoventix. Free for personal and commercial use, no attribution required.
Built by Web Innoventix
Need a custom interface, a full website, or SEO that gets you cited by AI? We design, build and rank it end to end.
Get a free quoteSimilar components
Browse all →
Dashboard KPI Row
Originalrow of KPI stat cards with trends

Dashboard Stat Widgets
Originalassorted dashboard stat widgets

Dashboard Activity
Originalrecent activity feed widget

Dashboard Chart Widget
Originalchart panel widget with tabs

Dashboard Revenue
Originalrevenue overview card with chart

Dashboard Users
Originalactive users widget

Dashboard Tasks
Originaltasks/checklist widget

Dashboard Calendar Widget
Originalmini calendar dashboard widget

Dashboard Notifications
Originalnotifications panel widget

Spotlight Hero
OriginalA centred hero with a soft radial spotlight, badge and dual call-to-action.

Split Hero
OriginalA two-column hero pairing a headline and CTAs with a product mock and social proof.

Gradient Spotlight Hero
OriginalA minimal centred hero with a soft gradient-mesh backdrop, announcement pill and dual call-to-action buttons.

