{
  "name": "slider",
  "type": "registry:ui",
  "title": "Slider",
  "description": "The level control with the onChange/onCommit split: live feel every movement, persist once on release — hardware and API consumers never flood.",
  "dependencies": [
    "@candlelight-ds/tokens",
    "@radix-ui/react-slider",
    "clsx",
    "tailwind-merge"
  ],
  "files": [
    {
      "path": "components/ui/Slider.tsx",
      "type": "registry:ui",
      "content": "'use client'\n\n/**\n * Slider — Radix slider in the accent fill. The onChange/onCommit split is\n * the point: onChange fires every movement (live feel), onCommit fires once\n * on release (persist + reconcile) so hardware/API consumers never flood.\n *\n * Use when: setting a level — brightness, volume, temperature, intensity.\n * Don't use when: picking among a few discrete options (SegmentedControl).\n */\n\nimport * as RadixSlider from '@radix-ui/react-slider'\nimport { cn } from '@/lib/utils'\n\ninterface SliderProps {\n  value: number\n  min?: number\n  max?: number\n  step?: number\n  /** Every movement — keep it cheap (local state, throttled live apply). */\n  onChange?: (value: number) => void\n  /** Once on release — persist, reconcile, announce. */\n  onCommit?: (value: number) => void\n  disabled?: boolean\n  /** Accessible name; required since sliders rarely carry visible labels. */\n  label: string\n  /**\n   * Track treatment: 'fill' (default) paints the accent up to the value;\n   * 'spectrum' paints a content gradient across the whole track and the\n   * thumb alone marks the value — for tracks that ARE the thing being\n   * picked (a color-temperature ramp). Pass the CSS gradient yourself;\n   * it is content, not chrome, which is why the gradient ban stands down.\n   */\n  track?: 'fill' | 'spectrum'\n  /** The spectrum's CSS background (only read when track=\"spectrum\"). */\n  spectrum?: string\n  className?: string\n}\n\nexport function Slider({\n  value,\n  min = 0,\n  max = 100,\n  step = 1,\n  onChange,\n  onCommit,\n  disabled = false,\n  label,\n  track = 'fill',\n  spectrum,\n  className,\n}: SliderProps) {\n  return (\n    <RadixSlider.Root\n      value={[value]}\n      min={min}\n      max={max}\n      step={step}\n      disabled={disabled}\n      onValueChange={(values) => onChange?.(values[0])}\n      onValueCommit={(values) => onCommit?.(values[0])}\n      className={cn(\n        'relative flex h-5 w-full touch-none select-none items-center',\n        disabled && 'opacity-40',\n        className\n      )}\n    >\n      <RadixSlider.Track\n        className=\"relative h-1.5 grow overflow-hidden rounded-full bg-fill-active\"\n        style={\n          track === 'spectrum' && spectrum\n            ? // Content, not chrome: the track IS the spectrum being picked.\n              { background: spectrum }\n            : undefined\n        }\n      >\n        {track === 'fill' ? (\n          <RadixSlider.Range\n            className=\"absolute h-full rounded-full\"\n            style={{ background: 'var(--brass)' }}\n          />\n        ) : null}\n      </RadixSlider.Track>\n      <RadixSlider.Thumb\n        aria-label={label}\n        className={cn(\n          'block h-3.5 w-3.5 rounded-full bg-ink shadow-md transition-transform',\n          'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-brass focus-visible:ring-offset-2 focus-visible:ring-offset-stage',\n          !disabled && 'hover:scale-110 active:scale-95'\n        )}\n      />\n    </RadixSlider.Root>\n  )\n}\n",
      "target": "components/ui/Slider.tsx"
    }
  ],
  "meta": {
    "candlelight": {
      "category": "primitive",
      "gRules": [
        "G3"
      ],
      "useWhen": "Setting a level — brightness, volume, temperature, intensity.",
      "dontUseWhen": "Picking among a few discrete options (SegmentedControl).",
      "states": [
        "resting",
        "dragging (live onChange)",
        "released (onCommit)",
        "disabled",
        "spectrum track"
      ],
      "keyboard": [
        {
          "keys": "←/→",
          "does": "steps the value"
        },
        {
          "keys": "Home/End",
          "does": "min/max"
        }
      ],
      "acceptanceTests": [
        "onChange fires every movement; onCommit exactly once on release.",
        "Flat two-zone progress paint — no gradient chrome (the spectrum track is content, not chrome)."
      ]
    }
  },
  "registryDependencies": [
    "utils"
  ]
}