{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "stat-range-slider",
  "title": "Stat range slider",
  "description": "A dual-thumb min/max range slider with optional tier ticks — the stat filter for a build optimizer (\"Resilience ≥ 60\", \"Mobility 30–70\").",
  "registryDependencies": [
    "@engram/cn",
    "@engram/tokens"
  ],
  "files": [
    {
      "path": "src/components/stat-range-slider.tsx",
      "content": "\"use client\";\n\nimport type { CSSProperties, ReactNode } from \"react\";\nimport { cn } from \"../lib/cn.js\";\n\nexport interface StatRangeSliderProps {\n  /** Track minimum. Default 0. */\n  min?: number;\n  /** Track maximum. Default 100. */\n  max?: number;\n  /** The selected [low, high] bounds. */\n  value: [number, number];\n  /** Step between values. Default 1. */\n  step?: number;\n  /** Tier breakpoint spacing — draws ticks every `tiers` units (e.g. 10). */\n  tiers?: number;\n  onChange?: (value: [number, number]) => void;\n  /** Row label shown above the track. */\n  label?: ReactNode;\n  className?: string;\n}\n\n/**\n * A dual-thumb min/max range slider with optional tier ticks — the stat filter\n * for a build optimizer (\"Resilience ≥ 60\", \"Mobility 30–70\"). Two overlaid\n * range inputs keep it keyboard-accessible; `tiers` marks the breakpoints.\n */\nexport function StatRangeSlider({\n  min = 0,\n  max = 100,\n  value,\n  step = 1,\n  tiers,\n  onChange,\n  label,\n  className,\n}: StatRangeSliderProps) {\n  const [lo, hi] = value;\n  const span = max - min || 1;\n  const loPct = ((lo - min) / span) * 100;\n  const hiPct = ((hi - min) / span) * 100;\n\n  const setLo = (v: number) => onChange?.([Math.min(v, hi), hi]);\n  const setHi = (v: number) => onChange?.([lo, Math.max(v, lo)]);\n\n  const ticks = tiers ? Math.floor(span / tiers) : 0;\n\n  return (\n    <div className={cn(\"flex flex-col gap-1.5\", className)}>\n      {label != null ? (\n        <div className=\"flex items-center justify-between\">\n          <span className=\"font-engram-display text-[11px] text-engram-muted uppercase tracking-engram-label\">\n            {label}\n          </span>\n          <span className=\"font-engram-display font-bold text-engram-fg text-xs tabular-nums\">\n            {lo}–{hi}\n          </span>\n        </div>\n      ) : null}\n      <div className=\"relative h-5\">\n        {/* Track */}\n        <div className=\"absolute inset-x-0 top-1/2 h-1.5 -translate-y-1/2 bg-engram-track\" />\n        {/* Selected range */}\n        <div\n          className=\"absolute top-1/2 h-1.5 -translate-y-1/2 bg-engram-accent\"\n          style={{ left: `${loPct}%`, width: `${hiPct - loPct}%` }}\n        />\n        {/* Tier ticks */}\n        {ticks > 0\n          ? Array.from({ length: ticks - 1 }, (_, i) => (\n              <span\n                // fixed tier ticks — position is the identity\n                // biome-ignore lint/suspicious/noArrayIndexKey: positional ticks\n                key={i}\n                aria-hidden\n                className=\"absolute top-1/2 h-2 w-px -translate-y-1/2 bg-engram-bg\"\n                style={{ left: `${((i + 1) / ticks) * 100}%` }}\n              />\n            ))\n          : null}\n        {/* Thumbs (overlaid range inputs) */}\n        <input\n          type=\"range\"\n          aria-label=\"Minimum\"\n          min={min}\n          max={max}\n          step={step}\n          value={lo}\n          onChange={(e) => setLo(Number(e.target.value))}\n          className=\"engram-range pointer-events-none absolute inset-0 m-0 h-5 w-full appearance-none bg-transparent\"\n          style={{ \"--thumb\": \"var(--engram-accent)\" } as CSSProperties}\n        />\n        <input\n          type=\"range\"\n          aria-label=\"Maximum\"\n          min={min}\n          max={max}\n          step={step}\n          value={hi}\n          onChange={(e) => setHi(Number(e.target.value))}\n          className=\"engram-range pointer-events-none absolute inset-0 m-0 h-5 w-full appearance-none bg-transparent\"\n          style={{ \"--thumb\": \"var(--engram-accent)\" } as CSSProperties}\n        />\n      </div>\n    </div>\n  );\n}\n",
      "type": "registry:component",
      "target": "components/engram/stat-range-slider.tsx"
    }
  ],
  "meta": {
    "level": "component"
  },
  "docs": "Extend without forking: edit the copied source, use `asChild` (Radix Slot) to change the rendered element, pass the typed `annotations` prop for curated data (verdict/tags/per-plug), or use slot / render-prop props for arbitrary content. Requires the @engram/tokens theme (--engram-* CSS variables).",
  "categories": [
    "stats"
  ],
  "type": "registry:component"
}