{
  "$schema": "https://ui.shadcn.com/schema/registry.json",
  "name": "morphiq",
  "homepage": "https://morphiq.prathampatel.design",
  "items": [
    {
      "name": "prism-glass",
      "type": "registry:component",
      "title": "Prism Glass",
      "description": "A GPU-accelerated refractive lens for images and rendered textures. Spectral dispersion, uniform frost and a directional rim light, from an SDF-defined shape — no 3D model required. It refracts the texture you give it, not the DOM behind it.",
      "dependencies": [
        "three",
        "@react-three/fiber",
        "@react-three/drei",
        "maath"
      ],
      "files": [
        {
          "path": "packages/prism-glass/src/index.js",
          "type": "registry:component",
          "target": "components/prism-glass/index.js"
        },
        {
          "path": "packages/prism-glass/src/PrismGlass.jsx",
          "type": "registry:component",
          "target": "components/prism-glass/PrismGlass.jsx"
        },
        {
          "path": "packages/prism-glass/src/shader.js",
          "type": "registry:component",
          "target": "components/prism-glass/shader.js"
        },
        {
          "path": "packages/prism-glass/src/sdf.js",
          "type": "registry:component",
          "target": "components/prism-glass/sdf.js"
        },
        {
          "path": "packages/prism-glass/types/index.d.ts",
          "type": "registry:file",
          "target": "components/prism-glass/index.d.ts"
        }
      ]
    },
    {
      "name": "dock",
      "type": "registry:component",
      "title": "Magnifying Dock",
      "description": "A dock whose items swell as the pointer nears, on springs. Distance drives the scale, so the row breathes rather than one icon popping.",
      "dependencies": [
        "framer-motion",
        "gsap",
        "@gsap/react"
      ],
      "files": [
        {
          "path": "src/components/Dock/index.js",
          "type": "registry:component",
          "target": "components/dock/index.js"
        },
        {
          "path": "src/components/Dock/Dock.jsx",
          "type": "registry:component",
          "target": "components/dock/Dock.jsx"
        },
        {
          "path": "src/components/Dock/Icons.jsx",
          "type": "registry:component",
          "target": "components/dock/Icons.jsx"
        },
        {
          "path": "src/components/Dock/Dock.css",
          "type": "registry:file",
          "target": "components/dock/Dock.css"
        },
        {
          "path": "src/components/Dock/Dock.d.ts",
          "type": "registry:file",
          "target": "components/dock/Dock.d.ts"
        }
      ]
    },
    {
      "name": "ferrofluid-nav",
      "type": "registry:component",
      "title": "Ferrofluid Nav",
      "description": "A nav whose active pill stretches out of one item, thins to a neck and gathers into the next. Two capsule fields blended with a polynomial smooth-minimum, evaluated per pixel — the neck is surface tension, not a translate.",
      "dependencies": [],
      "files": [
        {
          "path": "src/components/FerrofluidNav/index.js",
          "type": "registry:component",
          "target": "components/ferrofluid-nav/index.js"
        },
        {
          "path": "src/components/FerrofluidNav/FerrofluidNav.jsx",
          "type": "registry:component",
          "target": "components/ferrofluid-nav/FerrofluidNav.jsx"
        },
        {
          "path": "src/components/FerrofluidNav/FerrofluidNav.css",
          "type": "registry:file",
          "target": "components/ferrofluid-nav/FerrofluidNav.css"
        },
        {
          "path": "src/components/FerrofluidNav/FerrofluidNav.d.ts",
          "type": "registry:file",
          "target": "components/ferrofluid-nav/FerrofluidNav.d.ts"
        }
      ]
    },
    {
      "name": "elastic-headline",
      "type": "registry:component",
      "title": "Elastic Headline",
      "description": "A headline strung on an elastic. Letters are nodes on a mass-spring chain pinned at both ends and coupled by the discrete Laplacian, so a pull travels outward and reflects off the ends — grab one and the whole line deforms, then rings out.",
      "dependencies": [],
      "files": [
        {
          "path": "src/components/ElasticHeadline/index.js",
          "type": "registry:component",
          "target": "components/elastic-headline/index.js"
        },
        {
          "path": "src/components/ElasticHeadline/ElasticHeadline.jsx",
          "type": "registry:component",
          "target": "components/elastic-headline/ElasticHeadline.jsx"
        },
        {
          "path": "src/components/ElasticHeadline/ElasticHeadline.css",
          "type": "registry:file",
          "target": "components/elastic-headline/ElasticHeadline.css"
        },
        {
          "path": "src/components/ElasticHeadline/ElasticHeadline.d.ts",
          "type": "registry:file",
          "target": "components/elastic-headline/ElasticHeadline.d.ts"
        }
      ]
    },
    {
      "name": "pressure-text",
      "type": "registry:component",
      "title": "Pressure Text",
      "description": "Type that reacts to the cursor. Letters thicken and widen under the pointer while their neighbours give up the space, so the word keeps its overall width. Both axes are synthesised from a single cut, so it morphs rather than cross-dissolving between weights.",
      "dependencies": [],
      "files": [
        {
          "path": "src/components/PressureText/index.js",
          "type": "registry:component",
          "target": "components/pressure-text/index.js"
        },
        {
          "path": "src/components/PressureText/PressureText.jsx",
          "type": "registry:component",
          "target": "components/pressure-text/PressureText.jsx"
        },
        {
          "path": "src/components/PressureText/PressureText.css",
          "type": "registry:file",
          "target": "components/pressure-text/PressureText.css"
        },
        {
          "path": "src/components/PressureText/PressureText.d.ts",
          "type": "registry:file",
          "target": "components/pressure-text/PressureText.d.ts"
        }
      ]
    },
    {
      "name": "scroll-expand",
      "type": "registry:component",
      "title": "Scroll Expand",
      "description": "A framed panel pinned to the viewport that opens out to full bleed as you scroll past it, with the media inside settling back from a slight push-in. Progress is published as two CSS custom properties, so anything you drop inside can join the animation with one line of CSS.",
      "dependencies": [],
      "files": [
        {
          "path": "src/components/ScrollExpand/index.js",
          "type": "registry:component",
          "target": "components/scroll-expand/index.js"
        },
        {
          "path": "src/components/ScrollExpand/ScrollExpand.jsx",
          "type": "registry:component",
          "target": "components/scroll-expand/ScrollExpand.jsx"
        },
        {
          "path": "src/components/ScrollExpand/ScrollExpand.css",
          "type": "registry:file",
          "target": "components/scroll-expand/ScrollExpand.css"
        },
        {
          "path": "src/components/ScrollExpand/ScrollExpand.d.ts",
          "type": "registry:file",
          "target": "components/scroll-expand/ScrollExpand.d.ts"
        }
      ]
    },
    {
      "name": "ascii-field",
      "type": "registry:component",
      "title": "ASCII Field",
      "description": "A canvas field of glyphs that scramble around the cursor and settle back to rest.",
      "dependencies": [
        "gsap",
        "@gsap/react"
      ],
      "files": [
        {
          "path": "src/components/AsciiField/index.js",
          "type": "registry:component",
          "target": "components/ascii-field/index.js"
        },
        {
          "path": "src/components/AsciiField/AsciiField.jsx",
          "type": "registry:component",
          "target": "components/ascii-field/AsciiField.jsx"
        },
        {
          "path": "src/components/AsciiField/AsciiField.css",
          "type": "registry:file",
          "target": "components/ascii-field/AsciiField.css"
        },
        {
          "path": "src/components/AsciiField/AsciiField.d.ts",
          "type": "registry:file",
          "target": "components/ascii-field/AsciiField.d.ts"
        }
      ]
    },
    {
      "name": "bitmap-noise",
      "type": "registry:component",
      "title": "Bitmap Noise",
      "description": "A self-generating dither field. Two drifting noise layers interfere to form patches of particles that appear, dissolve and reform in place. Canvas 2D, no WebGL.",
      "dependencies": [
        "gsap",
        "@gsap/react"
      ],
      "files": [
        {
          "path": "src/components/BitmapNoise/index.js",
          "type": "registry:component",
          "target": "components/bitmap-noise/index.js"
        },
        {
          "path": "src/components/BitmapNoise/BitmapNoise.jsx",
          "type": "registry:component",
          "target": "components/bitmap-noise/BitmapNoise.jsx"
        },
        {
          "path": "src/components/bitmap-core/engine.js",
          "type": "registry:component",
          "target": "components/bitmap-core/engine.js"
        },
        {
          "path": "src/components/bitmap-core/sources.js",
          "type": "registry:component",
          "target": "components/bitmap-core/sources.js"
        },
        {
          "path": "src/components/bitmap-core/dither.js",
          "type": "registry:component",
          "target": "components/bitmap-core/dither.js"
        },
        {
          "path": "src/components/bitmap-core/bitmap.css",
          "type": "registry:file",
          "target": "components/bitmap-core/bitmap.css"
        },
        {
          "path": "src/components/BitmapNoise/BitmapNoise.d.ts",
          "type": "registry:file",
          "target": "components/bitmap-noise/BitmapNoise.d.ts"
        },
        {
          "path": "src/components/bitmap-core/bitmap.d.ts",
          "type": "registry:file",
          "target": "components/bitmap-core/bitmap.d.ts"
        }
      ]
    },
    {
      "name": "bitmap-image",
      "type": "registry:component",
      "title": "Bitmap Image",
      "description": "Converts an image into a dithered bitmap — ordered Bayer or true error diffusion (Floyd-Steinberg, Atkinson, Jarvis), which no shader can do. Canvas 2D, no WebGL.",
      "dependencies": [
        "gsap",
        "@gsap/react"
      ],
      "files": [
        {
          "path": "src/components/BitmapImage/index.js",
          "type": "registry:component",
          "target": "components/bitmap-image/index.js"
        },
        {
          "path": "src/components/BitmapImage/BitmapImage.jsx",
          "type": "registry:component",
          "target": "components/bitmap-image/BitmapImage.jsx"
        },
        {
          "path": "src/components/bitmap-core/engine.js",
          "type": "registry:component",
          "target": "components/bitmap-core/engine.js"
        },
        {
          "path": "src/components/bitmap-core/sources.js",
          "type": "registry:component",
          "target": "components/bitmap-core/sources.js"
        },
        {
          "path": "src/components/bitmap-core/dither.js",
          "type": "registry:component",
          "target": "components/bitmap-core/dither.js"
        },
        {
          "path": "src/components/bitmap-core/bitmap.css",
          "type": "registry:file",
          "target": "components/bitmap-core/bitmap.css"
        },
        {
          "path": "src/components/BitmapImage/BitmapImage.d.ts",
          "type": "registry:file",
          "target": "components/bitmap-image/BitmapImage.d.ts"
        },
        {
          "path": "src/components/bitmap-core/bitmap.d.ts",
          "type": "registry:file",
          "target": "components/bitmap-core/bitmap.d.ts"
        }
      ]
    },
    {
      "name": "bitmap-text",
      "type": "registry:component",
      "title": "Bitmap Text",
      "description": "Type rasterised and dithered into particles. A grain control decides whether the letterforms read as solid or as a cloud that still resolves as words. Canvas 2D, no WebGL.",
      "dependencies": [
        "gsap",
        "@gsap/react"
      ],
      "files": [
        {
          "path": "src/components/BitmapText/index.js",
          "type": "registry:component",
          "target": "components/bitmap-text/index.js"
        },
        {
          "path": "src/components/BitmapText/BitmapText.jsx",
          "type": "registry:component",
          "target": "components/bitmap-text/BitmapText.jsx"
        },
        {
          "path": "src/components/bitmap-core/engine.js",
          "type": "registry:component",
          "target": "components/bitmap-core/engine.js"
        },
        {
          "path": "src/components/bitmap-core/sources.js",
          "type": "registry:component",
          "target": "components/bitmap-core/sources.js"
        },
        {
          "path": "src/components/bitmap-core/dither.js",
          "type": "registry:component",
          "target": "components/bitmap-core/dither.js"
        },
        {
          "path": "src/components/bitmap-core/bitmap.css",
          "type": "registry:file",
          "target": "components/bitmap-core/bitmap.css"
        },
        {
          "path": "src/components/BitmapText/BitmapText.d.ts",
          "type": "registry:file",
          "target": "components/bitmap-text/BitmapText.d.ts"
        },
        {
          "path": "src/components/bitmap-core/bitmap.d.ts",
          "type": "registry:file",
          "target": "components/bitmap-core/bitmap.d.ts"
        }
      ]
    },
    {
      "name": "weight-grid",
      "type": "registry:component",
      "title": "Weight Grid",
      "description": "A bento grid where the cell under the cursor takes area from its neighbours and the total never changes. Track weights are renormalised against their axis sum, so growing a cell is taking space off the ones beside it — not growing the grid.",
      "dependencies": [],
      "files": [
        {
          "path": "src/components/WeightGrid/index.js",
          "type": "registry:component",
          "target": "components/weight-grid/index.js"
        },
        {
          "path": "src/components/WeightGrid/WeightGrid.jsx",
          "type": "registry:component",
          "target": "components/weight-grid/WeightGrid.jsx"
        },
        {
          "path": "src/components/WeightGrid/WeightGrid.css",
          "type": "registry:file",
          "target": "components/weight-grid/WeightGrid.css"
        },
        {
          "path": "src/components/WeightGrid/WeightGrid.d.ts",
          "type": "registry:file",
          "target": "components/weight-grid/WeightGrid.d.ts"
        }
      ]
    },
    {
      "name": "smear-cursor",
      "type": "registry:component",
      "title": "Smear Cursor",
      "description": "A cursor trail that is motion blur rather than a string of dots. Ribbon width falls as 1/(1+speed·k), the way a camera spreads the same exposure over more ground the faster the subject moves.",
      "dependencies": [],
      "files": [
        {
          "path": "src/components/SmearCursor/index.js",
          "type": "registry:component",
          "target": "components/smear-cursor/index.js"
        },
        {
          "path": "src/components/SmearCursor/SmearCursor.jsx",
          "type": "registry:component",
          "target": "components/smear-cursor/SmearCursor.jsx"
        },
        {
          "path": "src/components/SmearCursor/SmearCursor.css",
          "type": "registry:file",
          "target": "components/smear-cursor/SmearCursor.css"
        },
        {
          "path": "src/components/SmearCursor/SmearCursor.d.ts",
          "type": "registry:file",
          "target": "components/smear-cursor/SmearCursor.d.ts"
        }
      ]
    },
    {
      "name": "sonar-list",
      "type": "registry:component",
      "title": "Sonar List",
      "description": "A ping leaves the click and sweeps outward; each row rings as the wavefront reaches it. Arrival is d/c, a real propagation time, so rows near the click ring first whatever their index — and each row is its own damped oscillator, evaluated in closed form.",
      "dependencies": [],
      "files": [
        {
          "path": "src/components/SonarList/index.js",
          "type": "registry:component",
          "target": "components/sonar-list/index.js"
        },
        {
          "path": "src/components/SonarList/SonarList.jsx",
          "type": "registry:component",
          "target": "components/sonar-list/SonarList.jsx"
        },
        {
          "path": "src/components/SonarList/SonarList.css",
          "type": "registry:file",
          "target": "components/sonar-list/SonarList.css"
        },
        {
          "path": "src/components/SonarList/SonarList.d.ts",
          "type": "registry:file",
          "target": "components/sonar-list/SonarList.d.ts"
        }
      ]
    },
    {
      "name": "thrown-marquee",
      "type": "registry:component",
      "title": "Thrown Marquee",
      "description": "A marquee you can grab and throw. Velocity decays exponentially toward the idle drift rather than toward zero, so a hard throw drops fast then creeps and the band returns to its resting speed with no special case.",
      "dependencies": [],
      "files": [
        {
          "path": "src/components/ThrownMarquee/index.js",
          "type": "registry:component",
          "target": "components/thrown-marquee/index.js"
        },
        {
          "path": "src/components/ThrownMarquee/ThrownMarquee.jsx",
          "type": "registry:component",
          "target": "components/thrown-marquee/ThrownMarquee.jsx"
        },
        {
          "path": "src/components/ThrownMarquee/ThrownMarquee.css",
          "type": "registry:file",
          "target": "components/thrown-marquee/ThrownMarquee.css"
        },
        {
          "path": "src/components/ThrownMarquee/ThrownMarquee.d.ts",
          "type": "registry:file",
          "target": "components/thrown-marquee/ThrownMarquee.d.ts"
        }
      ]
    },
    {
      "name": "thread-pull",
      "type": "registry:component",
      "title": "Thread Pull",
      "description": "A thread strung under a line of text that hangs in a real catenary when you pull it. Length is conserved, so dragging to one side starves that segment and floods the other; the parameter is solved by Newton each frame.",
      "dependencies": [],
      "files": [
        {
          "path": "src/components/ThreadPull/index.js",
          "type": "registry:component",
          "target": "components/thread-pull/index.js"
        },
        {
          "path": "src/components/ThreadPull/ThreadPull.jsx",
          "type": "registry:component",
          "target": "components/thread-pull/ThreadPull.jsx"
        },
        {
          "path": "src/components/ThreadPull/ThreadPull.css",
          "type": "registry:file",
          "target": "components/thread-pull/ThreadPull.css"
        },
        {
          "path": "src/components/ThreadPull/ThreadPull.d.ts",
          "type": "registry:file",
          "target": "components/thread-pull/ThreadPull.d.ts"
        }
      ]
    },
    {
      "name": "magnetic-field",
      "type": "registry:component",
      "title": "Magnetic Field",
      "description": "Iron filings aligning to a dipole under the cursor. B proportional to (3(m·r̂)r̂ − m)/r³, so the pattern has two lobes and the loops between them — a radial fan has neither.",
      "dependencies": [],
      "files": [
        {
          "path": "src/components/MagneticField/index.js",
          "type": "registry:component",
          "target": "components/magnetic-field/index.js"
        },
        {
          "path": "src/components/MagneticField/MagneticField.jsx",
          "type": "registry:component",
          "target": "components/magnetic-field/MagneticField.jsx"
        },
        {
          "path": "src/components/MagneticField/MagneticField.css",
          "type": "registry:file",
          "target": "components/magnetic-field/MagneticField.css"
        },
        {
          "path": "src/components/MagneticField/MagneticField.d.ts",
          "type": "registry:file",
          "target": "components/magnetic-field/MagneticField.d.ts"
        }
      ]
    },
    {
      "name": "depth-of-field",
      "type": "registry:component",
      "title": "Depth of Field",
      "description": "A card stack blurred by a real circle of confusion, so the near side defocuses harder than the far side — the asymmetry that makes a photograph read as one. The focal plane racks with the pointer.",
      "dependencies": [],
      "files": [
        {
          "path": "src/components/DepthOfField/index.js",
          "type": "registry:component",
          "target": "components/depth-of-field/index.js"
        },
        {
          "path": "src/components/DepthOfField/DepthOfField.jsx",
          "type": "registry:component",
          "target": "components/depth-of-field/DepthOfField.jsx"
        },
        {
          "path": "src/components/DepthOfField/DepthOfField.css",
          "type": "registry:file",
          "target": "components/depth-of-field/DepthOfField.css"
        },
        {
          "path": "src/components/DepthOfField/DepthOfField.d.ts",
          "type": "registry:file",
          "target": "components/depth-of-field/DepthOfField.d.ts"
        }
      ]
    },
    {
      "name": "folding-panel",
      "type": "registry:component",
      "title": "Folding Panel",
      "description": "A panel that folds along real crease lines. Facets are placed by walking the fold outward so the paper stays connected, the panel foreshortens by cos θ as it closes, and each facet shades by Lambert's cosine law from its own normal.",
      "dependencies": [],
      "files": [
        {
          "path": "src/components/FoldingPanel/index.js",
          "type": "registry:component",
          "target": "components/folding-panel/index.js"
        },
        {
          "path": "src/components/FoldingPanel/FoldingPanel.jsx",
          "type": "registry:component",
          "target": "components/folding-panel/FoldingPanel.jsx"
        },
        {
          "path": "src/components/FoldingPanel/FoldingPanel.css",
          "type": "registry:file",
          "target": "components/folding-panel/FoldingPanel.css"
        },
        {
          "path": "src/components/FoldingPanel/FoldingPanel.d.ts",
          "type": "registry:file",
          "target": "components/folding-panel/FoldingPanel.d.ts"
        }
      ]
    },
    {
      "name": "elastic-rail",
      "type": "registry:component",
      "title": "Elastic Rail",
      "description": "A scroll progress rail that bulges with overscroll and twangs back. It obeys the wave equation, so its pitch follows f = (1/2L)·√(T/μ) — a longer rail rings lower, with nothing tuned per page.",
      "dependencies": [],
      "files": [
        {
          "path": "src/components/ElasticRail/index.js",
          "type": "registry:component",
          "target": "components/elastic-rail/index.js"
        },
        {
          "path": "src/components/ElasticRail/ElasticRail.jsx",
          "type": "registry:component",
          "target": "components/elastic-rail/ElasticRail.jsx"
        },
        {
          "path": "src/components/ElasticRail/ElasticRail.css",
          "type": "registry:file",
          "target": "components/elastic-rail/ElasticRail.css"
        },
        {
          "path": "src/components/ElasticRail/ElasticRail.d.ts",
          "type": "registry:file",
          "target": "components/elastic-rail/ElasticRail.d.ts"
        }
      ]
    },
    {
      "name": "gravity-menu",
      "type": "registry:component",
      "title": "Gravity Menu",
      "description": "Menu items on stable orbits, bent past the pointer by a softened inverse-square attraction. The softening term is what stops an item crossing the cursor being flung off screen in a single frame.",
      "dependencies": [],
      "files": [
        {
          "path": "src/components/GravityMenu/index.js",
          "type": "registry:component",
          "target": "components/gravity-menu/index.js"
        },
        {
          "path": "src/components/GravityMenu/GravityMenu.jsx",
          "type": "registry:component",
          "target": "components/gravity-menu/GravityMenu.jsx"
        },
        {
          "path": "src/components/GravityMenu/GravityMenu.css",
          "type": "registry:file",
          "target": "components/gravity-menu/GravityMenu.css"
        },
        {
          "path": "src/components/GravityMenu/GravityMenu.d.ts",
          "type": "registry:file",
          "target": "components/gravity-menu/GravityMenu.d.ts"
        }
      ]
    },
    {
      "name": "caustic-surface",
      "type": "registry:component",
      "title": "Caustic Surface",
      "description": "The net of light on a pool floor, lit by conservation of light rather than a texture: brightness is 1/|det(I + D(1 − 1/n)H)| of the refraction map, so the lines are where the surface folds the light. Pointer ripples bend the net. WebGL2.",
      "dependencies": [],
      "files": [
        {
          "path": "src/components/CausticSurface/index.js",
          "type": "registry:component",
          "target": "components/caustic-surface/index.js"
        },
        {
          "path": "src/components/CausticSurface/CausticSurface.jsx",
          "type": "registry:component",
          "target": "components/caustic-surface/CausticSurface.jsx"
        },
        {
          "path": "src/components/CausticSurface/CausticSurface.css",
          "type": "registry:file",
          "target": "components/caustic-surface/CausticSurface.css"
        },
        {
          "path": "src/components/gl-core/gl.js",
          "type": "registry:component",
          "target": "components/gl-core/gl.js"
        },
        {
          "path": "src/components/CausticSurface/CausticSurface.d.ts",
          "type": "registry:file",
          "target": "components/caustic-surface/CausticSurface.d.ts"
        }
      ]
    },
    {
      "name": "halftone-screen",
      "type": "registry:component",
      "title": "Halftone Screen",
      "description": "Four-colour process halftone as a press prints it: CMYK screened at 15/75/0/45°, grey-component replacement, and dot area — not radius — matched to ink coverage, including where dots merge. A loupe under the pointer. WebGL2.",
      "dependencies": [],
      "files": [
        {
          "path": "src/components/HalftoneScreen/index.js",
          "type": "registry:component",
          "target": "components/halftone-screen/index.js"
        },
        {
          "path": "src/components/HalftoneScreen/HalftoneScreen.jsx",
          "type": "registry:component",
          "target": "components/halftone-screen/HalftoneScreen.jsx"
        },
        {
          "path": "src/components/HalftoneScreen/HalftoneScreen.css",
          "type": "registry:file",
          "target": "components/halftone-screen/HalftoneScreen.css"
        },
        {
          "path": "src/components/gl-core/gl.js",
          "type": "registry:component",
          "target": "components/gl-core/gl.js"
        },
        {
          "path": "src/components/HalftoneScreen/HalftoneScreen.d.ts",
          "type": "registry:file",
          "target": "components/halftone-screen/HalftoneScreen.d.ts"
        }
      ]
    },
    {
      "name": "shatter-reveal",
      "type": "registry:component",
      "title": "Shatter Reveal",
      "description": "An image that breaks into Lloyd-relaxed Voronoi shards when struck, each a rigid body with its own mass and polygon inertia, spun by the strike and slowed by quadratic drag. Reveals the content underneath. Canvas 2D.",
      "dependencies": [],
      "files": [
        {
          "path": "src/components/ShatterReveal/index.js",
          "type": "registry:component",
          "target": "components/shatter-reveal/index.js"
        },
        {
          "path": "src/components/ShatterReveal/ShatterReveal.jsx",
          "type": "registry:component",
          "target": "components/shatter-reveal/ShatterReveal.jsx"
        },
        {
          "path": "src/components/ShatterReveal/ShatterReveal.css",
          "type": "registry:file",
          "target": "components/shatter-reveal/ShatterReveal.css"
        },
        {
          "path": "src/components/ShatterReveal/ShatterReveal.d.ts",
          "type": "registry:file",
          "target": "components/shatter-reveal/ShatterReveal.d.ts"
        }
      ]
    },
    {
      "name": "liquid-transition",
      "type": "registry:component",
      "title": "Liquid Transition",
      "description": "A fluid front that sweeps over changing content: the middle leads by a Poiseuille profile, the edge rings under tension by the damped wave equation, and droplets trail the drain. Canvas 2D.",
      "dependencies": [],
      "files": [
        {
          "path": "src/components/LiquidTransition/index.js",
          "type": "registry:component",
          "target": "components/liquid-transition/index.js"
        },
        {
          "path": "src/components/LiquidTransition/LiquidTransition.jsx",
          "type": "registry:component",
          "target": "components/liquid-transition/LiquidTransition.jsx"
        },
        {
          "path": "src/components/LiquidTransition/LiquidTransition.css",
          "type": "registry:file",
          "target": "components/liquid-transition/LiquidTransition.css"
        },
        {
          "path": "src/components/LiquidTransition/LiquidTransition.d.ts",
          "type": "registry:file",
          "target": "components/liquid-transition/LiquidTransition.d.ts"
        }
      ]
    },
    {
      "name": "channel-switch",
      "type": "registry:component",
      "title": "Channel Switch",
      "description": "Content changes like a CRT changing channel — collapse to a line and a dot, a phosphor feedback buffer decaying as e^(−Δt/τ), and a damped vertical hold rolling the new picture into lock. Children stay live DOM.",
      "dependencies": [],
      "files": [
        {
          "path": "src/components/ChannelSwitch/index.js",
          "type": "registry:component",
          "target": "components/channel-switch/index.js"
        },
        {
          "path": "src/components/ChannelSwitch/ChannelSwitch.jsx",
          "type": "registry:component",
          "target": "components/channel-switch/ChannelSwitch.jsx"
        },
        {
          "path": "src/components/ChannelSwitch/ChannelSwitch.css",
          "type": "registry:file",
          "target": "components/channel-switch/ChannelSwitch.css"
        },
        {
          "path": "src/components/ChannelSwitch/ChannelSwitch.d.ts",
          "type": "registry:file",
          "target": "components/channel-switch/ChannelSwitch.d.ts"
        }
      ]
    },
    {
      "name": "wet-ink",
      "type": "registry:component",
      "title": "Wet Ink",
      "description": "A word written in ink that bleeds along the paper's fibres by anisotropic diffusion and dries darker at its rim, stepped under the explicit stability limit. Canvas 2D.",
      "dependencies": [],
      "files": [
        {
          "path": "src/components/WetInk/index.js",
          "type": "registry:component",
          "target": "components/wet-ink/index.js"
        },
        {
          "path": "src/components/WetInk/WetInk.jsx",
          "type": "registry:component",
          "target": "components/wet-ink/WetInk.jsx"
        },
        {
          "path": "src/components/WetInk/WetInk.css",
          "type": "registry:file",
          "target": "components/wet-ink/WetInk.css"
        },
        {
          "path": "src/components/WetInk/WetInk.d.ts",
          "type": "registry:file",
          "target": "components/wet-ink/WetInk.d.ts"
        }
      ]
    },
    {
      "name": "focus-peaking",
      "type": "registry:component",
      "title": "Focus Peaking",
      "description": "Lights an image's in-focus edges on hover, like a camera monitor: the Sobel gradient of luma, thresholded with a soft knee and tinted over a dimmed picture. WebGL2.",
      "dependencies": [],
      "files": [
        {
          "path": "src/components/FocusPeaking/index.js",
          "type": "registry:component",
          "target": "components/focus-peaking/index.js"
        },
        {
          "path": "src/components/FocusPeaking/FocusPeaking.jsx",
          "type": "registry:component",
          "target": "components/focus-peaking/FocusPeaking.jsx"
        },
        {
          "path": "src/components/FocusPeaking/FocusPeaking.css",
          "type": "registry:file",
          "target": "components/focus-peaking/FocusPeaking.css"
        },
        {
          "path": "src/components/gl-core/gl.js",
          "type": "registry:component",
          "target": "components/gl-core/gl.js"
        },
        {
          "path": "src/components/FocusPeaking/FocusPeaking.d.ts",
          "type": "registry:file",
          "target": "components/focus-peaking/FocusPeaking.d.ts"
        }
      ]
    },
    {
      "name": "brushed-metal",
      "type": "registry:component",
      "title": "Brushed Metal",
      "description": "A brushed metal panel under a light at the pointer, shaded with anisotropic GGX so the highlight streaks across the grain. Colour is the metal's F0; anisotropy 0 is polished. WebGL2.",
      "dependencies": [],
      "files": [
        {
          "path": "src/components/BrushedMetal/index.js",
          "type": "registry:component",
          "target": "components/brushed-metal/index.js"
        },
        {
          "path": "src/components/BrushedMetal/BrushedMetal.jsx",
          "type": "registry:component",
          "target": "components/brushed-metal/BrushedMetal.jsx"
        },
        {
          "path": "src/components/BrushedMetal/BrushedMetal.css",
          "type": "registry:file",
          "target": "components/brushed-metal/BrushedMetal.css"
        },
        {
          "path": "src/components/gl-core/gl.js",
          "type": "registry:component",
          "target": "components/gl-core/gl.js"
        },
        {
          "path": "src/components/BrushedMetal/BrushedMetal.d.ts",
          "type": "registry:file",
          "target": "components/brushed-metal/BrushedMetal.d.ts"
        }
      ]
    }
  ]
}
