{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "realistic-button",
  "type": "registry:component",
  "title": "Realistic Button",
  "author": "Harsh Kanjiya <https://harshkanjiya.com>",
  "description": "A skeuomorphic realistic button with hover and active states.",
  "dependencies": [],
  "devDependencies": [],
  "registryDependencies": [],
  "files": [
    {
      "path": "components/realistic-button/realistic-button.tsx",
      "content": "'use client';\r\n\r\nimport { useState, useEffect } from 'react';\r\nimport styles from './realistic-button.module.css';\r\nimport { useSound } from '@/hooks/use-sound';\r\n\r\ntype TextState = 'off' | 'drawing' | 'on';\r\n\r\nexport default function RealisticButton() {\r\n    const [isActive, setIsActive] = useState(false);\r\n    const [isPressed, setIsPressed] = useState(false);\r\n    const [textState, setTextState] = useState<TextState>('off');\r\n\r\n    const playClick = useSound(\"/audio/ui-sounds/mech-key-press.mp3\");\r\n\r\n    useEffect(() => {\r\n        if (isActive) {\r\n            setTextState('drawing');\r\n            const timer = setTimeout(() => setTextState('on'), 900);\r\n            return () => clearTimeout(timer);\r\n        } else {\r\n            setTextState('off');\r\n        }\r\n    }, [isActive]);\r\n\r\n    const onClick = () => {\r\n        playClick();\r\n        setIsPressed(true);\r\n        setIsActive(false);\r\n        setTimeout(() => setIsPressed(false), 200);\r\n    }\r\n\r\n    return (\r\n        <div className={`${styles.wrap} sm:scale-[0.6] scale-[0.5]`}>\r\n            <button\r\n                className={`${styles.button} ${isPressed ? styles.buttonPressed : ''} relative overflow-hidden w-[250px] h-[96px] bg-black z-20 border-transparent rounded-[24px]`}\r\n                onMouseEnter={() => setIsActive(true)}\r\n                onClick={onClick}\r\n                onMouseLeave={() => { setIsActive(false); setIsPressed(false); }}\r\n                onMouseDown={() => setIsPressed(true)}\r\n                onMouseUp={() => setIsPressed(false)}\r\n                onTouchStart={() => setIsPressed(true)}\r\n                onTouchEnd={() => setIsPressed(false)}\r\n                style={{\r\n                    boxShadow: isActive || isPressed\r\n                        ? 'inset 0 1px 1px rgba(255, 255, 255, 0.6), inset 0 -6px 1px -4px #ff7300, inset 0 -15px 6px -8px #cc5500,'\r\n                        : 'inset 0 1px 1px rgb(255 255 255 / 40%), inset 0 -6px 1px -4px #ff7300, inset 0 -15px 6px -8px #ff6600',\r\n                    transform: isPressed ? 'scale(0.94)' : 'scale(1)',\r\n                    transition: isPressed\r\n                        ? 'transform 0.07s ease, box-shadow 0.07s ease'\r\n                        : 'transform 0.2s ease, box-shadow 0.3s ease',\r\n                }}\r\n            >\r\n                <div className={`${styles.corner} absolute opacity-10 transition-all duration-400`}></div>\r\n\r\n                <div\r\n                    className={`${styles.inner} z-10 absolute flex items-center justify-center rounded-[20px] transition-all duration-300`}\r\n                    style={{\r\n                        inset: '14px 13px',\r\n                        background: 'linear-gradient(180deg, #232324 5%, #46484b 100%)',\r\n                        boxShadow: 'inset 0 -5px 15px -1px rgba(0, 0, 0, 0.3), inset 0 -4px 3px -3px black, inset 0 -10px 20px -8px rgb(255 255 255 / 40%), inset 0 1px 0 1px rgb(255 255 255 / 20%)'\r\n                    }}\r\n                >\r\n                    <svg\r\n                        width=\"100%\"\r\n                        height=\"100%\"\r\n                        viewBox=\"0 0 184 68\"\r\n                        xmlns=\"http://www.w3.org/2000/svg\"\r\n                        style={{ overflow: 'visible' }}\r\n                    >\r\n                        {/* {showGlow && (\r\n                            <text\r\n                                x=\"92\"\r\n                                y=\"34\"\r\n                                dominantBaseline=\"middle\"\r\n                                textAnchor=\"middle\"\r\n                                className={glowClass}\r\n                            >\r\n                                Start For Free\r\n                            </text>\r\n                        )} */}\r\n                        <text\r\n                            x=\"92\"\r\n                            y=\"34\"\r\n                            dominantBaseline=\"middle\"\r\n                            textAnchor=\"middle\"\r\n                            className={isPressed ? styles.svgTextBlink : ''}\r\n                            style={{ fontSize: '26px', fill: isPressed ? 'rgb(147 147 147)' : 'rgb(247 245 243 / 70%)' }}\r\n                        >\r\n                            Start For Free\r\n                        </text>\r\n                    </svg>\r\n                </div>\r\n            </button>\r\n\r\n            <div\r\n                className={`${styles.led} absolute z-30 rounded-full w-1.5 h-1.5`}\r\n                style={{\r\n                    top: '100%',\r\n                    marginTop: '14px',\r\n                    backgroundColor: '#f35f3a',\r\n                    boxShadow: '0 -10px 35px 17px #ff5100, inset 0 1px 2px 0px rgba(255, 255, 255, 0.6), 0 0 0px 3px rgb(0 0 0 / 60%), 0 0 2px 4px rgba(152, 81, 0, 0.8)',\r\n                }}\r\n            ></div>\r\n\r\n            <div\r\n                className={`${styles.bg} absolute z-10 bg-black rounded-[30px] overflow-hidden`}\r\n                style={{\r\n                    inset: '-5px',\r\n                    boxShadow: isPressed\r\n                        ? '0 20px 10px -10px rgba(0, 0, 0, 0.3), inset 4px 0 18px 6px rgba(0, 0, 0, 0.95), inset -4px 0 18px 6px rgba(0, 0, 0, 0.95), inset 0 4px 18px 6px rgba(0, 0, 0, 0.95), inset 0 -4px 18px 6px rgba(0, 0, 0, 0.95)'\r\n                        : isActive\r\n                            ? '0 20px 10px -10px rgba(0, 0, 0, 0.3), inset 0 0 28px 10px rgba(255, 100, 0, 0.45)'\r\n                            : '0 20px 10px -10px rgba(0, 0, 0, 0.3)',\r\n                    transition: isPressed ? 'box-shadow 0.07s ease' : 'box-shadow 0.25s ease',\r\n                }}\r\n            >\r\n                <div\r\n                    className=\"absolute inset-0 rounded-[30px] z-10 pointer-events-none\"\r\n                    style={{\r\n                        boxShadow:\r\n                            'inset 0 -2px 0px -1px rgb(120 176 255 / 32%), inset 0 0 5px 1px black, inset 0 0 0 1px black',\r\n                    }}\r\n                ></div>\r\n                <div\r\n                    className={`${styles.shine1} absolute`}\r\n                    style={{\r\n                        width: '10px',\r\n                        height: '10px',\r\n                        left: '50%',\r\n                        bottom: '0',\r\n                        transform: 'translateX(-50%)',\r\n                        margin: 'auto',\r\n                        borderRadius: '50%',\r\n                        filter: 'blur(2px)',\r\n                        backgroundColor: 'rgb(255, 115, 0)',\r\n                    }}\r\n                ></div>\r\n                <div className={`${styles.shine2} absolute transition-all duration-500 opacity-0`}></div>\r\n            </div>\r\n\r\n            <div className={`${styles.bgGlow} absolute z-0 transition-all duration-500`}></div>\r\n        </div>\r\n    );\r\n}\r\n",
      "type": "registry:component"
    },
    {
      "path": "components/realistic-button/index.ts",
      "content": "export { default as RealisticButton } from \"./realistic-button\"\r\n",
      "type": "registry:component"
    },
    {
      "path": "components/realistic-button/realistic-button.module.css",
      "content": ".wrap {\r\n    --radius: 24px;\r\n    --bg: #000000;\r\n    display: flex;\r\n    align-items: center;\r\n    justify-content: center;\r\n    flex-direction: column;\r\n    position: relative;\r\n    pointer-events: none;\r\n    width: fit-content;\r\n}\r\n\r\n.wrap::before {\r\n    content: \"\";\r\n    position: absolute;\r\n    width: 250%;\r\n    height: 250%;\r\n    border-radius: var(--radius);\r\n    background-color: rgba(255, 255, 255, 0.05);\r\n    filter: blur(60px);\r\n    transform: skewY(-20deg);\r\n}\r\n\r\n.wrap::after {\r\n    content: \"\";\r\n    position: absolute;\r\n    width: 100%;\r\n    height: 100%;\r\n    border-radius: var(--radius);\r\n    background-color: rgba(0, 0, 0, 0.5);\r\n    filter: blur(30px);\r\n}\r\n\r\n.button {\r\n    box-shadow: inset 0 1px 1px rgb(255 255 255 / 40%),\r\n        inset 0 -6px 1px -4px #ff7300,\r\n        inset 0 -15px 6px -8px #ff6600;\r\n    cursor: pointer;\r\n    pointer-events: auto;\r\n}\r\n\r\n.button::before {\r\n    content: \"\";\r\n    position: absolute;\r\n    inset: 0;\r\n    border-radius: calc(var(--radius) * 0.8);\r\n    border-top: 40px solid #414244;\r\n    border-left: 32px solid #2b2b2c;\r\n    border-right: 32px solid #2b2b2c;\r\n    border-bottom: 40px solid #15161a;\r\n    filter: blur(5px);\r\n    transition: all 0.5s ease;\r\n}\r\n\r\n.button::after {\r\n    content: \"\";\r\n    position: absolute;\r\n    left: 0;\r\n    right: 0;\r\n    margin: auto;\r\n    top: 101%;\r\n    height: 40px;\r\n    width: 96px;\r\n    border-radius: 40px 40px 0 0;\r\n    background: #ff7300;\r\n    filter: contrast(10) blur(7px);\r\n    transition: all 0.3s ease;\r\n    opacity: 1;\r\n}\r\n\r\n.buttonActive::after {\r\n    width: 120px;\r\n    background: #ff9500;\r\n    filter: contrast(12) blur(9px);\r\n}\r\n\r\n.buttonPressed::before {\r\n    border-top: 16px solid #414244;\r\n    border-left: 18px solid #2b2b2c;\r\n    border-right: 18px solid #2b2b2c;\r\n    border-bottom: 16px solid #15161a;\r\n    transition: all 0.07s ease;\r\n}\r\n\r\n/* --- corners --- */\r\n\r\n.corner {\r\n    transition: all 0.4s ease;\r\n    opacity: 0.1;\r\n}\r\n\r\n.corner::before,\r\n.corner::after {\r\n    content: \"\";\r\n    position: absolute;\r\n    top: 0;\r\n    border-top: 44px solid white;\r\n    border-left: 12px solid transparent;\r\n    border-right: 12px solid transparent;\r\n    filter: blur(5px);\r\n    transition: all 0.4s ease;\r\n}\r\n\r\n.corner::before {\r\n    left: 8px;\r\n    transform: rotate(-40deg);\r\n}\r\n\r\n.corner::after {\r\n    right: 8px;\r\n    transform: rotate(40deg);\r\n}\r\n\r\n.cornerActive {\r\n    opacity: 0.65;\r\n}\r\n\r\n.cornerActive::before,\r\n.cornerActive::after {\r\n    border-top-color: #ff8c00;\r\n    filter: blur(5px);\r\n}\r\n\r\n/* --- inner panel --- */\r\n\r\n.inner {\r\n    transition: all 0.3s ease;\r\n}\r\n\r\n/* --- svg text states --- */\r\n\r\n.svgTextOff {\r\n    fill: #0a0a0a;\r\n    stroke: none;\r\n    font-size: 14px;\r\n    font-weight: 600;\r\n    letter-spacing: 1.5px;\r\n    font-family: inherit;\r\n}\r\n\r\n.svgTextDrawing {\r\n    fill: #0a0a0a;\r\n    stroke: #ff9040;\r\n    stroke-width: 0.6;\r\n    stroke-dasharray: 1000;\r\n    font-size: 14px;\r\n    font-weight: 600;\r\n    letter-spacing: 1.5px;\r\n    font-family: inherit;\r\n    animation: drawText 0.9s ease forwards;\r\n}\r\n\r\n.svgTextOn {\r\n    fill: #ff9040;\r\n    stroke: #ff9040;\r\n    stroke-width: 0.3;\r\n    stroke-dashoffset: 0;\r\n    font-size: 14px;\r\n    font-weight: 600;\r\n    letter-spacing: 1.5px;\r\n    font-family: inherit;\r\n}\r\n\r\n.svgTextGlowDrawing {\r\n    fill: transparent;\r\n    stroke: #ce7c02;\r\n    stroke-width: 14;\r\n    stroke-dasharray: 1000;\r\n    font-size: 14px;\r\n    font-weight: 600;\r\n    letter-spacing: 1.5px;\r\n    font-family: inherit;\r\n    filter: blur(6px);\r\n    opacity: 0.5;\r\n    animation: drawText 0.9s ease forwards;\r\n}\r\n\r\n.svgTextGlowOn {\r\n    fill: #ce7c02;\r\n    stroke: none;\r\n    font-size: 14px;\r\n    font-weight: 600;\r\n    letter-spacing: 1.5px;\r\n    font-family: inherit;\r\n    filter: blur(6px);\r\n    opacity: 0.5;\r\n}\r\n\r\n@keyframes drawText {\r\n    from {\r\n        stroke-dashoffset: 1000;\r\n    }\r\n\r\n    to {\r\n        stroke-dashoffset: 0;\r\n    }\r\n}\r\n\r\n.svgTextBlink {\r\n    animation: textBlink 0.5s step-end infinite;\r\n}\r\n\r\n@keyframes textBlink {\r\n\r\n    0%,\r\n    100% {\r\n        opacity: 1;\r\n    }\r\n\r\n    100% {\r\n        opacity: 0.4;\r\n    }\r\n}\r\n\r\n/* --- symbol body --- */\r\n\r\n.symbol {\r\n    fill: #212123;\r\n    transition: fill 0.4s ease;\r\n}\r\n\r\n.symbolActive {\r\n    fill: #2a1808;\r\n}\r\n\r\n/* --- symbol stroke paths (idle: animated draw) --- */\r\n\r\n.symbolPath {\r\n    filter: brightness(1.1) contrast(1.1);\r\n}\r\n\r\n.symbolPath path {\r\n    stroke-dasharray: 650;\r\n    stroke-dashoffset: -650;\r\n    stroke-width: 5;\r\n    stroke: #ff7a3c;\r\n    animation: symbolPath 2s ease-in-out;\r\n}\r\n\r\n.symbolPathGlow path {\r\n    stroke-dasharray: 650;\r\n    stroke-dashoffset: -650;\r\n    stroke-width: 30;\r\n    stroke: #ce7c02;\r\n    filter: blur(30px);\r\n    animation: symbolPath 2s ease-in-out;\r\n}\r\n\r\n.symbolPath circle {\r\n    fill: #ff593c;\r\n    opacity: 0;\r\n    animation: symbolCircle 2s ease-in-out;\r\n}\r\n\r\n.symbolPathGlow circle {\r\n    fill: #ce7c02;\r\n    filter: blur(30px);\r\n    opacity: 0;\r\n    animation: symbolCircle 2s ease-in-out;\r\n}\r\n\r\n/* --- symbol stroke paths (active: persistent orange glow) --- */\r\n\r\n.symbolPathActive path {\r\n    stroke-dashoffset: 0;\r\n    stroke: #ff9040;\r\n    animation: symbolGlowPulse 1.5s ease-in-out infinite alternate;\r\n    opacity: 1;\r\n}\r\n\r\n.symbolPathGlowActive path {\r\n    stroke-dashoffset: 0;\r\n    animation: symbolGlowPulse 1.5s ease-in-out infinite alternate;\r\n    opacity: 0.75;\r\n}\r\n\r\n.symbolPathActive circle {\r\n    opacity: 1;\r\n    animation: symbolGlowPulse 1.5s ease-in-out infinite alternate;\r\n}\r\n\r\n.symbolPathGlowActive circle {\r\n    opacity: 0.6;\r\n    animation: symbolGlowPulse 1.5s ease-in-out infinite alternate;\r\n}\r\n\r\n/* --- background layers --- */\r\n\r\n.bg {\r\n    border-radius: calc(var(--radius) * 1.25);\r\n}\r\n\r\n.bg::before {\r\n    content: \"\";\r\n    position: absolute;\r\n    border-radius: inherit;\r\n    inset: 0;\r\n    z-index: 1;\r\n}\r\n\r\n.shine1 {\r\n    animation: bg 2.4s linear 0.3s infinite;\r\n}\r\n\r\n.shine2 {\r\n    transition: all 0.5s linear;\r\n}\r\n\r\n.shine2::before {\r\n    content: \"\";\r\n    position: absolute;\r\n    z-index: 0;\r\n    transition: all 0.3s ease;\r\n    background: rgb(255, 115, 0);\r\n    width: 10px;\r\n    height: 10px;\r\n    left: 0;\r\n    right: 0;\r\n    bottom: 0;\r\n    margin: auto;\r\n    border-radius: 50%;\r\n    filter: blur(2px);\r\n    animation: bg 2.4s linear infinite;\r\n}\r\n\r\n.bgGlow {\r\n    position: absolute;\r\n    inset: 0;\r\n    border-radius: calc(var(--radius) * 1.25);\r\n    transition: all 0.5s linear;\r\n}\r\n\r\n.bgGlow::before {\r\n    content: \"\";\r\n    position: absolute;\r\n    inset: 0;\r\n    border-radius: inherit;\r\n    background: linear-gradient(to bottom, #ff7300 0%, black 100%);\r\n    filter: blur(12px);\r\n    opacity: 0;\r\n    animation: bgGlow 3s linear infinite;\r\n}\r\n\r\n.led {\r\n    animation: none;\r\n}\r\n\r\n/* --- keyframes --- */\r\n\r\n@keyframes symbolPath {\r\n    0% {\r\n        stroke-dashoffset: -650;\r\n    }\r\n\r\n    50% {\r\n        stroke-dashoffset: 0;\r\n    }\r\n\r\n    100% {\r\n        stroke-dashoffset: 650;\r\n    }\r\n}\r\n\r\n@keyframes symbolCircle {\r\n    0% {\r\n        opacity: 0;\r\n    }\r\n\r\n    50% {\r\n        opacity: 1;\r\n    }\r\n\r\n    100% {\r\n        opacity: 0;\r\n    }\r\n}\r\n\r\n@keyframes symbolGlowPulse {\r\n    0% {\r\n        opacity: 0.8;\r\n    }\r\n\r\n    100% {\r\n        opacity: 1;\r\n    }\r\n}\r\n\r\n@keyframes bg {\r\n    0% {\r\n        transform: translateY(0) scale(0);\r\n    }\r\n\r\n    12% {\r\n        transform: translateY(0) scale(25);\r\n    }\r\n\r\n    60%,\r\n    100% {\r\n        transform: translateY(-280px) scale(20, 18);\r\n    }\r\n}\r\n\r\n@keyframes bgGlow {\r\n    0% {\r\n        opacity: 0;\r\n    }\r\n\r\n    40% {\r\n        opacity: 1;\r\n    }\r\n\r\n    80%,\r\n    100% {\r\n        opacity: 0;\r\n    }\r\n}\r\n\r\n@keyframes bgGlowPulse {\r\n    0% {\r\n        opacity: 0.6;\r\n        filter: blur(20px);\r\n    }\r\n\r\n    100% {\r\n        opacity: 0.9;\r\n        filter: blur(25px);\r\n    }\r\n}\r\n\r\n@keyframes ledPulse {\r\n    0% {\r\n        box-shadow: 0 -5px 14px 4px #ff7300,\r\n            inset 0 1px 2px 0px rgba(255, 255, 255, 0.6),\r\n            0 0 0px 2px rgba(255, 130, 0, 0.25);\r\n    }\r\n\r\n    100% {\r\n        box-shadow: 0 -6px 18px 6px #ff9500,\r\n            inset 0 1px 2px 0px rgba(255, 255, 255, 0.8),\r\n            0 0 0px 2px rgba(255, 160, 0, 0.35);\r\n    }\r\n}\r\n\r\n@keyframes reflexLedTurnOff {\r\n\r\n    30%,\r\n    60% {\r\n        box-shadow: inset 0 1px 1px rgba(255, 255, 255, 0.4),\r\n            inset 0 -6px 1px -4px #9b8100,\r\n            inset 0 -15px 6px -8px #373326;\r\n    }\r\n\r\n    60.1%,\r\n    65% {\r\n        box-shadow: inset 0 1px 1px rgba(255, 255, 255, 0.4),\r\n            inset 0 -6px 1px -4px rgba(255, 255, 255, 0.1),\r\n            inset 0 -15px 6px -8px rgba(255, 255, 255, 0.1);\r\n    }\r\n\r\n    65.1%,\r\n    70% {\r\n        box-shadow: inset 0 1px 1px rgb(255 255 255 / 40%),\r\n            inset 0 -6px 1px -4px #9b8100,\r\n            inset 0 -15px 6px -8px #373326;\r\n    }\r\n\r\n    70.1%,\r\n    100% {\r\n        box-shadow: inset 0 1px 1px rgba(255, 255, 255, 0.4),\r\n            inset 0 -6px 1px -4px rgba(255, 255, 255, 0.1),\r\n            inset 0 -15px 6px -8px rgba(255, 255, 255, 0.1);\r\n    }\r\n}\r\n\r\n@keyframes reflexLedBlurTurnOff {\r\n\r\n    30%,\r\n    60% {\r\n        background: #ffc400;\r\n    }\r\n\r\n    60.1%,\r\n    65% {\r\n        background: transparent;\r\n    }\r\n\r\n    65.1%,\r\n    70% {\r\n        background: #ffc400;\r\n    }\r\n\r\n    70.1%,\r\n    100% {\r\n        background: transparent;\r\n    }\r\n}\r\n\r\n@keyframes bgBeforeTurnOff {\r\n\r\n    30%,\r\n    60% {\r\n        box-shadow: inset 0 -2px 0px -1px rgba(255, 230, 120, 0.3),\r\n            inset 0 0 5px 1px black,\r\n            inset 0 0 0 1px black;\r\n    }\r\n\r\n    60.1%,\r\n    65% {\r\n        box-shadow: inset 0 -2px 0px -1px rgba(160, 160, 160, 0.3),\r\n            inset 0 0 5px 1px black,\r\n            inset 0 0 0 1px black;\r\n    }\r\n\r\n    65.1%,\r\n    70% {\r\n        box-shadow: inset 0 -2px 0px -1px rgba(255, 230, 120, 0.3),\r\n            inset 0 0 5px 1px black,\r\n            inset 0 0 0 1px black;\r\n    }\r\n\r\n    70.1%,\r\n    100% {\r\n        box-shadow: inset 0 -2px 0px -1px rgba(160, 160, 160, 0.3),\r\n            inset 0 0 5px 1px black,\r\n            inset 0 0 0 1px black;\r\n    }\r\n}",
      "type": "registry:file",
      "target": "components/realistic-button/realistic-button.module.css"
    },
    {
      "path": "hooks/use-sound.ts",
      "content": "import { useCallback, useEffect, useRef } from \"react\";\n\n/**\n * Custom React hook to load and play a sound from a given URL using the Web Audio API.\n *\n * This hook fetches the audio file at the specified URL, decodes it, and prepares it for playback.\n * It returns a `play` function that can be called to play the loaded sound.\n *\n * @param url - The URL of the audio file to load and play.\n * @returns A function that, when called, plays the loaded sound.\n *\n * @remarks\n * - If the Web Audio API is not supported in the browser, a warning is logged and playback is disabled.\n * - The audio context and buffer are managed internally using React refs.\n * - Errors during fetching or decoding the audio are logged to the console.\n *\n * @example\n * ```tsx\n * const playClick = useSound('/sounds/click.mp3');\n * // Later in an event handler:\n * playClick();\n * ```\n */\nexport function useSound(url: string) {\n  const audioCtxRef = useRef<AudioContext | null>(null);\n  const bufferRef = useRef<AudioBuffer | null>(null);\n\n  useEffect(() => {\n    const AudioContextClass =\n      window.AudioContext ||\n      (window as unknown as { webkitAudioContext: typeof AudioContext })\n        .webkitAudioContext;\n\n    if (!AudioContextClass) {\n      console.warn(\"Web Audio API is not supported in this browser.\");\n      return;\n    }\n\n    const audioCtx = new AudioContextClass();\n    audioCtxRef.current = audioCtx;\n\n    fetch(url)\n      .then((res) => res.arrayBuffer())\n      .then((data) => audioCtx.decodeAudioData(data))\n      .then((decoded) => {\n        bufferRef.current = decoded;\n      })\n      .catch((err) => {\n        console.log(`Failed to load click sound from ${url}:`, err);\n      });\n  }, [url]);\n\n  const play = useCallback((volume: number = 1) => {\n    if (audioCtxRef.current && bufferRef.current) {\n      const source = audioCtxRef.current.createBufferSource();\n      const gainNode = audioCtxRef.current.createGain();\n\n      source.buffer = bufferRef.current;\n      gainNode.gain.value = volume;\n\n      source.connect(gainNode);\n      gainNode.connect(audioCtxRef.current.destination);\n      source.start(0);\n    }\n  }, []);\n\n  return play;\n}\n",
      "type": "registry:hook"
    }
  ]
}