{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "trust-stats",
  "type": "registry:block",
  "title": "Stats strip",
  "description": "Four big numbers that count up once in view, with mono labels and hairline dividers.",
  "author": "StoreKit <hello@storekit.dev>",
  "categories": [
    "trust",
    "any"
  ],
  "dependencies": [
    "motion"
  ],
  "registryDependencies": [
    "https://storekit-eight.vercel.app/r/cn.json"
  ],
  "files": [
    {
      "path": "trust/trust-stats.tsx",
      "content": "\"use client\"\n\nimport { useEffect, useRef } from \"react\"\nimport { animate, useInView, useReducedMotion } from \"motion/react\"\nimport { cn } from \"@/components/storekit/lib/cn\"\n\n/* Four-up proof strip. Numbers count up from zero once, the first time the\n   strip scrolls into view. Tabular numerals keep the width steady while they\n   count; reduced motion shows the final value immediately. */\n\nconst EASE = [0.23, 1, 0.32, 1] as const\n\ntype Stat = { value: number; label: string; decimals?: number; prefix?: string; suffix?: string }\n\nfunction format(n: number, s: Stat) {\n  const num = n.toLocaleString(\"en-US\", { minimumFractionDigits: s.decimals ?? 0, maximumFractionDigits: s.decimals ?? 0 })\n  return `${s.prefix ?? \"\"}${num}${s.suffix ?? \"\"}`\n}\n\nfunction Counter({ stat, run }: { stat: Stat; run: boolean }) {\n  const ref = useRef<HTMLSpanElement>(null)\n  const reduce = useReducedMotion()\n\n  useEffect(() => {\n    const node = ref.current\n    if (!node || !run) return\n    if (reduce) {\n      node.textContent = format(stat.value, stat)\n      return\n    }\n    const controls = animate(0, stat.value, {\n      duration: 1.4,\n      ease: EASE,\n      onUpdate: (v) => {\n        node.textContent = format(v, stat)\n      },\n    })\n    return () => controls.stop()\n    // eslint-disable-next-line react-hooks/exhaustive-deps\n  }, [run, reduce, stat.value, stat.decimals, stat.prefix, stat.suffix])\n\n  return (\n    <span ref={ref} aria-hidden>\n      {format(0, stat)}\n    </span>\n  )\n}\n\nexport function TrustStats({\n  stats = [\n    { value: 1240, label: \"Batches tested\", suffix: \"+\" },\n    { value: 120, label: \"Members on subscription\", suffix: \"k\" },\n    { value: 48, label: \"Hours to ship\", suffix: \"h\" },\n    { value: 4.9, label: \"Customer rating\", decimals: 1 },\n  ],\n  className,\n}: {\n  stats?: Stat[]\n  className?: string\n}) {\n  const ref = useRef<HTMLDListElement>(null)\n  const inView = useInView(ref, { once: true, margin: \"0px 0px -15% 0px\" })\n\n  return (\n    <dl\n      ref={ref}\n      data-sk-section=\"trust\"\n      data-sk-variant=\"trust-stats\"\n      className={cn(\n        \"grid grid-cols-2 gap-px overflow-hidden rounded-sk-card border border-sk-line bg-sk-line lg:grid-cols-4\",\n        className\n      )}\n    >\n      {stats.map((s) => (\n        <div key={s.label} className=\"flex flex-col-reverse justify-end gap-2 bg-sk-paper px-5 py-6 sm:px-6 sm:py-8\">\n          <dt className=\"font-sk-mono text-[11px] uppercase tracking-[0.1em] text-sk-muted sm:tracking-[0.14em]\">{s.label}</dt>\n          <dd\n            className=\"font-sk-display font-semibold leading-[1.1] tracking-[-0.02em] tabular-nums text-sk-ink\"\n            style={{ fontSize: \"clamp(2rem, 4vw, 3rem)\" }}\n          >\n            <span className=\"sr-only\">{format(s.value, s)}</span>\n            <Counter stat={s} run={inView} />\n          </dd>\n        </div>\n      ))}\n    </dl>\n  )\n}\n",
      "type": "registry:block",
      "target": "components/storekit/trust/trust-stats.tsx"
    }
  ],
  "meta": {
    "section": "trust",
    "variant": "stats",
    "niche": [
      "any"
    ],
    "commerce": [],
    "previewHeight": 280
  }
}