{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "voice-powered-orb",
  "title": "Voice powered orb",
  "description": "Voice powered orb is a production-ready interactive component from BJORK UI, packaged for shadcn registries.",
  "dependencies": [
    "clsx",
    "next-themes",
    "ogl",
    "tailwind-merge"
  ],
  "files": [
    {
      "path": "components/bjork-ui/interactive/voice-powered-orb.tsx",
      "content": "\"use client\";\n\nimport React, { useEffect, useRef, FC, useState } from \"react\";\nimport { Renderer, Program, Mesh, Triangle, Vec3 } from \"ogl\";\nimport { useTheme } from \"next-themes\";\nimport { cn } from \"@/lib/utils\";\n\ninterface VoicePoweredOrbProps {\n  className?: string;\n  hue?: number;\n  enableVoiceControl?: boolean;\n  voiceSensitivity?: number;\n  maxRotationSpeed?: number;\n  maxHoverIntensity?: number;\n  onVoiceDetected?: (detected: boolean) => void;\n}\n\nexport const VoicePoweredOrb: FC<VoicePoweredOrbProps> = ({\n  className,\n  hue = 0,\n  enableVoiceControl = true,\n  voiceSensitivity = 1.5,\n  maxRotationSpeed = 1.2,\n  maxHoverIntensity = 0.8,\n  onVoiceDetected,\n}) => {\n  const ctnDom = useRef<HTMLDivElement>(null);\n  const audioContextRef = useRef<AudioContext | null>(null);\n  const analyserRef = useRef<AnalyserNode | null>(null);\n  const microphoneRef = useRef<MediaStreamAudioSourceNode | null>(null);\n  const dataArrayRef = useRef<Uint8Array | null>(null);\n  const mediaStreamRef = useRef<MediaStream | null>(null);\n  const { resolvedTheme } = useTheme();\n  const [mounted, setMounted] = useState(false);\n  const isLight = mounted && resolvedTheme === \"light\";\n\n  useEffect(() => {\n    setMounted(true);\n  }, []);\n\n  const vert = /* glsl */ `\n    precision highp float;\n    attribute vec2 position;\n    attribute vec2 uv;\n    varying vec2 vUv;\n    void main() {\n      vUv = uv;\n      gl_Position = vec4(position, 0.0, 1.0);\n    }\n  `;\n\n  const frag = /* glsl */ `\n    precision highp float;\n\n    uniform float iTime;\n    uniform vec3 iResolution;\n    uniform float hue;\n    uniform float hover;\n    uniform float rot;\n    uniform float hoverIntensity;\n    uniform float lightMode;\n    varying vec2 vUv;\n\n    vec3 rgb2yiq(vec3 c) {\n      float y = dot(c, vec3(0.299, 0.587, 0.114));\n      float i = dot(c, vec3(0.596, -0.274, -0.322));\n      float q = dot(c, vec3(0.211, -0.523, 0.312));\n      return vec3(y, i, q);\n    }\n\n    vec3 yiq2rgb(vec3 c) {\n      float r = c.x + 0.956 * c.y + 0.621 * c.z;\n      float g = c.x - 0.272 * c.y - 0.647 * c.z;\n      float b = c.x - 1.106 * c.y + 1.703 * c.z;\n      return vec3(r, g, b);\n    }\n\n    vec3 adjustHue(vec3 color, float hueDeg) {\n      float hueRad = hueDeg * 3.14159265 / 180.0;\n      vec3 yiq = rgb2yiq(color);\n      float cosA = cos(hueRad);\n      float sinA = sin(hueRad);\n      float i = yiq.y * cosA - yiq.z * sinA;\n      float q = yiq.y * sinA + yiq.z * cosA;\n      yiq.y = i;\n      yiq.z = q;\n      return yiq2rgb(yiq);\n    }\n\n    vec3 hash33(vec3 p3) {\n      p3 = fract(p3 * vec3(0.1031, 0.11369, 0.13787));\n      p3 += dot(p3, p3.yxz + 19.19);\n      return -1.0 + 2.0 * fract(vec3(\n        p3.x + p3.y,\n        p3.x + p3.z,\n        p3.y + p3.z\n      ) * p3.zyx);\n    }\n\n    float snoise3(vec3 p) {\n      const float K1 = 0.333333333;\n      const float K2 = 0.166666667;\n      vec3 i = floor(p + (p.x + p.y + p.z) * K1);\n      vec3 d0 = p - (i - (i.x + i.y + i.z) * K2);\n      vec3 e = step(vec3(0.0), d0 - d0.yzx);\n      vec3 i1 = e * (1.0 - e.zxy);\n      vec3 i2 = 1.0 - e.zxy * (1.0 - e);\n      vec3 d1 = d0 - (i1 - K2);\n      vec3 d2 = d0 - (i2 - K1);\n      vec3 d3 = d0 - 0.5;\n      vec4 h = max(0.6 - vec4(\n        dot(d0, d0),\n        dot(d1, d1),\n        dot(d2, d2),\n        dot(d3, d3)\n      ), 0.0);\n      vec4 n = h * h * h * h * vec4(\n        dot(d0, hash33(i)),\n        dot(d1, hash33(i + i1)),\n        dot(d2, hash33(i + i2)),\n        dot(d3, hash33(i + 1.0))\n      );\n      return dot(vec4(31.316), n);\n    }\n\n    vec4 extractAlpha(vec3 colorIn) {\n      float a = max(max(colorIn.r, colorIn.g), colorIn.b);\n      return vec4(colorIn.rgb / (a + 1e-5), a);\n    }\n\n    const float innerRadius = 0.6;\n    const float noiseScale = 0.65;\n\n    float light1(float intensity, float attenuation, float dist) {\n      return intensity / (1.0 + dist * attenuation);\n    }\n\n    float light2(float intensity, float attenuation, float dist) {\n      return intensity / (1.0 + dist * dist * attenuation);\n    }\n\n    vec4 draw(vec2 uv) {\n      vec3 darkColor1 = vec3(0.925490, 0.360784, 0.074510);\n      vec3 darkColor2 = vec3(0.847059, 0.415686, 0.172549);\n      vec3 darkColor3 = vec3(0.180392, 0.180392, 0.180392);\n      vec3 lightColor1 = vec3(0.737255, 0.270588, 0.078431);\n      vec3 lightColor2 = vec3(0.921569, 0.580392, 0.329412);\n      vec3 lightColor3 = vec3(0.929412, 0.890196, 0.811765);\n\n      vec3 color1 = adjustHue(mix(darkColor1, lightColor1, lightMode), hue);\n      vec3 color2 = adjustHue(mix(darkColor2, lightColor2, lightMode), hue);\n      vec3 color3 = mix(darkColor3, lightColor3, lightMode);\n\n      float ang = atan(uv.y, uv.x);\n      float len = length(uv);\n      float invLen = len > 0.0 ? 1.0 / len : 0.0;\n\n      float n0 = snoise3(vec3(uv * noiseScale, iTime * 0.5)) * 0.5 + 0.5;\n      float r0 = mix(mix(innerRadius, 1.0, 0.4), mix(innerRadius, 1.0, 0.6), n0);\n      float d0 = distance(uv, (r0 * invLen) * uv);\n      float v0 = light1(1.0, 10.0, d0);\n      v0 *= smoothstep(r0 * 1.05, r0, len);\n      float cl = cos(ang + iTime * 2.0) * 0.5 + 0.5;\n\n      float a = iTime * -1.0;\n      vec2 pos = vec2(cos(a), sin(a)) * r0;\n      float d = distance(uv, pos);\n      float v1 = light2(1.5, 5.0, d);\n      v1 *= light1(1.0, 50.0, d0);\n\n      float v2 = smoothstep(1.0, mix(innerRadius, 1.0, n0 * 0.5), len);\n      float v3 = smoothstep(innerRadius, mix(innerRadius, 1.0, 0.5), len);\n\n      vec3 col = mix(color1, color2, cl);\n      col = mix(color3, col, v0);\n      col = (col + v1) * v2 * v3;\n      col = clamp(col, 0.0, 1.0);\n\n      return extractAlpha(col);\n    }\n\n    vec4 mainImage(vec2 fragCoord) {\n      vec2 center = iResolution.xy * 0.5;\n      float size = min(iResolution.x, iResolution.y);\n      vec2 uv = (fragCoord - center) / size * 2.0;\n\n      float angle = rot;\n      float s = sin(angle);\n      float c = cos(angle);\n      uv = vec2(c * uv.x - s * uv.y, s * uv.x + c * uv.y);\n\n      uv.x += hover * hoverIntensity * 0.1 * sin(uv.y * 10.0 + iTime);\n      uv.y += hover * hoverIntensity * 0.1 * sin(uv.x * 10.0 + iTime);\n\n      return draw(uv);\n    }\n\n    void main() {\n      vec2 fragCoord = vUv * iResolution.xy;\n      vec4 col = mainImage(fragCoord);\n      vec3 outputColor = mix(col.rgb * col.a, col.rgb, lightMode);\n      gl_FragColor = vec4(outputColor, col.a);\n    }\n  `;\n\n  // Voice analysis function\n  const analyzeAudio = () => {\n    if (!analyserRef.current || !dataArrayRef.current) return 0;\n\n    analyserRef.current.getByteFrequencyData(dataArrayRef.current);\n\n    // Calculate RMS (Root Mean Square) for better voice detection\n    let sum = 0;\n    for (let i = 0; i < dataArrayRef.current.length; i++) {\n      const value = dataArrayRef.current[i] / 255;\n      sum += value * value;\n    }\n    const rms = Math.sqrt(sum / dataArrayRef.current.length);\n\n    // Apply sensitivity and boost the signal\n    const level = Math.min(rms * voiceSensitivity * 3.0, 1);\n\n    return level;\n  };\n\n  // Stop microphone and cleanup\n  const stopMicrophone = () => {\n    try {\n      // Stop all tracks in the media stream\n      if (mediaStreamRef.current) {\n        mediaStreamRef.current.getTracks().forEach(track => {\n          track.stop();\n        });\n        mediaStreamRef.current = null;\n      }\n\n      // Disconnect and cleanup audio nodes\n      if (microphoneRef.current) {\n        microphoneRef.current.disconnect();\n        microphoneRef.current = null;\n      }\n\n      if (analyserRef.current) {\n        analyserRef.current.disconnect();\n        analyserRef.current = null;\n      }\n\n      // Close audio context\n      if (audioContextRef.current && audioContextRef.current.state !== 'closed') {\n        audioContextRef.current.close();\n        audioContextRef.current = null;\n      }\n\n      dataArrayRef.current = null;\n      console.log('Microphone stopped and cleaned up');\n    } catch (error) {\n      console.warn('Error stopping microphone:', error);\n    }\n  };\n\n  // Initialize microphone access\n  const initMicrophone = async () => {\n    try {\n      // Clean up any existing microphone first\n      stopMicrophone();\n\n      const stream = await navigator.mediaDevices.getUserMedia({\n        audio: {\n          echoCancellation: false,  // Better for voice analysis\n          noiseSuppression: false,  // Better for voice analysis\n          autoGainControl: false,   // Better for voice analysis\n          sampleRate: 44100,\n        },\n      });\n\n      // Store the stream reference for cleanup\n      mediaStreamRef.current = stream;\n\n      const AudioContextConstructor =\n        window.AudioContext ||\n        (window as Window & { webkitAudioContext?: typeof AudioContext })\n          .webkitAudioContext;\n\n      if (!AudioContextConstructor) {\n        throw new Error(\"AudioContext is not available in this browser.\");\n      }\n\n      audioContextRef.current = new AudioContextConstructor();\n\n      // Resume audio context if needed\n      if (audioContextRef.current.state === 'suspended') {\n        await audioContextRef.current.resume();\n      }\n\n      analyserRef.current = audioContextRef.current.createAnalyser();\n      microphoneRef.current = audioContextRef.current.createMediaStreamSource(stream);\n\n      // Optimize for voice detection\n      analyserRef.current.fftSize = 512;  // Higher resolution\n      analyserRef.current.smoothingTimeConstant = 0.3;  // Less smoothing for responsiveness\n      analyserRef.current.minDecibels = -90;\n      analyserRef.current.maxDecibels = -10;\n\n      microphoneRef.current.connect(analyserRef.current);\n      dataArrayRef.current = new Uint8Array(analyserRef.current.frequencyBinCount);\n\n      console.log('Microphone initialized successfully');\n      return true;\n    } catch (error) {\n      console.warn(\"Microphone access denied or not available:\", error);\n      return false;\n    }\n  };\n\n  useEffect(() => {\n    const container = ctnDom.current;\n    if (!container) return;\n\n    let rendererInstance: Renderer | null = null;\n    let glContext: Renderer[\"gl\"] | null = null;\n    let rafId: number;\n    let program: Program | null = null;\n\n    try {\n      rendererInstance = new Renderer({\n        alpha: true,\n        premultipliedAlpha: false,\n        antialias: true,\n        dpr: window.devicePixelRatio || 1\n      });\n      glContext = rendererInstance.gl;\n      // Set clear color to transparent to avoid white flash\n      glContext.clearColor(0, 0, 0, 0);\n      // Enable alpha blending for proper transparency\n      glContext.enable(glContext.BLEND);\n      glContext.blendFunc(glContext.SRC_ALPHA, glContext.ONE_MINUS_SRC_ALPHA);\n\n      // Clear any existing canvas\n      while (container.firstChild) {\n        container.removeChild(container.firstChild);\n      }\n      container.appendChild(glContext.canvas as HTMLCanvasElement);\n\n      const geometry = new Triangle(glContext);\n      program = new Program(glContext, {\n        vertex: vert,\n        fragment: frag,\n        uniforms: {\n          iTime: { value: 0 },\n          iResolution: {\n            value: new Vec3(\n              glContext.canvas.width,\n              glContext.canvas.height,\n              glContext.canvas.width / glContext.canvas.height\n            ),\n          },\n          hue: { value: hue },\n          hover: { value: 0 },\n          rot: { value: 0 },\n          hoverIntensity: { value: 0 },\n          lightMode: { value: isLight ? 1 : 0 },\n        },\n      });\n\n      const mesh = new Mesh(glContext, { geometry, program });\n\n      const resize = () => {\n        if (!container || !rendererInstance || !glContext) return;\n        const dpr = window.devicePixelRatio || 1;\n        const width = container.clientWidth;\n        const height = container.clientHeight;\n\n        if (width === 0 || height === 0) return;\n\n        rendererInstance.setSize(width * dpr, height * dpr);\n        glContext.canvas.style.width = width + \"px\";\n        glContext.canvas.style.height = height + \"px\";\n\n        if (program) {\n          program.uniforms.iResolution.value.set(\n            glContext.canvas.width,\n            glContext.canvas.height,\n            glContext.canvas.width / glContext.canvas.height\n          );\n        }\n      };\n      window.addEventListener(\"resize\", resize);\n      resize();\n\n      let lastTime = 0;\n      let currentRot = 0;\n      let voiceLevel = 0;\n      const baseRotationSpeed = 0.3;\n      let isMicrophoneInitialized = false;\n\n      // Initialize or stop microphone based on voice control setting\n      if (enableVoiceControl) {\n        initMicrophone().then((success) => {\n          isMicrophoneInitialized = success;\n        });\n      } else {\n        // Stop microphone when voice control is disabled\n        stopMicrophone();\n        isMicrophoneInitialized = false;\n      }\n\n      const update = (t: number) => {\n        rafId = requestAnimationFrame(update);\n        if (!program) return;\n\n        const dt = (t - lastTime) * 0.001;\n        lastTime = t;\n        program.uniforms.iTime.value = t * 0.001;\n        program.uniforms.hue.value = hue;\n        program.uniforms.lightMode.value = isLight ? 1 : 0;\n\n        // Handle voice input\n        if (enableVoiceControl && isMicrophoneInitialized) {\n          voiceLevel = analyzeAudio();\n\n          // Notify parent component about voice detection\n          if (onVoiceDetected) {\n            onVoiceDetected(voiceLevel > 0.1);\n          }\n\n          // Map voice level to rotation speed with more visible effect\n          const voiceRotationSpeed = baseRotationSpeed + (voiceLevel * maxRotationSpeed * 2.0);\n\n          // Always rotate when there's voice input, even at low levels\n          if (voiceLevel > 0.05) {\n            currentRot += dt * voiceRotationSpeed;\n          }\n\n          // Use voice level to drive hover effects for visual feedback\n          program.uniforms.hover.value = Math.min(voiceLevel * 2.0, 1.0);\n          program.uniforms.hoverIntensity.value = Math.min(voiceLevel * maxHoverIntensity * 0.8, maxHoverIntensity);\n        } else {\n          // Keep effects at 0 when not using voice control\n          program.uniforms.hover.value = 0;\n          program.uniforms.hoverIntensity.value = 0;\n          if (onVoiceDetected) {\n            onVoiceDetected(false);\n          }\n        }\n\n        program.uniforms.rot.value = currentRot;\n\n        if (rendererInstance && glContext) {\n          // Clear the canvas with transparent background before rendering\n          glContext.clear(glContext.COLOR_BUFFER_BIT | glContext.DEPTH_BUFFER_BIT);\n          rendererInstance.render({ scene: mesh });\n        }\n      };\n\n      rafId = requestAnimationFrame(update);\n\n      return () => {\n        cancelAnimationFrame(rafId);\n        window.removeEventListener(\"resize\", resize);\n\n        // Clean up canvas safely\n        if (container && glContext && glContext.canvas) {\n          try {\n            if (container.contains(glContext.canvas)) {\n              container.removeChild(glContext.canvas);\n            }\n          } catch (error) {\n            console.warn(\"Canvas cleanup error:\", error);\n          }\n        }\n\n        // Stop microphone and clean up audio resources\n        stopMicrophone();\n\n        if (glContext) {\n          glContext.getExtension(\"WEBGL_lose_context\")?.loseContext();\n        }\n      };\n\n    } catch (error) {\n      console.error(\"Error initializing Voice Powered Orb:\", error);\n      if (container && container.firstChild) {\n        container.removeChild(container.firstChild);\n      }\n      return () => {\n        window.removeEventListener(\"resize\", () => {});\n      };\n    }\n  }, [\n    hue,\n    isLight,\n    enableVoiceControl,\n    voiceSensitivity,\n    maxRotationSpeed,\n    maxHoverIntensity,\n    vert,\n    frag\n  ]);\n\n  return (\n    <div\n      ref={ctnDom}\n      className={cn(\n        \"w-full h-full relative\",\n        className\n      )}\n    >\n     \n    </div>\n  );\n};\n",
      "type": "registry:component",
      "target": "@components/bjork-ui/interactive/voice-powered-orb.tsx"
    },
    {
      "path": "lib/utils.ts",
      "content": "import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs))\n}\n",
      "type": "registry:lib",
      "target": "@lib/utils.ts"
    }
  ],
  "cssVars": {
    "light": {
      "bjork-bg": "#f7f3ea",
      "bjork-surface": "#fffcf6",
      "bjork-surface-muted": "rgba(250, 246, 237, 0.94)",
      "bjork-surface-hover": "#f5efe3",
      "bjork-surface-active": "#efe7d8",
      "bjork-panel": "#f8f2e7",
      "bjork-menu": "rgba(255, 252, 246, 0.98)",
      "bjork-field": "rgba(255, 252, 246, 0.96)",
      "bjork-field-muted": "rgba(248, 242, 231, 0.82)",
      "bjork-field-inset": "rgba(239, 231, 216, 0.72)",
      "bjork-error-bg": "#fff0e8",
      "bjork-text": "#171717",
      "bjork-text-strong": "rgba(23, 23, 23, 0.9)",
      "bjork-text-medium": "rgba(23, 23, 23, 0.72)",
      "bjork-text-muted": "rgba(23, 23, 23, 0.52)",
      "bjork-text-soft": "rgba(23, 23, 23, 0.36)",
      "bjork-text-faint": "rgba(23, 23, 23, 0.22)",
      "bjork-inverted-text": "#fff8f0",
      "bjork-border": "#eee6db",
      "bjork-border-muted": "#f5ede2",
      "bjork-border-strong": "#e1d7c8",
      "bjork-thumb": "#a49b8e",
      "bjork-track": "#ded6ca",
      "bjork-accent": "#ec7d43",
      "bjork-accent-hover": "#f0935f",
      "bjork-accent-soft": "rgba(236, 125, 67, 0.1)",
      "bjork-accent-muted": "rgba(236, 125, 67, 0.2)",
      "bjork-accent-badge": "rgba(236, 125, 67, 0.16)",
      "bjork-accent-badge-foreground": "#8d421d",
      "bjork-accent-foreground": "#3f2112",
      "bjork-shadow-surface": "inset 0 7px 14px rgba(88, 72, 49, 0.045), inset 0 0.5px 0.5px rgba(255, 255, 255, 0.92), inset 1px 0 0 rgba(88, 72, 49, 0.026), inset -1px 0 0 rgba(255, 255, 255, 0.68), 0 14px 22px -9px rgba(66, 52, 33, 0.11)",
      "bjork-shadow-soft": "inset 0 1px 0 rgba(88, 72, 49, 0.045), inset 0 0.5px 0.5px rgba(255, 255, 255, 0.86)",
      "bjork-shadow-panel": "inset 0 1px 0 rgba(88, 72, 49, 0.04), inset 1px 0 0 rgba(88, 72, 49, 0.024), inset -1px 0 0 rgba(255, 255, 255, 0.64), 0 18px 38px -30px rgba(66, 52, 33, 0.2)",
      "bjork-shadow-menu": "inset 0 1px 0 rgba(88, 72, 49, 0.04), inset 0 12px 24px rgba(88, 72, 49, 0.022), inset 1px 0 0 rgba(88, 72, 49, 0.024), inset -1px 0 0 rgba(255, 255, 255, 0.62), 0 22px 44px -26px rgba(66, 52, 33, 0.22)",
      "bjork-shadow-inset": "inset 0 1px 10px rgba(88, 72, 49, 0.12), inset 0 0.5px 0.5px rgba(255, 255, 255, 0.72)",
      "bjork-ring-offset": "#f7f3ea"
    },
    "dark": {
      "bjork-bg": "#111111",
      "bjork-surface": "#121212",
      "bjork-surface-muted": "rgba(22, 22, 22, 0.92)",
      "bjork-surface-hover": "#161616",
      "bjork-surface-active": "#202020",
      "bjork-panel": "#0d0d0d",
      "bjork-menu": "rgba(18, 18, 18, 0.98)",
      "bjork-field": "rgba(18, 18, 18, 0.95)",
      "bjork-field-muted": "rgba(18, 18, 18, 0.55)",
      "bjork-field-inset": "rgba(9, 9, 9, 0.75)",
      "bjork-error-bg": "#130d0a",
      "bjork-text": "#ededed",
      "bjork-text-strong": "rgba(237, 237, 237, 0.9)",
      "bjork-text-medium": "rgba(237, 237, 237, 0.72)",
      "bjork-text-muted": "rgba(237, 237, 237, 0.52)",
      "bjork-text-soft": "rgba(237, 237, 237, 0.36)",
      "bjork-text-faint": "rgba(237, 237, 237, 0.22)",
      "bjork-inverted-text": "#080808",
      "bjork-border": "#232323",
      "bjork-border-muted": "#1c1c1c",
      "bjork-border-strong": "#343434",
      "bjork-thumb": "#626262",
      "bjork-track": "#090909",
      "bjork-accent": "#ec5c13",
      "bjork-accent-hover": "#f07832",
      "bjork-accent-soft": "rgba(236, 92, 19, 0.12)",
      "bjork-accent-muted": "rgba(236, 92, 19, 0.24)",
      "bjork-accent-badge": "#ec5c13",
      "bjork-accent-badge-foreground": "#fff2ea",
      "bjork-accent-foreground": "#fff2ea",
      "bjork-shadow-surface": "inset 0 7px 14px rgba(255, 255, 255, 0.03), inset 0 0.5px 0.5px rgba(255, 255, 255, 0.06), 0 14px 20px -6px rgba(0, 0, 0, 0.45)",
      "bjork-shadow-soft": "inset 0 1px 0 rgba(255, 255, 255, 0.045)",
      "bjork-shadow-panel": "inset 0 1px 0 rgba(255, 255, 255, 0.035), 0 18px 36px -28px rgba(0, 0, 0, 0.9)",
      "bjork-shadow-menu": "inset 0 1px 0 rgba(255, 255, 255, 0.055), inset 0 12px 24px rgba(255, 255, 255, 0.018), inset 0 -18px 26px rgba(0, 0, 0, 0.24), 0 22px 42px -22px rgba(0, 0, 0, 0.9)",
      "bjork-shadow-inset": "inset 0 1px 10px rgba(0, 0, 0, 0.45)",
      "bjork-ring-offset": "#080808"
    }
  },
  "css": {
    ".bjork-range": {
      "box-shadow": "inset 0 1px 1px rgba(255, 255, 255, 0.04), 0 0 14px rgba(189, 69, 20, 0.06)"
    },
    ".bjork-range::-webkit-slider-thumb": {
      "appearance": "none",
      "width": "16px",
      "height": "8px",
      "border": "0",
      "border-radius": "999px",
      "background": "var(--bjork-thumb)",
      "box-shadow": "inset 0 1px 0 rgba(255, 255, 255, 0.18), 0 0 0 1px rgba(0, 0, 0, 0.42)"
    },
    ".bjork-range::-moz-range-thumb": {
      "width": "16px",
      "height": "8px",
      "border": "0",
      "border-radius": "999px",
      "background": "var(--bjork-thumb)",
      "box-shadow": "inset 0 1px 0 rgba(255, 255, 255, 0.18), 0 0 0 1px rgba(0, 0, 0, 0.42)"
    },
    ".bjork-layered-button-accent, .bjork-layered-button-raised": {
      "position": "relative",
      "isolation": "isolate",
      "appearance": "none",
      "overflow": "hidden",
      "border": "0",
      "border-radius": "13px",
      "box-shadow": "inset 0 1px 0 #ffffff38, 0 4px 6px -1px #0000001a, 0 2px 4px -2px #0000001a",
      "transition": "filter 150ms ease-out, box-shadow 150ms ease-out"
    },
    ".bjork-layered-button-accent::after, .bjork-layered-button-raised::after": {
      "position": "absolute",
      "inset": "0",
      "pointer-events": "none",
      "content": "\"\"",
      "border": "1.5px solid transparent",
      "border-radius": "inherit",
      "background": "linear-gradient(#ffffffb8, #0000003d 41% 75%, #ffffff47) border-box",
      "mix-blend-mode": "overlay",
      "-webkit-mask-image": "linear-gradient(#000, #000), linear-gradient(#000, #000)",
      "mask-image": "linear-gradient(#000, #000), linear-gradient(#000, #000)",
      "-webkit-mask-clip": "padding-box, border-box",
      "mask-clip": "padding-box, border-box",
      "-webkit-mask-origin": "padding-box, border-box",
      "mask-origin": "padding-box, border-box",
      "-webkit-mask-composite": "xor",
      "mask-composite": "exclude"
    },
    ".bjork-layered-button-accent": {
      "color": "oklch(100% 0 0)",
      "text-shadow": "0 -1px #00000040",
      "background": "radial-gradient(ellipse at -20px top, rgba(255, 255, 255, 0.14), transparent), linear-gradient(180deg, #ec5c13 0%, #ec5c13 62%, color-mix(in oklab, #ec5c13 84%, black 16%) 100%)"
    },
    ".bjork-layered-button-raised": {
      "color": "oklch(100% 0 0)",
      "text-shadow": "0 -1px #00000026",
      "background": "radial-gradient(ellipse at -20px top, #ffffff38, #fff0), linear-gradient(180deg, oklch(0.1881 0.006 265), oklch(0.5493 0.0081 265))"
    },
    ".dark .bjork-layered-button-raised": {
      "color": "oklch(0.2574 0.0056 265)",
      "text-shadow": "0 -1px #00000026",
      "background": "radial-gradient(ellipse at -20px top, #ffffff38, #fff0), linear-gradient(180deg, color-mix(in oklab, oklch(0.9674 0.0013 265) 80%, oklch(0.2574 0.0056 265) 20%), color-mix(in oklab, oklch(0.669 0.0107 265) 80%, oklch(0.2574 0.0056 265) 20%))"
    },
    "@media (hover: hover)": {
      ".bjork-layered-button-accent:hover": {
        "filter": "brightness(1.08) saturate(1.04)"
      },
      ".bjork-layered-button-raised:hover": {
        "filter": "brightness(1.08) contrast(0.9)"
      }
    }
  },
  "meta": {
    "collection": "Interactive",
    "registryUrl": "https://ui.isaiahbjork.com/voice-powered-orb.json",
    "installCommand": "npx shadcn@latest add https://ui.isaiahbjork.com/voice-powered-orb.json"
  },
  "type": "registry:component"
}