{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "gallery-knob-gallery-graphic",
  "type": "registry:ui",
  "title": "Graphic Knob Kit",
  "description": "Eight authored vector knob designs with distinct marker, scale and body geometry.",
  "dependencies": [
    "maruaudio@>=0.0.3 <0.1.0"
  ],
  "registryDependencies": [
    "https://pluginui.com/r/gallery-knob-gallery-core.json"
  ],
  "files": [
    {
      "path": "components/ui/knob-gallery-graphic.tsx",
      "content": "/**\n * Source: https://pluginui.com/controls\n * Copyright © [Maru](https://maru.audio)\n *\n * Maru UI Kit — https://maru.audio/ui-kit\n *\n * Installed from the Maru UI registry. This file is yours now: edit it\n * freely, it will not be overwritten unless you re-run the add command.\n *\n * Keep this item’s companion files and CSS imports together. Dependencies\n * declared by the registry are installed with the source.\n */\nimport { useId } from \"react\"\nimport type { ReactNode } from \"react\"\nimport { knobAngle } from \"maruaudio/ui/shared/knob-gallery-types\"\nimport type {\n  GalleryLight,\n  GalleryKnobDesignProps,\n  KnobOption,\n} from \"maruaudio/ui/shared/knob-gallery-types\"\n\nconst rad = (angle: number) => (angle * Math.PI) / 180\nconst point = (radius: number, angle: number) => ({\n  x: 50 + radius * Math.sin(rad(angle)),\n  y: 50 - radius * Math.cos(rad(angle)),\n})\nconst arc = (radius: number, start: number, end: number) => {\n  const a = point(radius, start)\n  const b = point(radius, end)\n  return `M ${a.x} ${a.y} A ${radius} ${radius} 0 ${end - start > 180 ? 1 : 0} 1 ${b.x} ${b.y}`\n}\nconst lightVector = (light: GalleryLight) => ({\n  x: Math.cos(rad(light.azimuth)),\n  y: Math.sin(rad(light.azimuth)),\n})\n\nfunction Frame({ size, children }: { size: number; children: ReactNode }) {\n  return (\n    <svg\n      width={size}\n      height={size}\n      viewBox=\"0 0 100 100\"\n      aria-hidden=\"true\"\n      style={{ display: \"block\", overflow: \"visible\" }}\n    >\n      {children}\n    </svg>\n  )\n}\n\n/** All materials use screen coordinates; turning a marker never turns its illumination. */\nfunction Material({\n  id,\n  light,\n  pale = false,\n}: {\n  id: string\n  light: GalleryLight\n  pale?: boolean\n}) {\n  const vector = lightVector(light)\n  const amount = Math.max(0, Math.min(1.5, light.intensity))\n  const spread = 10 + light.elevation * 0.32\n  return (\n    <defs>\n      <linearGradient\n        id={`${id}-body`}\n        gradientUnits=\"userSpaceOnUse\"\n        x1={50 + vector.x * 40}\n        y1={50 + vector.y * 40}\n        x2={50 - vector.x * 40}\n        y2={50 - vector.y * 40}\n      >\n        <stop stopColor={pale ? \"#eee9dd\" : \"#41464d\"} />\n        <stop offset=\".5\" stopColor={pale ? \"#d3d0c6\" : \"#25292f\"} />\n        <stop offset=\"1\" stopColor={pale ? \"#aaa99f\" : \"#111519\"} />\n      </linearGradient>\n      <linearGradient\n        id={`${id}-edge`}\n        gradientUnits=\"userSpaceOnUse\"\n        x1={50 + vector.x * 40}\n        y1={50 + vector.y * 40}\n        x2={50 - vector.x * 40}\n        y2={50 - vector.y * 40}\n      >\n        <stop stopColor=\"#ffffff\" stopOpacity={0.14 + amount * 0.45} />\n        <stop offset=\".45\" stopColor=\"#b9bdc6\" stopOpacity=\".06\" />\n        <stop offset=\"1\" stopColor=\"#000000\" stopOpacity=\".8\" />\n      </linearGradient>\n      <radialGradient\n        id={`${id}-shine`}\n        gradientUnits=\"userSpaceOnUse\"\n        cx={50 + vector.x * (37 - spread * 0.3)}\n        cy={50 + vector.y * (37 - spread * 0.3)}\n        r={30 + spread}\n      >\n        <stop stopColor=\"#ffffff\" stopOpacity={amount * 0.19} />\n        <stop offset=\"1\" stopColor=\"#ffffff\" stopOpacity=\"0\" />\n      </radialGradient>\n    </defs>\n  )\n}\n\nfunction Scale({\n  count = 28,\n  radius = 43,\n  accent,\n  value,\n  active = false,\n}: {\n  count?: number\n  radius?: number\n  accent: string\n  value: number\n  active?: boolean\n}) {\n  return (\n    <g>\n      {Array.from({ length: count }, (_, index) => {\n        const angle = -135 + (index / (count - 1)) * 270\n        const outer = point(radius, angle)\n        const inner = point(radius - (index % 3 === 0 ? 3 : 1.6), angle)\n        return (\n          <line\n            key={index}\n            x1={inner.x}\n            y1={inner.y}\n            x2={outer.x}\n            y2={outer.y}\n            stroke={active && index / (count - 1) <= value ? accent : \"#8b8c93\"}\n            strokeOpacity={active && index / (count - 1) <= value ? 0.85 : 0.35}\n            strokeWidth=\".7\"\n          />\n        )\n      })}\n    </g>\n  )\n}\n\nfunction Encoder({ value, size, accent }: GalleryKnobDesignProps) {\n  const angle = knobAngle(value)\n  return (\n    <Frame size={size}>\n      <circle\n        cx=\"50\"\n        cy=\"50\"\n        r=\"29\"\n        fill=\"#14171c\"\n        stroke=\"#717681\"\n        strokeOpacity=\".4\"\n        strokeWidth=\".6\"\n      />\n      {Array.from({ length: 37 }, (_, index) => (\n        <path\n          key={index}\n          d={arc(38, -135 + index * 7.5 - 1.8, -135 + index * 7.5 + 1.8)}\n          fill=\"none\"\n          stroke={index / 36 <= value ? accent : \"#656772\"}\n          strokeOpacity={index / 36 <= value ? 0.95 : 0.27}\n          strokeWidth=\"2.3\"\n        />\n      ))}\n      <circle\n        cx=\"50\"\n        cy=\"50\"\n        r=\"25\"\n        fill=\"none\"\n        stroke=\"#7e848e\"\n        strokeOpacity=\".2\"\n        strokeWidth=\".5\"\n      />\n      <g transform={`rotate(${angle} 50 50)`}>\n        <path\n          d=\"M 50 26 L 50 33\"\n          stroke={accent}\n          strokeWidth=\"2\"\n          strokeLinecap=\"round\"\n        />\n        <path d=\"M 50 20 L 47.8 17 L 52.2 17 Z\" fill={accent} />\n      </g>\n      <path\n        d=\"M 43 50 H 57 M 50 43 V 57\"\n        stroke=\"#a7aab0\"\n        strokeOpacity=\".16\"\n        strokeWidth=\".6\"\n      />\n      <text\n        x=\"50\"\n        y=\"77\"\n        textAnchor=\"middle\"\n        fill=\"#9b9ea6\"\n        fontSize=\"3.6\"\n        letterSpacing=\"1.3\"\n        fontFamily=\"monospace\"\n      >\n        ENC\n      </text>\n    </Frame>\n  )\n}\n\nfunction Orbit({ value, size, accent }: GalleryKnobDesignProps) {\n  const angle = knobAngle(value)\n  const marker = point(33, angle)\n  return (\n    <Frame size={size}>\n      <path\n        d={arc(41, -135, 135)}\n        stroke=\"#7b7d87\"\n        strokeOpacity=\".25\"\n        strokeWidth=\".5\"\n        fill=\"none\"\n      />\n      <circle\n        cx=\"50\"\n        cy=\"50\"\n        r=\"33\"\n        fill=\"#191b21\"\n        stroke=\"#9fa1ab\"\n        strokeOpacity=\".55\"\n        strokeWidth=\".65\"\n      />\n      <circle\n        cx=\"50\"\n        cy=\"50\"\n        r=\"23\"\n        fill=\"none\"\n        stroke=\"#898b96\"\n        strokeOpacity=\".18\"\n        strokeWidth=\".5\"\n      />\n      <circle\n        cx=\"50\"\n        cy=\"50\"\n        r=\"3.2\"\n        fill=\"#0e1016\"\n        stroke=\"#aaa9b4\"\n        strokeWidth=\".4\"\n      />\n      <g transform={`rotate(${angle} 50 50)`}>\n        <path d=\"M 50 23 L 50 43\" stroke={accent} strokeWidth=\".7\" />\n        <circle cx=\"50\" cy=\"24\" r=\"2\" fill={accent} />\n      </g>\n      <circle\n        cx={marker.x}\n        cy={marker.y}\n        r=\"3.8\"\n        fill=\"#14161c\"\n        stroke={accent}\n        strokeWidth=\"1\"\n      />\n      {[-135, -67.5, 0, 67.5, 135].map((a) => {\n        const p = point(41, a)\n        return (\n          <circle\n            key={a}\n            cx={p.x}\n            cy={p.y}\n            r=\".9\"\n            fill=\"#b6b3bb\"\n            fillOpacity=\".45\"\n          />\n        )\n      })}\n    </Frame>\n  )\n}\n\nfunction Engraved({ value, size, accent, light }: GalleryKnobDesignProps) {\n  const id = useId()\n  const angle = knobAngle(value)\n  return (\n    <Frame size={size}>\n      <Material id={id} light={light} />\n      <circle cx=\"50\" cy=\"51.3\" r=\"35\" fill=\"#080a0d\" />\n      <circle\n        cx=\"50\"\n        cy=\"50\"\n        r=\"35\"\n        fill={`url(#${id}-body)`}\n        stroke={`url(#${id}-edge)`}\n        strokeWidth=\"1\"\n      />\n      <circle\n        cx=\"50\"\n        cy=\"50\"\n        r=\"30.5\"\n        fill=\"none\"\n        stroke=\"#090c10\"\n        strokeWidth=\".8\"\n      />\n      <Scale count={55} radius={29.3} accent={accent} value={value} />\n      {[-135, -67.5, 0, 67.5, 135].map((a, i) => {\n        const p = point(24, a)\n        return (\n          <text\n            key={a}\n            x={p.x}\n            y={p.y + 1.2}\n            textAnchor=\"middle\"\n            fill=\"#b4b8be\"\n            fontFamily=\"monospace\"\n            fontSize=\"3.3\"\n          >\n            {i * 25}\n          </text>\n        )\n      })}\n      <circle\n        cx=\"50\"\n        cy=\"50\"\n        r=\"17.5\"\n        fill=\"#20252b\"\n        stroke={`url(#${id}-edge)`}\n        strokeWidth=\".7\"\n      />\n      <circle cx=\"50\" cy=\"50\" r=\"17.5\" fill={`url(#${id}-shine)`} />\n      <g transform={`rotate(${angle} 50 50)`}>\n        <path d=\"M 50 33 V 42\" stroke=\"#090b10\" strokeWidth=\"2.1\" />\n        <path d=\"M 50 33 V 42\" stroke={accent} strokeWidth=\"1\" />\n        <path d=\"M 50 20 L 48.5 17 H 51.5 Z\" fill={accent} />\n      </g>\n      <path\n        d=\"M 47 52 H 53 M 50 49 V 55\"\n        stroke=\"#8a929f\"\n        strokeOpacity=\".4\"\n        strokeWidth=\".5\"\n      />\n      <text\n        x=\"50\"\n        y=\"92\"\n        textAnchor=\"middle\"\n        fill=\"#a7a7b0\"\n        fontFamily=\"monospace\"\n        fontSize=\"3.2\"\n        letterSpacing=\"1\"\n      >\n        CALIBRATED / 270°\n      </text>\n    </Frame>\n  )\n}\n\nfunction Faceted({ value, size, accent, light }: GalleryKnobDesignProps) {\n  const id = useId()\n  const angle = knobAngle(value)\n  const vector = lightVector(light)\n  const vertices = Array.from({ length: 8 }, (_, index) => {\n    const a = angle + index * 45 + 22.5\n    return { outer: point(33, a), inner: point(25, a) }\n  })\n  return (\n    <Frame size={size}>\n      <Material id={id} light={light} />\n      <Scale count={19} radius={43} accent={accent} value={value} />\n      <polygon\n        points={vertices\n          .map(({ outer }) => `${outer.x},${outer.y + 2}`)\n          .join(\" \")}\n        fill=\"#080b10\"\n      />\n      {vertices.map((vertex, index) => {\n        const next = vertices[(index + 1) % 8]\n        const normal = rad(angle + index * 45 + 45 - 90)\n        const diffuse =\n          Math.cos(normal) * vector.x + Math.sin(normal) * vector.y\n        const elevation = Math.cos(rad(light.elevation))\n        const luminance =\n          17 + light.intensity * (9 + Math.max(0, diffuse) * 33 * elevation)\n        return (\n          <polygon\n            key={index}\n            points={`${vertex.outer.x},${vertex.outer.y} ${next.outer.x},${next.outer.y} ${next.inner.x},${next.inner.y} ${vertex.inner.x},${vertex.inner.y}`}\n            fill={`hsl(220 9% ${luminance}%)`}\n            stroke=\"#06090d\"\n            strokeOpacity=\".28\"\n            strokeWidth=\".4\"\n          />\n        )\n      })}\n      <polygon\n        points={vertices.map(({ inner }) => `${inner.x},${inner.y}`).join(\" \")}\n        fill=\"#20242c\"\n        stroke={`url(#${id}-edge)`}\n        strokeWidth=\".6\"\n      />\n      <polygon\n        points={vertices.map(({ inner }) => `${inner.x},${inner.y}`).join(\" \")}\n        fill={`url(#${id}-shine)`}\n      />\n      <g transform={`rotate(${angle} 50 50)`}>\n        <path d=\"M 50 25 L 47.7 28 H 52.3 Z\" fill={accent} />\n        <path d=\"M 50 30 V 40\" stroke={accent} strokeWidth=\"1\" />\n      </g>\n    </Frame>\n  )\n}\n\nfunction Ceramic({ value, size, accent, light }: GalleryKnobDesignProps) {\n  const id = useId()\n  const angle = knobAngle(value)\n  return (\n    <Frame size={size}>\n      <Material id={id} light={light} pale />\n      <defs>\n        <clipPath id={`${id}-clip`}>\n          <circle cx=\"50\" cy=\"50\" r=\"31\" />\n        </clipPath>\n      </defs>\n      <Scale count={13} radius={42} accent={accent} value={value} />\n      <circle cx=\"50\" cy=\"51.5\" r=\"33\" fill=\"#05080c\" />\n      <circle\n        cx=\"50\"\n        cy=\"50\"\n        r=\"33\"\n        fill={`url(#${id}-body)`}\n        stroke={`url(#${id}-edge)`}\n        strokeWidth=\".7\"\n      />\n      <g clipPath={`url(#${id}-clip)`}>\n        <g transform={`rotate(${angle} 50 50)`}>\n          <path d=\"M 50 18 A 32 32 0 0 1 50 82 Z\" fill=\"#282c32\" />\n          <path d=\"M 50 19 V 81\" stroke=\"#0a1115\" strokeWidth=\".8\" />\n          <path\n            d=\"M 46.5 21 V 32\"\n            stroke={accent}\n            strokeWidth=\"1.6\"\n            strokeLinecap=\"round\"\n          />\n        </g>\n        <circle cx=\"50\" cy=\"50\" r=\"31\" fill={`url(#${id}-shine)`} />\n      </g>\n      <circle\n        cx=\"50\"\n        cy=\"50\"\n        r=\"30.8\"\n        fill=\"none\"\n        stroke={`url(#${id}-edge)`}\n        strokeWidth=\".5\"\n      />\n      <g transform={`rotate(${angle} 50 50)`}>\n        <path d=\"M 50 16 L 47.8 13 H 52.2 Z\" fill={accent} />\n      </g>\n    </Frame>\n  )\n}\n\nfunction Radar({ value, size, accent }: GalleryKnobDesignProps) {\n  const angle = knobAngle(value)\n  return (\n    <Frame size={size}>\n      <circle\n        cx=\"50\"\n        cy=\"50\"\n        r=\"35\"\n        fill=\"#111a1b\"\n        stroke=\"#839d9a\"\n        strokeOpacity=\".25\"\n        strokeWidth=\".6\"\n      />\n      {[11, 21, 30].map((radius) => (\n        <circle\n          key={radius}\n          cx=\"50\"\n          cy=\"50\"\n          r={radius}\n          fill=\"none\"\n          stroke=\"#8eada7\"\n          strokeOpacity=\".19\"\n          strokeWidth=\".5\"\n        />\n      ))}\n      <path\n        d=\"M 15 50 H 85 M 50 15 V 85\"\n        stroke=\"#8eada7\"\n        strokeOpacity=\".14\"\n        strokeWidth=\".5\"\n      />\n      <Scale count={37} radius={40} accent={accent} value={value} />\n      <g transform={`rotate(${angle} 50 50)`}>\n        <path\n          d=\"M 50 50 L 42 21 A 30 30 0 0 1 50 20 Z\"\n          fill={accent}\n          fillOpacity=\".09\"\n        />\n        <path d=\"M 50 50 V 20\" stroke={accent} strokeWidth=\".8\" />\n        <circle\n          cx=\"50\"\n          cy=\"20\"\n          r=\"2.6\"\n          fill=\"#111a1b\"\n          stroke={accent}\n          strokeWidth=\".8\"\n        />\n        <circle cx=\"50\" cy=\"20\" r=\".8\" fill={accent} />\n      </g>\n      <circle cx=\"50\" cy=\"50\" r=\"2\" fill={accent} />\n      <text\n        x=\"50\"\n        y=\"75\"\n        textAnchor=\"middle\"\n        fill=\"#809b96\"\n        fontFamily=\"monospace\"\n        fontSize=\"3.6\"\n        letterSpacing=\".6\"\n      >\n        R /{\" \"}\n        {Math.round(value * 100)\n          .toString()\n          .padStart(3, \"0\")}\n      </text>\n    </Frame>\n  )\n}\n\nfunction NumberWheel({ value, size, accent, light }: GalleryKnobDesignProps) {\n  const id = useId()\n  const angle = knobAngle(value)\n  return (\n    <Frame size={size}>\n      <Material id={id} light={light} pale />\n      <circle cx=\"50\" cy=\"52\" r=\"34\" fill=\"#080a10\" />\n      <circle\n        cx=\"50\"\n        cy=\"50\"\n        r=\"34\"\n        fill={`url(#${id}-body)`}\n        stroke={`url(#${id}-edge)`}\n        strokeWidth=\".7\"\n      />\n      <g transform={`rotate(${angle} 50 50)`}>\n        {Array.from({ length: 10 }, (_, index) => {\n          const a = index * 36\n          const p = point(26, a)\n          return (\n            <g key={index}>\n              <text\n                x={p.x}\n                y={p.y + 2.4}\n                transform={`rotate(${a} ${p.x} ${p.y})`}\n                textAnchor=\"middle\"\n                fill=\"#32343a\"\n                fontFamily=\"monospace\"\n                fontWeight=\"600\"\n                fontSize=\"6.6\"\n              >\n                {index}\n              </text>\n              <path\n                d={arc(31, a - 1, a + 1)}\n                fill=\"none\"\n                stroke=\"#383b40\"\n                strokeWidth=\".65\"\n              />\n            </g>\n          )\n        })}\n      </g>\n      <circle cx=\"50\" cy=\"50\" r=\"34\" fill={`url(#${id}-shine)`} />\n      <circle\n        cx=\"50\"\n        cy=\"50\"\n        r=\"15\"\n        fill=\"#191d24\"\n        stroke=\"#484b53\"\n        strokeWidth=\".5\"\n      />\n      <circle\n        cx=\"50\"\n        cy=\"50\"\n        r=\"13\"\n        fill=\"none\"\n        stroke=\"#858791\"\n        strokeWidth=\".5\"\n        strokeOpacity=\".3\"\n      />\n      <g transform={`rotate(${angle} 50 50)`}>\n        <path\n          d=\"M 50 39 V 44\"\n          stroke={accent}\n          strokeWidth=\"1.7\"\n          strokeLinecap=\"round\"\n        />\n        <path d=\"M 50 13 L 47.5 9 H 52.5 Z\" fill={accent} />\n      </g>\n      <path d=\"M 47.5 90 H 52.5\" stroke={accent} strokeWidth=\".6\" />\n    </Frame>\n  )\n}\n\nfunction Recessed({ value, size, accent, light }: GalleryKnobDesignProps) {\n  const id = useId()\n  const angle = knobAngle(value)\n  const vector = lightVector(light)\n  return (\n    <Frame size={size}>\n      <Material id={id} light={light} />\n      <circle\n        cx=\"50\"\n        cy=\"50\"\n        r=\"37\"\n        fill=\"#080b11\"\n        stroke={`url(#${id}-edge)`}\n        strokeWidth=\".7\"\n      />\n      <circle\n        cx={50 - vector.x * 1.3}\n        cy={50 - vector.y * 1.3}\n        r=\"32\"\n        fill=\"#0d1118\"\n      />\n      <circle\n        cx=\"50\"\n        cy=\"50\"\n        r=\"30\"\n        fill=\"#272b34\"\n        stroke={`url(#${id}-edge)`}\n        strokeWidth=\".7\"\n      />\n      <circle cx=\"50\" cy=\"50\" r=\"30\" fill={`url(#${id}-shine)`} />\n      <circle\n        cx=\"50\"\n        cy=\"50\"\n        r=\"28.3\"\n        fill=\"none\"\n        stroke=\"#808795\"\n        strokeOpacity=\".12\"\n        strokeWidth=\".5\"\n      />\n      <g transform={`rotate(${angle} 50 50)`}>\n        <rect\n          x=\"48.7\"\n          y=\"24.5\"\n          width=\"2.6\"\n          height=\"7\"\n          rx=\"1.3\"\n          fill=\"#11151c\"\n        />\n        <rect x=\"49.5\" y=\"25.5\" width=\"1\" height=\"5\" rx=\".5\" fill={accent} />\n        <circle cx=\"50\" cy=\"8\" r=\"1.1\" fill={accent} />\n      </g>\n      {[-135, 0, 135].map((a) => {\n        const p = point(43, a)\n        return (\n          <circle\n            key={a}\n            cx={p.x}\n            cy={p.y}\n            r=\".55\"\n            fill=\"#adaeba\"\n            fillOpacity=\".55\"\n          />\n        )\n      })}\n    </Frame>\n  )\n}\n\nexport const GRAPHIC_ENCODER_OPTION: KnobOption = {\n  id: \"graphic-encoder\",\n  name: \"Segmented encoder\",\n  family: \"Graphic\",\n  technique: \"Flat vector · discrete perimeter\",\n  description:\n    \"Precise luminous segments around a quiet carbon dial. A compact control-room language with no simulated material.\",\n  Design: Encoder,\n}\n\nexport const GRAPHIC_ORBIT_OPTION: KnobOption = {\n  id: \"graphic-orbit\",\n  name: \"Thin orbit\",\n  family: \"Graphic\",\n  technique: \"Flat vector · orbital marker\",\n  description:\n    \"An open, fine-line instrument with a satellite pointer and radial hairline. Airy and architectural at small sizes.\",\n  Design: Orbit,\n}\n\nexport const GRAPHIC_ENGRAVED_OPTION: KnobOption = {\n  id: \"graphic-engraved\",\n  name: \"Calibration dial\",\n  family: \"Graphic\",\n  technique: \"Fixed-light SVG · engraved scale\",\n  description:\n    \"A miniature measurement instrument: recessed numbering, dense engraved divisions and an independent central pointer.\",\n  Design: Engraved,\n}\n\nexport const GRAPHIC_FACETED_OPTION: KnobOption = {\n  id: \"graphic-faceted\",\n  name: \"Folded octagon\",\n  family: \"Graphic\",\n  technique: \"Calculated facet normals · fixed light\",\n  description:\n    \"Eight folded faces create a changing sculptural silhouette. Each facet responds to the same screen-space light as the dial turns.\",\n  Design: Faceted,\n}\n\nexport const GRAPHIC_CERAMIC_OPTION: KnobOption = {\n  id: \"graphic-ceramic\",\n  name: \"Split ceramic\",\n  family: \"Graphic\",\n  technique: \"Fixed-light SVG · two-tone inlay\",\n  description:\n    \"A pearl and charcoal ceramic disc, with an asymmetric seam and a fine inset accent. The inlay turns beneath fixed illumination.\",\n  Design: Ceramic,\n}\n\nexport const GRAPHIC_RADAR_OPTION: KnobOption = {\n  id: \"graphic-radar\",\n  name: \"Concentric radar\",\n  family: \"Graphic\",\n  technique: \"Flat vector · reticle and sweep\",\n  description:\n    \"A smoked instrument screen with concentric rings, a fine sweep needle and a restrained tracking point.\",\n  Design: Radar,\n}\n\nexport const GRAPHIC_NUMBER_WHEEL_OPTION: KnobOption = {\n  id: \"graphic-number-wheel\",\n  name: \"Number wheel\",\n  family: \"Graphic\",\n  technique: \"Fixed-light SVG · rotating typography\",\n  description:\n    \"Printed index numbers turn on a warm enamel wheel, surrounding a small graphite hub. A distinctly editorial approach.\",\n  Design: NumberWheel,\n}\n\nexport const GRAPHIC_RECESSED_OPTION: KnobOption = {\n  id: \"graphic-recessed\",\n  name: \"Recessed puck\",\n  family: \"Graphic\",\n  technique: \"Fixed-light SVG · socket and inset\",\n  description:\n    \"A nearly flush graphite puck seated in a dark recess. Just three reference dots and a tiny inset marker keep it exceptionally quiet.\",\n  Design: Recessed,\n}\n\nexport const GRAPHIC_OPTIONS: KnobOption[] = [\n  GRAPHIC_ENCODER_OPTION,\n  GRAPHIC_ORBIT_OPTION,\n  GRAPHIC_ENGRAVED_OPTION,\n  GRAPHIC_FACETED_OPTION,\n  GRAPHIC_CERAMIC_OPTION,\n  GRAPHIC_RADAR_OPTION,\n  GRAPHIC_NUMBER_WHEEL_OPTION,\n  GRAPHIC_RECESSED_OPTION,\n]\n",
      "type": "registry:component",
      "target": "@ui/knob-gallery-graphic.tsx"
    }
  ]
}
