# Model usage

> An AI gateway dashboard: requests, tokens and spend, tokens by model over time, latency, a written summary, and a model table that focuses the chart.

A shadcn/ui block from the [@overtrue](https://ui.overtrue.xyz/?utm_source=shadcn.exchange) registry, listed on [shadcn.exchange](https://shadcn.exchange/r/overtrue/model-usage).

- Page, with a live preview: https://shadcn.exchange/r/overtrue/model-usage
- Screenshot: https://shadcn.exchange/shot/overtrue/model-usage/light.png
- Registry item: https://ui.overtrue.xyz/r/model-usage.json
- Categories: blocks
- Listed: 2026-10-28, source last changed 2026-10-28

## Install

```bash
npx shadcn@latest add https://shadcn.exchange/r/overtrue/model-usage.json
```

Run it in a project that has shadcn/ui set up. It adds the files below and installs what they depend on.

## Dependencies

- npm packages: `@tabler/icons-react`

## Notes from the registry

Documentation: https://ui.overtrue.xyz/blocks/model-usage. Requires an initialized shadcn/ui project with Tailwind CSS v4.

## Files

### `src/registry/overtrue/model-usage.tsx`

```tsx
"use client";

import * as React from "react";
import { IconCalendarStats, IconSparkles } from "@tabler/icons-react";

import { cn } from "@/lib/utils";
import { NumberTicker } from "./number-ticker";
import { Sparkline } from "./sparkline";
import { DeltaBadge } from "./delta-badge";
import {
  StackedAreaChart,
  type StackedAreaAnnotation,
} from "./stacked-area-chart";
import { LatencyHistogram } from "./latency-histogram";
import { InsightCard, type InsightSource } from "./insight-card";

export interface ModelUsageModel {
  /** Field name for this model in each `usage` row. */
  id: string;
  label: string;
  /** Provider or deployment, shown under the name. */
  provider?: string;
  color?: string;
  requests: number;
  inputTokens: number;
  outputTokens: number;
  /** Spend for the period, in currency units. */
  cost: number;
  /** 95th percentile latency in milliseconds. */
  p95: number;
  /** Failed requests as a fraction, e.g. 0.004 for 0.4%. */
  errorRate: number;
}

export interface ModelUsageMetric {
  id: string;
  label: string;
  value: number;
  format?: "number" | "compact" | "currency" | "milliseconds";
  /** Fractional change against the previous period. */
  change?: number;
  /** Lower is better, e.g. spend or latency. */
  invert?: boolean;
  history?: number[];
  hint?: string;
}

export interface ModelUsageData {
  title: string;
  period: string;
  currency?: string;
  /** Headline figures; the first is lit as the hero. */
  metrics: ModelUsageMetric[];
  /** One row per day: an `date` ISO string plus a token count per model id. */
  usage: Record<string, unknown>[];
  models: ModelUsageModel[];
  /** Markers on the usage chart, such as a routing change. */
  annotations?: StackedAreaAnnotation[];
  latency: {
    /** Gateway request latencies in milliseconds. */
    values: number[];
    compare?: number[];
    threshold?: number;
  };
  /** A written summary with optional `{{metric:…}}` and `{{cite:n}}` tokens. */
  summary?: { text: string; sources?: InsightSource[] };
}

export interface ModelUsageProps
  extends Omit<React.ComponentProps<"section">, "title"> {
  data: ModelUsageData;
  actions?: React.ReactNode;
  locale?: string;
  /** Regenerate the summary with your own model. */
  onRegenerateSummary?: () => void;
  /** Show the summary as it streams in. */
  summaryStreaming?: boolean;
}

/** An AI gateway dashboard: requests, tokens and spend by model, latency, and a written summary. */
export function ModelUsage({
  data,
  actions,
  locale = "en-US",
  onRegenerateSummary,
  summaryStreaming = false,
  className,
  ...props
}: ModelUsageProps) {
  const currency = data.currency ?? "USD";
  const [focused, setFocused] = React.useState<string | null>(null);
  const formats = React.useMemo(
    () => ({
      compact: new Intl.NumberFormat(locale, {
        notation: "compact",
        maximumFractionDigits: 1,
      }),
      number: new Intl.NumberFormat(locale),
      money: new Intl.NumberFormat(locale, {
        style: "currency",
        currency,
        maximumFractionDigits: 0,
      }),
      percent: new Intl.NumberFormat(locale, {
        style: "percent",
        maximumFractionDigits: 2,
      }),
      day: new Intl.DateTimeFormat(locale, { month: "short", day: "numeric" }),
    }),
    [currency, locale],
  );
  const models = React.useMemo(
    () => [...data.models].sort((a, b) => b.cost - a.cost),
    [data.models],
  );
  const series = data.models.map((model) => ({
    key: model.id,
    label: model.label,
    color: model.color,
  }));
  const hidden = focused
    ? data.models.filter((model) => model.id !== focused).map((model) => model.id)
    : [];
  const maxCost = Math.max(...models.map((model) => model.cost), 1);
  const totalCost = models.reduce((sum, model) => sum + model.cost, 0);

  return (
    <section
      data-slot="model-usage"
      aria-label={`${data.title}, ${data.period}`}
      className={cn(
        "@container/usage flex min-w-0 flex-col gap-3 text-foreground sm:gap-4",
        className,
      )}
      {...props}
    >
      <header
        data-slot="model-usage-header"
        className="flex flex-wrap items-end justify-between gap-3"
      >
        <div className="min-w-0">
          <h2 className="truncate text-base font-semibold tracking-tight">
            {data.title}
          </h2>
          <p className="flex items-center gap-1.5 text-xs text-muted-foreground">
            <IconCalendarStats aria-hidden="true" className="size-3.5" />
            {data.period}
          </p>
        </div>
        {actions && (
          <div className="flex flex-wrap items-center gap-2">{actions}</div>
        )}
      </header>

      <div className="grid gap-3 sm:gap-4">
        <dl
          data-slot="model-usage-metrics"
          className="grid grid-cols-1 gap-px overflow-hidden rounded-2xl border border-border/70 bg-border/70 shadow-[0_1px_2px_rgb(0_0_0/0.04),0_8px_24px_-12px_rgb(0_0_0/0.10)] @md/usage:grid-cols-2 @4xl/usage:grid-cols-4 dark:shadow-[inset_0_1px_0_rgb(255_255_255/0.05),0_1px_2px_rgb(0_0_0/0.5)]"
        >
          {data.metrics.map((metric, index) => (
            <UsageMetric
              key={metric.id}
              metric={metric}
              hero={index === 0}
              locale={locale}
              currency={currency}
            />
          ))}
        </dl>

        <StackedAreaChart
          title="Tokens by model"
          description={
            focused
              ? `Showing ${data.models.find((model) => model.id === focused)?.label} only. Select it again in the table to show every model.`
              : "Input and output tokens per day, stacked by model"
          }
          data={data.usage}
          index="date"
          series={series}
          hiddenSeries={hidden}
          onHiddenSeriesChange={(next) => {
            const visible = data.models.filter((model) => !next.includes(model.id));
            setFocused(visible.length === 1 ? visible[0].id : null);
          }}
          annotations={data.annotations}
          height={300}
          valueFormatter={(value) => formats.compact.format(value)}
          xFormatter={(value) =>
            formats.day.format(value instanceof Date ? value : new Date(String(value)))
          }
        />

        <div className="grid gap-3 sm:gap-4 @4xl/usage:grid-cols-[minmax(0,1fr)_minmax(0,1.15fr)]">
          {data.summary && (
            <InsightCard
              title="Usage summary"
              source={data.period}
              icon={<IconSparkles aria-hidden="true" className="size-4" />}
              text={data.summary.text}
              sources={data.summary.sources}
              status={summaryStreaming ? "streaming" : "done"}
              onRegenerate={onRegenerateSummary}
            />
          )}
          <LatencyHistogram
            title="Gateway latency"
            description="Every request in the period, against the previous one"
            values={data.latency.values}
            compare={data.latency.compare}
            compareLabel="Previous"
            seriesLabel="This period"
            threshold={data.latency.threshold}
            thresholdLabel="SLO"
          />
        </div>

        <div
          data-slot="model-usage-table"
          className="overflow-hidden rounded-2xl border border-border/70 bg-card text-card-foreground shadow-[0_1px_2px_rgb(0_0_0/0.04),0_8px_24px_-12px_rgb(0_0_0/0.10)] dark:shadow-[inset_0_1px_0_rgb(255_255_255/0.05),0_1px_2px_rgb(0_0_0/0.5)]"
        >
          <div className="flex flex-wrap items-baseline justify-between gap-2 px-5 pt-5 pb-3">
            <div>
              <h3 className="text-sm font-semibold tracking-tight">Models</h3>
              <p className="text-[13px] leading-5 text-muted-foreground">
                Select a model to show it alone on the chart.
              </p>
            </div>
            <p className="text-xs text-muted-foreground tabular-nums">
              {formats.money.format(totalCost)} across {models.length} models
            </p>
          </div>
          <div className="overflow-x-auto">
            <table className="w-full min-w-[640px] border-collapse text-sm">
              <thead>
                <tr className="border-y border-border/60 text-left text-xs text-muted-foreground">
                  <th scope="col" className="w-[24%] px-5 py-2 font-medium">Model</th>
                  <th scope="col" className="px-3 py-2 text-right font-medium">Requests</th>
                  <th scope="col" className="w-[22%] px-3 py-2 font-medium">Tokens in · out</th>
                  <th scope="col" className="w-[28%] px-3 py-2 font-medium">Spend</th>
                  <th scope="col" className="px-3 py-2 text-right font-medium">p95</th>
                  <th scope="col" className="px-5 py-2 text-right font-medium">Errors</th>
                </tr>
              </thead>
              <tbody>
                {models.map((model) => {
                  const index = data.models.indexOf(model);
                  const color = model.color ?? `var(--color-chart-${(index % 5) + 1})`;
                  const tokens = model.inputTokens + model.outputTokens;
                  const active = focused === model.id;
                  const dimmed = focused !== null && !active;
                  return (
                    <tr
                      key={model.id}
                      data-slot="model-usage-row"
                      data-active={active || undefined}
                      className={cn(
                        "border-b border-border/50 transition-opacity duration-150 last:border-b-0",
                        dimmed && "opacity-45",
                        active && "bg-primary/[0.04]",
                      )}
                    >
                      <th scope="row" className="px-5 py-2.5 text-left font-normal">
                        <button
                          type="button"
                          aria-pressed={active}
                          onClick={() => setFocused(active ? null : model.id)}
                          className="group flex items-center gap-2.5 rounded-md text-left outline-none focus-visible:ring-2 focus-visible:ring-ring/50"
                        >
                          <span
                            aria-hidden="true"
                            className="size-2.5 shrink-0 rounded-[3px] shadow-[0_0_0_3px_color-mix(in_oklab,currentColor_16%,transparent)]"
                            style={{ background: color, color }}
                          />
                          <span className="min-w-0">
                            <span className="block truncate font-medium group-hover:underline group-hover:underline-offset-4">
                              {model.label}
                            </span>
                            {model.provider && (
                              <span className="block truncate font-mono text-[11px] text-muted-foreground">
                                {model.provider}
                              </span>
                            )}
                          </span>
                        </button>
                      </th>
                      <td className="px-3 py-2.5 text-right tabular-nums">
                        {formats.compact.format(model.requests)}
                      </td>
                      <td className="px-3 py-2.5">
                        <div className="flex items-center gap-2.5">
                          <span className="w-12 shrink-0 tabular-nums">
                            {formats.compact.format(tokens)}
                          </span>
                          <span
                            className="flex h-1.5 min-w-16 flex-1 overflow-hidden rounded-full bg-muted"
                            role="img"
                            aria-label={`${formats.compact.format(model.inputTokens)} input, ${formats.compact.format(model.outputTokens)} output`}
                          >
                            <span
                              className="h-full"
                              style={{
                                width: `${(model.inputTokens / Math.max(tokens, 1)) * 100}%`,
                                background: color,
                              }}
                            />
                            <span
                              className="h-full opacity-45"
                              style={{ flex: 1, background: color }}
                            />
                          </span>
                        </div>
                      </td>
                      <td className="px-3 py-2.5">
                        <div className="flex items-center gap-2.5">
                          <span className="w-16 shrink-0 tabular-nums">
                            {formats.money.format(model.cost)}
                          </span>
                          <span className="h-1.5 min-w-20 flex-1 overflow-hidden rounded-full bg-muted">
                            <span
                              className="block h-full rounded-full"
                              style={{
                                width: `${(model.cost / maxCost) * 100}%`,
                                background: `linear-gradient(90deg, color-mix(in oklab, ${color} 70%, transparent), ${color})`,
                              }}
                            />
                          </span>
                          <span className="w-12 shrink-0 text-right text-xs text-muted-foreground tabular-nums">
                            {formats.percent.format(model.cost / Math.max(totalCost, 1))}
                          </span>
                        </div>
                      </td>
                      <td className="px-3 py-2.5 text-right tabular-nums">
                        {formats.number.format(Math.round(model.p95))}
                        <span className="ml-0.5 text-xs text-muted-foreground">ms</span>
                      </td>
                      <td className="px-5 py-2.5 text-right tabular-nums">
                        <span
                          className={cn(
                            "inline-flex items-center gap-1.5",
                            model.errorRate >= 0.01
                              ? "text-rose-600 dark:text-rose-400"
                              : model.errorRate >= 0.005
                                ? "text-amber-700 dark:text-amber-300"
                                : "text-muted-foreground",
                          )}
                        >
                          {model.errorRate >= 0.005 && (
                            <span aria-hidden="true" className="size-1.5 rounded-full bg-current" />
                          )}
                          {formats.percent.format(model.errorRate)}
                        </span>
                      </td>
                    </tr>
                  );
                })}
              </tbody>
            </table>
          </div>
        </div>
      </div>
    </section>
  );
}

function UsageMetric({
  metric,
  hero,
  locale,
  currency,
}: {
  metric: ModelUsageMetric;
  hero: boolean;
  locale: string;
  currency: string;
}) {
  const format = metric.format ?? "number";
  return (
    <div
      data-slot="model-usage-metric"
      data-hero={hero || undefined}
      className={cn(
        "relative flex min-w-0 flex-col gap-3 bg-card p-5",
        hero &&
          "bg-[radial-gradient(120%_90%_at_0%_0%,color-mix(in_oklab,var(--color-primary)_10%,transparent),transparent_60%)] bg-card",
      )}
    >
      <div className="flex items-center justify-between gap-2">
        <dt className="truncate text-xs text-muted-foreground">{metric.label}</dt>
        {metric.change !== undefined && (
          <DeltaBadge delta={metric.change} invert={metric.invert} variant="soft" />
        )}
      </div>
      <dd className="flex min-w-0 flex-col gap-1">
        <NumberTicker
          value={metric.value}
          locale={locale}
          currency={currency}
          format={format === "currency" ? "currency" : format === "compact" ? "compact" : "number"}
          formatOptions={
            format === "currency"
              ? { style: "currency", currency, maximumFractionDigits: 0 }
              : format === "compact"
                ? { notation: "compact", maximumFractionDigits: 1 }
                : undefined
          }
          suffix={
            format === "milliseconds" ? (
              <span className="ml-0.5 text-base font-medium tracking-normal text-muted-foreground">
                ms
              </span>
            ) : undefined
          }
          className={cn(
            "font-semibold tracking-[-0.035em] tabular-nums",
            hero ? "text-3xl" : "text-2xl",
          )}
        />
        {metric.hint && (
          <span className="text-xs text-muted-foreground">{metric.hint}</span>
        )}
      </dd>
      {metric.history && metric.history.length > 1 && (
        <Sparkline
          data={metric.history}
          label={`${metric.label}, recent trend`}
          className={cn(
            "h-10",
            metric.change === undefined
              ? "text-muted-foreground"
              : (metric.change >= 0) !== Boolean(metric.invert)
                ? "text-primary"
                : "text-rose-500 dark:text-rose-400",
          )}
          filled
          endpoint
        />
      )}
    </div>
  );
}

/* Sample data --------------------------------------------------------------- */

function random(seed: number) {
  return () => {
    seed |= 0;
    seed = (seed + 0x6d2b79f5) | 0;
    let t = Math.imul(seed ^ (seed >>> 15), 1 | seed);
    t = (t + Math.imul(t ^ (t >>> 7), 61 | t)) ^ t;
    return ((t ^ (t >>> 14)) >>> 0) / 4294967296;
  };
}
function logNormal(count: number, median: number, spread: number, seed: number) {
  const next = random(seed);
  return Array.from({ length: count }, () => {
    const u = Math.max(next(), 1e-9);
    const v = next();
    const z = Math.sqrt(-2 * Math.log(u)) * Math.cos(2 * Math.PI * v);
    return Math.round(median * Math.exp(spread * z));
  });
}

const sampleModels = [
  // id, label, provider, base daily tokens, $ per million tokens, output share, tokens per request, p95, error rate
  ["large", "Atlas Large", "atlas/large-2026-08", 26_000_000, 15, 0.32, 3100, 2840, 0.0062],
  ["medium", "Atlas Medium", "atlas/medium-2026-06", 42_000_000, 3, 0.28, 1900, 1320, 0.0031],
  ["small", "Atlas Small", "atlas/small-2026-09", 31_000_000, 0.6, 0.24, 1100, 610, 0.0018],
  ["embed", "Embed v3", "atlas/embed-v3", 54_000_000, 0.1, 0, 420, 140, 0.0004],
  ["rerank", "Rerank v2", "atlas/rerank-v2", 13_000_000, 1, 0, 680, 210, 0.0011],
] as const;

function buildSampleUsage(): ModelUsageData {
  const next = random(42);
  const days = 30;
  const routedOn = 17; // Summaries move from Large to Small on this day.
  const usage: Record<string, unknown>[] = [];
  const totals: Record<string, number> = {};
  for (let day = 0; day < days; day++) {
    const date = new Date(Date.UTC(2026, 8, 13 + day));
    const weekday = date.getUTCDay();
    const weekend = weekday === 0 || weekday === 6 ? 0.58 : 1;
    const growth = 1 + day * 0.012;
    const row: Record<string, unknown> = { date: date.toISOString().slice(0, 10) };
    for (const [id, , , base] of sampleModels) {
      let value = base * weekend * growth * (0.9 + next() * 0.2);
      if (id === "large" && day >= routedOn) value *= 0.46;
      if (id === "small" && day >= routedOn) value *= 1.55;
      row[id] = Math.round(value);
      totals[id] = (totals[id] ?? 0) + Math.round(value);
    }
    usage.push(row);
  }
  const models: ModelUsageModel[] = sampleModels.map(
    ([id, label, provider, , price, outputShare, perRequest, p95, errorRate]) => {
      const tokens = totals[id];
      return {
        id,
        label,
        provider,
        requests: Math.round(tokens / perRequest),
        inputTokens: Math.round(tokens * (1 - outputShare)),
        outputTokens: Math.round(tokens * outputShare),
        cost: Math.round((tokens / 1_000_000) * price),
        p95,
        errorRate,
      };
    },
  );
  const sum = (pick: (model: ModelUsageModel) => number) =>
    models.reduce((total, model) => total + pick(model), 0);
  const dailyTotals = usage.map((row) =>
    sampleModels.reduce((total, [id]) => total + Number(row[id]), 0),
  );
  const weekly = (values: number[]) =>
    Array.from({ length: Math.ceil(values.length / 3) }, (_, index) =>
      values.slice(index * 3, index * 3 + 3).reduce((a, b) => a + b, 0),
    );
  const dailyCost = usage.map((row) =>
    sampleModels.reduce(
      (total, [id, , , , price]) => total + (Number(row[id]) / 1_000_000) * price,
      0,
    ),
  );
  const latency = [
    ...logNormal(2600, 420, 0.7, 7),
    ...logNormal(600, 1900, 0.35, 9),
  ];
  return {
    title: "AI gateway",
    period: "Sep 13 – Oct 12, 2026",
    currency: "USD",
    metrics: [
      {
        id: "requests",
        label: "Requests",
        value: sum((model) => model.requests),
        format: "compact",
        change: 0.214,
        hint: "Across five models",
        history: weekly(dailyTotals.map((tokens) => tokens / 1500)),
      },
      {
        id: "tokens",
        label: "Tokens",
        value: sum((model) => model.inputTokens + model.outputTokens),
        format: "compact",
        change: 0.187,
        hint: "Input and output",
        history: weekly(dailyTotals),
      },
      {
        id: "spend",
        label: "Spend",
        value: sum((model) => model.cost),
        format: "currency",
        change: -0.082,
        invert: true,
        hint: "After routing summaries to Atlas Small",
        history: weekly(dailyCost),
      },
      {
        id: "p95",
        label: "p95 latency",
        value: 1640,
        format: "milliseconds",
        change: -0.126,
        invert: true,
        hint: "Gateway, end to end",
        history: [2010, 1980, 1940, 1890, 1860, 1720, 1690, 1660, 1650, 1640],
      },
    ],
    usage,
    models,
    annotations: [
      { x: usage[routedOn].date as string, label: "Summaries routed to Atlas Small" },
    ],
    latency: {
      values: latency,
      compare: [...logNormal(2600, 470, 0.72, 11), ...logNormal(700, 2300, 0.35, 13)],
      threshold: 2500,
    },
    summary: {
      text: "Spend fell {{metric:Spend|-8.2%|positive}} while requests grew {{metric:Requests|+21.4%|neutral}}, because summaries moved from Atlas Large to Atlas Small on Sep 30 {{cite:1}}. Atlas Small now handles a third of all generation traffic at {{metric:p95|610 ms|positive}} {{cite:2}}. Atlas Large still has the highest error rate, mostly timeouts on long contexts {{cite:3}}; capping its context at 64K tokens would remove most of them.",
      sources: [
        { id: "1", label: "Routing rule summaries-v4" },
        { id: "2", label: "Gateway latency" },
        { id: "3", label: "Error log, Atlas Large" },
      ],
    },
  };
}

/** Fictional AI gateway usage for Acme Studio, for demos and tests. */
export const sampleModelUsage: ModelUsageData = buildSampleUsage();
```

### `src/registry/overtrue/number-ticker.tsx`

```tsx
"use client";
import {
  useEffect,
  useLayoutEffect,
  useMemo,
  useState,
  useSyncExternalStore,
  type ComponentProps,
  type CSSProperties,
  type ReactNode,
} from "react";
import { cn } from "@/lib/utils";

export type NumberTickerFormat = "number" | "currency" | "percent" | "compact";

export interface NumberTickerProps extends Omit<
  ComponentProps<"span">,
  "children" | "prefix"
> {
  value: number;
  /** Preset Intl options. Percent expects a fraction: 0.124 renders 12.4%. */
  format?: NumberTickerFormat;
  /** Merged over the preset, e.g. `{ maximumFractionDigits: 0 }`. */
  formatOptions?: Intl.NumberFormatOptions;
  locale?: string;
  /** ISO 4217 code used by the currency preset. */
  currency?: string;
  prefix?: ReactNode;
  suffix?: ReactNode;
  /** Roll duration in milliseconds. */
  duration?: number;
  /** Tint the number briefly: emerald when it rises, red when it falls. */
  highlightChanges?: boolean;
  /** Roll up from zero on first mount instead of rendering the value directly. */
  animateOnMount?: boolean;
}

// Each column is a wheel of five 0–9 runs. It rests in the middle run, so two
// rapid changes in either direction can always roll forward or backward.
const CELLS = 50;
const REST = 20;
const STAGGER = 32;
const MAX_STAGGER = 224;
const SLIDE_EASE = "cubic-bezier(0.2, 1, 0.32, 1)";
// Overshoot scales with distance, so longer rolls get a gentler curve: every
// wheel settles past its digit by about a tenth of a cell, whatever it travelled.
const SETTLE = [1.534, 1.368, 1.3, 1.262, 1.236, 1.217, 1.203, 1.191, 1.181];
const rollEase = (cells: number) =>
  `cubic-bezier(0.2, ${SETTLE[Math.min(Math.max(Math.abs(cells), 1), 9) - 1]}, 0.32, 1)`;
const SIZE_EASE = "cubic-bezier(0.32, 0.72, 0, 1)";
const REDUCED_QUERY = "(prefers-reduced-motion: reduce)";

function subscribeReducedMotion(callback: () => void) {
  const query = window.matchMedia(REDUCED_QUERY);
  query.addEventListener("change", callback);
  return () => query.removeEventListener("change", callback);
}

function usePrefersReducedMotion() {
  return useSyncExternalStore(
    subscribeReducedMotion,
    () => window.matchMedia(REDUCED_QUERY).matches,
    () => false,
  );
}

const presets: Record<
  NumberTickerFormat,
  (currency: string) => Intl.NumberFormatOptions
> = {
  number: () => ({}),
  currency: (currency) => ({ style: "currency", currency }),
  percent: () => ({
    style: "percent",
    minimumFractionDigits: 1,
    maximumFractionDigits: 1,
  }),
  compact: () => ({ notation: "compact", maximumSignificantDigits: 3 }),
};

interface TickerFormatter {
  format: Intl.NumberFormat;
  /** The locale's digit glyphs, so Arabic-Indic or Devanagari numerals roll too. */
  glyphs: string[];
  /** One padded cell per wheel position, created once and shared by every column. */
  cells: ReactNode[];
}

const formatterCache = new Map<string, TickerFormatter>();

function resolveOptions(
  format: NumberTickerFormat,
  currency: string,
  overrides: Intl.NumberFormatOptions | undefined,
): Intl.NumberFormatOptions {
  const options = { ...presets[format](currency), ...overrides };
  // Keep a preset's fixed precision from conflicting with a partial override.
  const { minimumFractionDigits: min, maximumFractionDigits: max } = options;
  if (min !== undefined && max !== undefined && min > max) {
    if (overrides?.maximumFractionDigits !== undefined)
      options.minimumFractionDigits = max;
    else options.maximumFractionDigits = min;
  }
  return options;
}

function getFormatter(
  locale: string,
  options: Intl.NumberFormatOptions,
): TickerFormatter {
  const key = `${locale}|${JSON.stringify(options)}`;
  let entry = formatterCache.get(key);
  if (!entry) {
    let format: Intl.NumberFormat;
    try {
      format = new Intl.NumberFormat(locale, options);
    } catch {
      format = new Intl.NumberFormat("en-US");
    }
    const digits = new Intl.NumberFormat(format.resolvedOptions().locale, {
      useGrouping: false,
      numberingSystem: format.resolvedOptions().numberingSystem,
    } as Intl.NumberFormatOptions);
    const glyphs = Array.from({ length: 10 }, (_, digit) =>
      digits.format(digit),
    );
    const cells = Array.from({ length: CELLS }, (_, cell) => (
      <span key={cell} className="block py-(--ticker-gap)">
        {glyphs[cell % 10]}
      </span>
    ));
    entry = { format, glyphs, cells };
    formatterCache.set(key, entry);
  }
  return entry;
}

type Slot =
  | { key: string; kind: "digit"; digit: number; order: number }
  | { key: string; kind: "char"; char: string };

type Item = Slot & { phase: "idle" | "enter" | "exit" };

/**
 * Split a formatted number into keyed slots. Integer digits are keyed by place
 * value and fraction digits by position, so the ones column stays the ones
 * column when 999 becomes 1,000 and only the new leading columns enter.
 */
function toSlots(value: number, formatter: TickerFormatter) {
  if (!Number.isFinite(value)) {
    return {
      text: "—",
      slots: [{ key: "missing", kind: "char", char: "—" }] as Slot[],
    };
  }
  const parts = formatter.format.formatToParts(value);
  const isDigit = (char: string) => formatter.glyphs.includes(char);
  let integerDigits = 0;
  for (const part of parts)
    if (part.type === "integer")
      for (const char of part.value) if (isDigit(char)) integerDigits++;

  const slots: Slot[] = [];
  const seen = new Map<string, number>();
  let integerIndex = 0;
  let fractionIndex = 0;
  const pushChar = (type: string, char: string) => {
    const count = seen.get(type) ?? 0;
    seen.set(type, count + 1);
    slots.push({ key: `${type}${count}:${char}`, kind: "char", char });
  };
  for (const part of parts) {
    if (part.type === "integer" || part.type === "fraction") {
      for (const char of part.value) {
        const digit = formatter.glyphs.indexOf(char);
        if (digit < 0) pushChar(part.type, char);
        else if (part.type === "integer")
          slots.push({
            key: `i${integerDigits - 1 - integerIndex++}`,
            kind: "digit",
            digit,
            order: 0,
          });
        else
          slots.push({
            key: `f${fractionIndex++}`,
            kind: "digit",
            digit,
            order: 0,
          });
      }
    } else if (part.type === "group") {
      slots.push({
        key: `g${integerDigits - integerIndex}:${part.value}`,
        kind: "char",
        char: part.value,
      });
    } else {
      pushChar(part.type, part.value);
    }
  }
  // Stagger from the rightmost digit outward, like a carry moving left.
  let order = 0;
  for (let i = slots.length - 1; i >= 0; i--) {
    const slot = slots[i];
    if (slot.kind === "digit") slots[i] = { ...slot, order: order++ };
  }
  return { text: parts.map((part) => part.value).join(""), slots };
}

/** Keep removed slots in place for one transition so they can collapse out. */
function mergeSlots(previous: Item[], next: Slot[], animate: boolean): Item[] {
  const previousKeys = new Set(previous.map((item) => item.key));
  const live: Item[] = next.map((slot) => ({
    ...slot,
    phase: animate && !previousKeys.has(slot.key) ? "enter" : "idle",
  }));
  if (!animate) return live;
  const nextKeys = new Set(next.map((slot) => slot.key));
  const leadingExits = new Map<string, Item[]>();
  let pending: Item[] = [];
  for (const item of previous) {
    if (nextKeys.has(item.key)) {
      if (pending.length) leadingExits.set(item.key, pending);
      pending = [];
    } else if (item.phase !== "exit") {
      pending.push({ ...item, phase: "exit" });
    }
  }
  const merged: Item[] = [];
  for (const item of live) {
    const exits = leadingExits.get(item.key);
    if (exits) merged.push(...exits);
    merged.push(item);
  }
  return merged.concat(pending);
}

function zeroed(slots: Slot[]): Slot[] {
  return slots.map((slot) =>
    slot.kind === "digit" ? { ...slot, digit: 0 } : slot,
  );
}

interface TickerState {
  signature: string;
  value: number;
  items: Item[];
  direction: number;
  flash: "up" | "down" | null;
  version: number;
}

/** An odometer-style number: each digit rolls on its own wheel when `value` changes. */
export function NumberTicker({
  value,
  format = "number",
  formatOptions,
  locale = "en-US",
  currency = "USD",
  prefix,
  suffix,
  duration = 800,
  highlightChanges = false,
  animateOnMount = false,
  className,
  ...props
}: NumberTickerProps) {
  const reduced = usePrefersReducedMotion();
  const optionsKey = JSON.stringify(formatOptions ?? null);
  const formatter = useMemo(
    () => getFormatter(locale, resolveOptions(format, currency, formatOptions)),
    // formatOptions is compared by content so inline objects stay cheap.
    // eslint-disable-next-line react-hooks/exhaustive-deps
    [locale, format, currency, optionsKey],
  );
  const { text, slots } = useMemo(
    () => toSlots(value, formatter),
    [value, formatter],
  );

  const [armed, setArmed] = useState(!animateOnMount);
  const shown = armed ? slots : zeroed(slots);
  const signature = (armed ? "" : "0|") + shown.map(slotKey).join("|");
  const shownValue = armed ? value : 0;

  const [state, setState] = useState<TickerState>(() => ({
    signature,
    value: shownValue,
    items: shown.map((slot) => ({ ...slot, phase: "idle" })),
    direction: 0,
    flash: null,
    version: 0,
  }));
  if (state.signature !== signature) {
    const direction = Math.sign(shownValue - state.value);
    // The first roll up from zero is an entrance, not a change worth tinting.
    const entrance = state.signature.startsWith("0|");
    setState({
      signature,
      value: shownValue,
      items: mergeSlots(state.items, shown, !reduced),
      direction,
      flash:
        highlightChanges && !entrance && direction !== 0
          ? direction > 0
            ? "up"
            : "down"
          : null,
      version: state.version + 1,
    });
  }

  // Roll up from zero after the first paint (or settle at once without motion).
  useLayoutEffect(() => {
    if (armed) return;
    if (reduced) {
      setArmed(true);
      return;
    }
    let inner = 0;
    const outer = requestAnimationFrame(() => {
      inner = requestAnimationFrame(() => setArmed(true));
    });
    return () => {
      cancelAnimationFrame(outer);
      cancelAnimationFrame(inner);
    };
  }, [armed, reduced]);

  // Drop collapsed slots and fade the tint once the roll has settled.
  const { version } = state;
  const hasExits = state.items.some((item) => item.phase === "exit");
  useEffect(() => {
    if (!hasExits) return;
    const timer = window.setTimeout(
      () =>
        setState((current) =>
          current.version === version
            ? {
                ...current,
                items: current.items.filter((item) => item.phase !== "exit"),
              }
            : current,
        ),
      duration + MAX_STAGGER,
    );
    return () => window.clearTimeout(timer);
  }, [version, hasExits, duration]);
  const flashing = state.flash !== null;
  useEffect(() => {
    if (!flashing) return;
    const timer = window.setTimeout(
      () =>
        setState((current) =>
          current.version === version ? { ...current, flash: null } : current,
        ),
      Math.max(360, duration * 0.75),
    );
    return () => window.clearTimeout(timer);
  }, [version, flashing, duration]);

  const animate = !reduced;
  return (
    <span
      data-slot="number-ticker"
      data-direction={
        state.direction > 0 ? "up" : state.direction < 0 ? "down" : undefined
      }
      className={cn("inline-block whitespace-nowrap tabular-nums", className)}
      {...props}
    >
      {prefix}
      <span className="sr-only">{text}</span>
      {/* Digits always run left to right, even inside right-to-left text. */}
      <span
        aria-hidden="true"
        dir="ltr"
        data-slot="number-ticker-value"
        className={cn(
          "transition-colors motion-reduce:transition-none",
          state.flash === "up" && "text-emerald-700 dark:text-emerald-400",
          state.flash === "down" && "text-red-600 dark:text-red-400",
        )}
        style={{ transitionDuration: state.flash ? "140ms" : "900ms" }}
      >
        {state.items.map((item) => (
          <TickerSlot
            key={item.key}
            item={item}
            direction={state.direction}
            formatter={formatter}
            duration={duration}
            animate={animate}
          />
        ))}
      </span>
      {suffix}
    </span>
  );
}

function slotKey(slot: Slot) {
  return slot.kind === "digit" ? `${slot.key}=${slot.digit}` : slot.key;
}

function TickerSlot({
  item,
  direction,
  formatter,
  duration,
  animate,
}: {
  item: Item;
  direction: number;
  formatter: TickerFormatter;
  duration: number;
  animate: boolean;
}) {
  // New slots mount collapsed, then open on the next frame so the change transitions.
  const [open, setOpen] = useState(item.phase !== "enter" || !animate);
  useEffect(() => {
    if (open) return;
    let inner = 0;
    const outer = requestAnimationFrame(() => {
      inner = requestAnimationFrame(() => setOpen(true));
    });
    return () => {
      cancelAnimationFrame(outer);
      cancelAnimationFrame(inner);
    };
  }, [open]);

  const collapsed = !open || item.phase === "exit";
  const travel = direction < 0 ? -1 : 1;
  const offset = item.phase === "exit" ? -travel : travel;
  const delay =
    item.kind === "digit" ? Math.min(item.order * STAGGER, MAX_STAGGER) : 0;
  const style: CSSProperties = {
    gridTemplateColumns: collapsed ? "0fr" : "1fr",
    opacity: collapsed ? 0 : 1,
    transform: collapsed ? `translateY(${offset * 0.42}em)` : undefined,
    transition: animate
      ? `grid-template-columns ${duration * 0.7}ms ${SIZE_EASE}, opacity ${duration * 0.5}ms ease, transform ${duration}ms ${SLIDE_EASE}`
      : "none",
  };
  return (
    <span className="inline-grid" style={style} data-phase={item.phase}>
      <span className="min-w-0 [clip-path:inset(-50%_0)]">
        {item.kind === "digit" ? (
          <DigitWheel
            digit={item.digit}
            direction={direction}
            formatter={formatter}
            duration={duration}
            delay={delay}
            animate={animate}
          />
        ) : (
          <span className="whitespace-pre">{item.char}</span>
        )}
      </span>
    </span>
  );
}

function DigitWheel({
  digit,
  direction,
  formatter,
  duration,
  delay,
  animate,
}: {
  digit: number;
  direction: number;
  formatter: TickerFormatter;
  duration: number;
  delay: number;
  animate: boolean;
}) {
  const [wheel, setWheel] = useState({
    digit,
    cell: REST + digit,
    travel: 0,
    rolling: false,
  });
  if (wheel.digit !== digit) {
    // Roll forward when the value rises and backward when it falls, wrapping
    // through 9 → 0 the way a mechanical counter carries.
    const forward = (digit - wheel.digit + 10) % 10;
    const backward = (wheel.digit - digit + 10) % 10;
    const step =
      direction > 0
        ? forward
        : direction < 0
          ? -backward
          : forward <= backward
            ? forward
            : -backward;
    let cell = wheel.cell + step;
    if (cell < 0 || cell >= CELLS) cell = REST + digit;
    setWheel(
      animate
        ? { digit, cell, travel: cell - wheel.cell, rolling: true }
        : { digit, cell: REST + digit, travel: 0, rolling: false },
    );
  }

  // Once settled, jump back to the matching cell in the middle run (same glyph).
  useEffect(() => {
    if (!wheel.rolling) return;
    const timer = window.setTimeout(
      () =>
        setWheel((current) => ({
          digit: current.digit,
          cell: REST + current.digit,
          travel: 0,
          rolling: false,
        })),
      duration + delay + 40,
    );
    return () => window.clearTimeout(timer);
  }, [wheel, duration, delay]);

  // Cells carry --ticker-gap of padding above and below, and the clipping window
  // reaches that far past the line box. At rest only padding shows in the
  // overhang; while rolling, neighbors fade through it like a real wheel.
  return (
    <span className="relative inline-block [--ticker-gap:0.2em]">
      <span className="invisible">{formatter.glyphs[digit]}</span>
      <span className="absolute inset-x-0 -inset-y-(--ticker-gap) overflow-hidden [mask-image:linear-gradient(to_bottom,transparent,#000_var(--ticker-gap),#000_calc(100%_-_var(--ticker-gap)),transparent)]">
        <span
          className="absolute inset-x-0 top-0 flex flex-col text-center"
          style={{
            transform: `translateY(${(-wheel.cell * 100) / CELLS}%)`,
            transition: wheel.rolling
              ? `transform ${duration}ms ${rollEase(wheel.travel)} ${delay}ms`
              : "none",
            willChange: wheel.rolling ? "transform" : undefined,
          }}
        >
          {formatter.cells}
        </span>
      </span>
    </span>
  );
}
```

### `src/registry/overtrue/sparkline.tsx`

```tsx
"use client";
import { useId, type CSSProperties } from "react";
import { cn } from "@/lib/utils";

export interface SparklineProps {
  data: number[];
  label: string;
  className?: string;
  filled?: boolean;
  /** Mark the most recent value. */
  endpoint?: boolean;
  /** Any CSS color. Defaults to the current text color, which is primary. */
  color?: string;
  /** Draw the line in and raise the area when the sparkline mounts. Skipped under reduced motion. */
  animate?: boolean;
}

const WIDTH = 240;
const HEIGHT = 48;
const PAD_X = 3;
const PAD_Y = 5;
const EASE = "ease-[cubic-bezier(0.22,1,0.36,1)]";

/** Monotone cubic path: smooth, but never overshoots the data. */
function monotonePath(points: [number, number][]) {
  const n = points.length;
  if (n < 2) return "";
  const dx: number[] = [];
  const slope: number[] = [];
  for (let i = 0; i < n - 1; i++) {
    dx.push(points[i + 1][0] - points[i][0]);
    slope.push((points[i + 1][1] - points[i][1]) / dx[i]);
  }
  const tangent = [slope[0]];
  for (let i = 1; i < n - 1; i++) {
    tangent.push(
      slope[i - 1] * slope[i] <= 0 ? 0 : (slope[i - 1] + slope[i]) / 2,
    );
  }
  tangent.push(slope[n - 2]);
  for (let i = 0; i < n - 1; i++) {
    if (slope[i] === 0) {
      tangent[i] = tangent[i + 1] = 0;
      continue;
    }
    const a = tangent[i] / slope[i];
    const b = tangent[i + 1] / slope[i];
    const h = a * a + b * b;
    if (h > 9) {
      const t = 3 / Math.sqrt(h);
      tangent[i] = t * a * slope[i];
      tangent[i + 1] = t * b * slope[i];
    }
  }
  const r = (value: number) => Math.round(value * 100) / 100;
  let d = `M${r(points[0][0])},${r(points[0][1])}`;
  for (let i = 0; i < n - 1; i++) {
    const [x0, y0] = points[i];
    const [x1, y1] = points[i + 1];
    const h = dx[i] / 3;
    d += `C${r(x0 + h)},${r(y0 + tangent[i] * h)} ${r(x1 - h)},${r(y1 - tangent[i + 1] * h)} ${r(x1)},${r(y1)}`;
  }
  return d;
}

/** A compact overview. Use a full chart when individual values need inspection. */
export function Sparkline({
  data,
  label,
  className,
  filled = true,
  endpoint = true,
  color,
  animate = true,
}: SparklineProps) {
  const gradient = `sparkline-${useId().replace(/:/g, "")}`;
  const values = data.filter(Number.isFinite);
  let low = Infinity,
    high = -Infinity;
  for (const value of values) {
    low = Math.min(low, value);
    high = Math.max(high, value);
  }
  const points = values.map((value, i): [number, number] => [
    values.length > 1
      ? PAD_X + (i / (values.length - 1)) * (WIDTH - PAD_X * 2)
      : WIDTH / 2,
    high === low
      ? HEIGHT / 2
      : HEIGHT - PAD_Y - ((value - low) / (high - low)) * (HEIGHT - PAD_Y * 2),
  ]);
  const line = monotonePath(points);
  const last = points[points.length - 1];
  const lastValue = values[values.length - 1];
  const motion = animate ? "motion-reduce:transition-none" : "transition-none";
  return (
    <div
      data-slot="sparkline"
      role="img"
      aria-label={`${label}: ${values.length ? values.join(", ") : "No data"}`}
      className={cn("relative h-12 w-full text-primary", className)}
      style={color ? { color } : undefined}
    >
      {values.length > 1 && filled && (
        <svg
          viewBox={`0 0 ${WIDTH} ${HEIGHT}`}
          preserveAspectRatio="none"
          aria-hidden="true"
          data-slot="sparkline-area"
          className={cn(
            "absolute inset-0 size-full origin-bottom overflow-visible transition-[opacity,scale] delay-75 duration-700",
            EASE,
            animate && "starting:scale-y-0 starting:opacity-0",
            motion,
          )}
        >
          <defs>
            <linearGradient id={gradient} 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>
          <path
            d={`${line}L${last[0]},${HEIGHT}L${points[0][0]},${HEIGHT}Z`}
            fill={`url(#${gradient})`}
            className={cn("transition-[d] duration-500", EASE, motion)}
          />
        </svg>
      )}
      <svg
        viewBox={`0 0 ${WIDTH} ${HEIGHT}`}
        preserveAspectRatio="none"
        aria-hidden="true"
        data-slot="sparkline-line"
        className={cn(
          // The line wipes in from the left; the inset leaves room for its glow.
          "absolute inset-0 size-full overflow-visible [clip-path:inset(-60%_-8%_-60%_-8%)] transition-[clip-path] duration-700",
          EASE,
          animate &&
            values.length > 1 &&
            "starting:[clip-path:inset(-60%_100%_-60%_-8%)]",
          motion,
        )}
      >
        {values.length > 1 ? (
          <path
            d={line}
            fill="none"
            stroke="currentColor"
            strokeWidth="2"
            strokeLinejoin="round"
            strokeLinecap="round"
            vectorEffect="non-scaling-stroke"
            className={cn(
              "transition-[d] duration-500 dark:[filter:drop-shadow(0_0_6px_color-mix(in_oklab,currentColor_50%,transparent))]",
              EASE,
              motion,
            )}
          />
        ) : values.length === 0 ? (
          <path
            d={`M${PAD_X} ${HEIGHT / 2}H${WIDTH - PAD_X}`}
            stroke="currentColor"
            strokeDasharray="2 5"
            strokeLinecap="round"
            opacity="0.3"
            vectorEffect="non-scaling-stroke"
          />
        ) : null}
      </svg>
      {/* Drawn in HTML so the marker stays round when the line stretches. */}
      {endpoint && last && (
        <span
          aria-hidden="true"
          data-slot="sparkline-endpoint"
          className={cn(
            // Moves with the line, and on mount appears once the line has drawn in.
            "absolute -translate-x-1/2 -translate-y-1/2 [transition:left_500ms_cubic-bezier(0.22,1,0.36,1),top_500ms_cubic-bezier(0.22,1,0.36,1),opacity_300ms_ease-out_550ms,scale_500ms_cubic-bezier(0.22,1,0.36,1)_550ms]",
            animate && "starting:scale-0 starting:opacity-0",
            motion,
          )}
          style={
            {
              left: `${(last[0] / WIDTH) * 100}%`,
              top: `${(last[1] / HEIGHT) * 100}%`,
            } as CSSProperties
          }
        >
          {/* Pulses once whenever the latest value changes. */}
          <span
            key={lastValue}
            className={cn(
              "absolute inset-0 scale-[3.2] rounded-full bg-current opacity-0 transition-[opacity,scale] duration-1000 ease-out starting:scale-100 starting:opacity-40 motion-reduce:hidden",
              !animate && "hidden",
            )}
          />
          <span className="relative block size-2 rounded-full border-[1.5px] border-card bg-current shadow-[0_0_0_3px_color-mix(in_oklab,currentColor_18%,transparent)] dark:shadow-[0_0_0_3px_color-mix(in_oklab,currentColor_24%,transparent),0_0_12px_1px_color-mix(in_oklab,currentColor_70%,transparent)]" />
        </span>
      )}
    </div>
  );
}
```

### `src/registry/overtrue/delta-badge.tsx`

```tsx
/** Adapted from dashboardcn (MIT), copyright 2026 dashboardcn contributors.
 * Source: https://github.com/NoahGdev/dashboardcn/tree/b1ffacbca0f7a0be60135c8665b9e8c267205c48
 *
 * MIT License
 *
 * Copyright (c) 2026 dashboardcn contributors
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 *
 * ---
 *
 * Portions of this project are derived from shadcn/ui and shadcn/registry-template
 * (https://github.com/shadcn-ui/ui), Copyright (c) 2023 shadcn, licensed under the
 * MIT License. The notice above applies to those portions as well.
 */
import * as React from "react";
import {
  IconArrowDownRight as ArrowDownRight,
  IconArrowUpRight as ArrowUpRight,
  IconMinus as Minus,
} from "@tabler/icons-react";

import { cn } from "@/lib/utils";
import { formatDelta } from "./metric-format";

export type DeltaDirection = "up" | "down" | "flat";

export function getDeltaDirection(delta: number | undefined): DeltaDirection {
  if (delta === undefined || delta === 0 || !Number.isFinite(delta))
    return "flat";
  return delta > 0 ? "up" : "down";
}

const directionIcon: Record<DeltaDirection, React.ElementType> = {
  up: ArrowUpRight,
  down: ArrowDownRight,
  flat: Minus,
};

type Tone = "positive" | "negative" | "neutral";

const toneText: Record<Tone, string> = {
  positive: "text-emerald-700 dark:text-emerald-400",
  negative: "text-rose-700 dark:text-rose-400",
  neutral: "text-muted-foreground",
};

const toneSoft: Record<Tone, string> = {
  positive: "bg-emerald-500/10 dark:bg-emerald-400/10",
  negative: "bg-rose-500/10 dark:bg-rose-400/10",
  neutral: "bg-muted dark:bg-muted/70",
};

const toneOutline: Record<Tone, string> = {
  positive:
    "bg-emerald-500/[0.06] ring-emerald-600/20 dark:bg-emerald-400/[0.07] dark:ring-emerald-400/25",
  negative:
    "bg-rose-500/[0.06] ring-rose-600/20 dark:bg-rose-400/[0.07] dark:ring-rose-400/25",
  neutral: "bg-muted/40 ring-border",
};

export interface DeltaBadgeProps extends React.ComponentProps<"span"> {
  /** Fractional change, e.g. 0.124 for +12.4%. */
  delta: number;
  /** Treat a decrease as good and an increase as bad (churn, latency, errors). */
  invert?: boolean;
  variant?: "outline" | "soft" | "text";
  showIcon?: boolean;
}

/** A change chip: the arrow shows direction, the color shows whether it helps. */
function DeltaBadge({
  delta,
  invert = false,
  variant = "outline",
  showIcon = true,
  className,
  children,
  ...props
}: DeltaBadgeProps) {
  const direction = getDeltaDirection(delta);
  const positive =
    direction === "flat" ? null : (direction === "up") !== invert;
  const tone: Tone =
    positive === true
      ? "positive"
      : positive === false
        ? "negative"
        : "neutral";
  const Icon = directionIcon[direction];
  const pill = variant !== "text";

  return (
    <span
      data-slot="delta-badge"
      data-direction={direction}
      data-positive={positive}
      data-variant={variant}
      className={cn(
        "inline-flex shrink-0 items-center gap-0.5 text-xs leading-none font-medium tracking-[-0.01em] whitespace-nowrap tabular-nums",
        pill && "h-5 rounded-full",
        pill && (showIcon ? "pr-1.5 pl-1" : "px-1.5"),
        variant === "outline" && ["ring-1 ring-inset", toneOutline[tone]],
        variant === "soft" && toneSoft[tone],
        toneText[tone],
        className,
      )}
      {...props}
    >
      {showIcon ? (
        <Icon
          data-slot="delta-badge-icon"
          className="size-3 shrink-0"
          stroke={2.5}
          aria-hidden="true"
        />
      ) : null}
      {children ?? formatDelta(delta)}
    </span>
  );
}

export { DeltaBadge };
```

### `src/registry/overtrue/metric-format.tsx`

```tsx
/** Adapted from dashboardcn (MIT), copyright 2026 dashboardcn contributors.
 * Source: https://github.com/NoahGdev/dashboardcn/tree/b1ffacbca0f7a0be60135c8665b9e8c267205c48
 *
 * MIT License
 *
 * Copyright (c) 2026 dashboardcn contributors
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 *
 * ---
 *
 * Portions of this project are derived from shadcn/ui and shadcn/registry-template
 * (https://github.com/shadcn-ui/ui), Copyright (c) 2023 shadcn, licensed under the
 * MIT License. The notice above applies to those portions as well.
 */
export type NumberFormat = "number" | "compact" | "currency" | "percent";

export interface FormatNumberOptions {
  format?: NumberFormat;
  /** ISO 4217 code, used when format is "currency". Defaults to USD. */
  currency?: string;
  locale?: string;
  maximumFractionDigits?: number;
  /** Abbreviate large values, e.g. "$158K" instead of "$158,143". */
  compact?: boolean;
}

const formatterCache = new Map<string, Intl.NumberFormat>();

function getFormatter(locale: string, options: Intl.NumberFormatOptions) {
  const key = locale + JSON.stringify(options);
  let formatter = formatterCache.get(key);
  if (!formatter) {
    formatter = new Intl.NumberFormat(locale, options);
    formatterCache.set(key, formatter);
  }
  return formatter;
}

/**
 * Format a metric value for display.
 *
 * formatNumber(1234567)                          -> "1,234,567"
 * formatNumber(1234567, { format: "compact" })   -> "1.2M"
 * formatNumber(48.2, { format: "currency" })     -> "$48.20"
 * formatNumber(158143, { format: "currency", compact: true }) -> "$158K"
 * formatNumber(0.124, { format: "percent" })     -> "12.4%"
 */
export function formatNumber(
  value: number,
  {
    format = "number",
    currency = "USD",
    locale = "en-US",
    maximumFractionDigits,
    compact = false,
  }: FormatNumberOptions = {},
): string {
  if (!Number.isFinite(value)) return "—";

  // Compact values keep three significant digits: $158K, $1.23M, 41.2K.
  const compactOptions: Intl.NumberFormatOptions = compact
    ? maximumFractionDigits === undefined
      ? { notation: "compact", maximumSignificantDigits: 3 }
      : { notation: "compact", maximumFractionDigits }
    : {};
  switch (format) {
    case "compact":
      return getFormatter(locale, {
        notation: "compact",
        maximumFractionDigits: maximumFractionDigits ?? 1,
      }).format(value);
    case "currency":
      return getFormatter(locale, {
        style: "currency",
        currency,
        maximumFractionDigits: maximumFractionDigits ?? 2,
        ...compactOptions,
      }).format(value);
    case "percent":
      return getFormatter(locale, {
        style: "percent",
        maximumFractionDigits: maximumFractionDigits ?? 1,
      }).format(value);
    default:
      return getFormatter(locale, {
        maximumFractionDigits: maximumFractionDigits ?? 0,
        ...compactOptions,
      }).format(value);
  }
}

/**
 * Format a fractional change as a signed percentage.
 *
 * formatDelta(0.124)  -> "+12.4%"
 * formatDelta(-0.03)  -> "-3.0%"
 * formatDelta(0)      -> "0.0%"
 */
export function formatDelta(delta: number, locale = "en-US"): string {
  if (!Number.isFinite(delta)) return "—";
  return getFormatter(locale, {
    style: "percent",
    signDisplay: "exceptZero",
    maximumFractionDigits: 1,
    minimumFractionDigits: 1,
  }).format(delta);
}

/**
 * Fractional change between two values. Returns 0 when there is no baseline.
 */
export function computeDelta(current: number, previous: number): number {
  if (!previous) return 0;
  return (current - previous) / Math.abs(previous);
}
```

### `src/registry/overtrue/stacked-area-chart.tsx`

```tsx
"use client";

import * as React from "react";

import { cn } from "@/lib/utils";

/* ------------------------------------------------------------------------ */
/* Types                                                                     */
/* ------------------------------------------------------------------------ */

/** How the series combine: stacked, normalised to 100%, centered as a streamgraph, or overlapping. */
export type StackedAreaStack = "normal" | "expand" | "stream" | "none";
export type StackedAreaCurve = "monotone" | "linear" | "step";
/** An x value as it appears in the data: a number, an ISO date string, a Date, or a category label. */
export type StackedAreaXValue = string | number | Date;

export interface StackedAreaSeries {
  /** Field in each row that holds this series' value. */
  key: string;
  /** Name in the legend and tooltip. Defaults to `key`. */
  label?: string;
  /** Any CSS color. Defaults to the chart palette, cycling with softer tints past five. */
  color?: string;
}

export interface StackedAreaReferenceLine {
  /** Value on the y axis. Drawn in normal and overlapping modes, where the axis is in value units. */
  y: number;
  label?: string;
  color?: string;
}

export interface StackedAreaAnnotation {
  /** Where the marker sits, in the same form as the index values. */
  x: StackedAreaXValue;
  label: string;
  color?: string;
}

/** One series at one point, as listed in the tooltip. */
export interface StackedAreaItem {
  key: string;
  label: string;
  color: string;
  value: number;
  /** Share of the visible total at this point (or over the range, in a summary), 0–1. */
  share: number;
}

/** The point under the crosshair, passed to `renderTooltip` and `onHover`. */
export interface StackedAreaPoint {
  /** Position in the sorted data. */
  index: number;
  /** A Date on time axes, otherwise the number or label from the data. */
  x: StackedAreaXValue;
  /** The x value formatted for the tooltip. */
  label: string;
  /** The original row. */
  row: Record<string, unknown>;
  /** Sum of the visible series. */
  total: number;
  /** Visible series, top of the stack first. */
  items: StackedAreaItem[];
  /** Annotations that fall on this point. */
  annotations: StackedAreaAnnotation[];
}

/** Totals across the whole range, passed to a `header` function. */
export interface StackedAreaSummary {
  /** Sum of every visible series over every point. */
  total: number;
  /** Visible total at the first and the last point. */
  first: number;
  last: number;
  /** Every series with its total over the range and its share of `total`, in legend order. */
  series: (StackedAreaItem & { hidden: boolean })[];
  /** Number of points. */
  count: number;
  /** The chart's value formatter. */
  format: (value: number) => string;
}

export type StackedAreaXFormatter = (
  value: StackedAreaXValue,
  context: "axis" | "tooltip",
) => string;

export interface StackedAreaChartProps extends Omit<
  React.ComponentProps<"div">,
  "title" | "children" | "color"
> {
  /** Rows, one per x value. Missing or negative values count as zero. */
  data: Record<string, unknown>[];
  /** Field holding the x value: numbers, ISO date strings, Dates, or category labels. */
  index: string;
  /** Series to stack, bottom first. */
  series: StackedAreaSeries[];
  stack?: StackedAreaStack;
  curve?: StackedAreaCurve;
  /** Plot height in pixels. Defaults to 280. */
  height?: number;
  title?: React.ReactNode;
  description?: React.ReactNode;
  /** Controls placed at the top right. */
  actions?: React.ReactNode;
  /** Content under the title, such as a headline total. A function receives the totals for the visible series. */
  header?: React.ReactNode | ((summary: StackedAreaSummary) => React.ReactNode);
  /** Formats values in the tooltip, legend, and summary. Defaults to compact numbers from 10,000. */
  valueFormatter?: (value: number) => string;
  /** Formats y axis ticks. Defaults to compact numbers such as 2.4M, or percentages when expanded. */
  axisFormatter?: (value: number) => string;
  /** Formats x values on the axis and in the tooltip. Dates default to Intl formats matched to the spacing. */
  xFormatter?: StackedAreaXFormatter;
  /** Short name of the y axis, shown above it. */
  yLabel?: string;
  referenceLines?: StackedAreaReferenceLine[];
  /** Thin vertical markers with a label, for events such as a deploy. */
  annotations?: StackedAreaAnnotation[];
  /** Keys of hidden series. Pass with `onHiddenSeriesChange` to control the legend. */
  hiddenSeries?: string[];
  defaultHiddenSeries?: string[];
  onHiddenSeriesChange?: (hidden: string[]) => void;
  /** Show the interactive legend. Defaults to true. */
  showLegend?: boolean;
  legendPosition?: "top" | "bottom";
  /** Replaces the tooltip content. */
  renderTooltip?: (point: StackedAreaPoint) => React.ReactNode;
  /** Called when the crosshair moves to a point, and with null when it leaves. */
  onHover?: (point: StackedAreaPoint | null) => void;
  /** Tween between states when series toggle, the stack mode changes, or data updates. Defaults to true. */
  animate?: boolean;
}

/* ------------------------------------------------------------------------ */
/* Formatting                                                                */
/* ------------------------------------------------------------------------ */

const DAY = 86_400_000;
const tidy = (value: number) => +value.toPrecision(12);
const lowerK = (text: string) => text.replace(/K$/, "k");
const compactAxis = new Intl.NumberFormat("en-US", {
  notation: "compact",
  maximumFractionDigits: 1,
});
const compactValue = new Intl.NumberFormat("en-US", {
  notation: "compact",
  maximumSignificantDigits: 3,
});
const grouped = new Intl.NumberFormat("en-US", { maximumFractionDigits: 2 });

function defaultValueFormatter(value: number) {
  if (!Number.isFinite(value)) return "—";
  return Math.abs(value) >= 10_000
    ? lowerK(compactValue.format(value))
    : grouped.format(value);
}

function defaultAxisFormatter(value: number) {
  return value === 0 ? "0" : lowerK(compactAxis.format(value));
}

function percentAxis(value: number) {
  return `${tidy(value * 100)}%`;
}

function formatShare(share: number, digits = 1) {
  const pct = share * 100;
  if (!Number.isFinite(pct) || pct === 0) return "0%";
  if (pct < 0.1) return "<0.1%";
  return `${pct.toFixed(digits)}%`;
}

// "Atlas Large hidden" reads better than a pressed state for screen readers.
const sentence = (parts: string[]) => parts.filter(Boolean).join(" ");

/* ------------------------------------------------------------------------ */
/* X values                                                                  */
/* ------------------------------------------------------------------------ */

type XKind = "time" | "number" | "category";

const DATE_ONLY = /^(\d{4})-(\d{2})(?:-(\d{2}))?$/;
const DATE_TIME =
  /^\d{4}-\d{2}-\d{2}[T ]\d{2}:\d{2}(?::\d{2}(?:\.\d+)?)?(?:Z|[+-]\d{2}:?\d{2})?$/;

/** Date-only strings are local calendar days, so "2026-10-03" never renders as Oct 2. */
function toTime(raw: unknown): number | null {
  if (raw instanceof Date) {
    const t = raw.getTime();
    return Number.isNaN(t) ? null : t;
  }
  if (typeof raw !== "string") return null;
  const day = DATE_ONLY.exec(raw);
  if (day) return new Date(+day[1], +day[2] - 1, day[3] ? +day[3] : 1).getTime();
  if (DATE_TIME.test(raw)) {
    const t = Date.parse(raw.replace(" ", "T"));
    return Number.isNaN(t) ? null : t;
  }
  return null;
}

function xKindOf(values: unknown[]): XKind {
  if (!values.length) return "category";
  if (values.every((v) => typeof v === "number" && Number.isFinite(v)))
    return "number";
  if (values.every((v) => toTime(v) !== null)) return "time";
  return "category";
}

function makeDateFormatter(step: number, spansYears: boolean) {
  const f = (options: Intl.DateTimeFormatOptions) =>
    new Intl.DateTimeFormat("en-US", options);
  if (step < DAY) {
    const time = f({ hour: "2-digit", minute: "2-digit", hourCycle: "h23" });
    const day = f({ month: "short", day: "numeric" });
    const tip = f({
      weekday: "short",
      month: "short",
      day: "numeric",
      hour: "2-digit",
      minute: "2-digit",
      hourCycle: "h23",
    });
    // Midnight ticks name the day, so a multi-day axis stays readable.
    return (d: Date, c: "axis" | "tooltip") =>
      c === "tooltip"
        ? tip.format(d)
        : d.getHours() === 0 && d.getMinutes() === 0
          ? day.format(d)
          : time.format(d);
  }
  if (step < 28 * DAY) {
    const axis = f({ month: "short", day: "numeric" });
    const tip = f({
      weekday: "short",
      month: "short",
      day: "numeric",
      ...(spansYears ? { year: "numeric" } : {}),
    });
    return (d: Date, c: "axis" | "tooltip") =>
      (c === "axis" ? axis : tip).format(d);
  }
  if (step < 360 * DAY) {
    const axis = f(
      spansYears ? { month: "short", year: "2-digit" } : { month: "short" },
    );
    const tip = f({ month: "long", year: "numeric" });
    return (d: Date, c: "axis" | "tooltip") =>
      (c === "axis" ? axis : tip).format(d);
  }
  const year = f({ year: "numeric" });
  return (d: Date) => year.format(d);
}

/* ------------------------------------------------------------------------ */
/* Model                                                                     */
/* ------------------------------------------------------------------------ */

interface Model {
  kind: XKind;
  rows: Record<string, unknown>[];
  /** Numeric x positions: epoch ms, numbers, or the row index for categories. */
  xs: number[];
  /** Parsed x values: Dates on time axes. */
  xValues: StackedAreaXValue[];
  /** Identity of each point, used to match points across updates. */
  keys: string[];
  /** Clean values per series and point. */
  values: number[][];
  /** Typical spacing between points, in x units. */
  step: number;
}

function buildModel(
  data: Record<string, unknown>[],
  index: string,
  keys: string[],
): Model {
  const kind = xKindOf(data.map((row) => row?.[index]));
  const items = data.map((row, i) => {
    const raw = row?.[index];
    if (kind === "number") return { row, x: raw as number, value: raw as number };
    if (kind === "time") {
      const t = toTime(raw)!;
      return { row, x: t, value: new Date(t) as StackedAreaXValue };
    }
    return { row, x: i, value: String(raw ?? "") as StackedAreaXValue };
  });
  if (kind !== "category") items.sort((a, b) => a.x - b.x);
  const xs = items.map((item) => item.x);
  const diffs: number[] = [];
  for (let i = 1; i < xs.length; i++)
    if (xs[i] > xs[i - 1]) diffs.push(xs[i] - xs[i - 1]);
  diffs.sort((a, b) => a - b);
  return {
    kind,
    rows: items.map((item) => item.row ?? {}),
    xs,
    xValues: items.map((item) => item.value),
    keys:
      kind === "category" ? items.map((_, i) => String(i)) : xs.map(String),
    values: keys.map((key) =>
      items.map((item) => {
        const v = Number(item.row?.[key]);
        return Number.isFinite(v) && v > 0 ? v : 0;
      }),
    ),
    step: diffs.length ? diffs[diffs.length >> 1] : 1,
  };
}

/* ------------------------------------------------------------------------ */
/* Scales                                                                    */
/* ------------------------------------------------------------------------ */

function niceStep(raw: number) {
  if (!(raw > 0)) return 1;
  const magnitude = 10 ** Math.floor(Math.log10(raw));
  const r = raw / magnitude;
  return (
    (r <= 1 ? 1 : r <= 2 ? 2 : r <= 2.5 ? 2.5 : r <= 5 ? 5 : 10) * magnitude
  );
}

/** Ticks from zero: three to `most` intervals of 1, 2, 2.5 or 5 × 10ⁿ, with the least wasted headroom. */
function niceScale(max: number, most: number) {
  if (!(max > 0)) return { hi: 1, ticks: [0, 0.5, 1] };
  const target = max * 1.02;
  const exponent = Math.floor(Math.log10(target));
  let best: { step: number; count: number; score: number } | null = null;
  for (let e = exponent - 2; e <= exponent + 1; e++)
    for (const m of [1, 2, 2.5, 5]) {
      const step = m * 10 ** e;
      const count = Math.ceil(target / step - 1e-9);
      if (count < 3 || count > most) continue;
      const hi = count * step;
      const score =
        (hi - target) / hi + Math.abs(count - 4) * 0.04 + (m === 2.5 ? 0.04 : 0);
      if (!best || score < best.score) best = { step, count, score };
    }
  const step = best?.step ?? niceStep(target / 4);
  const count = best?.count ?? Math.max(1, Math.ceil(target / step - 1e-9));
  return {
    hi: tidy(count * step),
    ticks: Array.from({ length: count + 1 }, (_, i) => tidy(i * step)),
  };
}

/* ------------------------------------------------------------------------ */
/* Frames: the stacked geometry in data units, tweened between states        */
/* ------------------------------------------------------------------------ */

interface Frame {
  keys: string[];
  xs: number[];
  series: string[];
  /** Lower and upper edge per series and point, in y units. */
  y0: number[][];
  y1: number[][];
  /** 1 when a series is shown, 0 when hidden; fractional mid-tween. */
  weight: number[];
  x0: number;
  x1: number;
  lo: number;
  hi: number;
}

function stackFrame(
  model: Model,
  seriesKeys: string[],
  visible: boolean[],
  stack: StackedAreaStack,
  lo: number,
  hi: number,
): Frame {
  const n = model.xs.length;
  const y0 = seriesKeys.map(() => new Array<number>(n).fill(0));
  const y1 = seriesKeys.map(() => new Array<number>(n).fill(0));
  for (let j = 0; j < n; j++) {
    let total = 0;
    for (let s = 0; s < seriesKeys.length; s++)
      if (visible[s]) total += model.values[s][j];
    if (stack === "none") {
      for (let s = 0; s < seriesKeys.length; s++)
        y1[s][j] = visible[s] ? model.values[s][j] : 0;
      continue;
    }
    const scale = stack === "expand" ? (total > 0 ? 1 / total : 0) : 1;
    let running = stack === "stream" ? -total / 2 : 0;
    for (let s = 0; s < seriesKeys.length; s++) {
      y0[s][j] = running;
      running += visible[s] ? model.values[s][j] * scale : 0;
      y1[s][j] = running;
    }
  }
  const first = model.xs[0] ?? 0;
  const last = model.xs[n - 1] ?? 1;
  const pad = n > 1 ? 0 : model.step / 2 || 0.5;
  return {
    keys: model.keys,
    xs: model.xs,
    series: seriesKeys,
    y0,
    y1,
    weight: visible.map((v) => (v ? 1 : 0)),
    x0: first - pad,
    x1: last + pad,
    lo,
    hi,
  };
}

function framesEqual(a: Frame, b: Frame) {
  if (a === b) return true;
  const same = (p: number, q: number) => Math.abs(p - q) < 1e-9;
  if (
    a.keys.length !== b.keys.length ||
    a.series.length !== b.series.length ||
    !same(a.x0, b.x0) ||
    !same(a.x1, b.x1) ||
    !same(a.lo, b.lo) ||
    !same(a.hi, b.hi)
  )
    return false;
  for (let i = 0; i < a.keys.length; i++)
    if (a.keys[i] !== b.keys[i] || !same(a.xs[i], b.xs[i])) return false;
  for (let s = 0; s < a.series.length; s++) {
    if (a.series[s] !== b.series[s] || a.weight[s] !== b.weight[s]) return false;
    for (let i = 0; i < a.keys.length; i++)
      if (!same(a.y0[s][i], b.y0[s][i]) || !same(a.y1[s][i], b.y1[s][i]))
        return false;
  }
  return true;
}

/**
 * Interpolates two frames. Points are matched by identity, so a sliding window keeps
 * every shared point still and glides the x domain instead of morphing the shape.
 */
function lerpFrame(a: Frame, b: Frame, t: number): Frame {
  const mix = (p: number, q: number) => p + (q - p) * t;
  const seriesIndex = new Map(a.series.map((key, i) => [key, i]));
  let keys = b.keys;
  let xs: number[];
  let fromIndex: number[];
  let toIndex: number[];
  if (
    a.keys.length === b.keys.length &&
    a.keys.every((key, i) => key === b.keys[i])
  ) {
    xs = b.xs.map((x, i) => mix(a.xs[i], x));
    fromIndex = toIndex = b.keys.map((_, i) => i);
  } else {
    const inA = new Map(a.keys.map((key, i) => [key, i]));
    const inB = new Map(b.keys.map((key, i) => [key, i]));
    const xOf = (key: string) =>
      inB.has(key) ? b.xs[inB.get(key)!] : a.xs[inA.get(key)!];
    keys = [...new Set([...a.keys, ...b.keys])].sort((p, q) => xOf(p) - xOf(q));
    xs = keys.map(xOf);
    fromIndex = keys.map((key) => inA.get(key) ?? -1);
    toIndex = keys.map((key) => inB.get(key) ?? -1);
  }
  const y0: number[][] = [];
  const y1: number[][] = [];
  const weight: number[] = [];
  b.series.forEach((key, s) => {
    const sa = seriesIndex.get(key) ?? -1;
    const lower: number[] = [];
    const upper: number[] = [];
    keys.forEach((_, j) => {
      const ia = fromIndex[j];
      const ib = toIndex[j];
      const to0 = ib >= 0 ? b.y0[s][ib] : null;
      const to1 = ib >= 0 ? b.y1[s][ib] : null;
      // A new series grows from its own base; a leaving point holds still.
      const from0 = sa >= 0 && ia >= 0 ? a.y0[sa][ia] : (to0 ?? 0);
      const from1 = sa >= 0 && ia >= 0 ? a.y1[sa][ia] : (to0 ?? 0);
      lower.push(mix(from0, to0 ?? from0));
      upper.push(mix(from1, to1 ?? from1));
    });
    y0.push(lower);
    y1.push(upper);
    weight.push(mix(sa >= 0 ? a.weight[sa] : 0, b.weight[s]));
  });
  return {
    keys,
    xs,
    series: b.series,
    y0,
    y1,
    weight,
    x0: mix(a.x0, b.x0),
    x1: mix(a.x1, b.x1),
    lo: mix(a.lo, b.lo),
    hi: mix(a.hi, b.hi),
  };
}

/* ------------------------------------------------------------------------ */
/* Curves                                                                    */
/* ------------------------------------------------------------------------ */

const r2 = (value: number) => Math.round(value * 100) / 100;

/** Steffen's monotone tangents: no overshoot between points, so stacked edges never cross. */
function monotoneTangents(xs: number[], ys: number[]) {
  const n = xs.length;
  const m = new Array<number>(n).fill(0);
  if (n < 2) return m;
  const h: number[] = [];
  const d: number[] = [];
  for (let i = 0; i < n - 1; i++) {
    h.push(xs[i + 1] - xs[i]);
    d.push(h[i] ? (ys[i + 1] - ys[i]) / h[i] : 0);
  }
  if (n === 2) {
    m[0] = m[1] = d[0];
    return m;
  }
  for (let i = 1; i < n - 1; i++) {
    const s0 = d[i - 1];
    const s1 = d[i];
    if (s0 * s1 <= 0) continue;
    const p = (s0 * h[i] + s1 * h[i - 1]) / (h[i - 1] + h[i] || 1);
    m[i] =
      Math.sign(s0) *
      Math.min(2 * Math.abs(s0), 2 * Math.abs(s1), Math.abs(p));
  }
  // One-sided ends keep the tangent within the first and last secant.
  m[0] = (3 * d[0] - m[1]) / 2;
  m[n - 1] = (3 * d[n - 2] - m[n - 2]) / 2;
  return m;
}

/** Path commands from the first point to the last (or back), without the opening move. */
function edge(
  xs: number[],
  ys: number[],
  curve: StackedAreaCurve,
  reverse: boolean,
) {
  const n = xs.length;
  if (n < 2) return "";
  let out = "";
  if (curve === "linear") {
    if (reverse)
      for (let i = n - 2; i >= 0; i--) out += `L${r2(xs[i])} ${r2(ys[i])}`;
    else for (let i = 1; i < n; i++) out += `L${r2(xs[i])} ${r2(ys[i])}`;
    return out;
  }
  if (curve === "step") {
    if (reverse)
      for (let i = n - 2; i >= 0; i--) {
        const mid = (xs[i] + xs[i + 1]) / 2;
        out += `H${r2(mid)}V${r2(ys[i])}H${r2(xs[i])}`;
      }
    else
      for (let i = 0; i < n - 1; i++) {
        const mid = (xs[i] + xs[i + 1]) / 2;
        out += `H${r2(mid)}V${r2(ys[i + 1])}H${r2(xs[i + 1])}`;
      }
    return out;
  }
  const m = monotoneTangents(xs, ys);
  const segment = (i: number) => {
    const h = (xs[i + 1] - xs[i]) / 3;
    return [
      xs[i] + h,
      ys[i] + m[i] * h,
      xs[i + 1] - h,
      ys[i + 1] - m[i + 1] * h,
    ];
  };
  if (reverse)
    for (let i = n - 2; i >= 0; i--) {
      const [c1x, c1y, c2x, c2y] = segment(i);
      out += `C${r2(c2x)} ${r2(c2y)} ${r2(c1x)} ${r2(c1y)} ${r2(xs[i])} ${r2(ys[i])}`;
    }
  else
    for (let i = 0; i < n - 1; i++) {
      const [c1x, c1y, c2x, c2y] = segment(i);
      out += `C${r2(c1x)} ${r2(c1y)} ${r2(c2x)} ${r2(c2y)} ${r2(xs[i + 1])} ${r2(ys[i + 1])}`;
    }
  return out;
}

/* ------------------------------------------------------------------------ */
/* Hooks                                                                     */
/* ------------------------------------------------------------------------ */

function useReducedMotion() {
  return React.useSyncExternalStore(
    (onChange) => {
      const query = window.matchMedia("(prefers-reduced-motion: reduce)");
      query.addEventListener("change", onChange);
      return () => query.removeEventListener("change", onChange);
    },
    () => window.matchMedia("(prefers-reduced-motion: reduce)").matches,
    () => false,
  );
}

function useControllable<T>(
  value: T | undefined,
  defaultValue: T,
  onChange?: (value: T) => void,
) {
  const [inner, setInner] = React.useState(defaultValue);
  const controlled = value !== undefined;
  const set = React.useCallback(
    (next: T) => {
      if (!controlled) setInner(next);
      onChange?.(next);
    },
    [controlled, onChange],
  );
  return [controlled ? value : inner, set] as const;
}

const easeOut = (t: number) => 1 - (1 - t) ** 3;
const easeInOut = (t: number) =>
  t < 0.5 ? 4 * t * t * t : 1 - (-2 * t + 2) ** 3 / 2;

/** Default palette: the five chart colors, then softer tints of the same five. */
function paletteColor(i: number) {
  const base = `var(--color-chart-${(i % 5) + 1})`;
  const round = Math.floor(i / 5);
  return round === 0
    ? base
    : `color-mix(in oklab, ${base} ${Math.max(40, 100 - round * 28)}%, var(--color-card))`;
}

const focusRing =
  "outline-none focus-visible:ring-2 focus-visible:ring-primary/30 focus-visible:shadow-[0_0_0_4px_color-mix(in_oklab,var(--color-primary)_10%,transparent)]";
const gridColor = "color-mix(in oklab, var(--color-foreground) 7%, transparent)";
const baseColor = "color-mix(in oklab, var(--color-foreground) 14%, transparent)";

/* ------------------------------------------------------------------------ */
/* StackedAreaChart                                                          */
/* ------------------------------------------------------------------------ */

/**
 * A composition over time: stacked, normalised, streamgraph, or overlapping areas with
 * an interactive legend, a snapping crosshair, annotations, and tweened re-stacking.
 */
export function StackedAreaChart({
  data,
  index,
  series,
  stack = "normal",
  curve = "monotone",
  height = 280,
  title,
  description,
  actions,
  header,
  valueFormatter = defaultValueFormatter,
  axisFormatter,
  xFormatter,
  yLabel,
  referenceLines,
  annotations,
  hiddenSeries,
  defaultHiddenSeries = [],
  onHiddenSeriesChange,
  showLegend = true,
  legendPosition = "bottom",
  renderTooltip,
  onHover,
  animate = true,
  className,
  ...props
}: StackedAreaChartProps) {
  const id = React.useId().replace(/:/g, "");
  const reduced = useReducedMotion();
  const motion = animate && !reduced;

  const [hidden, setHidden] = useControllable(
    hiddenSeries,
    defaultHiddenSeries,
    onHiddenSeriesChange,
  );
  const hiddenSet = React.useMemo(() => new Set(hidden), [hidden]);

  // Geometry depends only on series keys, so inline series arrays never restart a tween.
  const seriesSignature = series.map((s) => s.key).join("\u0000");
  const seriesKeys = React.useMemo(
    () => (seriesSignature ? seriesSignature.split("\u0000") : []),
    [seriesSignature],
  );
  const meta = series.map((s, i) => ({
    key: s.key,
    label: s.label ?? s.key,
    color: s.color ?? paletteColor(i),
  }));

  const model = React.useMemo(
    () => buildModel(data, index, seriesKeys),
    [data, index, seriesKeys],
  );
  const n = model.xs.length;
  const visible = seriesKeys.map((key) => !hiddenSet.has(key));
  const visibleSignature = visible.map(Number).join("");
  const anyVisible = visible.some(Boolean);

  /* ------------------------------------------------------------- format */

  const formatX = React.useMemo(() => {
    if (xFormatter) return xFormatter;
    if (model.kind === "time") {
      const first = model.xs[0] ?? 0;
      const last = model.xs[n - 1] ?? 0;
      const date = makeDateFormatter(
        model.step,
        new Date(first).getFullYear() !== new Date(last).getFullYear(),
      );
      return (value: StackedAreaXValue, context: "axis" | "tooltip") =>
        date(value instanceof Date ? value : new Date(value), context);
    }
    if (model.kind === "number")
      return (value: StackedAreaXValue) =>
        typeof value === "number" ? grouped.format(value) : String(value);
    return (value: StackedAreaXValue) => String(value);
  }, [xFormatter, model, n]);

  const formatTick = React.useMemo(
    () =>
      axisFormatter ?? (stack === "expand" ? percentAxis : defaultAxisFormatter),
    [axisFormatter, stack],
  );

  /* -------------------------------------------------------------- scale */

  const refs = React.useMemo(
    () =>
      (referenceLines ?? []).filter(
        (line) => Number.isFinite(line.y) && (stack === "normal" || stack === "none"),
      ),
    [referenceLines, stack],
  );

  const scale = React.useMemo(() => {
    const vis = visibleSignature.split("").map((v) => v === "1");
    let peak = 0;
    for (let j = 0; j < n; j++) {
      let total = 0;
      for (let s = 0; s < seriesKeys.length; s++) {
        if (!vis[s]) continue;
        const v = model.values[s][j];
        if (stack === "none") peak = Math.max(peak, v);
        else total += v;
      }
      peak = Math.max(peak, total);
    }
    if (stack === "expand")
      return { lo: 0, hi: 1, ticks: [0, 0.25, 0.5, 0.75, 1], peak };
    if (stack === "stream") {
      const half = (peak || 1) / 2;
      return { lo: -half * 1.06, hi: half * 1.06, ticks: [0], peak };
    }
    for (const line of refs) peak = Math.max(peak, line.y);
    const nice = niceScale(peak, height < 200 ? 4 : 5);
    return { lo: 0, hi: nice.hi, ticks: nice.ticks, peak };
  }, [model, n, seriesKeys, visibleSignature, stack, refs, height]);

  const target = React.useMemo(
    () =>
      stackFrame(
        model,
        seriesKeys,
        visibleSignature.split("").map((v) => v === "1"),
        stack,
        scale.lo,
        scale.hi,
      ),
    [model, seriesKeys, visibleSignature, stack, scale],
  );

  /* ------------------------------------------------------------- motion */

  const [tween, setTween] = React.useState<Frame | null>(null);
  const shownRef = React.useRef<Frame>(target);
  const modelRef = React.useRef(model);
  React.useLayoutEffect(() => {
    const from = shownRef.current;
    const dataChanged = modelRef.current !== model;
    modelRef.current = model;
    if (from === target) return;
    if (!motion || framesEqual(from, target)) {
      shownRef.current = target;
      setTween(null);
      return;
    }
    // Data updates glide a little longer than toggles, which should feel immediate.
    const duration = dataChanged ? 460 : 320;
    const ease = dataChanged ? easeInOut : easeOut;
    const start = performance.now();
    setTween(from);
    let frame = requestAnimationFrame(function step(now) {
      const t = Math.min(1, (now - start) / duration);
      if (t >= 1) {
        shownRef.current = target;
        setTween(null);
        return;
      }
      const next = lerpFrame(from, target, ease(t));
      shownRef.current = next;
      setTween(next);
      frame = requestAnimationFrame(step);
    });
    return () => cancelAnimationFrame(frame);
  }, [target, model, motion]);
  const shown = tween ?? target;

  /* ------------------------------------------------------------- layout */

  const plotRef = React.useRef<HTMLDivElement>(null);
  const [width, setWidth] = React.useState(0);
  React.useLayoutEffect(() => {
    const el = plotRef.current;
    if (!el) return;
    const measure = () => setWidth(Math.round(el.clientWidth));
    measure();
    const observer = new ResizeObserver(measure);
    observer.observe(el);
    return () => observer.disconnect();
  }, []);
  const W = width || 640;
  const H = Math.max(96, height);

  // Annotation labels stack into lanes above the plot only when they would collide.
  const marks = React.useMemo(() => {
    if (!annotations?.length || !n) return [];
    const lanes: number[] = [];
    const span = target.x1 - target.x0 || 1;
    return annotations
      .map((note) => {
        let x: number | null = null;
        if (model.kind === "time") x = toTime(note.x);
        else if (model.kind === "number")
          x = typeof note.x === "number" ? note.x : Number(note.x);
        else {
          const i = model.xValues.findIndex((v) => v === String(note.x));
          x = i >= 0 ? i : null;
        }
        if (x == null || !Number.isFinite(x)) return null;
        // The nearest point, so the tooltip can repeat the note.
        let nearest = 0;
        for (let i = 1; i < n; i++)
          if (Math.abs(model.xs[i] - x) < Math.abs(model.xs[nearest] - x))
            nearest = i;
        return { note, x, nearest, fraction: (x - target.x0) / span };
      })
      .filter((m): m is NonNullable<typeof m> => m !== null)
      .filter((m) => m.fraction >= -0.001 && m.fraction <= 1.001)
      .sort((a, b) => a.x - b.x)
      .map((m) => {
        const w = Math.min(W, m.note.label.length * 6.3 + 24);
        const px = m.fraction * W;
        const flip = px + w > W && px - w >= 0;
        const left = flip ? px - w : Math.max(0, Math.min(px, W - w));
        let lane = lanes.findIndex((right) => right + 6 <= left);
        if (lane < 0) lane = lanes.push(0) - 1;
        lanes[lane] = left + w;
        return { ...m, w, left, lane, flip };
      });
  }, [annotations, n, model, target.x0, target.x1, W]);
  const laneCount = marks.length
    ? Math.max(...marks.map((m) => m.lane)) + 1
    : 0;
  const padTop = 8 + laneCount * 26;
  const padBottom = 1;
  const plotH = H - padTop - padBottom;

  const X = (x: number) => ((x - shown.x0) / (shown.x1 - shown.x0 || 1)) * W;
  const entranceBase =
    padTop + ((scale.hi - (stack === "stream" ? 0 : scale.lo)) / (scale.hi - scale.lo || 1)) * plotH;
  const Y = (y: number) =>
    padTop + ((shown.hi - y) / (shown.hi - shown.lo || 1)) * plotH;

  const geometry = React.useMemo(() => {
    const px = shown.xs.map(
      (x) => ((x - shown.x0) / (shown.x1 - shown.x0 || 1)) * W,
    );
    const py = (y: number) =>
      padTop + ((shown.hi - y) / (shown.hi - shown.lo || 1)) * plotH;
    return shown.series.map((key, s) => {
      const top = shown.y1[s].map(py);
      const bottom = shown.y0[s].map(py);
      let thickness = 0;
      for (let j = 0; j < top.length; j++)
        thickness = Math.max(thickness, bottom[j] - top[j]);
      if (!px.length) return { key, area: "", line: "", base: "", thickness };
      const single = px.length === 1;
      const xs = single ? [px[0] - W / 2, px[0] + W / 2] : px;
      const t = single ? [top[0], top[0]] : top;
      const b = single ? [bottom[0], bottom[0]] : bottom;
      const head = `M${r2(xs[0])} ${r2(t[0])}${edge(xs, t, curve, false)}`;
      return {
        key,
        line: head,
        base: `M${r2(xs[0])} ${r2(b[0])}${edge(xs, b, curve, false)}`,
        area: `${head}L${r2(xs[xs.length - 1])} ${r2(b[b.length - 1])}${edge(xs, b, curve, true)}Z`,
        thickness,
      };
    });
  }, [shown, W, padTop, plotH, curve]);

  /* -------------------------------------------------------------- ticks */

  const yTicks = scale.ticks;
  const yTickLabels = stack === "stream" ? [] : yTicks.map(formatTick);

  const xTicks = React.useMemo(() => {
    if (!n) return [] as { x: number; label: string }[];
    const labelWidth = 64;
    const room = Math.max(2, Math.floor(W / labelWidth));
    if (model.kind === "number") {
      const lo = model.xs[0];
      const hi = model.xs[n - 1];
      if (hi <= lo) return [{ x: lo, label: formatX(lo, "axis") }];
      const step = niceStep((hi - lo) / Math.max(1, room - 1));
      const ticks: { x: number; label: string }[] = [];
      for (
        let v = Math.ceil(lo / step - 1e-9) * step;
        v <= hi + step * 1e-6;
        v += step
      )
        ticks.push({ x: tidy(v), label: formatX(tidy(v), "axis") });
      return ticks;
    }
    // Every k-th point. Sub-day axes land on round hours; others count back from the
    // latest point so the newest value is always labelled.
    const subDay = model.kind === "time" && model.step < DAY;
    const steps = subDay
      ? [1, 2, 3, 4, 6, 8, 12, 24, 48, 72, 168]
      : model.kind === "time" && model.step >= 28 * DAY
        ? [1, 2, 3, 6, 12, 24, 60]
        : [1, 2, 3, 4, 5, 7, 10, 14, 15, 20, 28, 30, 50, 60, 100];
    const k =
      steps.find((step) => Math.floor((n - 1) / step) + 1 <= room) ??
      Math.ceil(n / room);
    let phase = (n - 1) % k;
    if (subDay) {
      const span = k * model.step;
      for (let o = 0; o < Math.min(k, n); o++) {
        const d = new Date(model.xs[o]);
        const sinceMidnight =
          model.xs[o] - new Date(d.getFullYear(), d.getMonth(), d.getDate()).getTime();
        if (Math.round(sinceMidnight) % Math.round(span) === 0) {
          phase = o;
          break;
        }
      }
    }
    const ticks: { x: number; label: string }[] = [];
    for (let i = phase; i < n; i += k)
      ticks.push({ x: model.xs[i], label: formatX(model.xValues[i], "axis") });
    return ticks;
  }, [n, model, W, formatX]);

  /* ---------------------------------------------------------- summaries */

  const summary = React.useMemo<StackedAreaSummary>(() => {
    const totals = seriesKeys.map((_, s) =>
      model.values[s].reduce((sum, v) => sum + v, 0),
    );
    const vis = visibleSignature.split("").map((v) => v === "1");
    const total = totals.reduce((sum, v, s) => sum + (vis[s] ? v : 0), 0);
    const at = (j: number) =>
      j < 0
        ? 0
        : seriesKeys.reduce(
            (sum, _, s) => sum + (vis[s] ? model.values[s][j] : 0),
            0,
          );
    return {
      total,
      first: n ? at(0) : 0,
      last: n ? at(n - 1) : 0,
      count: n,
      format: valueFormatter,
      series: seriesKeys.map((key, s) => ({
        key,
        label: series[s]?.label ?? key,
        color: series[s]?.color ?? paletteColor(s),
        value: totals[s],
        share: vis[s] && total > 0 ? totals[s] / total : 0,
        hidden: !vis[s],
      })),
    };
  }, [model, n, seriesKeys, visibleSignature, valueFormatter, series]);

  const pointAt = React.useCallback(
    (j: number): StackedAreaPoint => {
      const items: StackedAreaItem[] = [];
      let total = 0;
      for (let s = 0; s < seriesKeys.length; s++)
        if (visible[s]) total += model.values[s][j];
      for (let s = seriesKeys.length - 1; s >= 0; s--) {
        if (!visible[s]) continue;
        const value = model.values[s][j];
        items.push({
          key: seriesKeys[s],
          label: series[s]?.label ?? seriesKeys[s],
          color: series[s]?.color ?? paletteColor(s),
          value,
          share: total > 0 ? value / total : 0,
        });
      }
      return {
        index: j,
        x: model.xValues[j],
        label: formatX(model.xValues[j], "tooltip"),
        row: model.rows[j],
        total,
        items,
        annotations: marks.filter((m) => m.nearest === j).map((m) => m.note),
      };
    },
    // eslint-disable-next-line react-hooks/exhaustive-deps
    [model, seriesKeys, visibleSignature, series, formatX, marks],
  );

  /* -------------------------------------------------------- interaction */

  const [active, setActive] = React.useState<number | null>(null);
  const [pointerBand, setPointerBand] = React.useState<string | null>(null);
  const [hovered, setHighlight] = React.useState<string | null>(null);
  // A series hidden while hovered no longer dims the rest.
  const highlight = hovered != null && !hiddenSet.has(hovered) ? hovered : null;
  const [announcement, setAnnouncement] = React.useState("");
  const activeIndex = active != null && active < n ? active : null;
  const activePoint = React.useMemo(
    () => (activeIndex == null || !anyVisible ? null : pointAt(activeIndex)),
    [activeIndex, anyVisible, pointAt],
  );

  const onHoverRef = React.useRef(onHover);
  React.useEffect(() => {
    onHoverRef.current = onHover;
  });
  React.useEffect(() => {
    onHoverRef.current?.(activePoint);
  }, [activePoint]);

  const nearestIndex = (px: number) => {
    if (!n) return null;
    const x = target.x0 + (px / W) * (target.x1 - target.x0);
    let lo = 0;
    let hi = n - 1;
    while (lo < hi) {
      const mid = (lo + hi) >> 1;
      if (model.xs[mid] < x) lo = mid + 1;
      else hi = mid;
    }
    if (lo > 0 && Math.abs(model.xs[lo - 1] - x) <= Math.abs(model.xs[lo] - x))
      lo -= 1;
    return lo;
  };

  const handlePointer = (event: React.PointerEvent<HTMLDivElement>) => {
    if (!n || !anyVisible) return;
    const rect = event.currentTarget.getBoundingClientRect();
    const px = event.clientX - rect.left;
    const py = event.clientY - rect.top;
    const j = nearestIndex(Math.min(W, Math.max(0, px)));
    setActive(j);
    if (j == null) return;
    // Which band sits under the pointer, so its tooltip row can stand out.
    let band: string | null = null;
    for (let s = seriesKeys.length - 1; s >= 0; s--) {
      if (!visible[s]) continue;
      const top = Y(target.y1[s][j]);
      const bottom = Y(target.y0[s][j]);
      if (py >= Math.min(top, bottom) - 2 && py <= Math.max(top, bottom) + 2) {
        band = seriesKeys[s];
        break;
      }
    }
    setPointerBand(band);
  };

  const describe = (point: StackedAreaPoint) =>
    `${point.label}: total ${valueFormatter(point.total)}. ${point.items
      .map(
        (item) =>
          `${item.label} ${valueFormatter(item.value)}, ${formatShare(item.share)}`,
      )
      .join("; ")}.${point.annotations.length ? ` ${point.annotations.map((a) => a.label).join(". ")}.` : ""}`;

  const onKeyDown = (event: React.KeyboardEvent<HTMLDivElement>) => {
    if (!n || !anyVisible) return;
    let next: number | null = null;
    if (event.key === "ArrowRight")
      next = activeIndex == null ? 0 : Math.min(n - 1, activeIndex + 1);
    else if (event.key === "ArrowLeft")
      next = activeIndex == null ? n - 1 : Math.max(0, activeIndex - 1);
    else if (event.key === "Home") next = 0;
    else if (event.key === "End") next = n - 1;
    else if (event.key === "Escape" && activeIndex != null) {
      event.preventDefault();
      setActive(null);
      return;
    }
    if (next == null) return;
    event.preventDefault();
    setPointerBand(null);
    setActive(next);
    setAnnouncement(describe(pointAt(next)));
  };

  const toggle = (key: string, solo: boolean) => {
    const label = series.find((s) => s.key === key)?.label ?? key;
    if (solo) {
      const only =
        seriesKeys.filter((k) => !hiddenSet.has(k)).length === 1 &&
        !hiddenSet.has(key);
      setHidden(only ? [] : seriesKeys.filter((k) => k !== key));
      setAnnouncement(only ? "Showing all series." : `Showing only ${label}.`);
      return;
    }
    const isHidden = hiddenSet.has(key);
    setHidden(
      isHidden ? hidden.filter((k) => k !== key) : [...hidden, key],
    );
    setAnnouncement(sentence([label, isHidden ? "shown." : "hidden."]));
  };

  /* -------------------------------------------------------------- render */

  const headerContent =
    typeof header === "function" ? header(summary) : header;
  const hasHeader =
    title != null || description != null || actions != null || headerContent != null;

  const activeX = activeIndex != null ? X(model.xs[activeIndex]) : 0;
  const activeKeyIndex =
    activeIndex != null
      ? shown.keys.indexOf(model.keys[activeIndex])
      : -1;

  // Keep the tooltip inside the plot, beside the crosshair on the roomier side.
  const tooltipRef = React.useRef<HTMLDivElement>(null);
  const [tooltipWidth, setTooltipWidth] = React.useState(200);
  React.useLayoutEffect(() => {
    const el = tooltipRef.current;
    if (el && el.offsetWidth && el.offsetWidth !== tooltipWidth)
      setTooltipWidth(el.offsetWidth);
  });
  const tooltipLeft =
    activeX + 14 + tooltipWidth <= W || activeX < W / 2
      ? Math.min(activeX + 14, Math.max(0, W - tooltipWidth))
      : Math.max(0, activeX - 14 - tooltipWidth);

  const glide = motion
    ? "transition-transform duration-150 ease-out"
    : "";

  const summaryText = (() => {
    if (!n) return "No data.";
    const parts = summary.series
      .filter((s) => !s.hidden)
      .map((s) => `${s.label} ${formatShare(s.share, 0)}`)
      .join(", ");
    const range =
      n > 1
        ? `from ${formatX(model.xValues[0], "tooltip")} to ${formatX(model.xValues[n - 1], "tooltip")}`
        : formatX(model.xValues[0], "tooltip");
    return `${stack === "expand" ? "Share" : "Stacked values"} of ${summary.series.filter((s) => !s.hidden).length} series ${range}. Total ${valueFormatter(summary.total)}: ${parts}.`;
  })();

  const legend = showLegend && seriesKeys.length > 0 && (
    <div
      role="group"
      aria-label="Series"
      data-slot="stacked-area-legend"
      className={cn(
        "flex flex-wrap items-center gap-x-0.5 gap-y-0.5 px-3",
        legendPosition === "bottom" ? "mt-3 border-t py-2" : "mt-3",
      )}
    >
      {meta.map((s, i) => {
        const isHidden = hiddenSet.has(s.key);
        const share = summary.series[i]?.share ?? 0;
        return (
          <button
            key={s.key}
            type="button"
            data-slot="stacked-area-legend-item"
            data-key={s.key}
            data-hidden={isHidden || undefined}
            aria-pressed={!isHidden}
            title="Click to toggle. Alt-click to show only this series."
            onClick={(event) => toggle(s.key, event.altKey)}
            onKeyDown={(event) => {
              if (event.key === "Enter" && event.altKey) {
                event.preventDefault();
                toggle(s.key, true);
              }
            }}
            onPointerEnter={() => !isHidden && setHighlight(s.key)}
            onPointerLeave={() => setHighlight(null)}
            onFocus={() => !isHidden && setHighlight(s.key)}
            onBlur={() => setHighlight(null)}
            className={cn(
              "group/legend inline-flex h-7 max-w-full items-center gap-2 rounded-md px-2 text-xs transition-colors hover:bg-muted/70 motion-reduce:transition-none",
              focusRing,
            )}
          >
            <span
              aria-hidden="true"
              className="size-2.5 shrink-0 rounded-[3px] transition-[background,box-shadow] duration-200 motion-reduce:transition-none"
              style={
                isHidden
                  ? {
                      boxShadow: `inset 0 0 0 1.25px color-mix(in oklab, ${s.color} 55%, transparent)`,
                    }
                  : {
                      background: `linear-gradient(to bottom, color-mix(in oklab, ${s.color} 55%, transparent), color-mix(in oklab, ${s.color} 16%, transparent))`,
                      boxShadow: `inset 0 1.5px 0 ${s.color}`,
                    }
              }
            />
            <span
              className={cn(
                "truncate font-medium transition-colors motion-reduce:transition-none",
                isHidden ? "text-muted-foreground/70" : "text-foreground",
              )}
            >
              {s.label}
            </span>
            {!isHidden && (
              <span className="text-muted-foreground tabular-nums">
                {formatShare(share, 0)}
              </span>
            )}
          </button>
        );
      })}
      {legendPosition === "bottom" && seriesKeys.length > 1 && (
        <span className="ml-auto hidden pr-2 text-[11px] text-muted-foreground @3xl/stacked-area:inline">
          Alt-click to show one
        </span>
      )}
    </div>
  );

  const crosshairDots =
    activeIndex != null && activeKeyIndex >= 0
      ? shown.series
          .map((key, s) => {
            if (!visible[s] || shown.weight[s] < 0.5) return null;
            return {
              key,
              color: meta[s]?.color ?? paletteColor(s),
              y: Y(shown.y1[s][activeKeyIndex]),
            };
          })
          .filter((d): d is NonNullable<typeof d> => d !== null)
      : [];

  const lowestVisible = visible.indexOf(true);
  // Larger overlapping areas sit behind smaller ones; stacked bands draw top first.
  const drawOrder = React.useMemo(() => {
    const order = seriesKeys.map((_, s) => s);
    if (stack === "none")
      return order.sort(
        (a, b) =>
          Math.max(0, ...model.values[b]) - Math.max(0, ...model.values[a]),
      );
    return order.reverse();
  }, [seriesKeys, stack, model]);

  return (
    <div
      data-slot="stacked-area-chart"
      data-stack={stack}
      data-curve={curve}
      data-highlight={highlight ?? undefined}
      className={cn(
        "@container/stacked-area flex min-w-0 flex-col rounded-2xl border border-border/70 bg-card text-card-foreground",
        "shadow-[0_1px_2px_rgb(0_0_0/0.04),0_8px_24px_-12px_rgb(0_0_0/0.10)] dark:shadow-[inset_0_1px_0_rgb(255_255_255/0.05),0_1px_2px_rgb(0_0_0/0.5)]",
        "[--sac-fill-bottom:0] [--sac-fill-top:0.32] dark:[--sac-fill-top:0.36] data-[stack=stream]:[--sac-fill-bottom:0.1]",
        !(showLegend && legendPosition === "bottom") && "pb-5",
        className,
      )}
      {...props}
    >
      {hasHeader && (
        <div className="flex flex-col gap-4 px-5 pt-5">
          {(title != null || description != null || actions != null) && (
            <div className="flex flex-wrap items-start gap-x-4 gap-y-3">
              <div className="min-w-[min(100%,8rem)] flex-1 space-y-1">
                {title != null && (
                  <h3 className="truncate text-sm leading-5 font-semibold tracking-tight">
                    {title}
                  </h3>
                )}
                {description != null && (
                  <p
                    id={`${id}-description`}
                    className="text-[13px] leading-5 text-muted-foreground"
                  >
                    {description}
                  </p>
                )}
              </div>
              {actions != null && (
                <div className="flex shrink-0 flex-wrap items-center gap-2">{actions}</div>
              )}
            </div>
          )}
          {headerContent != null && (
            <div data-slot="stacked-area-header">{headerContent}</div>
          )}
        </div>
      )}

      {legendPosition === "top" && legend}

      <div className={cn("px-5", hasHeader || legendPosition === "top" ? "mt-4" : "mt-5")}>
        {yLabel && stack !== "stream" && (
          <p
            aria-hidden="true"
            className="mb-1 text-[11px] leading-4 text-muted-foreground"
          >
            {yLabel}
          </p>
        )}
        <div className="flex">
          {/* Value axis: an invisible copy of the labels sizes the gutter, so nothing is measured. */}
          {stack !== "stream" && (
            <div
              aria-hidden="true"
              className="relative shrink-0 pr-2 text-[11px] leading-none text-muted-foreground tabular-nums"
              style={{ height: H }}
            >
              <div className="invisible h-0 overflow-hidden">
                {yTickLabels.map((label, i) => (
                  <div key={i}>{label}</div>
                ))}
              </div>
              {yTicks.map((tick, i) => (
                <span
                  key={`${tick}-${i}`}
                  className={cn("absolute right-2 top-0 whitespace-nowrap", glide)}
                  style={{ transform: `translateY(calc(${r2(Y(tick))}px - 50%))` }}
                >
                  {yTickLabels[i]}
                </span>
              ))}
            </div>
          )}

          <div className="min-w-0 flex-1">
            <div
              ref={plotRef}
              role="group"
              aria-roledescription="stacked area chart"
              aria-label={`${typeof title === "string" ? `${title}. ` : ""}${summaryText} Use the left and right arrow keys to read each point.`}
              aria-describedby={description != null ? `${id}-description` : undefined}
              tabIndex={n && anyVisible ? 0 : -1}
              data-slot="stacked-area-plot"
              onPointerMove={handlePointer}
              onPointerDown={handlePointer}
              onPointerLeave={() => {
                setActive(null);
                setPointerBand(null);
              }}
              onKeyDown={onKeyDown}
              onBlur={() => setActive(null)}
              className={cn(
                "relative cursor-crosshair touch-pan-y rounded-sm select-none",
                "outline-none focus-visible:ring-2 focus-visible:ring-primary/30 focus-visible:ring-offset-4 focus-visible:ring-offset-card",
              )}
              style={{ height: H }}
            >
              {/* Gridlines */}
              <div aria-hidden="true" className="pointer-events-none absolute inset-0">
                {yTicks.map((tick, i) => (
                  <span
                    key={`${tick}-${i}`}
                    className={cn("absolute inset-x-0 top-0 h-px", glide)}
                    style={{
                      transform: `translateY(${r2(Y(tick))}px)`,
                      background:
                        stack !== "stream" && tick === scale.lo ? baseColor : gridColor,
                    }}
                  />
                ))}
              </div>

              <svg
                aria-hidden="true"
                width="100%"
                height={H}
                viewBox={`0 0 ${W} ${H}`}
                preserveAspectRatio="none"
                className="absolute inset-0 overflow-visible"
              >
                <defs>
                  <clipPath id={`${id}-clip`}>
                    <rect x={0} y={-6} width={W} height={H + 12} />
                  </clipPath>
                  {meta.map((s, i) => (
                    <linearGradient
                      key={s.key}
                      id={`${id}-fill-${i}`}
                      x1="0"
                      y1="0"
                      x2="0"
                      y2="1"
                    >
                      <stop
                        offset="0"
                        style={{ stopColor: s.color, stopOpacity: "var(--sac-fill-top)" }}
                      />
                      <stop
                        offset="1"
                        style={{ stopColor: s.color, stopOpacity: "var(--sac-fill-bottom)" }}
                      />
                    </linearGradient>
                  ))}
                </defs>
                <g clipPath={`url(#${id}-clip)`}>
                  {drawOrder.map((s) => {
                    const g = geometry[s];
                    const m = meta[s];
                    if (!g || !m) return null;
                    const weight = shown.weight[s] ?? 0;
                    const isHidden = !visible[s];
                    const drawn = weight >= 0.002 || g.thickness >= 0.05;
                    const dim = highlight != null && highlight !== m.key;
                    const alpha = Math.min(1, weight * 1.5);
                    // Bands rise from the baseline and lines draw in, bottom series first.
                    const delay = `${s * 40}ms`;
                    return (
                      <g
                        key={m.key}
                        data-slot="stacked-area-series"
                        data-key={m.key}
                        data-hidden={isHidden || undefined}
                        className={cn(
                          animate &&
                            "motion-safe:animate-[stacked-area-rise_760ms_cubic-bezier(0.22,1,0.36,1)_both]",
                        )}
                        style={{ animationDelay: delay, transformOrigin: `0px ${r2(entranceBase)}px` }}
                      >
                        {drawn && (
                          <g
                            className="transition-opacity duration-150 motion-reduce:transition-none"
                            style={{ opacity: dim ? 0.24 : 1 }}
                          >
                            <path
                              d={g.area}
                              fill={`url(#${id}-fill-${s})`}
                              fillOpacity={(stack === "none" ? 0.8 : 1) * alpha}
                            />
                            {stack === "stream" && s === lowestVisible && (
                              <path
                                d={g.base}
                                fill="none"
                                stroke={m.color}
                                strokeWidth={2}
                                strokeLinejoin="round"
                                strokeLinecap="round"
                                strokeOpacity={alpha}
                                pathLength={1}
                                strokeDasharray="1 1"
                                className={cn(
                                  "dark:[filter:drop-shadow(0_0_6px_color-mix(in_oklab,var(--sac-line)_50%,transparent))]",
                                  animate &&
                                    "motion-safe:animate-[stacked-area-draw_820ms_cubic-bezier(0.22,1,0.36,1)_both]",
                                )}
                                style={
                                  {
                                    "--sac-line": m.color,
                                    animationDelay: delay,
                                  } as React.CSSProperties
                                }
                              />
                            )}
                            <path
                              d={g.line}
                              fill="none"
                              stroke={m.color}
                              strokeWidth={2}
                              strokeLinejoin="round"
                              strokeLinecap="round"
                              strokeOpacity={alpha}
                              pathLength={1}
                              strokeDasharray="1 1"
                              className={cn(
                                "dark:[filter:drop-shadow(0_0_6px_color-mix(in_oklab,var(--sac-line)_50%,transparent))]",
                                animate &&
                                  "motion-safe:animate-[stacked-area-draw_820ms_cubic-bezier(0.22,1,0.36,1)_both]",
                              )}
                              style={
                                {
                                  "--sac-line": m.color,
                                  animationDelay: delay,
                                } as React.CSSProperties
                              }
                            />
                          </g>
                        )}
                      </g>
                    );
                  })}
                </g>
              </svg>

              {/* Reference lines */}
              {refs.map((line, i) => {
                const color = line.color ?? "var(--color-muted-foreground)";
                return (
                  <div
                    key={i}
                    aria-hidden="true"
                    data-slot="stacked-area-reference"
                    className={cn("pointer-events-none absolute inset-x-0 top-0", glide)}
                    style={{ transform: `translateY(${r2(Y(line.y))}px)` }}
                  >
                    <div
                      className="border-t border-dashed"
                      style={{ borderColor: `color-mix(in oklab, ${color} 70%, transparent)` }}
                    />
                    {line.label && (
                      <span
                        className="absolute right-0 bottom-1 rounded-sm bg-card/85 px-1 text-[10.5px] leading-4 font-medium whitespace-nowrap tabular-nums"
                        style={{ color }}
                      >
                        {line.label}
                      </span>
                    )}
                  </div>
                );
              })}

              {/* Annotations */}
              {marks.map((m, i) => {
                const color = m.note.color ?? "var(--color-foreground)";
                const x = X(m.x);
                const top = 4 + m.lane * 26;
                return (
                  <div
                    key={i}
                    aria-hidden="true"
                    data-slot="stacked-area-annotation"
                    data-active={m.nearest === activeIndex || undefined}
                    className="pointer-events-none absolute inset-0"
                  >
                    <span
                      className="absolute bottom-0 w-0 border-l border-dashed"
                      style={{
                        left: r2(x),
                        top: top + 20,
                        borderColor: `color-mix(in oklab, ${color} 38%, transparent)`,
                      }}
                    />
                    <span
                      className="absolute h-[7px] w-px"
                      style={{ left: r2(x), top: top + 14, background: `color-mix(in oklab, ${color} 38%, transparent)` }}
                    />
                    <span
                      className="absolute flex h-5 max-w-full items-center gap-1.5 rounded-md border bg-card px-1.5 text-[11px] leading-none font-medium whitespace-nowrap text-foreground shadow-xs"
                      style={{
                        top,
                        left: r2(m.left + (x - m.fraction * W)),
                        width: m.w,
                      }}
                    >
                      <span
                        className="size-1.5 shrink-0 rounded-full"
                        style={{ background: color }}
                      />
                      <span className="truncate">{m.note.label}</span>
                    </span>
                  </div>
                );
              })}

              {/* Crosshair */}
              {activePoint && (
                <div aria-hidden="true" className="pointer-events-none absolute inset-0">
                  <div
                    className={cn("absolute top-0 left-0 h-full w-px", glide)}
                    style={{ transform: `translateX(${r2(activeX)}px)` }}
                  >
                    <div
                      className="absolute inset-x-0 bottom-0 bg-foreground/25"
                      style={{ top: padTop - 4 }}
                    />
                  </div>
                  {crosshairDots.map((dot) => (
                    <span
                      key={dot.key}
                      className={cn(
                        "absolute top-0 left-0 -mt-1 -ml-1 size-2 rounded-full",
                        glide,
                      )}
                      style={{
                        background: dot.color,
                        boxShadow: `0 0 0 1.5px var(--color-card), 0 0 0 5px color-mix(in oklab, ${dot.color} 18%, transparent)`,
                        transform: `translate(${r2(activeX)}px, ${r2(dot.y)}px)`,
                      }}
                    />
                  ))}
                </div>
              )}

              {/* Tooltip */}
              {activePoint && (
                <div
                  ref={tooltipRef}
                  data-slot="stacked-area-tooltip"
                  aria-hidden="true"
                  className={cn(
                    "pointer-events-none absolute top-0 left-0 z-10 min-w-48 rounded-xl border border-border/70 bg-popover/90 px-3 py-2.5 text-xs text-popover-foreground shadow-xl backdrop-blur-md",
                    glide,
                  )}
                  style={{
                    transform: `translate(${r2(tooltipLeft)}px, ${padTop}px)`,
                  }}
                >
                  {renderTooltip ? (
                    renderTooltip(activePoint)
                  ) : (
                    <DefaultTooltip
                      point={activePoint}
                      format={valueFormatter}
                      emphasis={pointerBand}
                    />
                  )}
                </div>
              )}

              {!n && (
                <p className="absolute inset-0 grid place-items-center text-xs text-muted-foreground">
                  No data to show.
                </p>
              )}
              {n > 0 && !anyVisible && (
                <div className="absolute inset-0 flex flex-col items-center justify-center gap-2 text-xs text-muted-foreground">
                  <p>Every series is hidden.</p>
                  <button
                    type="button"
                    onClick={() => setHidden([])}
                    className={cn(
                      "h-7 rounded-md border bg-card px-2.5 font-medium text-foreground shadow-xs hover:bg-muted",
                      focusRing,
                    )}
                  >
                    Show all
                  </button>
                </div>
              )}
            </div>

            {/* Time axis */}
            <div
              aria-hidden="true"
              className="relative mt-2 h-4 text-[11px] leading-4 text-muted-foreground tabular-nums"
            >
              {xTicks.map((tick, i) => {
                const x = X(tick.x);
                if (x < -1 || x > W + 1) return null;
                const edgeClass =
                  x < 28 ? "" : x > W - 28 ? "-translate-x-full" : "-translate-x-1/2";
                return (
                  <span
                    key={`${tick.x}-${i}`}
                    className={cn("absolute top-0 whitespace-nowrap", edgeClass)}
                    style={{ left: r2(x) }}
                  >
                    {tick.label}
                  </span>
                );
              })}
            </div>
          </div>
        </div>
      </div>

      {legendPosition === "bottom" && legend}

      <div className="sr-only">
        <table>
          <caption>{summaryText}</caption>
          <thead>
            <tr>
              <th scope="col">{index}</th>
              {meta.map((s) => (
                <th key={s.key} scope="col">
                  {s.label}
                </th>
              ))}
              <th scope="col">Total</th>
            </tr>
          </thead>
          <tbody>
            {model.rows.map((_, j) => (
              <tr key={model.keys[j]}>
                <th scope="row">{formatX(model.xValues[j], "tooltip")}</th>
                {meta.map((s, si) => (
                  <td key={s.key}>{valueFormatter(model.values[si][j])}</td>
                ))}
                <td>
                  {valueFormatter(
                    model.values.reduce((sum, values) => sum + values[j], 0),
                  )}
                </td>
              </tr>
            ))}
          </tbody>
        </table>
      </div>
      <p className="sr-only" aria-live="polite">
        {announcement}
      </p>

      <style href="overtrue-stacked-area-chart" precedence="default">
        {`@keyframes stacked-area-rise{from{transform:scaleY(0)}to{transform:scaleY(1)}}@keyframes stacked-area-draw{from{stroke-dashoffset:1}to{stroke-dashoffset:0}}`}
      </style>
    </div>
  );
}

function DefaultTooltip({
  point,
  format,
  emphasis,
}: {
  point: StackedAreaPoint;
  format: (value: number) => string;
  emphasis: string | null;
}) {
  return (
    <div className="grid grid-cols-[auto_minmax(0,1fr)_auto_auto] items-center gap-x-2 gap-y-1">
      <p className="col-span-4 mb-1 font-medium text-foreground">{point.label}</p>
      {point.items.map((item) => (
        <React.Fragment key={item.key}>
          <span
            aria-hidden="true"
            className="h-2.5 w-[3px] rounded-full"
            style={{ background: item.color }}
          />
          <span
            className={cn(
              "truncate",
              emphasis === item.key ? "font-medium text-foreground" : "text-muted-foreground",
            )}
          >
            {item.label}
          </span>
          <span
            className={cn(
              "pl-3 text-right tabular-nums",
              emphasis === item.key ? "font-semibold" : "font-medium",
            )}
          >
            {format(item.value)}
          </span>
          <span className="w-11 text-right text-[11px] text-muted-foreground tabular-nums">
            {formatShare(item.share)}
          </span>
        </React.Fragment>
      ))}
      <span className="col-span-4 my-0.5 h-px bg-border" />
      <span />
      <span className="text-muted-foreground">Total</span>
      <span className="pl-3 text-right font-semibold tabular-nums">
        {format(point.total)}
      </span>
      <span />
      {point.annotations.map((note, i) => (
        <p
          key={i}
          className="col-span-4 mt-1 flex items-center gap-1.5 border-t border-dashed pt-1.5 text-[11px] text-muted-foreground"
        >
          <span
            aria-hidden="true"
            className="size-1.5 shrink-0 rounded-full"
            style={{ background: note.color ?? "var(--color-foreground)" }}
          />
          {note.label}
        </p>
      ))}
    </div>
  );
}
```

### `src/registry/overtrue/latency-histogram.tsx`

```tsx
"use client";

import * as React from "react";
import { IconX as X } from "@tabler/icons-react";

import { cn } from "@/lib/utils";

export type LatencyScale = "linear" | "log";

export type LatencyRange = [min: number, max: number];

export interface LatencyBucket {
  /** Inclusive lower edge. */
  start: number;
  /** Exclusive upper edge. */
  end: number;
  count: number;
}

/** One bar as drawn, passed to `renderTooltip`. */
export interface LatencyHistogramBucket extends LatencyBucket {
  index: number;
  /** Share of all requests in this bucket, 0–1. */
  share: number;
  /** Share of requests at or below this bucket's upper edge, 0–1. */
  cumulative: number;
  /** Raw comparison count in the same range, when `compare` is set. */
  compare?: number;
  /** Comparison share of its own total, 0–1. */
  compareShare?: number;
  /** The catch-all bar for values past the linear domain. */
  overflow: boolean;
  /** Whether the bucket lies past `threshold`. */
  overThreshold: boolean;
}

export interface LatencyHistogramColors {
  bar: string;
  compare: string;
  threshold: string;
  marker: string;
  selection: string;
}

export interface LatencyHistogramProps extends Omit<
  React.ComponentProps<"div">,
  "title" | "children" | "color"
> {
  /** Raw samples. Bucketed for you, with exact percentiles. */
  values?: number[];
  /** Pre-bucketed counts, used when `values` is not given. Percentiles are interpolated. */
  buckets?: LatencyBucket[];
  /** A comparison distribution, e.g. yesterday. Scaled to the main total so shapes compare. */
  compare?: number[] | LatencyBucket[];
  /** Name of the comparison in the legend and tooltip. */
  compareLabel?: string;
  /** Name of the main series in the legend. */
  seriesLabel?: string;
  /** Draw the comparison as a stepped line or as outlined bars. */
  compareStyle?: "step" | "outline";
  /** Percentiles to mark, as numbers such as 50 or 99.9. */
  percentiles?: number[];
  /** Latency objective. The slow tail past it is shaded and measured. */
  threshold?: number;
  thresholdLabel?: string;
  /** X scale. Pass with `onScaleChange` to control the built-in toggle. */
  scale?: LatencyScale;
  defaultScale?: LatencyScale;
  onScaleChange?: (scale: LatencyScale) => void;
  /** Show the linear/log toggle. Defaults to true. */
  showScaleToggle?: boolean;
  /** Brushed range. Pass `null` for none; leave undefined to let the component manage it. */
  range?: LatencyRange | null;
  defaultRange?: LatencyRange | null;
  onRangeChange?: (range: LatencyRange | null) => void;
  title?: React.ReactNode;
  description?: React.ReactNode;
  /** Controls placed at the top right, before the scale toggle. */
  actions?: React.ReactNode;
  /** Unit of the values. Defaults to "ms"; ms readouts switch to seconds from 1,000. */
  unit?: string;
  /** Formats latencies in readouts, markers, and ticks. */
  valueFormatter?: (value: number) => string;
  /** Target number of bars. Defaults to 40. */
  bucketCount?: number;
  /** Fix the latency domain. Linear charts otherwise end near p99.5 and gather the rest in an overflow bar. */
  domain?: LatencyRange;
  /** Plot height in pixels. Defaults to a third of the plot width, between 140 and 220. */
  height?: number;
  /** Override any series color with a CSS color. */
  colors?: Partial<LatencyHistogramColors>;
  /** Replaces the hover tooltip content. */
  renderTooltip?: (bucket: LatencyHistogramBucket) => React.ReactNode;
  /** Show the percentile summary above the plot. Defaults to true. */
  showSummary?: boolean;
}

/* ------------------------------------------------------------------------ */
/* Formatting                                                                */
/* ------------------------------------------------------------------------ */

const tidy = (value: number) => +value.toPrecision(12);
const compact = new Intl.NumberFormat("en-US", {
  notation: "compact",
  maximumFractionDigits: 1,
});
const whole = new Intl.NumberFormat("en-US");

function makeFormatter(unit: string) {
  const tight = unit.length <= 2;
  const join = (text: string, u: string) =>
    u ? `${text}${tight ? "" : " "}${u}` : text;
  return (value: number) => {
    if (!Number.isFinite(value)) return "—";
    const a = Math.abs(value);
    if (unit === "ms" && a >= 1000)
      return `${tidy(+(value / 1000).toFixed(a >= 10_000 ? 1 : 2))}s`;
    const digits = a >= 100 || a === 0 ? 0 : a >= 10 ? 1 : a >= 1 ? 2 : 3;
    return join(String(tidy(+value.toFixed(digits))), unit);
  };
}

function makeTickFormatter(unit: string) {
  const tight = unit.length <= 2;
  return (value: number) => {
    if (value === 0) return "0";
    if (unit === "ms" && Math.abs(value) >= 1000)
      return `${tidy(value / 1000)}s`;
    return `${tidy(value)}${tight ? "" : " "}${unit}`;
  };
}

function percentLabel(share: number) {
  const pct = share * 100;
  if (pct === 0) return "0%";
  if (pct < 0.1) return "<0.1%";
  if (pct > 99.9 && pct < 100) return ">99.9%";
  return `${pct >= 10 ? pct.toFixed(1) : pct.toFixed(2)}%`;
}

function niceStep(raw: number) {
  if (!(raw > 0)) return 1;
  const magnitude = 10 ** Math.floor(Math.log10(raw));
  const r = raw / magnitude;
  return (
    (r <= 1 ? 1 : r <= 2 ? 2 : r <= 2.5 ? 2.5 : r <= 5 ? 5 : 10) * magnitude
  );
}

/** Round down or up to the nearest 1, 2, or 5 times a power of ten. */
function nice125(value: number, up: boolean) {
  const magnitude = 10 ** Math.floor(Math.log10(value));
  const r = value / magnitude;
  const steps = [1, 2, 5, 10];
  if (up) return (steps.find((s) => s >= r - 1e-9) ?? 10) * magnitude;
  return ([...steps].reverse().find((s) => s <= r + 1e-9) ?? 1) * magnitude;
}

function lowerBound(sorted: Float64Array, value: number) {
  let lo = 0;
  let hi = sorted.length;
  while (lo < hi) {
    const mid = (lo + hi) >> 1;
    if (sorted[mid] < value) lo = mid + 1;
    else hi = mid;
  }
  return lo;
}

function upperBound(sorted: Float64Array, value: number) {
  let lo = 0;
  let hi = sorted.length;
  while (lo < hi) {
    const mid = (lo + hi) >> 1;
    if (sorted[mid] <= value) lo = mid + 1;
    else hi = mid;
  }
  return lo;
}

/* ------------------------------------------------------------------------ */
/* Model                                                                     */
/* ------------------------------------------------------------------------ */

interface Bar extends LatencyBucket {
  overflow: boolean;
  /** Left and right edges as 0–1 positions. */
  x0: number;
  x1: number;
}

interface Distribution {
  sorted: Float64Array | null;
  buckets: LatencyBucket[] | null;
  total: number;
  min: number;
  max: number;
  mean: number;
}

function distributionOf(
  values?: number[],
  buckets?: LatencyBucket[],
): Distribution {
  if (values) {
    const clean = values.filter((value) => Number.isFinite(value));
    const sorted = Float64Array.from(clean).sort();
    let sum = 0;
    for (const value of sorted) sum += value;
    return {
      sorted,
      buckets: null,
      total: sorted.length,
      min: sorted.length ? sorted[0] : 0,
      max: sorted.length ? sorted[sorted.length - 1] : 0,
      mean: sorted.length ? sum / sorted.length : 0,
    };
  }
  const list = (buckets ?? [])
    .filter(
      (b) =>
        Number.isFinite(b.start) && Number.isFinite(b.end) && b.end > b.start,
    )
    .sort((a, b) => a.start - b.start);
  let total = 0;
  let sum = 0;
  for (const b of list) {
    total += Math.max(0, b.count);
    sum += (Math.max(0, b.count) * (b.start + b.end)) / 2;
  }
  return {
    sorted: null,
    buckets: list,
    total,
    min: list.length ? list[0].start : 0,
    max: list.length ? list[list.length - 1].end : 0,
    mean: total ? sum / total : 0,
  };
}

/** Nearest-rank percentile from samples; interpolated inside buckets otherwise. */
function quantile(d: Distribution, p: number) {
  if (!d.total) return 0;
  if (d.sorted)
    return d.sorted[
      Math.min(d.total - 1, Math.max(0, Math.ceil(p * d.total) - 1))
    ];
  const target = p * d.total;
  let cumulative = 0;
  for (const b of d.buckets!) {
    if (cumulative + b.count >= target && b.count > 0)
      return b.start + ((target - cumulative) / b.count) * (b.end - b.start);
    cumulative += b.count;
  }
  return d.max;
}

/** Requests with a value in [a, b]. Partial buckets count in proportion. */
function countBetween(d: Distribution, a: number, b: number) {
  if (d.sorted) return upperBound(d.sorted, b) - lowerBound(d.sorted, a);
  let count = 0;
  for (const bucket of d.buckets!) {
    const overlap = Math.min(b, bucket.end) - Math.max(a, bucket.start);
    if (overlap > 0)
      count += (bucket.count * overlap) / (bucket.end - bucket.start);
  }
  return count;
}

function countAbove(d: Distribution, value: number) {
  if (d.sorted) return d.total - upperBound(d.sorted, value);
  return countBetween(d, value, Infinity);
}

interface Layout {
  bars: Bar[];
  lo: number;
  hi: number;
  /** Largest value covered, including the overflow bar. */
  top: number;
  pos: (value: number) => number;
  inv: (x: number) => number;
}

function layoutOf(
  d: Distribution,
  scale: LatencyScale,
  bucketCount: number,
  reach: number,
  domain?: LatencyRange,
): Layout {
  const count = Math.max(4, Math.round(bucketCount));
  // Pre-bucketed data keeps its own edges.
  if (d.buckets) {
    const list = d.buckets;
    const first = list[0]?.start ?? 0;
    const last = list[list.length - 1]?.end ?? 1;
    if (scale === "log") {
      const positive =
        list.find((b) => b.start > 0)?.start ?? list[0]?.end ?? 1;
      const lo = first > 0 ? first : positive / 2;
      const span = Math.log(last / lo) || 1;
      const pos = (v: number) =>
        Math.min(1, Math.max(0, Math.log(Math.max(v, lo) / lo) / span));
      const inv = (x: number) => lo * Math.exp(x * span);
      return {
        bars: list.map((b) => ({
          ...b,
          overflow: false,
          x0: pos(b.start),
          x1: pos(b.end),
        })),
        lo,
        hi: last,
        top: last,
        pos,
        inv,
      };
    }
    const span = last - first || 1;
    const pos = (v: number) => Math.min(1, Math.max(0, (v - first) / span));
    const inv = (x: number) => first + x * span;
    return {
      bars: list.map((b) => ({
        ...b,
        overflow: false,
        x0: pos(b.start),
        x1: pos(b.end),
      })),
      lo: first,
      hi: last,
      top: last,
      pos,
      inv,
    };
  }

  const sorted = d.sorted!;
  if (scale === "log") {
    const positive = sorted[lowerBound(sorted, Number.MIN_VALUE)] ?? 1;
    const lo =
      domain?.[0] && domain[0] > 0
        ? domain[0]
        : nice125(Math.max(positive, 1e-9), false);
    const hi = Math.max(
      domain?.[1] ?? nice125(Math.max(d.max, lo * 10), true),
      lo * 1.0001,
    );
    const span = Math.log(hi / lo);
    const step = span / count;
    const bars: Bar[] = Array.from({ length: count }, (_, i) => ({
      start: lo * Math.exp(i * step),
      end: lo * Math.exp((i + 1) * step),
      count: 0,
      overflow: false,
      x0: i / count,
      x1: (i + 1) / count,
    }));
    for (const v of sorted) {
      const i = v <= lo ? 0 : Math.floor(Math.log(v / lo) / step);
      bars[Math.min(count - 1, Math.max(0, i))].count += 1;
    }
    const pos = (v: number) =>
      Math.min(1, Math.max(0, Math.log(Math.max(v, lo) / lo) / span));
    return { bars, lo, hi, top: hi, pos, inv: (x) => lo * Math.exp(x * span) };
  }

  const lo = domain?.[0] ?? (d.min >= 0 ? 0 : -niceStep(-d.min));
  const wanted = domain?.[1] ?? Math.max(reach, lo + 1e-9);
  const step = niceStep((wanted - lo) / count);
  const n = Math.max(1, Math.ceil((wanted - lo) / step - 1e-9));
  const hi = lo + n * step;
  const overflowCount = d.total - upperBound(sorted, hi);
  const units = overflowCount > 0 ? n + 1.7 : n;
  const bars: Bar[] = Array.from({ length: n }, (_, i) => ({
    start: tidy(lo + i * step),
    end: tidy(lo + (i + 1) * step),
    count: 0,
    overflow: false,
    x0: i / units,
    x1: (i + 1) / units,
  }));
  for (
    let k = lowerBound(sorted, lo), end = upperBound(sorted, hi);
    k < end;
    k++
  )
    bars[Math.min(n - 1, Math.floor((sorted[k] - lo) / step))].count += 1;
  // Values below a fixed domain fold into the first bar.
  bars[0].count += lowerBound(sorted, lo);
  const top = Math.max(hi, d.max);
  if (overflowCount > 0)
    bars.push({
      start: hi,
      end: top,
      count: overflowCount,
      overflow: true,
      x0: (n + 0.7) / units,
      x1: 1,
    });
  const mainEnd = n / units;
  const overflowStart = (n + 0.7) / units;
  const pos = (v: number) => {
    if (v <= hi) return Math.max(0, ((v - lo) / (hi - lo)) * mainEnd);
    if (overflowCount <= 0 || top <= hi) return mainEnd;
    return Math.min(
      1,
      overflowStart + ((v - hi) / (top - hi)) * (1 - overflowStart),
    );
  };
  const inv = (x: number) => {
    if (x <= mainEnd) return lo + (x / mainEnd) * (hi - lo);
    if (x < overflowStart || overflowCount <= 0) return hi;
    return hi + ((x - overflowStart) / (1 - overflowStart)) * (top - hi);
  };
  return { bars, lo, hi, top, pos, inv };
}

/** Bin a comparison into the main bars' edges. */
function binCompare(compare: number[] | LatencyBucket[], bars: Bar[]) {
  const counts = new Array<number>(bars.length).fill(0);
  if (!bars.length) return { counts, total: 0 };
  const find = (v: number) => {
    let lo = 0;
    let hi = bars.length - 1;
    while (lo < hi) {
      const mid = (lo + hi + 1) >> 1;
      if (bars[mid].start <= v) lo = mid;
      else hi = mid - 1;
    }
    return lo;
  };
  let total = 0;
  for (const item of compare as (number | LatencyBucket)[]) {
    if (typeof item === "number") {
      if (!Number.isFinite(item)) continue;
      counts[find(item)] += 1;
      total += 1;
    } else if (Number.isFinite(item.count)) {
      counts[find((item.start + item.end) / 2)] += item.count;
      total += item.count;
    }
  }
  return { counts, total };
}

/* ------------------------------------------------------------------------ */
/* Hooks                                                                     */
/* ------------------------------------------------------------------------ */

function useReducedMotion() {
  return React.useSyncExternalStore(
    (onChange) => {
      const query = window.matchMedia("(prefers-reduced-motion: reduce)");
      query.addEventListener("change", onChange);
      return () => query.removeEventListener("change", onChange);
    },
    () => window.matchMedia("(prefers-reduced-motion: reduce)").matches,
    () => false,
  );
}

function useControllable<T>(
  value: T | undefined,
  defaultValue: T,
  onChange?: (value: T) => void,
) {
  const [inner, setInner] = React.useState(defaultValue);
  const controlled = value !== undefined;
  const set = React.useCallback(
    (next: T) => {
      if (!controlled) setInner(next);
      onChange?.(next);
    },
    [controlled, onChange],
  );
  return [controlled ? value : inner, set] as const;
}

const focusRing =
  "outline-none focus-visible:ring-2 focus-visible:ring-ring/50";
const percentileName = (p: number) => `p${tidy(p)}`;

/* ------------------------------------------------------------------------ */
/* LatencyHistogram                                                          */
/* ------------------------------------------------------------------------ */

/**
 * A latency distribution: bucketed requests with percentile markers, an SLO tail,
 * an optional comparison, and brushing to measure any range.
 */
export function LatencyHistogram({
  values,
  buckets,
  compare,
  compareLabel = "Previous",
  seriesLabel = "Current",
  compareStyle = "step",
  percentiles = [50, 90, 95, 99],
  threshold,
  thresholdLabel = "SLO",
  scale: scaleProp,
  defaultScale = "linear",
  onScaleChange,
  showScaleToggle = true,
  range: rangeProp,
  defaultRange = null,
  onRangeChange,
  title,
  description,
  actions,
  unit = "ms",
  valueFormatter,
  bucketCount = 40,
  domain,
  height,
  colors: colorsProp,
  renderTooltip,
  showSummary = true,
  className,
  ...props
}: LatencyHistogramProps) {
  const id = React.useId();
  const reduced = useReducedMotion();
  const format = React.useMemo(
    () => valueFormatter ?? makeFormatter(unit),
    [valueFormatter, unit],
  );
  const formatTick = React.useMemo(
    () => valueFormatter ?? makeTickFormatter(unit),
    [valueFormatter, unit],
  );
  const colors: LatencyHistogramColors = {
    bar: "var(--color-chart-1)",
    compare: "var(--color-muted-foreground)",
    threshold: "var(--color-destructive)",
    marker: "var(--color-foreground)",
    selection: "var(--color-primary)",
    ...colorsProp,
  };
  const [scale, setScale] = useControllable(
    scaleProp,
    defaultScale,
    onScaleChange,
  );
  const [range, setRange] = useControllable<LatencyRange | null>(
    rangeProp,
    defaultRange,
    onRangeChange,
  );
  const hasThreshold = threshold != null && Number.isFinite(threshold);

  const dist = React.useMemo(
    () => distributionOf(values, buckets),
    [values, buckets],
  );
  const sortedPercentiles = React.useMemo(
    () =>
      [...new Set(percentiles.filter((p) => p > 0 && p < 100))].sort(
        (a, b) => a - b,
      ),
    [percentiles],
  );
  const empty = dist.total === 0;
  const marks = React.useMemo(
    () =>
      dist.total === 0
        ? []
        : sortedPercentiles.map((p) => ({ p, value: quantile(dist, p / 100) })),
    [dist, sortedPercentiles],
  );

  // Linear charts end just past the slow tail (and the SLO); the rest lands in an overflow bar.
  const reach = Math.max(
    quantile(dist, 0.995),
    (marks[marks.length - 1]?.value ?? 0) * 1.04,
    hasThreshold ? threshold! * 1.12 : 0,
  );
  const layout = React.useMemo(
    () => layoutOf(dist, scale, bucketCount, reach, domain),
    [dist, scale, bucketCount, reach, domain],
  );
  const { bars, pos, inv } = layout;

  const comparison = React.useMemo(() => {
    if (!compare?.length) return null;
    const { counts, total } = binCompare(compare, bars);
    const percentilesOf = (() => {
      if (typeof compare[0] === "number") {
        const d = distributionOf(compare as number[]);
        return sortedPercentiles.map((p) => quantile(d, p / 100));
      }
      const d = distributionOf(undefined, compare as LatencyBucket[]);
      return sortedPercentiles.map((p) => quantile(d, p / 100));
    })();
    const factor = total ? dist.total / total : 0;
    return {
      counts,
      total,
      scaled: counts.map((c) => c * factor),
      percentiles: percentilesOf,
    };
  }, [compare, bars, dist.total, sortedPercentiles]);

  const maxCount = Math.max(
    1,
    ...bars.map((b) => b.count),
    ...(comparison?.scaled ?? [0]),
  );
  // The tallest bar fills the plot; gridlines sit at round counts below it.
  const yMax = maxCount * 1.06;
  const yStep = niceStep(maxCount / 3.2);
  const yTicks = Array.from(
    { length: Math.floor(yMax / yStep + 1e-9) + 1 },
    (_, i) => tidy(i * yStep),
  );

  const over = hasThreshold ? countAbove(dist, threshold!) : 0;
  const overShare = dist.total ? over / dist.total : 0;
  const thresholdX = hasThreshold ? pos(threshold!) : 1;

  const cumulative = React.useMemo(() => {
    let running = 0;
    return bars.map((b) => (running += b.count) / (dist.total || 1));
  }, [bars, dist.total]);

  const bucketAt = (index: number): LatencyHistogramBucket => {
    const b = bars[index];
    return {
      index,
      start: b.start,
      end: b.end,
      count: b.count,
      share: dist.total ? b.count / dist.total : 0,
      cumulative: cumulative[index] ?? 0,
      compare: comparison ? comparison.counts[index] : undefined,
      compareShare: comparison?.total
        ? comparison.counts[index] / comparison.total
        : undefined,
      overflow: b.overflow,
      overThreshold: hasThreshold && b.start >= threshold!,
    };
  };

  /* -------------------------------------------------------------- layout */

  const plotRef = React.useRef<HTMLDivElement>(null);
  const [width, setWidth] = React.useState(0);
  React.useLayoutEffect(() => {
    const el = plotRef.current;
    if (!el) return;
    const measure = () => setWidth(el.clientWidth);
    measure();
    const observer = new ResizeObserver(measure);
    observer.observe(el);
    return () => observer.disconnect();
  }, []);
  const W = width || 560;

  // Percentile chips stack into lanes only when they would collide.
  // With the summary on show, crowded chips drop their values, which the summary repeats.
  const chips = React.useMemo(() => {
    const place = (withValue: boolean) => {
      const lanes: number[] = [];
      return marks.map((mark) => {
        const text = withValue
          ? `${percentileName(mark.p)} ${format(mark.value)}`
          : percentileName(mark.p);
        const w = text.length * 6.1 + 14;
        const x = pos(mark.value) * W;
        const left = Math.min(Math.max(0, x - w / 2), Math.max(0, W - w));
        let lane = lanes.findIndex((right) => right + 4 <= left);
        if (lane < 0) lane = lanes.push(0) - 1;
        lanes[lane] = left + w;
        return { ...mark, x, left, lane, w, withValue };
      });
    };
    const full = place(true);
    if (!showSummary || full.every((chip) => chip.lane === 0)) return full;
    return place(false);
  }, [marks, pos, W, format, showSummary]);
  const laneCount = Math.max(1, ...chips.map((chip) => chip.lane + 1));
  const chipTop = laneCount * 20 + 6;
  // Without a fixed height the plot follows the card width, shorter on narrow cards.
  const H = Math.max(
    80,
    height ?? Math.round(Math.min(220, Math.max(140, W * 0.34))),
  );
  const barsHeight = H - chipTop;

  const xTicks = React.useMemo(() => {
    const ticks: number[] = [];
    if (empty) return ticks;
    if (scale === "log" || dist.buckets) {
      if (scale === "log") {
        const lo = layout.lo;
        const hi = layout.hi;
        const candidates: number[] = [];
        for (
          let e = Math.floor(Math.log10(lo));
          e <= Math.ceil(Math.log10(hi));
          e++
        )
          for (const m of [1, 2, 5]) {
            const v = tidy(m * 10 ** e);
            if (v >= lo * 0.999 && v <= hi * 1.001) candidates.push(v);
          }
        // Thin out 2s and then 5s until labels have room.
        for (const keep of [[1, 2, 5], [1, 5], [1]]) {
          const list = candidates.filter((v) =>
            keep.includes(
              Math.round(v / 10 ** Math.floor(Math.log10(v) + 1e-9)),
            ),
          );
          let ok = true;
          for (let i = 1; i < list.length; i++)
            if ((pos(list[i]) - pos(list[i - 1])) * W < 44) ok = false;
          if (ok || keep.length === 1) return list;
        }
      }
    }
    const lo = layout.lo;
    const hi = layout.hi;
    const step = niceStep((hi - lo) / Math.max(2, Math.floor(W / 76)));
    for (
      let v = Math.ceil(lo / step - 1e-9) * step;
      v <= hi + step * 1e-6;
      v += step
    )
      ticks.push(tidy(v));
    return ticks;
  }, [scale, dist.buckets, layout, pos, W, empty]);

  /* ----------------------------------------------------------- animation */

  // Bars grow in on mount and whenever the bucket layout changes; data updates tween.
  // Keyed on scale and bar count only, so live data with a drifting tail tweens instead of regrowing.
  const structure = `${scale}:${bars.length}`;
  const [grown, setGrown] = React.useState<string | null>(null);
  const [intro, setIntro] = React.useState(true);
  React.useEffect(() => {
    if (reduced) {
      setGrown(structure);
      setIntro(false);
      return;
    }
    setIntro(true);
    let frame = requestAnimationFrame(() => {
      frame = requestAnimationFrame(() => setGrown(structure));
    });
    const timer = window.setTimeout(
      () => setIntro(false),
      900 + bars.length * 9,
    );
    return () => {
      cancelAnimationFrame(frame);
      window.clearTimeout(timer);
    };
  }, [structure, reduced, bars.length]);
  const isGrown = grown === structure;

  /* --------------------------------------------------------- interaction */

  const [hover, setHover] = React.useState<number | null>(null);
  const [active, setActive] = React.useState<number | null>(null);
  const [brush, setBrush] = React.useState<LatencyRange | null>(null);
  const drag = React.useRef<{
    x: number;
    value: number;
    moved: boolean;
  } | null>(null);
  const anchor = React.useRef<number | null>(null);

  const xToFraction = (clientX: number) => {
    const rect = plotRef.current!.getBoundingClientRect();
    return Math.min(1, Math.max(0, (clientX - rect.left) / (rect.width || 1)));
  };
  const barAt = (x: number) => {
    for (let i = 0; i < bars.length; i++)
      if (x >= bars[i].x0 && x <= bars[i].x1) return i;
    // In a gap: the nearest bar.
    let best = -1;
    let distance = Infinity;
    bars.forEach((b, i) => {
      const dd = Math.min(Math.abs(x - b.x0), Math.abs(x - b.x1));
      if (dd < distance) {
        distance = dd;
        best = i;
      }
    });
    return best < 0 ? null : best;
  };

  const clampRange = (a: number, b: number): LatencyRange => [
    Math.min(a, b),
    Math.max(a, b),
  ];

  const onPointerDown = (event: React.PointerEvent<HTMLDivElement>) => {
    if (event.button !== 0 || !bars.length) return;
    const x = xToFraction(event.clientX);
    drag.current = { x: event.clientX, value: inv(x), moved: false };
    event.currentTarget.setPointerCapture(event.pointerId);
  };
  const onPointerMove = (event: React.PointerEvent<HTMLDivElement>) => {
    if (!bars.length) return;
    const x = xToFraction(event.clientX);
    const d = drag.current;
    if (d) {
      if (!d.moved && Math.abs(event.clientX - d.x) > 3) d.moved = true;
      if (d.moved) {
        setBrush(clampRange(d.value, inv(x)));
        setHover(null);
        return;
      }
    }
    setHover(barAt(x));
  };
  const onPointerUp = (event: React.PointerEvent<HTMLDivElement>) => {
    const d = drag.current;
    drag.current = null;
    if (!d) return;
    if (d.moved) {
      const next = clampRange(d.value, inv(xToFraction(event.clientX)));
      setBrush(null);
      setRange(next[1] - next[0] > 0 ? next : null);
    } else if (range) setRange(null);
  };

  const onKeyDown = (event: React.KeyboardEvent<HTMLDivElement>) => {
    if (!bars.length) return;
    const current = active ?? -1;
    const step = (delta: number) =>
      Math.min(
        bars.length - 1,
        Math.max(
          0,
          current < 0 ? (delta > 0 ? 0 : bars.length - 1) : current + delta,
        ),
      );
    let next: number | null = null;
    if (event.key === "ArrowRight") next = step(1);
    else if (event.key === "ArrowLeft") next = step(-1);
    else if (event.key === "Home") next = 0;
    else if (event.key === "End") next = bars.length - 1;
    else if (event.key === "Enter" && current >= 0) {
      setRange([bars[current].start, bars[current].end]);
      event.preventDefault();
      return;
    } else if (event.key === "Escape") {
      if (range) setRange(null);
      else setActive(null);
      anchor.current = null;
      event.preventDefault();
      return;
    }
    if (next == null) return;
    event.preventDefault();
    if (event.shiftKey) {
      if (anchor.current == null) anchor.current = current < 0 ? next : current;
      const a = Math.min(anchor.current, next);
      const b = Math.max(anchor.current, next);
      setRange([bars[a].start, bars[b].end]);
    } else anchor.current = null;
    setActive(next);
  };

  const shownRange = brush ?? range;
  const rangeCount = shownRange
    ? countBetween(dist, shownRange[0], shownRange[1])
    : 0;
  const rangeShare = dist.total ? rangeCount / dist.total : 0;
  const focusIndex = hover ?? active;
  const focusBucket =
    focusIndex != null && bars[focusIndex] ? bucketAt(focusIndex) : null;

  /* -------------------------------------------------------------- render */

  const describeBucket = (b: LatencyHistogramBucket) =>
    `${b.overflow ? `${format(b.start)} and above` : `${format(b.start)} to ${format(b.end)}`}: ${whole.format(Math.round(b.count))} requests, ${percentLabel(b.share)}`;
  const summaryText = [
    `${whole.format(Math.round(dist.total))} requests.`,
    marks
      .map((mark) => `${percentileName(mark.p)} ${format(mark.value)}`)
      .join(", ") + ".",
    hasThreshold
      ? `${percentLabel(overShare)} over the ${thresholdLabel} of ${format(threshold!)}.`
      : "",
  ]
    .filter(Boolean)
    .join(" ");
  const hasHeader =
    title != null || description != null || actions != null || showScaleToggle;
  const transition = intro
    ? "transform 760ms cubic-bezier(.16,1,.3,1)"
    : "transform 520ms cubic-bezier(.16,1,.3,1)";
  const barFill = (color: string) =>
    `color-mix(in oklab, ${color} 72%, var(--color-card))`;

  // The comparison as one stepped path across the bars.
  const comparePath = React.useMemo(() => {
    if (!comparison || compareStyle !== "step") return null;
    let path = "";
    let previousEnd = -1;
    bars.forEach((b, i) => {
      const y = 100 - (comparison.scaled[i] / yMax) * 100;
      const x0 = b.x0 * 1000;
      const x1 = b.x1 * 1000;
      if (Math.abs(x0 - previousEnd) > 0.5)
        path += `${path ? "V100" : ""}M${x0.toFixed(2)} 100`;
      path += `V${y.toFixed(2)}H${x1.toFixed(2)}`;
      previousEnd = x1;
    });
    return path + "V100";
  }, [comparison, compareStyle, bars, yMax]);

  return (
    <div
      data-slot="latency-histogram"
      data-scale={scale}
      data-brushing={brush ? true : undefined}
      className={cn(
        "@container/histogram flex min-w-0 flex-col rounded-xl border bg-card text-card-foreground shadow-xs",
        className,
      )}
      {...props}
    >
      {hasHeader && (
        <div className="flex items-start gap-3 px-4 pt-3.5">
          <div className="min-w-0 flex-1 space-y-1">
            {title != null && (
              <h3 className="truncate text-sm leading-6 font-semibold tracking-tight">
                {title}
              </h3>
            )}
            {description != null && (
              <p
                id={`${id}-description`}
                className="text-xs text-muted-foreground"
              >
                {description}
              </p>
            )}
          </div>
          <div className="flex shrink-0 items-center gap-2">
            {actions}
            {showScaleToggle && (
              <div
                role="group"
                aria-label="X axis scale"
                data-slot="histogram-scale-toggle"
                className="inline-flex h-7 items-center rounded-md border bg-muted/40 p-0.5"
              >
                {(["linear", "log"] as const).map((option) => (
                  <button
                    key={option}
                    type="button"
                    aria-pressed={scale === option}
                    onClick={() => setScale(option)}
                    className={cn(
                      "h-full rounded-[5px] px-2 text-xs font-medium text-muted-foreground transition-colors hover:text-foreground aria-pressed:bg-card aria-pressed:text-foreground aria-pressed:shadow-xs motion-reduce:transition-none",
                      focusRing,
                    )}
                  >
                    {option === "linear" ? "Linear" : "Log"}
                  </button>
                ))}
              </div>
            )}
          </div>
        </div>
      )}

      {showSummary && (marks.length > 0 || hasThreshold) && (
        // Narrow cards trade the stat grid for one line, so the distribution stays in view.
        <dl
          data-slot="histogram-summary-compact"
          className={cn(
            "mx-4 flex flex-wrap items-baseline gap-x-3 gap-y-1 text-xs @md/histogram:hidden",
            hasHeader ? "mt-1.5" : "mt-4",
          )}
        >
          {marks.map((mark, i) => {
            const previous = comparison?.percentiles[i];
            const delta = previous != null ? mark.value - previous : null;
            const hot = hasThreshold && mark.value > threshold!;
            return (
              <div key={mark.p} className="flex items-baseline gap-1">
                <dt className="font-mono text-[11px] text-muted-foreground">
                  {percentileName(mark.p)}
                </dt>
                <dd
                  className={cn(
                    "font-semibold tabular-nums",
                    hot && "text-destructive",
                  )}
                >
                  {format(mark.value)}
                </dd>
                {delta != null && Math.abs(delta) > 0 && (
                  <dd
                    className={cn(
                      "font-mono text-[10px] tabular-nums",
                      delta > 0
                        ? "text-destructive"
                        : "text-emerald-700 dark:text-emerald-400",
                    )}
                  >
                    {delta > 0 ? "▲" : "▼"}
                    {format(Math.abs(delta))}
                  </dd>
                )}
              </div>
            );
          })}
          {hasThreshold && (
            <div className="flex items-baseline gap-1">
              <dd
                className={cn(
                  "font-semibold tabular-nums",
                  over > 0
                    ? "text-destructive"
                    : "text-emerald-700 dark:text-emerald-400",
                )}
              >
                {percentLabel(overShare)}
              </dd>
              <dt className="text-[11px] text-muted-foreground">
                over {thresholdLabel}
              </dt>
            </div>
          )}
        </dl>
      )}

      {showSummary && (marks.length > 0 || hasThreshold) && (
        <dl
          data-slot="histogram-summary"
          className={cn(
            "mx-4 hidden overflow-hidden rounded-lg bg-muted/50 @md/histogram:grid dark:bg-muted/30",
            hasHeader ? "mt-3" : "mt-4",
          )}
          style={{
            gridTemplateColumns: `repeat(${marks.length + (hasThreshold ? 1 : 0)}, minmax(0, 1fr))`,
          }}
        >
          {marks.map((mark, i) => {
            const previous = comparison?.percentiles[i];
            const delta = previous != null ? mark.value - previous : null;
            const hot = hasThreshold && mark.value > threshold!;
            return (
              <div
                key={mark.p}
                className="min-w-0 border-s border-border/60 px-2 py-1.5 first:border-s-0 @sm/histogram:px-2.5 @md/histogram:px-3 @md/histogram:py-2"
              >
                <dt className="font-mono text-[11px] leading-4 text-muted-foreground">
                  {percentileName(mark.p)}
                </dt>
                <dd
                  className={cn(
                    "truncate text-sm leading-6 font-semibold tracking-tight tabular-nums @sm/histogram:text-base @md/histogram:text-lg",
                    hot && "text-destructive",
                  )}
                >
                  {format(mark.value)}
                </dd>
                {delta != null && Math.abs(delta) > 0 && (
                  <dd
                    className={cn(
                      "truncate font-mono text-[11px] leading-4 whitespace-nowrap tabular-nums",
                      delta > 0
                        ? "text-destructive"
                        : "text-emerald-700 dark:text-emerald-400",
                    )}
                    title={`${compareLabel}: ${format(previous!)}`}
                  >
                    {delta > 0 ? "▲" : "▼"} {format(Math.abs(delta))}
                  </dd>
                )}
              </div>
            );
          })}
          {hasThreshold && (
            <div className="min-w-0 border-s border-border/60 px-2 py-1.5 first:border-s-0 @sm/histogram:px-2.5 @md/histogram:px-3 @md/histogram:py-2">
              <dt className="truncate text-[11px] leading-4 text-muted-foreground">
                Over {thresholdLabel}
              </dt>
              <dd
                className={cn(
                  "truncate text-sm leading-6 font-semibold tracking-tight tabular-nums @sm/histogram:text-base @md/histogram:text-lg",
                  over > 0
                    ? "text-destructive"
                    : "text-emerald-700 dark:text-emerald-400",
                )}
              >
                {percentLabel(overShare)}
              </dd>
              <dd className="truncate font-mono text-[11px] leading-4 text-muted-foreground tabular-nums">
                {whole.format(Math.round(over))}
                <span className="hidden @sm/histogram:inline">
                  {" "}
                  of {compact.format(dist.total).replace("K", "k")}
                </span>
              </dd>
            </div>
          )}
        </dl>
      )}

      <div className="mt-3 flex px-4 @md/histogram:mt-4">
        <div className="min-w-0 flex-1">
          <div
            ref={plotRef}
            data-slot="histogram-plot"
            role="group"
            aria-roledescription="histogram"
            aria-label={`${typeof title === "string" ? `${title}. ` : ""}${summaryText} Use the arrow keys to read buckets, Shift to select a range.`}
            aria-describedby={
              description != null ? `${id}-description` : undefined
            }
            tabIndex={0}
            onPointerDown={onPointerDown}
            onPointerMove={onPointerMove}
            onPointerUp={onPointerUp}
            onPointerCancel={() => {
              drag.current = null;
              setBrush(null);
            }}
            onPointerLeave={() => {
              if (!drag.current) setHover(null);
            }}
            onKeyDown={onKeyDown}
            onBlur={() => setActive(null)}
            className={cn(
              "relative cursor-crosshair touch-pan-y rounded-sm select-none",
              "outline-none focus-visible:ring-2 focus-visible:ring-ring/50 focus-visible:ring-offset-4 focus-visible:ring-offset-card",
            )}
            style={{ height: H }}
          >
            {empty && (
              <p className="absolute inset-0 grid place-items-center text-xs text-muted-foreground">
                No requests to show.
              </p>
            )}

            {/* Value grid */}
            <div
              aria-hidden="true"
              className="pointer-events-none absolute inset-x-0 bottom-0"
              style={{ top: chipTop }}
            >
              {yTicks.map((tick) => (
                <span
                  key={tick}
                  className={cn(
                    "absolute inset-x-0 h-px",
                    tick === 0 ? "bg-border" : "bg-border/55",
                  )}
                  style={{ bottom: `${(tick / yMax) * 100}%` }}
                />
              ))}
            </div>

            {/* SLO tail */}
            {hasThreshold && thresholdX < 1 && (
              <div
                aria-hidden="true"
                data-slot="histogram-threshold-region"
                className="pointer-events-none absolute inset-y-0 right-0"
                style={{
                  left: `${thresholdX * 100}%`,
                  background: `linear-gradient(to bottom, color-mix(in oklab, ${colors.threshold} 9%, transparent), color-mix(in oklab, ${colors.threshold} 3%, transparent)), repeating-linear-gradient(-45deg, color-mix(in oklab, ${colors.threshold} 9%, transparent) 0 1px, transparent 1px 6px)`,
                }}
              />
            )}

            {/* Bars */}
            <div
              aria-hidden="true"
              className="pointer-events-none absolute inset-x-0 bottom-0"
              style={{ top: chipTop }}
            >
              {comparison &&
                compareStyle === "outline" &&
                bars.map((b, i) => (
                  <span
                    key={`c-${structure}-${i}`}
                    className="absolute bottom-0 origin-bottom rounded-t-[2px] border border-b-0 border-dashed"
                    style={{
                      left: `calc(${b.x0 * 100}% + 1px)`,
                      width: `calc(${(b.x1 - b.x0) * 100}% - 2px)`,
                      height: `${(comparison.scaled[i] / yMax) * 100}%`,
                      borderColor: `color-mix(in oklab, ${colors.compare} 70%, transparent)`,
                      transform: `scaleY(${isGrown ? 1 : 0})`,
                      transition: reduced ? undefined : transition,
                    }}
                  />
                ))}
              {bars.map((b, i) => {
                const h = b.count / yMax;
                const inRange = shownRange
                  ? b.end > shownRange[0] && b.start < shownRange[1]
                  : true;
                const dim =
                  (focusIndex != null && focusIndex !== i) || !inRange;
                const split =
                  hasThreshold && b.start < threshold! && b.end > threshold!;
                const hot = hasThreshold && b.start >= threshold!;
                const color = hot ? colors.threshold : colors.bar;
                const cut = split
                  ? ((thresholdX - b.x0) / (b.x1 - b.x0)) * 100
                  : 0;
                const fill = split
                  ? `linear-gradient(to right, ${barFill(colors.bar)} ${cut}%, ${barFill(colors.threshold)} ${cut}%)`
                  : barFill(color);
                const cap = split
                  ? `linear-gradient(to right, ${colors.bar} ${cut}%, ${colors.threshold} ${cut}%)`
                  : color;
                return (
                  <span
                    key={`${structure}-${i}`}
                    data-slot="histogram-bar"
                    data-index={i}
                    data-over={hot || undefined}
                    data-overflow={b.overflow || undefined}
                    className={cn(
                      "absolute inset-y-0 transition-opacity duration-200 motion-reduce:transition-none",
                      dim &&
                        (shownRange && !inRange ? "opacity-30" : "opacity-55"),
                    )}
                    style={{
                      left: `${b.x0 * 100}%`,
                      width: `${(b.x1 - b.x0) * 100}%`,
                    }}
                  >
                    <span
                      className="absolute inset-x-px bottom-0 h-full origin-bottom @lg/histogram:inset-x-[1.5px]"
                      style={{
                        transform: `scaleY(${isGrown ? h : 0})`,
                        transition: reduced ? undefined : transition,
                        transitionDelay:
                          intro && !reduced ? `${i * 9}ms` : undefined,
                      }}
                    >
                      <span
                        className={cn(
                          "absolute inset-0 rounded-t-[2px]",
                          b.overflow &&
                            "[mask-image:repeating-linear-gradient(-45deg,#000_0_3px,rgb(0_0_0/0.55)_3px_5px)]",
                        )}
                        style={{ background: fill }}
                      />
                    </span>
                    {/* The cap is drawn unscaled so it stays a crisp line at any height. */}
                    {b.count > 0 && (
                      <span
                        className="absolute inset-x-px h-[1.5px] rounded-full @lg/histogram:inset-x-[1.5px]"
                        style={{
                          bottom: `calc(${(isGrown ? h : 0) * 100}% - 1px)`,
                          background: cap,
                          transition: reduced
                            ? undefined
                            : intro
                              ? "bottom 760ms cubic-bezier(.16,1,.3,1)"
                              : "bottom 520ms cubic-bezier(.16,1,.3,1)",
                          transitionDelay:
                            intro && !reduced ? `${i * 9}ms` : undefined,
                        }}
                      />
                    )}
                  </span>
                );
              })}
              {comparePath && (
                <svg
                  data-slot="histogram-compare"
                  className="absolute inset-0 size-full origin-bottom overflow-visible"
                  viewBox="0 0 1000 100"
                  preserveAspectRatio="none"
                  style={{
                    transform: `scaleY(${isGrown ? 1 : 0})`,
                    transition: reduced ? undefined : transition,
                  }}
                >
                  <path
                    d={comparePath}
                    fill="none"
                    stroke={colors.compare}
                    strokeWidth={1.5}
                    strokeDasharray="4 3"
                    strokeLinejoin="round"
                    vectorEffect="non-scaling-stroke"
                    opacity={0.85}
                  />
                </svg>
              )}
            </div>

            {/* Selection */}
            {shownRange && (
              <div
                aria-hidden="true"
                data-slot="histogram-selection"
                className="pointer-events-none absolute inset-y-0"
                style={{
                  left: `${pos(shownRange[0]) * 100}%`,
                  width: `${Math.max(0, pos(shownRange[1]) - pos(shownRange[0])) * 100}%`,
                  background: `color-mix(in oklab, ${colors.selection} 9%, transparent)`,
                  boxShadow: `inset 1.5px 0 0 ${colors.selection}, inset -1.5px 0 0 ${colors.selection}`,
                }}
              >
                <span
                  className="absolute top-1/2 -left-[3px] h-5 w-1.5 -translate-y-1/2 rounded-full border border-card"
                  style={{ background: colors.selection }}
                />
                <span
                  className="absolute top-1/2 -right-[3px] h-5 w-1.5 -translate-y-1/2 rounded-full border border-card"
                  style={{ background: colors.selection }}
                />
              </div>
            )}

            {/* Threshold line */}
            {hasThreshold && thresholdX < 1 && (
              <div
                aria-hidden="true"
                data-slot="histogram-threshold"
                className="pointer-events-none absolute bottom-0"
                style={{ left: `${thresholdX * 100}%`, top: chipTop - 2 }}
              >
                <span
                  className="absolute inset-y-0 w-0 border-l-[1.5px] border-dashed"
                  style={{ borderColor: colors.threshold }}
                />
                <span
                  className="absolute top-1 left-1 rounded-sm bg-card/85 px-1 font-mono text-[10px] leading-4 font-medium whitespace-nowrap"
                  style={{ color: colors.threshold }}
                >
                  {thresholdLabel} {format(threshold!)}
                </span>
              </div>
            )}

            {/* Percentile markers */}
            {chips.map((chip) => {
              const hot = hasThreshold && chip.value > threshold!;
              const color = hot ? colors.threshold : colors.marker;
              return (
                <div
                  key={chip.p}
                  data-slot="histogram-marker"
                  data-percentile={chip.p}
                  aria-hidden="true"
                  className="pointer-events-none"
                >
                  <span
                    className="absolute bottom-0 w-0 border-l border-dashed opacity-55"
                    style={{
                      left: chip.x,
                      top: chip.lane * 20 + 18,
                      borderColor: color,
                    }}
                  />
                  <span
                    className={cn(
                      "absolute flex h-[18px] items-center gap-1 rounded-[5px] border bg-card px-1.5 font-mono text-[10px] leading-none whitespace-nowrap shadow-xs tabular-nums",
                      intro &&
                        !reduced &&
                        "motion-safe:animate-[histogram-rise_.5s_.35s_cubic-bezier(.16,1,.3,1)_both]",
                    )}
                    style={{
                      left: chip.left,
                      top: chip.lane * 20,
                      borderColor: `color-mix(in oklab, ${color} 28%, var(--color-border))`,
                    }}
                  >
                    <span className="text-muted-foreground">
                      {percentileName(chip.p)}
                    </span>
                    {chip.withValue && (
                      <span className="font-semibold" style={{ color }}>
                        {format(chip.value)}
                      </span>
                    )}
                  </span>
                </div>
              );
            })}

            {/* Tooltip */}
            {focusBucket && !brush && (
              <div
                data-slot="histogram-tooltip"
                aria-hidden="true"
                className="pointer-events-none absolute z-10 min-w-36 rounded-lg border bg-popover px-2.5 py-2 text-xs text-popover-foreground shadow-md"
                style={{
                  top: chipTop + 4,
                  // Sit beside the bar, on the side with more room, so it never hides it.
                  ...(bars[focusBucket.index].x0 + bars[focusBucket.index].x1 <
                  1
                    ? { left: bars[focusBucket.index].x1 * W + 8 }
                    : { right: W - bars[focusBucket.index].x0 * W + 8 }),
                }}
              >
                {renderTooltip ? (
                  renderTooltip(focusBucket)
                ) : (
                  <>
                    <p className="font-mono text-[11px] text-muted-foreground tabular-nums">
                      {focusBucket.overflow
                        ? `≥ ${format(focusBucket.start)}`
                        : `${format(focusBucket.start)} – ${format(focusBucket.end)}`}
                    </p>
                    <p className="mt-0.5 flex items-baseline gap-1.5">
                      <span className="text-sm font-semibold tabular-nums">
                        {whole.format(Math.round(focusBucket.count))}
                      </span>
                      <span className="text-muted-foreground tabular-nums">
                        {percentLabel(focusBucket.share)}
                      </span>
                    </p>
                    <p className="mt-1 text-[11px] text-muted-foreground tabular-nums">
                      {percentLabel(focusBucket.cumulative)} at or faster
                    </p>
                    {focusBucket.compare != null && comparison && (
                      <p className="mt-1.5 flex items-center gap-1.5 border-t border-dashed pt-1.5 text-[11px] text-muted-foreground tabular-nums">
                        <span
                          aria-hidden="true"
                          className="w-3 border-t-[1.5px] border-dashed"
                          style={{ borderColor: colors.compare }}
                        />
                        {compareLabel}
                        <span className="ml-auto font-medium text-foreground">
                          {whole.format(Math.round(focusBucket.compare))}
                        </span>
                        <span>
                          {percentLabel(focusBucket.compareShare ?? 0)}
                        </span>
                      </p>
                    )}
                  </>
                )}
              </div>
            )}
          </div>

          {/* Latency axis */}
          <div
            aria-hidden="true"
            className="relative mt-1.5 h-4 font-mono text-[10px] leading-4 text-muted-foreground tabular-nums"
          >
            {xTicks.map((tick, i) => {
              const x = pos(tick);
              if (x > layout.pos(layout.hi) + 1e-6) return null;
              return (
                <span
                  key={tick}
                  className={cn(
                    "absolute whitespace-nowrap",
                    i === 0 && x < 0.02
                      ? ""
                      : x > 0.97
                        ? "-translate-x-full"
                        : "-translate-x-1/2",
                  )}
                  style={{ left: `${x * 100}%` }}
                >
                  {formatTick(tick)}
                </span>
              );
            })}
            {bars[bars.length - 1]?.overflow && (
              <span
                className="absolute -translate-x-1/2 whitespace-nowrap"
                style={{
                  left: `${((bars[bars.length - 1].x0 + 1) / 2) * 100}%`,
                }}
              >
                +
              </span>
            )}
          </div>
        </div>
        <div
          aria-hidden="true"
          className="relative ml-2 w-8 shrink-0"
          style={{ height: H }}
        >
          {yTicks.map((tick) => (
            <span
              key={tick}
              className="absolute right-0 translate-y-1/2 font-mono text-[10px] leading-none text-muted-foreground tabular-nums"
              style={{ bottom: `${(tick / yMax) * (barsHeight / H) * 100}%` }}
            >
              {tick === 0 ? "0" : compact.format(tick).replace("K", "k")}
            </span>
          ))}
        </div>
      </div>

      <div
        data-slot="histogram-footer"
        className="mt-3 flex min-h-11 flex-wrap items-center justify-between gap-x-4 gap-y-2 border-t px-4 py-2"
      >
        <div
          data-slot="histogram-status"
          className="flex min-w-0 flex-wrap items-center gap-x-2 gap-y-0.5 text-xs"
        >
          {shownRange ? (
            <>
              <span
                className="rounded-[4px] px-1.5 py-px font-mono text-[11px] tabular-nums"
                style={{
                  background: `color-mix(in oklab, ${colors.selection} 10%, transparent)`,
                  color: colors.selection,
                }}
              >
                {format(shownRange[0])} – {format(shownRange[1])}
              </span>
              <span className="font-semibold tabular-nums">
                {percentLabel(rangeShare)}
              </span>
              <span className="text-muted-foreground tabular-nums">
                {whole.format(Math.round(rangeCount))} of{" "}
                {whole.format(Math.round(dist.total))} requests
              </span>
              {!brush && (
                <button
                  type="button"
                  onClick={() => setRange(null)}
                  className={cn(
                    "inline-flex size-5 items-center justify-center rounded text-muted-foreground hover:bg-muted hover:text-foreground",
                    focusRing,
                  )}
                >
                  <X className="size-3.5" aria-hidden="true" />
                  <span className="sr-only">Clear selection</span>
                </button>
              )}
            </>
          ) : (
            <span className="text-muted-foreground tabular-nums">
              <span className="font-medium text-foreground">
                {whole.format(Math.round(dist.total))}
              </span>{" "}
              requests
              <span aria-hidden="true"> · </span>mean{" "}
              <span className="font-medium text-foreground">
                {format(dist.mean)}
              </span>
              <span className="hidden @md/histogram:inline">
                <span aria-hidden="true"> · </span>max{" "}
                <span className="font-medium text-foreground">
                  {format(dist.max)}
                </span>
              </span>
              <span className="hidden @lg/histogram:inline">
                {" "}
                · drag to measure a range
              </span>
            </span>
          )}
        </div>
        {comparison && (
          <div
            data-slot="histogram-legend"
            className="flex items-center gap-3 text-[11px] text-muted-foreground"
          >
            <span className="flex items-center gap-1.5">
              <span
                aria-hidden="true"
                className="size-2.5 rounded-[2px]"
                style={{
                  background: barFill(colors.bar),
                  boxShadow: `inset 0 1.5px 0 ${colors.bar}`,
                }}
              />
              {seriesLabel}
            </span>
            <span className="flex items-center gap-1.5">
              <span
                aria-hidden="true"
                className="w-3.5 border-t-[1.5px] border-dashed"
                style={{ borderColor: colors.compare }}
              />
              {compareLabel}
            </span>
          </div>
        )}
      </div>

      <div className="sr-only">
        <table>
          <caption>{summaryText}</caption>
          <thead>
            <tr>
              <th scope="col">Latency</th>
              <th scope="col">Requests</th>
              {comparison && <th scope="col">{compareLabel}</th>}
            </tr>
          </thead>
          <tbody>
            {bars.map((b, i) =>
              b.count > 0 || comparison?.counts[i] ? (
                <tr key={i}>
                  <th scope="row">
                    {b.overflow
                      ? `${format(b.start)} and above`
                      : `${format(b.start)} to ${format(b.end)}`}
                  </th>
                  <td>{whole.format(Math.round(b.count))}</td>
                  {comparison && (
                    <td>{whole.format(Math.round(comparison.counts[i]))}</td>
                  )}
                </tr>
              ) : null,
            )}
          </tbody>
        </table>
      </div>
      <p className="sr-only" aria-live="polite">
        {active != null && bars[active]
          ? describeBucket(bucketAt(active))
          : range
            ? `Selected ${format(range[0])} to ${format(range[1])}: ${percentLabel(dist.total ? countBetween(dist, range[0], range[1]) / dist.total : 0)} of requests.`
            : ""}
      </p>

      <style href="overtrue-latency-histogram" precedence="default">
        {`@keyframes histogram-rise{from{opacity:0;transform:translateY(4px)}to{opacity:1;transform:none}}`}
      </style>
    </div>
  );
}
```

### `src/registry/overtrue/insight-card.tsx`

Left out to keep this page a readable size (34,743 characters). It is in the registry item above.
