{
  "$schema": "https://ui.shadcn.com/schema/registry.json",
  "name": "Sora UI",
  "homepage": "https://ui.soralabs.studio",
  "items": [
    {
      "name": "index",
      "type": "registry:style",
      "dependencies": [
        "tw-animate-css",
        "class-variance-authority",
        "lucide-react"
      ],
      "registryDependencies": ["utils"],
      "cssVars": {},
      "files": []
    },
    {
      "name": "cursor-trail-reveal",
      "type": "registry:ui",
      "title": "Cursor Trail Reveal",
      "description": "Desktop cursor trail that reveals staggered image strips with clip-path wipes as the pointer moves.",
      "dependencies": ["class-variance-authority"],
      "registryDependencies": ["utils"],
      "files": [
        {
          "path": "registry/catalog/cursor-trail-reveal/index.tsx",
          "type": "registry:ui",
          "target": "components/sora-ui/catalog/cursor-trail-reveal.tsx"
        }
      ]
    },
    {
      "name": "infinite-scrolling-images",
      "type": "registry:ui",
      "title": "Infinite Scrolling Images",
      "description": "An infinite card stack that advances with wheel, touch, or keyboard input using spring-based Motion transitions.",
      "dependencies": ["motion"],
      "registryDependencies": ["utils"],
      "files": [
        {
          "path": "registry/catalog/infinite-scrolling-images/index.tsx",
          "type": "registry:ui",
          "target": "components/sora-ui/catalog/infinite-scrolling-images.tsx"
        }
      ],
      "meta": {
        "keywords": [
          "infinite",
          "scrolling",
          "images",
          "stack",
          "motion",
          "wheel",
          "touch"
        ]
      }
    },
    {
      "name": "scroll-chapters",
      "type": "registry:ui",
      "title": "Scroll Chapters",
      "description": "A draggable, chaptered progress-bar nav — two-way cursor/scroll sync, ghost-cursor hover preview, snap-to-step seeking, and a per-chapter panel that can opt in or out of showing.",
      "dependencies": ["gsap", "@gsap/react"],
      "registryDependencies": ["@soralabs/lib-scroll-trigger-utils"],
      "files": [
        {
          "path": "registry/catalog/scroll-chapters/index.tsx",
          "type": "registry:ui",
          "target": "components/sora-ui/catalog/scroll-chapters.tsx"
        }
      ],
      "meta": {
        "keywords": [
          "scrollbar",
          "scroll",
          "chapters",
          "draggable",
          "progress",
          "nav",
          "gsap",
          "scrolltrigger"
        ],
        "inspiration": {
          "type": "reimplemented",
          "label": "Anime.js",
          "stack": "GSAP and vanilla JS"
        }
      }
    },
    {
      "name": "scroll-gallery",
      "type": "registry:ui",
      "title": "Scroll Gallery",
      "description": "A full-viewport sticky scroll slider with strip-mask image transitions and animated title swaps, driven by GSAP ScrollTrigger.",
      "dependencies": ["gsap", "@gsap/react"],
      "registryDependencies": ["utils", "@soralabs/lib-scroll-trigger-utils"],
      "files": [
        {
          "path": "registry/catalog/scroll-gallery/index.tsx",
          "type": "registry:ui",
          "target": "components/sora-ui/catalog/scroll-gallery.tsx"
        }
      ],
      "meta": {
        "demoProps": {
          "ScrollGallery": {
            "prefixLabel": {
              "value": "Featured"
            },
            "linkLabel": {
              "value": "Explore"
            },
            "showPrefix": {
              "value": true
            },
            "showLink": {
              "value": true
            },
            "showInfoBand": {
              "value": true
            },
            "scrollPerTransition": {
              "value": 600,
              "min": 200,
              "max": 1500,
              "step": 50
            },
            "stripsCount": {
              "value": 20,
              "min": 4,
              "max": 40,
              "step": 2
            },
            "scrub": {
              "value": 1,
              "min": 0,
              "max": 3,
              "step": 0.1
            }
          }
        }
      }
    },
    {
      "name": "sticky-scroll-cards",
      "type": "registry:ui",
      "title": "Sticky Scroll Cards",
      "description": "Scroll-pinned hero where a front card flips to reveal a stack of back cards, dismissed one at a time as you keep scrolling.",
      "dependencies": ["gsap", "@gsap/react"],
      "registryDependencies": ["@soralabs/lib-scroll-trigger-utils"],
      "files": [
        {
          "path": "registry/catalog/sticky-scroll-cards/index.tsx",
          "type": "registry:ui",
          "target": "components/sora-ui/catalog/sticky-scroll-cards.tsx"
        }
      ],
      "meta": {
        "keywords": [
          "sticky",
          "pin",
          "card",
          "flip",
          "stack",
          "scroll",
          "gsap",
          "scrolltrigger"
        ],
        "inspiration": {
          "type": "reimplemented",
          "label": "Codegrid",
          "stack": "GSAP and vanilla JS"
        }
      }
    },
    {
      "name": "text-reveal-box",
      "type": "registry:ui",
      "title": "Text Reveal Box",
      "description": "Scroll-pinned word-by-word text reveal with a highlight flash, powered by GSAP ScrollTrigger.",
      "dependencies": ["gsap", "@gsap/react"],
      "registryDependencies": ["@soralabs/lib-scroll-trigger-utils"],
      "files": [
        {
          "path": "registry/catalog/text-reveal-box/index.tsx",
          "type": "registry:ui",
          "target": "components/sora-ui/catalog/text-reveal-box.tsx"
        }
      ],
      "meta": {
        "keywords": [
          "scroll",
          "text",
          "reveal",
          "gsap",
          "scrolltrigger",
          "pin"
        ],
        "inspiration": {
          "type": "reimplemented",
          "label": "Deadlock Studios",
          "url": "https://github.com/Axyl1410",
          "stack": "GSAP and React"
        }
      }
    },
    {
      "name": "tilt-slide-transition",
      "type": "registry:ui",
      "title": "Tilt Slide Transition",
      "description": "Multi-page editorial portfolio transition with tilted scaling exit and diagonal clip-path entrance, powered by View Transition API, GSAP SplitText, and Lenis.",
      "dependencies": ["gsap", "@gsap/react", "lenis"],
      "files": [
        {
          "path": "registry/catalog/tilt-slide-transition/index.tsx",
          "type": "registry:ui",
          "target": "components/sora-ui/catalog/tilt-slide-transition.tsx"
        }
      ],
      "meta": {
        "keywords": [
          "tilt-transition",
          "slide-transition",
          "view-transition",
          "page-transition",
          "gsap",
          "splittext",
          "lenis",
          "portfolio",
          "editorial",
          "codegrid"
        ],
        "inspiration": {
          "type": "reimplemented",
          "label": "Codegrid & Paul Kalkbrenner",
          "url": "https://www.paulkalkbrenner.net",
          "stack": "Next.js, View Transition API, GSAP, and Lenis"
        }
      }
    },
    {
      "name": "demo-cursor-trail-reveal",
      "type": "registry:ui",
      "title": "Cursor Trail Reveal Demo",
      "description": "Full-page contact layout with cursor trail image reveals on desktop.",
      "registryDependencies": ["@soralabs/cursor-trail-reveal"],
      "files": [
        {
          "path": "registry/demo/catalog/cursor-trail-reveal/index.tsx",
          "type": "registry:ui",
          "target": "components/sora-ui/demo/catalog/cursor-trail-reveal.tsx"
        }
      ]
    },
    {
      "name": "demo-infinite-scrolling-images",
      "type": "registry:ui",
      "title": "Infinite Scrolling Images Demo",
      "description": "Preview for the infinite stacked image scroll effect.",
      "registryDependencies": ["@soralabs/infinite-scrolling-images"],
      "files": [
        {
          "path": "registry/demo/catalog/infinite-scrolling-images/index.tsx",
          "type": "registry:ui",
          "target": "components/sora-ui/demo/catalog/infinite-scrolling-images.tsx"
        }
      ]
    },
    {
      "name": "demo-scroll-chapters",
      "type": "registry:ui",
      "title": "Scroll Chapters Demo",
      "description": "Five chapters with a draggable, chaptered progress-bar nav — two of them opt out of showing a panel.",
      "registryDependencies": ["@soralabs/scroll-chapters"],
      "files": [
        {
          "path": "registry/demo/catalog/scroll-chapters/index.tsx",
          "type": "registry:ui",
          "target": "components/sora-ui/demo/catalog/scroll-chapters.tsx"
        }
      ]
    },
    {
      "name": "demo-scroll-gallery",
      "type": "registry:ui",
      "title": "Scroll Gallery Demo",
      "description": "Sticky scroll slider with 4 slides, strip-mask transitions, and animated title swaps.",
      "registryDependencies": ["@soralabs/scroll-gallery"],
      "files": [
        {
          "path": "registry/demo/catalog/scroll-gallery/index.tsx",
          "type": "registry:ui",
          "target": "components/sora-ui/demo/catalog/scroll-gallery.tsx"
        }
      ]
    },
    {
      "name": "demo-sticky-scroll-cards",
      "type": "registry:ui",
      "title": "Sticky Scroll Cards Demo",
      "description": "Front card flips to reveal 4 stacked back cards that dismiss one at a time as you scroll.",
      "registryDependencies": ["@soralabs/sticky-scroll-cards"],
      "files": [
        {
          "path": "registry/demo/catalog/sticky-scroll-cards/index.tsx",
          "type": "registry:ui",
          "target": "components/sora-ui/demo/catalog/sticky-scroll-cards.tsx"
        }
      ]
    },
    {
      "name": "demo-text-reveal-box",
      "type": "registry:ui",
      "title": "Text Reveal Box Demo",
      "description": "Scroll-pinned manifesto copy with word-by-word highlight reveal.",
      "registryDependencies": ["@soralabs/text-reveal-box"],
      "files": [
        {
          "path": "registry/demo/catalog/text-reveal-box/index.tsx",
          "type": "registry:ui",
          "target": "components/sora-ui/demo/catalog/text-reveal-box.tsx"
        }
      ]
    },
    {
      "name": "demo-tilt-slide-transition",
      "type": "registry:ui",
      "title": "Tilt Slide Transition Demo",
      "description": "Interactive tilt slide transition showcase switching between Home, Projects, and Info views.",
      "registryDependencies": ["@soralabs/tilt-slide-transition"],
      "files": [
        {
          "path": "registry/demo/catalog/tilt-slide-transition/index.tsx",
          "type": "registry:ui",
          "target": "components/sora-ui/demo/catalog/tilt-slide-transition.tsx"
        }
      ]
    },
    {
      "name": "demo-particle-hover-button",
      "type": "registry:ui",
      "title": "Particle Hover Button Demo",
      "description": "A heart-particle sponsor link, styled after the anime.js navbar Sponsor button.",
      "registryDependencies": ["@soralabs/particle-hover-button"],
      "files": [
        {
          "path": "registry/demo/primitives/buttons/particle-hover-button/index.tsx",
          "type": "registry:ui",
          "target": "components/sora-ui/demo/buttons/particle-hover-button.tsx"
        }
      ]
    },
    {
      "name": "demo-accordion",
      "type": "registry:ui",
      "title": "Accordion Demo",
      "description": "FAQ accordion with animated panels.",
      "registryDependencies": ["@soralabs/accordion"],
      "files": [
        {
          "path": "registry/demo/primitives/disclosure/accordion/index.tsx",
          "type": "registry:ui",
          "target": "components/sora-ui/demo/disclosure/accordion.tsx"
        }
      ]
    },
    {
      "name": "demo-expandable-tabs",
      "type": "registry:ui",
      "title": "Expandable Tabs Demo",
      "description": "Pill tab bar expanding into a floating profile/notifications/settings panel.",
      "registryDependencies": ["@soralabs/expandable-tabs"],
      "files": [
        {
          "path": "registry/demo/primitives/disclosure/expandable-tabs/index.tsx",
          "type": "registry:ui",
          "target": "components/sora-ui/demo/disclosure/expandable-tabs.tsx"
        }
      ]
    },
    {
      "name": "demo-inline-testimonials",
      "type": "registry:ui",
      "title": "Inline Testimonials Demo",
      "description": "Hover any avatar to reveal the author while the rest of the quote stream blurs out.",
      "registryDependencies": ["@soralabs/inline-testimonials"],
      "files": [
        {
          "path": "registry/demo/primitives/disclosure/inline-testimonials/index.tsx",
          "type": "registry:ui",
          "target": "components/sora-ui/demo/disclosure/inline-testimonials.tsx"
        }
      ]
    },
    {
      "name": "demo-border-trail",
      "type": "registry:ui",
      "title": "Border Trail Demo",
      "description": "Card with animated border spotlight.",
      "registryDependencies": ["@soralabs/border-trail"],
      "files": [
        {
          "path": "registry/demo/primitives/effects/border-trail/index.tsx",
          "type": "registry:ui",
          "target": "components/sora-ui/demo/effects/border-trail.tsx"
        }
      ],
      "meta": {
        "demoProps": {
          "BorderTrailDemo": {
            "size": {
              "value": 100,
              "min": 40,
              "max": 140,
              "step": 4
            },
            "duration": {
              "value": 5,
              "min": 1,
              "max": 12,
              "step": 0.5
            }
          }
        }
      }
    },
    {
      "name": "demo-border-trail-loading",
      "type": "registry:ui",
      "title": "Border Trail Loading Card Demo",
      "description": "Submit-triggered border trail that loops twice then fades.",
      "registryDependencies": ["@soralabs/border-trail"],
      "files": [
        {
          "path": "registry/demo/primitives/effects/border-trail-loading/index.tsx",
          "type": "registry:ui",
          "target": "components/sora-ui/demo/effects/border-trail-loading.tsx"
        }
      ],
      "meta": {
        "demoProps": {
          "BorderTrailLoadingCard": {
            "size": {
              "value": 120,
              "min": 60,
              "max": 160,
              "step": 4
            }
          }
        }
      }
    },
    {
      "name": "demo-border-trail-textarea",
      "type": "registry:ui",
      "title": "Border Trail Textarea Demo",
      "description": "Textarea with a continuous gradient border trail.",
      "registryDependencies": ["@soralabs/border-trail"],
      "files": [
        {
          "path": "registry/demo/primitives/effects/border-trail-textarea/index.tsx",
          "type": "registry:ui",
          "target": "components/sora-ui/demo/effects/border-trail-textarea.tsx"
        }
      ],
      "meta": {
        "demoProps": {
          "BorderTrailTextarea": {
            "size": {
              "value": 120,
              "min": 60,
              "max": 160,
              "step": 4
            },
            "duration": {
              "value": 5,
              "min": 1,
              "max": 12,
              "step": 0.5
            }
          }
        }
      }
    },
    {
      "name": "demo-cursor-bubble",
      "type": "registry:ui",
      "title": "Cursor Bubble Demo",
      "description": "A floating cursor label that elastic-pops into view over interactive links.",
      "registryDependencies": ["@soralabs/cursor-bubble"],
      "files": [
        {
          "path": "registry/demo/primitives/effects/cursor-bubble/index.tsx",
          "type": "registry:ui",
          "target": "components/sora-ui/demo/effects/cursor-bubble.tsx"
        }
      ]
    },
    {
      "name": "demo-hero-carousel",
      "type": "registry:ui",
      "title": "Hero Carousel Demo",
      "description": "Hero image slideshow cycling through a set of project preview screenshots.",
      "registryDependencies": ["@soralabs/hero-carousel"],
      "files": [
        {
          "path": "registry/demo/primitives/effects/hero-carousel/index.tsx",
          "type": "registry:ui",
          "target": "components/sora-ui/demo/effects/hero-carousel.tsx"
        }
      ]
    },
    {
      "name": "demo-highlight",
      "type": "registry:ui",
      "title": "Highlight Demo",
      "description": "Shared sliding highlight pill moving between nav items on hover.",
      "registryDependencies": ["@soralabs/highlight"],
      "files": [
        {
          "path": "registry/demo/primitives/effects/highlight/index.tsx",
          "type": "registry:ui",
          "target": "components/sora-ui/demo/effects/highlight.tsx"
        }
      ]
    },
    {
      "name": "demo-highlight-click",
      "type": "registry:ui",
      "title": "Highlight Click Demo",
      "description": "Per-item fade background activated on click — menu list style.",
      "registryDependencies": ["@soralabs/highlight"],
      "files": [
        {
          "path": "registry/demo/primitives/effects/highlight-click/index.tsx",
          "type": "registry:ui",
          "target": "components/sora-ui/demo/effects/highlight-click.tsx"
        }
      ]
    },
    {
      "name": "demo-logo-carousel-swapper",
      "type": "registry:ui",
      "title": "Logo Carousel Swapper Demo",
      "description": "Staggered four-column logo swapper with blur and vertical motion.",
      "registryDependencies": ["@soralabs/logo-carousel-swapper"],
      "files": [
        {
          "path": "registry/demo/primitives/effects/logo-carousel-swapper/index.tsx",
          "type": "registry:ui",
          "target": "components/sora-ui/demo/effects/logo-carousel-swapper.tsx"
        }
      ]
    },
    {
      "name": "demo-magnetic-cards",
      "type": "registry:ui",
      "title": "Magnetic Cards Demo",
      "description": "A fanned stack of cards reacting to cursor movement with GSAP-driven spring physics.",
      "registryDependencies": ["@soralabs/magnetic-cards"],
      "files": [
        {
          "path": "registry/demo/primitives/effects/magnetic-cards/index.tsx",
          "type": "registry:ui",
          "target": "components/sora-ui/demo/effects/magnetic-cards.tsx"
        }
      ]
    },
    {
      "name": "demo-progressive-blur",
      "type": "registry:ui",
      "title": "Progressive Blur Demo",
      "description": "A scrollable panel with progressive blur fading content under the top and bottom edges.",
      "registryDependencies": ["@soralabs/progressive-blur"],
      "files": [
        {
          "path": "registry/demo/primitives/effects/progressive-blur/index.tsx",
          "type": "registry:ui",
          "target": "components/sora-ui/demo/effects/progressive-blur.tsx"
        }
      ]
    },
    {
      "name": "demo-skeleton",
      "type": "registry:ui",
      "title": "Skeleton Demo",
      "description": "A profile card loading, then crossfading into content once ready.",
      "registryDependencies": ["@soralabs/skeleton"],
      "files": [
        {
          "path": "registry/demo/primitives/effects/skeleton/index.tsx",
          "type": "registry:ui",
          "target": "components/sora-ui/demo/effects/skeleton.tsx"
        }
      ]
    },
    {
      "name": "demo-skeleton-shimmer",
      "type": "registry:ui",
      "title": "Skeleton Shimmer Demo",
      "description": "Skeleton loading card that wipes away to reveal a profile card once content is ready.",
      "registryDependencies": ["@soralabs/skeleton-shimmer"],
      "files": [
        {
          "path": "registry/demo/primitives/effects/skeleton-shimmer/index.tsx",
          "type": "registry:ui",
          "target": "components/sora-ui/demo/effects/skeleton-shimmer.tsx"
        }
      ],
      "meta": {
        "demoProps": {
          "SkeletonShimmerDemo": {
            "shimmerDuration": {
              "value": 1.5,
              "min": 0.5,
              "max": 4,
              "step": 0.1
            },
            "loadDelay": {
              "value": 2500,
              "min": 500,
              "max": 6000,
              "step": 100
            }
          }
        }
      }
    },
    {
      "name": "demo-skeleton-shimmer-basic",
      "type": "registry:ui",
      "title": "Skeleton Shimmer Basic Demo",
      "description": "Standard skeleton shimmer loading state with blocks and overlay without View Transitions API.",
      "registryDependencies": ["@soralabs/skeleton-shimmer"],
      "files": [
        {
          "path": "registry/demo/primitives/effects/skeleton-shimmer-basic/index.tsx",
          "type": "registry:ui",
          "target": "components/sora-ui/demo/effects/skeleton-shimmer-basic.tsx"
        }
      ],
      "meta": {
        "demoProps": {
          "SkeletonShimmerBasicDemo": {
            "shimmerDuration": {
              "value": 1.5,
              "min": 0.5,
              "max": 4,
              "step": 0.1
            }
          }
        }
      }
    },
    {
      "name": "demo-tilt-card",
      "type": "registry:ui",
      "title": "Tilt Card Demo",
      "description": "Card tilting toward the cursor with layered depth content.",
      "registryDependencies": ["@soralabs/tilt-card"],
      "files": [
        {
          "path": "registry/demo/primitives/effects/tilt-card/index.tsx",
          "type": "registry:ui",
          "target": "components/sora-ui/demo/effects/tilt-card.tsx"
        }
      ],
      "meta": {
        "demoProps": {
          "TiltCardDemo": {
            "rotationFactor": {
              "value": 8,
              "min": 0,
              "max": 45,
              "step": 1
            },
            "perspective": {
              "value": 1000,
              "min": 400,
              "max": 2000,
              "step": 50
            },
            "scaleOnHover": {
              "value": 1,
              "min": 1,
              "max": 1.15,
              "step": 0.01
            },
            "isReverse": {
              "value": false
            },
            "glare": {
              "value": true
            }
          }
        }
      }
    },
    {
      "name": "demo-tilt-card-image",
      "type": "registry:ui",
      "title": "Tilt Card Image Demo",
      "description": "Image card with a subtle reversed tilt.",
      "registryDependencies": ["@soralabs/tilt-card"],
      "files": [
        {
          "path": "registry/demo/primitives/effects/tilt-card-image/index.tsx",
          "type": "registry:ui",
          "target": "components/sora-ui/demo/effects/tilt-card-image.tsx"
        }
      ],
      "meta": {
        "demoProps": {
          "TiltCardImageDemo": {
            "rotationFactor": {
              "value": 8,
              "min": 0,
              "max": 30,
              "step": 1
            },
            "isReverse": {
              "value": true
            }
          }
        }
      }
    },
    {
      "name": "demo-video-player",
      "type": "registry:ui",
      "title": "Video Player Demo",
      "description": "Trigger button that opens the modal video player with a sample chaptered video.",
      "registryDependencies": ["@soralabs/video-player"],
      "files": [
        {
          "path": "registry/demo/primitives/effects/video-player/index.tsx",
          "type": "registry:ui",
          "target": "components/sora-ui/demo/effects/video-player.tsx"
        }
      ]
    },
    {
      "name": "demo-dia-text-reveal",
      "type": "registry:ui",
      "title": "Dia Text Reveal Demo",
      "description": "Gradient sweep revealing a headline with a looping chromatic wash.",
      "registryDependencies": ["@soralabs/dia-text-reveal"],
      "files": [
        {
          "path": "registry/demo/primitives/texts/dia-text-reveal/index.tsx",
          "type": "registry:ui",
          "target": "components/sora-ui/demo/texts/dia-text-reveal.tsx"
        }
      ]
    },
    {
      "name": "demo-fog-text-reveal",
      "type": "registry:ui",
      "title": "Fog Text Reveal Demo",
      "description": "Inline text that materializes through a WebGL fog mask and cycles through messages, inheriting the surrounding font and color.",
      "registryDependencies": ["@soralabs/fog-text-reveal"],
      "files": [
        {
          "path": "registry/demo/primitives/texts/fog-text-reveal/index.tsx",
          "type": "registry:ui",
          "target": "components/sora-ui/demo/texts/fog-text-reveal.tsx"
        }
      ],
      "meta": {
        "demoProps": {
          "FogTextRevealExample": {
            "loop": {
              "value": true
            },
            "startOnView": {
              "value": true
            },
            "holdDuration": {
              "value": 320,
              "min": 0,
              "max": 2000,
              "step": 20
            },
            "maxBlur": {
              "value": 16,
              "min": 0,
              "max": 40,
              "step": 1
            }
          }
        }
      }
    },
    {
      "name": "demo-number-flow",
      "type": "registry:ui",
      "title": "Number Flow Demo",
      "description": "Number Flow demo with currency, input overlay, and countdown examples.",
      "registryDependencies": ["@soralabs/number-flow"],
      "files": [
        {
          "path": "registry/demo/primitives/texts/number-flow/index.tsx",
          "type": "registry:ui",
          "target": "components/sora-ui/demo/texts/number-flow.tsx"
        }
      ]
    },
    {
      "name": "demo-text-cursor-loop",
      "type": "registry:ui",
      "title": "Text Cursor Loop Demo",
      "description": "The anime.js hero line, with the cursor flashing red only while collapsing/revealing.",
      "registryDependencies": ["@soralabs/text-cursor-loop"],
      "files": [
        {
          "path": "registry/demo/primitives/texts/text-cursor-loop/index.tsx",
          "type": "registry:ui",
          "target": "components/sora-ui/demo/texts/text-cursor-loop.tsx"
        }
      ]
    },
    {
      "name": "demo-text-effect",
      "type": "registry:ui",
      "title": "Text Effect Demo",
      "description": "Scroll-triggered text reveal with blur, fade, slide, and scale presets.",
      "registryDependencies": ["@soralabs/text-effect"],
      "files": [
        {
          "path": "registry/demo/primitives/texts/text-effect/index.tsx",
          "type": "registry:ui",
          "target": "components/sora-ui/demo/texts/text-effect.tsx"
        }
      ],
      "meta": {
        "demoProps": {
          "TextEffectDemo": {
            "children": {
              "value": "Motion-first text effects"
            },
            "preset": {
              "value": "fade-in-blur",
              "options": {
                "Fade in blur": "fade-in-blur",
                "Blur": "blur",
                "Fade": "fade",
                "Slide": "slide",
                "Scale": "scale"
              }
            },
            "per": {
              "value": "word",
              "options": {
                "Word": "word",
                "Char": "char",
                "Line": "line"
              }
            },
            "delay": {
              "value": 0,
              "min": 0,
              "max": 2,
              "step": 0.1
            },
            "speedReveal": {
              "value": 1,
              "min": 0.25,
              "max": 3,
              "step": 0.25
            },
            "speedSegment": {
              "value": 1,
              "min": 0.25,
              "max": 3,
              "step": 0.25
            },
            "scrollTrigger": {
              "value": true
            }
          }
        }
      }
    },
    {
      "name": "demo-text-loop",
      "type": "registry:ui",
      "title": "Text Loop Demo",
      "description": "Cycling headline built with TextLoop.",
      "registryDependencies": ["@soralabs/text-loop"],
      "files": [
        {
          "path": "registry/demo/primitives/texts/text-loop/index.tsx",
          "type": "registry:ui",
          "target": "components/sora-ui/demo/texts/text-loop.tsx"
        }
      ],
      "meta": {
        "demoProps": {
          "TextLoopExample": {
            "interval": {
              "value": 2,
              "min": 0.5,
              "max": 5,
              "step": 0.1
            },
            "className": {
              "value": "font-medium text-2xl text-foreground"
            }
          }
        }
      }
    },
    {
      "name": "demo-text-morph",
      "type": "registry:ui",
      "title": "Text Morph Demo",
      "description": "Continue / Confirm pill button with per-character layout morph.",
      "registryDependencies": ["@soralabs/text-morph"],
      "files": [
        {
          "path": "registry/demo/primitives/texts/text-morph/index.tsx",
          "type": "registry:ui",
          "target": "components/sora-ui/demo/texts/text-morph.tsx"
        }
      ]
    },
    {
      "name": "demo-text-morph-input",
      "type": "registry:ui",
      "title": "Text Morph Input Demo",
      "description": "Live text morph driven by a controlled input.",
      "registryDependencies": ["@soralabs/text-morph"],
      "files": [
        {
          "path": "registry/demo/primitives/texts/text-morph-input/index.tsx",
          "type": "registry:ui",
          "target": "components/sora-ui/demo/texts/text-morph-input.tsx"
        }
      ]
    },
    {
      "name": "demo-text-reveal-mask",
      "type": "registry:ui",
      "title": "Text Reveal (Mask) Demo",
      "description": "Scroll-triggered masked text reveal with rich text emphasis.",
      "registryDependencies": ["@soralabs/text-reveal-mask"],
      "files": [
        {
          "path": "registry/demo/primitives/texts/text-reveal-mask/index.tsx",
          "type": "registry:ui",
          "target": "components/sora-ui/demo/texts/text-reveal-mask.tsx"
        }
      ],
      "meta": {
        "demoProps": {
          "MaskedTextRevealExample": {
            "splitBy": {
              "value": "lines",
              "options": {
                "Lines": "lines",
                "Words": "words",
                "Characters": "chars"
              }
            },
            "stagger": {
              "value": 0.1,
              "min": 0.01,
              "max": 0.5,
              "step": 0.01
            },
            "duration": {
              "value": 0.8,
              "min": 0.1,
              "max": 2,
              "step": 0.1
            },
            "yPercent": {
              "value": 110,
              "min": 50,
              "max": 200,
              "step": 5
            },
            "delay": {
              "value": 0,
              "min": 0,
              "max": 2,
              "step": 0.1
            },
            "viewportMargin": {
              "value": "0px 0px -20% 0px"
            }
          }
        }
      }
    },
    {
      "name": "demo-text-roll",
      "type": "registry:ui",
      "title": "Text Roll Demo",
      "description": "Interactive copy button with chromatic text roll feedback.",
      "registryDependencies": ["@soralabs/text-roll"],
      "files": [
        {
          "path": "registry/demo/primitives/texts/text-roll/index.tsx",
          "type": "registry:ui",
          "target": "components/sora-ui/demo/texts/text-roll.tsx"
        }
      ],
      "meta": {
        "demoProps": {
          "TextRollPlayground": {
            "className": {
              "value": "font-medium text-lg tabular-nums"
            },
            "stagger": {
              "value": 45,
              "min": 0,
              "max": 120,
              "step": 5
            },
            "duration": {
              "value": 300,
              "min": 100,
              "max": 600,
              "step": 25
            },
            "bounce": {
              "value": 0.6,
              "min": 0,
              "max": 1,
              "step": 0.1
            },
            "chromatic": {
              "value": true
            }
          }
        }
      }
    },
    {
      "name": "demo-typer",
      "type": "registry:ui",
      "title": "Typer Demo",
      "description": "A stacked headline that cascades in line by line, each character rippling through pill and accent states before settling into plain text.",
      "registryDependencies": ["@soralabs/typer"],
      "files": [
        {
          "path": "registry/demo/primitives/texts/typer/index.tsx",
          "type": "registry:ui",
          "target": "components/sora-ui/demo/texts/typer.tsx"
        }
      ],
      "meta": {
        "demoProps": {
          "TyperExample": {
            "fps": {
              "value": 20,
              "min": 5,
              "max": 40,
              "step": 1
            },
            "cycles": {
              "value": 3,
              "min": 1,
              "max": 6,
              "step": 1
            },
            "stagger": {
              "value": 0.15,
              "min": 0,
              "max": 0.6,
              "step": 0.05
            },
            "startOnView": {
              "value": true
            },
            "accent": {
              "value": "#12a150"
            }
          }
        }
      }
    },
    {
      "name": "demo-base-accordion",
      "type": "registry:ui",
      "title": "Base Accordion Demo",
      "description": "Base UI accordion with Motion spring physics, blur transitions, and animated focus ring.",
      "registryDependencies": ["@soralabs/base-accordion"],
      "files": [
        {
          "path": "registry/demo/ui/base/accordion/index.tsx",
          "type": "registry:ui",
          "target": "components/sora-ui/demo/base/accordion.tsx"
        }
      ],
      "meta": {
        "demoProps": {
          "AccordionDemo": {
            "variant": {
              "value": "default",
              "options": {
                "Default": "default",
                "Bordered": "bordered",
                "Separated": "separated",
                "Ghost": "ghost"
              }
            },
            "multiple": {
              "value": false
            },
            "showFocusRing": {
              "value": true
            },
            "disableAnimation": {
              "value": false
            }
          }
        }
      }
    },
    {
      "name": "demo-base-accordion-bordered",
      "type": "registry:ui",
      "title": "Base Accordion Bordered Demo",
      "description": "Base UI accordion in a bordered card container with refined surface styling.",
      "registryDependencies": ["@soralabs/base-accordion"],
      "files": [
        {
          "path": "registry/demo/ui/base/accordion-bordered/index.tsx",
          "type": "registry:ui",
          "target": "components/sora-ui/demo/base/accordion-bordered.tsx"
        }
      ]
    },
    {
      "name": "demo-base-accordion-multiple",
      "type": "registry:ui",
      "title": "Multiple Open Base Accordion Demo",
      "description": "Base UI accordion allowing multiple panels to expand simultaneously.",
      "registryDependencies": ["@soralabs/base-accordion"],
      "files": [
        {
          "path": "registry/demo/ui/base/accordion-multiple/index.tsx",
          "type": "registry:ui",
          "target": "components/sora-ui/demo/base/accordion-multiple.tsx"
        }
      ]
    },
    {
      "name": "demo-base-accordion-separated",
      "type": "registry:ui",
      "title": "Separated Base Accordion Demo",
      "description": "Base UI accordion with separated card-style items.",
      "registryDependencies": ["@soralabs/base-accordion"],
      "files": [
        {
          "path": "registry/demo/ui/base/accordion-separated/index.tsx",
          "type": "registry:ui",
          "target": "components/sora-ui/demo/base/accordion-separated.tsx"
        }
      ]
    },
    {
      "name": "demo-alert-dialog",
      "type": "registry:ui",
      "title": "Alert Dialog Demo",
      "description": "Base UI alert dialog with Motion 3D perspective transitions and media icon header.",
      "registryDependencies": ["@soralabs/base-alert-dialog"],
      "files": [
        {
          "path": "registry/demo/ui/base/alert-dialog/index.tsx",
          "type": "registry:ui",
          "target": "components/sora-ui/demo/base/alert-dialog.tsx"
        }
      ]
    },
    {
      "name": "demo-alert-dialog-small",
      "type": "registry:ui",
      "title": "Alert Dialog Small Demo",
      "description": "Compact Base UI alert dialog with two-column button layout.",
      "registryDependencies": ["@soralabs/base-alert-dialog"],
      "files": [
        {
          "path": "registry/demo/ui/base/alert-dialog-small/index.tsx",
          "type": "registry:ui",
          "target": "components/sora-ui/demo/base/alert-dialog-small.tsx"
        }
      ]
    },
    {
      "name": "demo-button",
      "type": "registry:ui",
      "title": "Button Demo",
      "description": "Interactive showcase of Base UI Button variants, sizes, icon combinations, and Motion scaling.",
      "registryDependencies": ["@soralabs/base-button"],
      "files": [
        {
          "path": "registry/demo/ui/base/button/index.tsx",
          "type": "registry:ui",
          "target": "components/sora-ui/demo/base/button.tsx"
        }
      ]
    },
    {
      "name": "demo-button-loading",
      "type": "registry:ui",
      "title": "Button Loading Demo",
      "dependencies": ["lucide-react"],
      "registryDependencies": ["@soralabs/base-button"],
      "files": [
        {
          "path": "registry/demo/ui/base/button-loading/index.tsx",
          "type": "registry:ui",
          "target": "components/sora-ui/demo/base/button-loading.tsx"
        }
      ]
    },
    {
      "name": "demo-button-motion",
      "type": "registry:ui",
      "title": "Button Motion Demo",
      "registryDependencies": ["@soralabs/base-button"],
      "files": [
        {
          "path": "registry/demo/ui/base/button-motion/index.tsx",
          "type": "registry:ui",
          "target": "components/sora-ui/demo/base/button-motion.tsx"
        }
      ]
    },
    {
      "name": "demo-button-sizes",
      "type": "registry:ui",
      "title": "Button Sizes Demo",
      "registryDependencies": ["@soralabs/base-button"],
      "files": [
        {
          "path": "registry/demo/ui/base/button-sizes/index.tsx",
          "type": "registry:ui",
          "target": "components/sora-ui/demo/base/button-sizes.tsx"
        }
      ]
    },
    {
      "name": "demo-button-variants",
      "type": "registry:ui",
      "title": "Button Variants Demo",
      "description": "Showcase of all visual button variants: default, secondary, destructive, outline, ghost, and link.",
      "registryDependencies": ["@soralabs/base-button"],
      "files": [
        {
          "path": "registry/demo/ui/base/button-variants/index.tsx",
          "type": "registry:ui",
          "target": "components/sora-ui/demo/base/button-variants.tsx"
        }
      ]
    },
    {
      "name": "demo-button-with-icon",
      "type": "registry:ui",
      "title": "Button With Icon Demo",
      "dependencies": ["lucide-react"],
      "registryDependencies": ["@soralabs/base-button"],
      "files": [
        {
          "path": "registry/demo/ui/base/button-with-icon/index.tsx",
          "type": "registry:ui",
          "target": "components/sora-ui/demo/base/button-with-icon.tsx"
        }
      ]
    },
    {
      "name": "demo-checkbox",
      "type": "registry:ui",
      "title": "Checkbox Demo",
      "description": "Base UI checkbox with Motion path-draw checkmark.",
      "registryDependencies": ["@soralabs/base-checkbox"],
      "files": [
        {
          "path": "registry/demo/ui/base/checkbox/index.tsx",
          "type": "registry:ui",
          "target": "components/sora-ui/demo/base/checkbox.tsx"
        }
      ]
    },
    {
      "name": "demo-checkbox-card",
      "type": "registry:ui",
      "title": "Checkbox Card Demo",
      "registryDependencies": ["@soralabs/base-checkbox"],
      "files": [
        {
          "path": "registry/demo/ui/base/checkbox-card/index.tsx",
          "type": "registry:ui",
          "target": "components/sora-ui/demo/base/checkbox-card.tsx"
        }
      ]
    },
    {
      "name": "demo-checkbox-indeterminate",
      "type": "registry:ui",
      "title": "Checkbox Indeterminate Demo",
      "registryDependencies": ["@soralabs/base-checkbox"],
      "files": [
        {
          "path": "registry/demo/ui/base/checkbox-indeterminate/index.tsx",
          "type": "registry:ui",
          "target": "components/sora-ui/demo/base/checkbox-indeterminate.tsx"
        }
      ]
    },
    {
      "name": "demo-checkbox-with-text",
      "type": "registry:ui",
      "title": "Checkbox With Text Demo",
      "registryDependencies": ["@soralabs/base-checkbox"],
      "files": [
        {
          "path": "registry/demo/ui/base/checkbox-with-text/index.tsx",
          "type": "registry:ui",
          "target": "components/sora-ui/demo/base/checkbox-with-text.tsx"
        }
      ]
    },
    {
      "name": "demo-context-menu",
      "type": "registry:ui",
      "title": "Context Menu Demo",
      "description": "Base UI Context Menu with spring entrance, nested submenus, checkable items, radio items, shortcuts, and destructive actions.",
      "registryDependencies": ["@soralabs/base-context-menu"],
      "files": [
        {
          "path": "registry/demo/ui/base/context-menu/index.tsx",
          "type": "registry:ui",
          "target": "components/sora-ui/demo/base/context-menu.tsx"
        }
      ]
    },
    {
      "name": "demo-context-menu-file",
      "type": "registry:ui",
      "title": "Context Menu File Demo",
      "description": "Base UI Context Menu with file management actions, icons, shortcuts, and submenus.",
      "registryDependencies": ["@soralabs/base-context-menu"],
      "files": [
        {
          "path": "registry/demo/ui/base/context-menu-file/index.tsx",
          "type": "registry:ui",
          "target": "components/sora-ui/demo/base/context-menu-file.tsx"
        }
      ]
    },
    {
      "name": "demo-context-menu-rtl",
      "type": "registry:ui",
      "title": "Context Menu RTL Demo",
      "description": "Context Menu rendered right-to-left with Base UI DirectionProvider.",
      "registryDependencies": ["@soralabs/base-context-menu"],
      "files": [
        {
          "path": "registry/demo/ui/base/context-menu-rtl/index.tsx",
          "type": "registry:ui",
          "target": "components/sora-ui/demo/base/context-menu-rtl.tsx"
        }
      ]
    },
    {
      "name": "demo-dialog",
      "type": "registry:ui",
      "title": "Dialog Demo",
      "description": "Base UI dialog with Motion spring transitions and form editing.",
      "registryDependencies": ["@soralabs/base-dialog"],
      "files": [
        {
          "path": "registry/demo/ui/base/dialog/index.tsx",
          "type": "registry:ui",
          "target": "components/sora-ui/demo/base/dialog.tsx"
        }
      ]
    },
    {
      "name": "demo-dialog-scrollable",
      "type": "registry:ui",
      "title": "Dialog Scrollable Demo",
      "registryDependencies": [
        "@soralabs/base-dialog",
        "@soralabs/base-button"
      ],
      "files": [
        {
          "path": "registry/demo/ui/base/dialog-scrollable/index.tsx",
          "type": "registry:ui",
          "target": "components/sora-ui/demo/base/dialog-scrollable.tsx"
        }
      ]
    },
    {
      "name": "demo-dialog-share",
      "type": "registry:ui",
      "title": "Dialog Share Link Demo",
      "dependencies": ["lucide-react"],
      "registryDependencies": [
        "@soralabs/base-dialog",
        "@soralabs/base-button"
      ],
      "files": [
        {
          "path": "registry/demo/ui/base/dialog-share/index.tsx",
          "type": "registry:ui",
          "target": "components/sora-ui/demo/base/dialog-share.tsx"
        }
      ]
    },
    {
      "name": "demo-dropdown-menu",
      "type": "registry:ui",
      "title": "Dropdown Menu Demo",
      "description": "Base UI Dropdown Menu with spring entrance, nested submenus, checkable items, radio items, shortcuts, and destructive actions.",
      "registryDependencies": ["@soralabs/base-dropdown-menu"],
      "files": [
        {
          "path": "registry/demo/ui/base/dropdown-menu/index.tsx",
          "type": "registry:ui",
          "target": "components/sora-ui/demo/base/dropdown-menu.tsx"
        }
      ]
    },
    {
      "name": "demo-dropdown-menu-rtl",
      "type": "registry:ui",
      "title": "Dropdown Menu RTL Demo",
      "description": "Dropdown Menu rendered right-to-left with Base UI DirectionProvider.",
      "registryDependencies": ["@soralabs/base-dropdown-menu"],
      "files": [
        {
          "path": "registry/demo/ui/base/dropdown-menu-rtl/index.tsx",
          "type": "registry:ui",
          "target": "components/sora-ui/demo/base/dropdown-menu-rtl.tsx"
        }
      ]
    },
    {
      "name": "demo-switch",
      "type": "registry:ui",
      "title": "Switch Demo",
      "description": "Base UI switch with Motion layout spring physics.",
      "registryDependencies": ["@soralabs/base-switch"],
      "files": [
        {
          "path": "registry/demo/ui/base/switch/index.tsx",
          "type": "registry:ui",
          "target": "components/sora-ui/demo/base/switch.tsx"
        }
      ]
    },
    {
      "name": "demo-switch-sizes",
      "type": "registry:ui",
      "title": "Switch Sizes Demo",
      "description": "Base UI switch rendered across sm, default, and lg sizes.",
      "registryDependencies": ["@soralabs/base-switch"],
      "files": [
        {
          "path": "registry/demo/ui/base/switch-sizes/index.tsx",
          "type": "registry:ui",
          "target": "components/sora-ui/demo/base/switch-sizes.tsx"
        }
      ]
    },
    {
      "name": "demo-switch-with-icon",
      "type": "registry:ui",
      "title": "Switch With Icon Demo",
      "description": "Base UI switch with track icons and description.",
      "dependencies": ["lucide-react"],
      "registryDependencies": ["@soralabs/base-switch"],
      "files": [
        {
          "path": "registry/demo/ui/base/switch-with-icon/index.tsx",
          "type": "registry:ui",
          "target": "components/sora-ui/demo/base/switch-with-icon.tsx"
        }
      ]
    },
    {
      "name": "demo-base-tooltip",
      "type": "registry:ui",
      "title": "Base Tooltip Demo",
      "description": "Base UI tooltip with spring bounce motion physics and arrow pointer.",
      "dependencies": ["lucide-react"],
      "registryDependencies": [
        "@soralabs/base-tooltip",
        "@soralabs/base-button"
      ],
      "files": [
        {
          "path": "registry/demo/ui/base/tooltip/index.tsx",
          "type": "registry:ui",
          "target": "components/sora-ui/demo/base/tooltip.tsx"
        }
      ]
    },
    {
      "name": "demo-radix-button",
      "type": "registry:ui",
      "title": "Radix Button Demo",
      "description": "Interactive showcase of Radix UI Slot Button variants, sizes, icon combinations, and Motion scaling.",
      "registryDependencies": ["@soralabs/radix-button"],
      "files": [
        {
          "path": "registry/demo/ui/radix/button/index.tsx",
          "type": "registry:ui",
          "target": "components/sora-ui/demo/radix/button.tsx"
        }
      ]
    },
    {
      "name": "demo-radix-button-loading",
      "type": "registry:ui",
      "title": "Radix Button Loading Demo",
      "description": "Disabled Radix UI button displaying an animated spinner.",
      "registryDependencies": ["@soralabs/radix-button"],
      "files": [
        {
          "path": "registry/demo/ui/radix/button-loading/index.tsx",
          "type": "registry:ui",
          "target": "components/sora-ui/demo/radix/button-loading.tsx"
        }
      ]
    },
    {
      "name": "demo-radix-button-motion",
      "type": "registry:ui",
      "title": "Radix Button Motion Scaling Demo",
      "description": "Customizable hover and tap Motion spring scaling on Radix UI button.",
      "registryDependencies": ["@soralabs/radix-button"],
      "files": [
        {
          "path": "registry/demo/ui/radix/button-motion/index.tsx",
          "type": "registry:ui",
          "target": "components/sora-ui/demo/radix/button-motion.tsx"
        }
      ]
    },
    {
      "name": "demo-radix-button-sizes",
      "type": "registry:ui",
      "title": "Radix Button Sizes Demo",
      "description": "Radix UI button size presets from extra small to large.",
      "registryDependencies": ["@soralabs/radix-button"],
      "files": [
        {
          "path": "registry/demo/ui/radix/button-sizes/index.tsx",
          "type": "registry:ui",
          "target": "components/sora-ui/demo/radix/button-sizes.tsx"
        }
      ]
    },
    {
      "name": "demo-radix-button-variants",
      "type": "registry:ui",
      "title": "Radix Button Variants Demo",
      "description": "Showcase of all visual Radix button variants: default, secondary, destructive, outline, ghost, and link.",
      "registryDependencies": ["@soralabs/radix-button"],
      "files": [
        {
          "path": "registry/demo/ui/radix/button-variants/index.tsx",
          "type": "registry:ui",
          "target": "components/sora-ui/demo/radix/button-variants.tsx"
        }
      ]
    },
    {
      "name": "demo-radix-button-with-icon",
      "type": "registry:ui",
      "title": "Radix Button with Icon Demo",
      "description": "Radix UI button combined with leading and trailing Lucide icons.",
      "registryDependencies": ["@soralabs/radix-button"],
      "files": [
        {
          "path": "registry/demo/ui/radix/button-with-icon/index.tsx",
          "type": "registry:ui",
          "target": "components/sora-ui/demo/radix/button-with-icon.tsx"
        }
      ]
    },
    {
      "name": "demo-radix-checkbox",
      "type": "registry:ui",
      "title": "Radix Checkbox Demo",
      "description": "Interactive showcase of Radix UI animated Checkbox with SVG stroke draw animation.",
      "registryDependencies": ["@soralabs/radix-checkbox"],
      "files": [
        {
          "path": "registry/demo/ui/radix/checkbox/index.tsx",
          "type": "registry:ui",
          "target": "components/sora-ui/demo/radix/checkbox.tsx"
        }
      ]
    },
    {
      "name": "demo-radix-checkbox-card",
      "type": "registry:ui",
      "title": "Radix Checkbox Card Demo",
      "description": "Selectable card container with embedded animated Radix UI checkbox.",
      "registryDependencies": ["@soralabs/radix-checkbox"],
      "files": [
        {
          "path": "registry/demo/ui/radix/checkbox-card/index.tsx",
          "type": "registry:ui",
          "target": "components/sora-ui/demo/radix/checkbox-card.tsx"
        }
      ]
    },
    {
      "name": "demo-radix-checkbox-indeterminate",
      "type": "registry:ui",
      "title": "Radix Checkbox Indeterminate Demo",
      "description": "Radix UI checkbox in a partially checked indeterminate state.",
      "registryDependencies": ["@soralabs/radix-checkbox"],
      "files": [
        {
          "path": "registry/demo/ui/radix/checkbox-indeterminate/index.tsx",
          "type": "registry:ui",
          "target": "components/sora-ui/demo/radix/checkbox-indeterminate.tsx"
        }
      ]
    },
    {
      "name": "demo-radix-checkbox-with-text",
      "type": "registry:ui",
      "title": "Radix Checkbox with Text Demo",
      "description": "Radix UI checkbox with supplementary title and description text.",
      "registryDependencies": ["@soralabs/radix-checkbox"],
      "files": [
        {
          "path": "registry/demo/ui/radix/checkbox-with-text/index.tsx",
          "type": "registry:ui",
          "target": "components/sora-ui/demo/radix/checkbox-with-text.tsx"
        }
      ]
    },
    {
      "name": "demo-radix-dialog",
      "type": "registry:ui",
      "title": "Radix Dialog Demo",
      "description": "Interactive showcase of Radix UI modal Dialog with 3D perspective spring entrance and exit animations.",
      "registryDependencies": [
        "@soralabs/radix-dialog",
        "@soralabs/radix-button"
      ],
      "files": [
        {
          "path": "registry/demo/ui/radix/dialog/index.tsx",
          "type": "registry:ui",
          "target": "components/sora-ui/demo/radix/dialog.tsx"
        }
      ]
    },
    {
      "name": "demo-radix-dialog-scrollable",
      "type": "registry:ui",
      "title": "Radix Dialog Scrollable Demo",
      "description": "Radix UI dialog with scrollable content area.",
      "registryDependencies": [
        "@soralabs/radix-dialog",
        "@soralabs/radix-button"
      ],
      "files": [
        {
          "path": "registry/demo/ui/radix/dialog-scrollable/index.tsx",
          "type": "registry:ui",
          "target": "components/sora-ui/demo/radix/dialog-scrollable.tsx"
        }
      ]
    },
    {
      "name": "demo-radix-dialog-share",
      "type": "registry:ui",
      "title": "Radix Dialog Share Demo",
      "description": "Interactive Radix UI dialog with link copying and sharing.",
      "registryDependencies": [
        "@soralabs/radix-dialog",
        "@soralabs/radix-button"
      ],
      "files": [
        {
          "path": "registry/demo/ui/radix/dialog-share/index.tsx",
          "type": "registry:ui",
          "target": "components/sora-ui/demo/radix/dialog-share.tsx"
        }
      ]
    },
    {
      "name": "hooks-use-auto-height",
      "type": "registry:hook",
      "title": "useAutoHeight",
      "description": "A hook that allows you to automatically adjust the height of an element based on its content.",
      "files": [
        {
          "path": "registry/hooks/use-auto-height/index.tsx",
          "type": "registry:hook",
          "target": "hooks/use-auto-height.tsx"
        }
      ]
    },
    {
      "name": "hooks-use-controlled-state",
      "type": "registry:hook",
      "title": "useControlledState",
      "description": "A hook that allows you to control a state.",
      "files": [
        {
          "path": "registry/hooks/use-controlled-state/index.tsx",
          "type": "registry:hook",
          "target": "hooks/use-controlled-state.tsx"
        }
      ]
    },
    {
      "name": "hooks-use-prefers-reduced-motion",
      "type": "registry:hook",
      "title": "usePrefersReducedMotion",
      "description": "A hook that tracks the OS-level Reduced Motion setting live, so GSAP-driven primitives can skip or shortcut their animations.",
      "files": [
        {
          "path": "registry/hooks/use-prefers-reduced-motion/index.tsx",
          "type": "registry:hook",
          "target": "hooks/use-prefers-reduced-motion.tsx"
        }
      ]
    },
    {
      "name": "icons-arrow-right",
      "type": "registry:ui",
      "title": "Arrow Right",
      "description": "Animated right arrow that nudges forward and redraws its stroke on hover using a pure CSS stroke-dash animation.",
      "registryDependencies": ["utils"],
      "files": [
        {
          "path": "registry/icons/arrow-right/index.tsx",
          "type": "registry:ui",
          "target": "components/sora-ui/icons/arrow-right.tsx"
        }
      ],
      "meta": {
        "keywords": ["arrow", "right", "next", "forward", "direction", "cta"],
        "releaseDate": "2026-07-31"
      }
    },
    {
      "name": "icons-bell",
      "type": "registry:ui",
      "title": "Bell",
      "description": "Notification bell that rattles from its hanger on trigger — a decaying rotation pivot.",
      "dependencies": ["motion"],
      "files": [
        {
          "path": "registry/icons/bell/index.tsx",
          "type": "registry:ui",
          "target": "components/sora-ui/icons/bell.tsx"
        }
      ],
      "meta": {
        "keywords": [
          "bell",
          "notification",
          "alert",
          "ring",
          "rattle",
          "inbox"
        ],
        "releaseDate": "2026-08-05"
      }
    },
    {
      "name": "icons-chevrons",
      "type": "registry:ui",
      "title": "Chevrons",
      "description": "Animated double up-chevron that cross-fades between the two carets on trigger.",
      "dependencies": ["motion"],
      "files": [
        {
          "path": "registry/icons/chevrons/index.tsx",
          "type": "registry:ui",
          "target": "components/sora-ui/icons/chevrons.tsx"
        }
      ],
      "meta": {
        "keywords": [
          "chevrons",
          "arrow",
          "up",
          "double",
          "scroll-top",
          "direction",
          "navigation"
        ],
        "releaseDate": "2026-08-05"
      }
    },
    {
      "name": "icons-copy",
      "type": "registry:ui",
      "title": "Copy",
      "description": "Animated copy icon that smoothly transitions into a checkmark on trigger with a scale and blur pop effect.",
      "dependencies": ["motion"],
      "files": [
        {
          "path": "registry/icons/copy/index.tsx",
          "type": "registry:ui",
          "target": "components/sora-ui/icons/copy.tsx"
        }
      ],
      "meta": {
        "keywords": [
          "copy",
          "clipboard",
          "duplicate",
          "check",
          "success",
          "action"
        ],
        "releaseDate": "2026-09-14"
      }
    },
    {
      "name": "lib-scroll-trigger-utils",
      "type": "registry:lib",
      "title": "Scroll Trigger Utils",
      "description": "Shared GSAP ScrollTrigger helpers (window/scroller detection, ready/resize waiting) used by scroll-driven primitives.",
      "files": [
        {
          "path": "registry/lib/scroll-trigger-utils/index.tsx",
          "type": "registry:lib",
          "target": "lib/scroll-trigger-utils.tsx"
        }
      ]
    },
    {
      "name": "particle-hover-button",
      "type": "registry:ui",
      "title": "Particle Hover Button",
      "description": "A wrapper that emits glowing, pooled particles from the cursor while hovering any button or link.",
      "dependencies": ["motion"],
      "registryDependencies": ["@soralabs/hooks-use-prefers-reduced-motion"],
      "files": [
        {
          "path": "registry/primitives/buttons/particle-hover-button/index.tsx",
          "type": "registry:ui",
          "target": "components/sora-ui/buttons/particle-hover-button.tsx"
        }
      ],
      "meta": {
        "keywords": [
          "button",
          "hover",
          "particles",
          "sponsor",
          "cta",
          "motion",
          "glow"
        ]
      }
    },
    {
      "name": "sliding-chip-button",
      "type": "registry:ui",
      "title": "Sliding Chip Button",
      "description": "A chip-style call-to-action link with a Motion-powered sliding label and rotating icon chips on hover.",
      "dependencies": ["motion", "class-variance-authority"],
      "registryDependencies": ["utils"],
      "files": [
        {
          "path": "registry/primitives/buttons/sliding-chip-button/index.tsx",
          "type": "registry:ui",
          "target": "components/sora-ui/buttons/sliding-chip-button.tsx"
        }
      ],
      "meta": {
        "inspiration": {
          "type": "inspired",
          "label": "Annnimate",
          "url": "https://www.annnimate.com"
        },
        "demoProps": {
          "SlidingChipButton": {
            "label": {
              "value": "Explore components"
            },
            "variant": {
              "value": "accent",
              "options": {
                "Accent": "accent",
                "Inverted": "inverted",
                "Outline": "outline",
                "Ghost": "ghost"
              }
            },
            "size": {
              "value": "default",
              "options": {
                "Small": "sm",
                "Default": "default",
                "Large": "lg"
              }
            },
            "duration": {
              "value": 0.7,
              "min": 0.2,
              "max": 2,
              "step": 0.1
            }
          }
        }
      }
    },
    {
      "name": "stagger-button",
      "type": "registry:ui",
      "title": "Stagger Button",
      "description": "A button that staggers per character or slides the whole label on hover, with a scaling background layer.",
      "dependencies": ["class-variance-authority"],
      "registryDependencies": ["utils"],
      "files": [
        {
          "path": "registry/primitives/buttons/stagger-button/index.tsx",
          "type": "registry:ui",
          "target": "components/sora-ui/buttons/stagger-button.tsx"
        }
      ],
      "meta": {
        "demoProps": {
          "StaggerButton": {
            "label": {
              "value": "Staggering Button"
            },
            "variant": {
              "value": "default",
              "options": {
                "Default": "default",
                "Accent": "accent",
                "Neutral": "neutral",
                "Destructive": "destructive",
                "Outline": "outline",
                "Secondary": "secondary",
                "Ghost": "ghost",
                "Link": "link"
              }
            },
            "size": {
              "value": "default",
              "options": {
                "Small": "sm",
                "Default": "default",
                "Medium": "md",
                "Large": "lg"
              }
            },
            "stagger": {
              "value": "char",
              "options": {
                "Char": "char",
                "Text": "text"
              }
            }
          }
        }
      }
    },
    {
      "name": "accordion",
      "type": "registry:ui",
      "title": "Accordion",
      "description": "An animated FAQ accordion with expandable panels, powered by Motion.",
      "dependencies": ["motion", "class-variance-authority"],
      "registryDependencies": ["utils", "@soralabs/hooks-use-auto-height"],
      "files": [
        {
          "path": "registry/primitives/disclosure/accordion/index.tsx",
          "type": "registry:ui",
          "target": "components/sora-ui/disclosure/accordion.tsx"
        }
      ],
      "meta": {
        "inspiration": {
          "type": "reimplemented",
          "label": "Annnimate",
          "url": "https://www.annnimate.com",
          "stack": "Motion and React"
        }
      }
    },
    {
      "name": "expandable-tabs",
      "type": "registry:ui",
      "title": "Expandable Tabs",
      "description": "A pill-shaped tab bar that expands into a floating panel, with Motion driving the shell, label, and content transitions.",
      "dependencies": ["motion", "lucide-react", "react-use-measure"],
      "registryDependencies": ["utils"],
      "files": [
        {
          "path": "registry/primitives/disclosure/expandable-tabs/index.tsx",
          "type": "registry:ui",
          "target": "components/sora-ui/disclosure/expandable-tabs.tsx"
        }
      ],
      "meta": {
        "inspiration": {
          "type": "reimplemented",
          "label": "beui.dev's Expandable Tabs",
          "url": "https://beui.dev",
          "stack": "Motion and React"
        }
      }
    },
    {
      "name": "inline-testimonials",
      "type": "registry:ui",
      "title": "Inline Testimonials",
      "description": "A flowing quote stream where each avatar reveals its author on hover, with Motion fading and blurring the rest.",
      "dependencies": ["motion"],
      "registryDependencies": ["utils"],
      "files": [
        {
          "path": "registry/primitives/disclosure/inline-testimonials/index.tsx",
          "type": "registry:ui",
          "target": "components/sora-ui/disclosure/inline-testimonials.tsx"
        }
      ]
    },
    {
      "name": "border-trail",
      "type": "registry:ui",
      "title": "Border Trail",
      "description": "Animated border spotlight that travels around a rounded container, powered by Motion.",
      "dependencies": ["motion"],
      "registryDependencies": ["utils"],
      "files": [
        {
          "path": "registry/primitives/effects/border-trail/index.tsx",
          "type": "registry:ui",
          "target": "components/sora-ui/effects/border-trail.tsx"
        }
      ],
      "meta": {
        "inspiration": {
          "type": "inspired",
          "label": "motion-primitives",
          "url": "https://motion-primitives.com/docs/border-trail"
        }
      }
    },
    {
      "name": "cursor-bubble",
      "type": "registry:ui",
      "title": "Cursor Bubble",
      "description": "A floating label that follows the cursor and elastic-pops into view over interactive targets, powered by GSAP.",
      "dependencies": ["gsap", "@gsap/react"],
      "registryDependencies": ["@soralabs/hooks-use-prefers-reduced-motion"],
      "files": [
        {
          "path": "registry/primitives/effects/cursor-bubble/index.tsx",
          "type": "registry:ui",
          "target": "components/sora-ui/effects/cursor-bubble.tsx"
        }
      ],
      "meta": {
        "keywords": ["cursor", "bubble", "hover", "label", "gsap"],
        "inspiration": {
          "type": "reimplemented",
          "label": "Truus.co",
          "url": "https://www.truus.co/",
          "stack": "GSAP and React"
        }
      }
    },
    {
      "name": "hero-carousel",
      "type": "registry:ui",
      "title": "Hero Carousel",
      "description": "Crossfading hero image slideshow with a progress pill, play/pause, and prev/next controls.",
      "registryDependencies": [
        "utils",
        "@soralabs/hooks-use-prefers-reduced-motion"
      ],
      "files": [
        {
          "path": "registry/primitives/effects/hero-carousel/index.tsx",
          "type": "registry:ui",
          "target": "components/sora-ui/effects/hero-carousel.tsx"
        }
      ],
      "meta": {
        "keywords": [
          "carousel",
          "hero",
          "slideshow",
          "crossfade",
          "images",
          "gallery"
        ]
      }
    },
    {
      "name": "highlight",
      "type": "registry:ui",
      "title": "Highlight",
      "description": "A Motion-powered highlight effect that allows you to highlight elements on hover, click or with a controlled value.",
      "dependencies": ["motion"],
      "registryDependencies": ["utils"],
      "files": [
        {
          "path": "registry/primitives/effects/highlight/index.tsx",
          "type": "registry:ui",
          "target": "components/sora-ui/effects/highlight.tsx"
        }
      ]
    },
    {
      "name": "logo-carousel-swapper",
      "type": "registry:ui",
      "title": "Logo Carousel Swapper",
      "description": "Staggered logo column swapper with fade, vertical shift, and motion blur powered by Motion.",
      "dependencies": ["motion", "class-variance-authority"],
      "registryDependencies": ["utils"],
      "files": [
        {
          "path": "registry/primitives/effects/logo-carousel-swapper/index.tsx",
          "type": "registry:ui",
          "target": "components/sora-ui/effects/logo-carousel-swapper.tsx"
        }
      ],
      "meta": {
        "keywords": [
          "logo",
          "carousel",
          "stagger",
          "blur",
          "motion",
          "brands",
          "swap"
        ],
        "demoProps": {
          "LogoCarouselSwapper": {
            "monochrome": {
              "value": true
            }
          }
        }
      }
    },
    {
      "name": "magnetic-cards",
      "type": "registry:ui",
      "title": "Magnetic Cards",
      "description": "A fanned stack of cards that fling away from the cursor on release, with GSAP InertiaPlugin easing each one back to rest.",
      "dependencies": ["gsap", "@gsap/react"],
      "registryDependencies": ["@soralabs/hooks-use-prefers-reduced-motion"],
      "files": [
        {
          "path": "registry/primitives/effects/magnetic-cards/index.tsx",
          "type": "registry:ui",
          "target": "components/sora-ui/effects/magnetic-cards.tsx"
        }
      ],
      "meta": {
        "keywords": ["magnetic", "cards", "cursor", "inertia", "gsap"],
        "inspiration": {
          "type": "reimplemented",
          "label": "Truus.co",
          "url": "https://www.truus.co/",
          "stack": "GSAP InertiaPlugin and React"
        }
      }
    },
    {
      "name": "pixel-image-loader",
      "type": "registry:ui",
      "title": "Pixel Image Loader",
      "description": "A canvas-based image that resolves from a blocky, pixelated placeholder up to full sharpness as it loads.",
      "registryDependencies": ["@soralabs/hooks-use-prefers-reduced-motion"],
      "files": [
        {
          "path": "registry/primitives/effects/pixel-image-loader/index.tsx",
          "type": "registry:ui",
          "target": "components/sora-ui/effects/pixel-image-loader.tsx"
        }
      ],
      "meta": {
        "demoProps": {
          "PixelImageLoader": {
            "src": {
              "value": "https://images.unsplash.com/photo-1526779259212-939e64788e3c?q=80&w=764&auto=format&fit=crop"
            },
            "alt": {
              "value": "Pixel image loader demo"
            },
            "aspect": {
              "value": "square",
              "options": {
                "Square": "square",
                "Video": "video",
                "Auto": "auto"
              }
            },
            "initialDelay": {
              "value": 0,
              "min": 0,
              "max": 1000,
              "step": 50
            },
            "stepDuration": {
              "value": 80,
              "min": 20,
              "max": 300,
              "step": 10
            },
            "trigger": {
              "value": "inView",
              "options": {
                "In View": "inView",
                "Immediate": "immediate"
              }
            },
            "className": {
              "value": "mx-auto w-72 rounded-lg"
            }
          }
        }
      }
    },
    {
      "name": "progressive-blur",
      "type": "registry:ui",
      "title": "Progressive Blur",
      "description": "A stacked-layer blur that ramps smoothly from sharp to fully blurred toward an edge, for fading content under a fixed header or above a scroll boundary.",
      "registryDependencies": [
        "utils",
        "@soralabs/hooks-use-prefers-reduced-motion"
      ],
      "files": [
        {
          "path": "registry/primitives/effects/progressive-blur/index.tsx",
          "type": "registry:ui",
          "target": "components/sora-ui/effects/progressive-blur.tsx"
        }
      ],
      "meta": {
        "keywords": [
          "progressive-blur",
          "blur",
          "scroll",
          "fade",
          "backdrop-filter",
          "gradient-blur"
        ],
        "inspiration": {
          "type": "adapted",
          "label": "gxuri (Skiper UI)",
          "url": "https://gxuri.me"
        }
      }
    },
    {
      "name": "skeleton",
      "type": "registry:ui",
      "title": "Skeleton",
      "description": "A loading placeholder with shimmer or fade variants, plus a transition that crossfades into real content once loading finishes.",
      "registryDependencies": ["utils"],
      "files": [
        {
          "path": "registry/primitives/effects/skeleton/index.tsx",
          "type": "registry:ui",
          "target": "components/sora-ui/effects/skeleton.tsx"
        }
      ],
      "meta": {
        "keywords": [
          "skeleton",
          "loading",
          "placeholder",
          "shimmer",
          "shimmer-effect"
        ]
      }
    },
    {
      "name": "skeleton-shimmer",
      "type": "registry:ui",
      "title": "Skeleton Shimmer",
      "description": "Skeleton loading placeholders with a shimmer effect that transitions to revealed content via a CSS view-transition wipe animation. Skeletons are sized using placeholder data to reduce layout shifts.",
      "dependencies": ["motion"],
      "registryDependencies": ["utils"],
      "files": [
        {
          "path": "registry/primitives/effects/skeleton-shimmer/index.tsx",
          "type": "registry:ui",
          "target": "components/sora-ui/effects/skeleton-shimmer.tsx"
        }
      ],
      "meta": {
        "keywords": [
          "skeleton",
          "shimmer",
          "loading",
          "placeholder",
          "view-transition",
          "wipe"
        ],
        "inspiration": {
          "type": "reimplemented",
          "label": "motion.dev skeleton-shimmer",
          "url": "https://examples.motion.dev/react/skeleton-shimmer"
        }
      }
    },
    {
      "name": "tilt-card",
      "type": "registry:ui",
      "title": "Tilt Card",
      "description": "3D tilt card that rotates toward the cursor on spring physics, with an optional glare reflection.",
      "dependencies": ["motion"],
      "registryDependencies": ["utils"],
      "files": [
        {
          "path": "registry/primitives/effects/tilt-card/index.tsx",
          "type": "registry:ui",
          "target": "components/sora-ui/effects/tilt-card.tsx"
        }
      ],
      "meta": {
        "inspiration": {
          "type": "inspired",
          "label": "motion-primitives",
          "url": "https://motion-primitives.com/docs/tilt"
        },
        "demoProps": {
          "TiltCard": {
            "rotationFactor": {
              "value": 15,
              "min": 5,
              "max": 30,
              "step": 1
            },
            "glare": {
              "value": true
            },
            "isReverse": {
              "value": false
            },
            "scaleOnHover": {
              "value": 1.02,
              "min": 1,
              "max": 1.15,
              "step": 0.01
            }
          }
        }
      }
    },
    {
      "name": "video-player",
      "type": "registry:ui",
      "title": "Video Player",
      "description": "Dependency-free custom video player: modal overlay, chaptered timeline, hover-scrub preview, speed menu, picture-in-picture, fullscreen, keyboard shortcuts, and focus trapping.",
      "dependencies": ["motion"],
      "registryDependencies": ["utils"],
      "files": [
        {
          "path": "registry/primitives/effects/video-player/index.tsx",
          "type": "registry:ui",
          "target": "components/sora-ui/effects/video-player.tsx"
        }
      ],
      "meta": {
        "keywords": [
          "video",
          "player",
          "modal",
          "chapters",
          "scrub",
          "preview",
          "picture-in-picture",
          "fullscreen"
        ]
      }
    },
    {
      "name": "dia-text-reveal",
      "type": "registry:ui",
      "title": "Dia Text Reveal",
      "description": "A gradient sweep that reveals text with a chromatic wash, powered by Motion.",
      "dependencies": ["motion"],
      "registryDependencies": ["utils"],
      "files": [
        {
          "path": "registry/primitives/texts/dia-text-reveal/index.tsx",
          "type": "registry:ui",
          "target": "components/sora-ui/texts/dia-text-reveal.tsx"
        }
      ],
      "meta": {
        "inspiration": {
          "type": "reimplemented",
          "label": "Dia Text",
          "url": "https://iconiqui.com/texts/dia-text",
          "stack": "Motion and React"
        }
      }
    },
    {
      "name": "draw-underline-link",
      "type": "registry:ui",
      "title": "Draw Underline Link",
      "description": "A link with a hand-drawn SVG underline that animates on hover, powered by Motion.",
      "dependencies": ["motion", "class-variance-authority"],
      "registryDependencies": ["utils"],
      "files": [
        {
          "path": "registry/primitives/texts/draw-underline-link/index.tsx",
          "type": "registry:ui",
          "target": "components/sora-ui/texts/draw-underline-link.tsx"
        }
      ],
      "meta": {
        "inspiration": {
          "type": "reimplemented",
          "label": "Osmo",
          "url": "https://osmo.supply",
          "stack": "Motion and React"
        },
        "demoProps": {
          "DrawUnderlineLink": {
            "label": {
              "value": "Hover me"
            },
            "variant": {
              "value": "default",
              "options": {
                "Default": "default",
                "Small": "sm",
                "Large": "lg"
              }
            },
            "duration": {
              "value": 0.5,
              "min": 0.2,
              "max": 2,
              "step": 0.1
            },
            "underlineColor": {
              "value": "#ff4c24"
            }
          }
        }
      }
    },
    {
      "name": "fog-text-reveal",
      "type": "registry:ui",
      "title": "Fog Text Reveal",
      "description": "Inline text that materializes through a soft, turbulent WebGL fog mask, inherits font and color from CSS, and cycles through an array of messages.",
      "dependencies": ["motion"],
      "registryDependencies": ["utils"],
      "files": [
        {
          "path": "registry/primitives/texts/fog-text-reveal/index.tsx",
          "type": "registry:ui",
          "target": "components/sora-ui/texts/fog-text-reveal.tsx"
        }
      ]
    },
    {
      "name": "number-flow",
      "type": "registry:ui",
      "title": "Number Flow",
      "description": "An animated, digit-by-digit number counter with a smooth rolling odometer effect, powered by Motion.",
      "dependencies": ["motion"],
      "registryDependencies": ["utils"],
      "files": [
        {
          "path": "registry/primitives/texts/number-flow/index.tsx",
          "type": "registry:ui",
          "target": "components/sora-ui/texts/number-flow.tsx"
        }
      ],
      "meta": {
        "inspiration": {
          "type": "reimplemented",
          "label": "Number Flow",
          "url": "https://number-flow.barvian.me/",
          "stack": "Motion and React"
        }
      }
    },
    {
      "name": "rolling-text",
      "type": "registry:ui",
      "title": "Rolling Text",
      "description": "Per-character slot-machine reveal that rolls each letter into place once it scrolls into view, powered by Motion.",
      "dependencies": ["motion"],
      "registryDependencies": ["utils"],
      "files": [
        {
          "path": "registry/primitives/texts/rolling-text/index.tsx",
          "type": "registry:ui",
          "target": "components/sora-ui/texts/rolling-text.tsx"
        }
      ],
      "meta": {
        "demoProps": {
          "RollingText": {
            "text": {
              "value": "MOTION FIRST"
            },
            "direction": {
              "value": "up",
              "options": {
                "up": "up",
                "down": "down"
              }
            },
            "speed": {
              "value": 0.05,
              "min": 0,
              "max": 0.2,
              "step": 0.01
            },
            "duration": {
              "value": 4,
              "min": 1,
              "max": 8,
              "step": 0.5
            },
            "className": {
              "value": "font-bold text-4xl uppercase tracking-tight"
            }
          }
        },
        "inspiration": {
          "type": "adapted",
          "label": "Skiper UI",
          "url": "https://skiper-ui.com/v1/skiper27"
        }
      }
    },
    {
      "name": "text-cursor-loop",
      "type": "registry:ui",
      "title": "Text Cursor Loop",
      "description": "Cycles through a list of words with a per-character collapse/reveal transition and a trailing cursor glyph that wipes across the text between words.",
      "dependencies": ["motion"],
      "meta": {
        "keywords": [
          "text",
          "loop",
          "cycle",
          "cursor",
          "typewriter",
          "hero",
          "motion"
        ]
      },
      "files": [
        {
          "path": "registry/primitives/texts/text-cursor-loop/index.tsx",
          "type": "registry:ui",
          "target": "components/sora-ui/texts/text-cursor-loop.tsx"
        }
      ]
    },
    {
      "name": "text-effect",
      "type": "registry:ui",
      "title": "Text Effect",
      "description": "Preset-driven staggered text reveals with blur, fade, slide, and scale animations, powered by Motion.",
      "dependencies": ["motion"],
      "registryDependencies": ["utils"],
      "files": [
        {
          "path": "registry/primitives/texts/text-effect/index.tsx",
          "type": "registry:ui",
          "target": "components/sora-ui/texts/text-effect.tsx"
        }
      ],
      "meta": {
        "inspiration": {
          "type": "inspired",
          "label": "motion-primitives",
          "url": "https://motion-primitives.com/docs/text-effect"
        },
        "demoProps": {
          "TextEffect": {
            "as": {
              "value": "h2",
              "options": {
                "h2": "h2",
                "p": "p",
                "span": "span"
              }
            },
            "children": {
              "value": "Motion-first text effects"
            },
            "className": {
              "value": "text-center font-bold text-3xl"
            },
            "preset": {
              "value": "fade-in-blur",
              "options": {
                "Fade in blur": "fade-in-blur",
                "Blur": "blur",
                "Fade": "fade",
                "Slide": "slide",
                "Scale": "scale"
              }
            },
            "per": {
              "value": "word",
              "options": {
                "Word": "word",
                "Char": "char",
                "Line": "line"
              }
            },
            "delay": {
              "value": 0,
              "min": 0,
              "max": 2,
              "step": 0.1
            },
            "speedReveal": {
              "value": 1,
              "min": 0.25,
              "max": 3,
              "step": 0.25
            },
            "speedSegment": {
              "value": 1,
              "min": 0.25,
              "max": 3,
              "step": 0.25
            },
            "scrollTrigger": {
              "value": true
            }
          }
        }
      }
    },
    {
      "name": "text-loop",
      "type": "registry:ui",
      "title": "Text Loop",
      "description": "Cycles through a list of items with an enter/exit animation, powered by Motion.",
      "dependencies": ["motion"],
      "registryDependencies": ["utils"],
      "files": [
        {
          "path": "registry/primitives/texts/text-loop/index.tsx",
          "type": "registry:ui",
          "target": "components/sora-ui/texts/text-loop.tsx"
        }
      ],
      "meta": {
        "inspiration": {
          "type": "inspired",
          "label": "motion-primitives",
          "url": "https://motion-primitives.com/docs/text-loop"
        }
      }
    },
    {
      "name": "text-morph",
      "type": "registry:ui",
      "title": "Text Morph",
      "description": "Per-character layout morphing for labels, counters, and live text swaps, powered by Motion.",
      "dependencies": ["motion"],
      "registryDependencies": ["utils"],
      "files": [
        {
          "path": "registry/primitives/texts/text-morph/index.tsx",
          "type": "registry:ui",
          "target": "components/sora-ui/texts/text-morph.tsx"
        }
      ],
      "meta": {
        "inspiration": {
          "type": "inspired",
          "label": "motion-primitives",
          "url": "https://motion-primitives.com/docs/text-morph"
        }
      }
    },
    {
      "name": "text-reveal-block",
      "type": "registry:ui",
      "title": "Text Reveal (Block)",
      "description": "Line-by-line text reveal with a colored block wipe, powered by GSAP SplitText.",
      "dependencies": ["gsap", "@gsap/react"],
      "registryDependencies": [
        "@soralabs/hooks-use-prefers-reduced-motion",
        "@soralabs/lib-scroll-trigger-utils"
      ],
      "files": [
        {
          "path": "registry/primitives/texts/text-reveal-block/index.tsx",
          "type": "registry:ui",
          "target": "components/sora-ui/texts/text-reveal-block.tsx"
        }
      ],
      "meta": {
        "demoProps": {
          "TextRevealBlock": {
            "as": {
              "value": "h2",
              "options": {
                "h1": "h1",
                "h2": "h2",
                "p": "p"
              }
            },
            "text": {
              "value": "Framed in shadow and light, every line arrives with deliberate tension."
            },
            "className": {
              "value": "mx-auto max-w-lg text-center font-semibold text-2xl leading-tight tracking-tight"
            },
            "animateOnScroll": {
              "value": false
            },
            "blockColor": {
              "value": "#fe0100"
            },
            "stagger": {
              "value": 0.15,
              "min": 0,
              "max": 0.5,
              "step": 0.05
            },
            "duration": {
              "value": 0.75,
              "min": 0.2,
              "max": 2,
              "step": 0.05
            },
            "delay": {
              "value": 0,
              "min": 0,
              "max": 1,
              "step": 0.05
            },
            "direction": {
              "value": "left",
              "options": {
                "left": "left",
                "right": "right",
                "up": "up",
                "down": "down"
              }
            }
          }
        }
      }
    },
    {
      "name": "text-reveal-mask",
      "type": "registry:ui",
      "title": "Text Reveal (Mask)",
      "description": "A scroll-triggered masked slide-up text reveal animation, powered by Motion.",
      "dependencies": ["motion"],
      "registryDependencies": ["utils"],
      "files": [
        {
          "path": "registry/primitives/texts/text-reveal-mask/index.tsx",
          "type": "registry:ui",
          "target": "components/sora-ui/texts/text-reveal-mask.tsx"
        }
      ],
      "meta": {
        "inspiration": {
          "type": "reimplemented",
          "label": "Annnimate",
          "url": "https://www.annnimate.com",
          "stack": "Motion and React"
        },
        "demoProps": {
          "MaskedTextReveal": {
            "as": {
              "value": "h2",
              "options": {
                "h2": "h2",
                "p": "p",
                "span": "span"
              }
            },
            "className": {
              "value": "mx-auto max-w-3xl text-center text-3xl leading-tight font-normal tracking-tight text-foreground/75 [&_strong]:font-medium [&_strong]:text-foreground"
            },
            "text": {
              "value": "Every stride is a statement. Every finish line a new beginning. We build gear for athletes who refuse to settle for yesterday's pace. Push beyond limits. Outrun expectations. This is where champions are made."
            },
            "splitBy": {
              "value": "lines",
              "options": {
                "Lines": "lines",
                "Words": "words",
                "Characters": "chars"
              }
            },
            "stagger": {
              "value": 0.1,
              "min": 0.01,
              "max": 0.5,
              "step": 0.01
            },
            "duration": {
              "value": 0.8,
              "min": 0.1,
              "max": 2,
              "step": 0.1
            },
            "yPercent": {
              "value": 110,
              "min": 50,
              "max": 200,
              "step": 5
            },
            "delay": {
              "value": 0,
              "min": 0,
              "max": 2,
              "step": 0.1
            },
            "viewportMargin": {
              "value": "0px 0px -25% 0px"
            }
          }
        }
      }
    },
    {
      "name": "text-roll",
      "type": "registry:ui",
      "title": "Text Roll",
      "description": "A per-character vertical text roll animation for label swaps and micro-interactions, powered by Motion.",
      "dependencies": ["motion"],
      "registryDependencies": ["utils"],
      "files": [
        {
          "path": "registry/primitives/texts/text-roll/index.tsx",
          "type": "registry:ui",
          "target": "components/sora-ui/texts/text-roll.tsx"
        }
      ],
      "meta": {
        "inspiration": {
          "type": "inspired",
          "label": "slot-text",
          "url": "https://textmotion.dev/"
        }
      }
    },
    {
      "name": "text-scramble",
      "type": "registry:ui",
      "title": "Text Scramble",
      "description": "A text scramble reveal animation that decodes characters on mount or when re-triggered, powered by Motion.",
      "dependencies": ["motion"],
      "files": [
        {
          "path": "registry/primitives/texts/text-scramble/index.tsx",
          "type": "registry:ui",
          "target": "components/sora-ui/texts/text-scramble.tsx"
        }
      ],
      "meta": {
        "demoProps": {
          "TextScramble": {
            "children": {
              "value": "Sora UI"
            },
            "as": {
              "value": "p",
              "options": {
                "p": "p",
                "h2": "h2",
                "span": "span"
              }
            },
            "className": {
              "value": "font-mono text-2xl font-bold uppercase tracking-widest text-foreground"
            },
            "scrambleColor": {
              "value": ""
            },
            "holdDuration": {
              "value": 0,
              "min": 0,
              "max": 2,
              "step": 0.1
            },
            "duration": {
              "value": 0.5,
              "min": 0.2,
              "max": 3,
              "step": 0.1
            },
            "speed": {
              "value": 0.03,
              "min": 0.01,
              "max": 0.15,
              "step": 0.01
            },
            "trigger": {
              "value": true
            },
            "triggerOnHover": {
              "value": false
            }
          }
        }
      }
    },
    {
      "name": "typer",
      "type": "registry:ui",
      "title": "Typer",
      "description": "A character-by-character reveal where each glyph ripples through randomized pill, accent, and outline states before settling into plain text. Adjacent same-state chars merge into rounded bars, and it's themed entirely through CSS variables.",
      "dependencies": [],
      "registryDependencies": ["utils"],
      "files": [
        {
          "path": "registry/primitives/texts/typer/index.tsx",
          "type": "registry:ui",
          "target": "components/sora-ui/texts/typer.tsx"
        }
      ]
    },
    {
      "name": "base-accordion",
      "type": "registry:ui",
      "title": "Base Accordion",
      "description": "An animated accordion component built on Base UI with spring physics, height collapse mask gradient, blur transitions, and gliding layoutId focus ring.",
      "dependencies": [
        "@base-ui/react",
        "motion",
        "lucide-react",
        "class-variance-authority"
      ],
      "registryDependencies": ["utils", "@soralabs/hooks-use-controlled-state"],
      "files": [
        {
          "path": "registry/ui/base/accordion/index.tsx",
          "type": "registry:ui",
          "target": "components/sora-ui/base/accordion.tsx"
        }
      ],
      "meta": {
        "agentMetadata": {
          "intent": "Expand and collapse related content sections inline.",
          "role": "disclosure",
          "a11yConstraints": [
            "Keep each trigger keyboard accessible and associated with its panel."
          ],
          "motionEngine": "Motion layout-height morphing with spring chevron transitions.",
          "compositionRules": [
            "Use one AccordionItem per independently discoverable section."
          ],
          "compositionRecipes": ["Use base/accordion for FAQ sections."]
        },
        "demoProps": {
          "Accordion": {
            "variant": {
              "value": "default",
              "options": {
                "Default": "default",
                "Bordered": "bordered",
                "Separated": "separated",
                "Ghost": "ghost"
              }
            },
            "multiple": {
              "value": false
            },
            "showFocusRing": {
              "value": true
            },
            "disableAnimation": {
              "value": false
            }
          }
        }
      }
    },
    {
      "name": "base-alert-dialog",
      "type": "registry:ui",
      "title": "Base Alert Dialog",
      "description": "An accessible alert dialog built on Base UI with smooth Motion 3D perspective entrance and exit animations, customizable sizes, and media slots.",
      "dependencies": ["@base-ui/react", "motion", "lucide-react"],
      "registryDependencies": [
        "utils",
        "@soralabs/hooks-use-controlled-state",
        "@soralabs/base-button"
      ],
      "meta": {
        "agentMetadata": {
          "intent": "Require explicit confirmation before an irreversible action.",
          "role": "modal-confirmation",
          "a11yConstraints": [
            "Preserve focus trapping and always provide a cancel action."
          ],
          "motionEngine": "Motion perspective spring entrance with backdrop presence transition.",
          "compositionRules": [
            "Use AlertDialogTrigger render for the initiating control."
          ],
          "compositionRecipes": [
            "Compose with base/button for destructive confirmation."
          ]
        }
      },
      "files": [
        {
          "path": "registry/ui/base/alert-dialog/index.tsx",
          "type": "registry:ui",
          "target": "components/sora-ui/base/alert-dialog.tsx"
        }
      ]
    },
    {
      "name": "base-button",
      "type": "registry:ui",
      "title": "Base Button",
      "description": "An interactive button component built on Base UI with Motion hover/tap scaling and shadcn/ui variants.",
      "dependencies": ["@base-ui/react", "motion", "class-variance-authority"],
      "registryDependencies": ["utils"],
      "files": [
        {
          "path": "registry/ui/base/button/index.tsx",
          "type": "registry:ui",
          "target": "components/sora-ui/base/button.tsx"
        }
      ],
      "meta": {
        "agentMetadata": {
          "intent": "Trigger an immediate user action with clear visual and motion feedback.",
          "role": "action",
          "a11yConstraints": [
            "Preserve native button keyboard activation and disabled semantics."
          ],
          "motionEngine": "Motion spring scale on hover and tap with reduced-motion bypass.",
          "compositionRules": [
            "Use as a trigger for dialogs, menus, and form submission."
          ],
          "compositionRecipes": ["Compose with base/dialog for modal actions."]
        },
        "demoProps": {
          "Button": {
            "children": {
              "value": "Button"
            },
            "variant": {
              "value": "default",
              "options": {
                "Default": "default",
                "Secondary": "secondary",
                "Destructive": "destructive",
                "Outline": "outline",
                "Ghost": "ghost",
                "Link": "link"
              }
            },
            "size": {
              "value": "default",
              "options": {
                "Extra Small": "xs",
                "Small": "sm",
                "Default": "default",
                "Large": "lg"
              }
            },
            "hoverScale": {
              "value": 1.05,
              "min": 1,
              "max": 1.3,
              "step": 0.01
            },
            "tapScale": {
              "value": 0.95,
              "min": 0.7,
              "max": 1,
              "step": 0.01
            },
            "disableAnimation": {
              "value": false
            }
          }
        }
      }
    },
    {
      "name": "base-checkbox",
      "type": "registry:ui",
      "title": "Base Checkbox",
      "description": "An accessible, stylable checkbox built on Base UI with a Motion-friendly animated indicator.",
      "dependencies": ["@base-ui/react", "motion"],
      "registryDependencies": ["utils", "@soralabs/hooks-use-controlled-state"],
      "files": [
        {
          "path": "registry/ui/base/checkbox/index.tsx",
          "type": "registry:ui",
          "target": "components/sora-ui/base/checkbox.tsx"
        }
      ],
      "meta": {
        "agentMetadata": {
          "intent": "Toggle an independent boolean setting.",
          "role": "input",
          "a11yConstraints": [
            "Preserve the checkbox role, label association, and keyboard toggling."
          ],
          "motionEngine": "Motion checkmark and elastic scale feedback.",
          "compositionRules": [
            "Pair with a visible label and optional description."
          ],
          "compositionRecipes": ["Compose with base/button in a settings form."]
        },
        "demoProps": {
          "Checkbox": {
            "label": {
              "value": "Accept terms and conditions"
            },
            "disabled": {
              "value": false
            }
          }
        }
      }
    },
    {
      "name": "base-context-menu",
      "type": "registry:ui",
      "title": "Base Context Menu",
      "description": "An accessible context menu built on Base UI with smooth Motion spring scale and submenu slide animations.",
      "dependencies": ["@base-ui/react", "motion", "lucide-react"],
      "registryDependencies": ["utils", "@soralabs/hooks-use-controlled-state"],
      "meta": {
        "agentMetadata": {
          "intent": "Offer contextual actions for a target using pointer or long-press interaction.",
          "role": "context-menu",
          "a11yConstraints": [
            "Keep essential actions available through a non-contextual path."
          ],
          "motionEngine": "Motion scale and opacity presence with directional submenu transitions.",
          "compositionRules": [
            "Use ContextMenuTrigger around the contextual target."
          ],
          "compositionRecipes": [
            "Compose with base/alert-dialog for destructive actions."
          ]
        }
      },
      "files": [
        {
          "path": "registry/ui/base/context-menu/index.tsx",
          "type": "registry:ui",
          "target": "components/sora-ui/base/context-menu.tsx"
        }
      ]
    },
    {
      "name": "base-dialog",
      "type": "registry:ui",
      "title": "Base Dialog",
      "description": "An accessible modal dialog built on Base UI with smooth Motion spring entrance and exit animations.",
      "dependencies": ["@base-ui/react", "motion", "lucide-react"],
      "registryDependencies": [
        "utils",
        "@soralabs/hooks-use-controlled-state",
        "@soralabs/base-button"
      ],
      "meta": {
        "agentMetadata": {
          "intent": "Present focused modal content that temporarily interrupts the current task.",
          "role": "overlay",
          "a11yConstraints": [
            "Keep focus trapped and provide DialogTitle and DialogDescription."
          ],
          "motionEngine": "Motion scale, perspective, and backdrop blur presence transition.",
          "compositionRules": [
            "Use DialogTrigger render with a semantic interactive trigger."
          ],
          "compositionRecipes": [
            "Compose with base/button for confirmation actions."
          ]
        }
      },
      "files": [
        {
          "path": "registry/ui/base/dialog/index.tsx",
          "type": "registry:ui",
          "target": "components/sora-ui/base/dialog.tsx"
        }
      ]
    },
    {
      "name": "base-dropdown-menu",
      "type": "registry:ui",
      "title": "Base Dropdown Menu",
      "description": "An accessible dropdown menu built on Base UI with smooth Motion spring scale and submenu slide animations.",
      "dependencies": ["@base-ui/react", "motion", "lucide-react"],
      "registryDependencies": ["utils", "@soralabs/hooks-use-controlled-state"],
      "meta": {
        "agentMetadata": {
          "intent": "Present a compact list of actions or choices from an anchored trigger.",
          "role": "menu",
          "a11yConstraints": [
            "Preserve roving focus, keyboard navigation, and Escape dismissal."
          ],
          "motionEngine": "Motion scale and opacity presence with collision-aware submenu cascades.",
          "compositionRules": ["Use a semantic button as the trigger."],
          "compositionRecipes": [
            "Compose with base/button for account actions."
          ]
        }
      },
      "files": [
        {
          "path": "registry/ui/base/dropdown-menu/index.tsx",
          "type": "registry:ui",
          "target": "components/sora-ui/base/dropdown-menu.tsx"
        }
      ]
    },
    {
      "name": "base-switch",
      "type": "registry:ui",
      "title": "Base Switch",
      "description": "An accessible, highly customizable switch built on Base UI with Motion spring layout physics.",
      "dependencies": ["@base-ui/react", "motion", "class-variance-authority"],
      "registryDependencies": ["utils", "@soralabs/hooks-use-controlled-state"],
      "files": [
        {
          "path": "registry/ui/base/switch/index.tsx",
          "type": "registry:ui",
          "target": "components/sora-ui/base/switch.tsx"
        }
      ],
      "meta": {
        "agentMetadata": {
          "intent": "Toggle a binary on/off setting or preference.",
          "role": "input",
          "a11yConstraints": [
            "Preserve the switch role, label association, and keyboard toggling via Space or Enter."
          ],
          "motionEngine": "Motion layout spring physics with stiffness: 500, damping: 30.",
          "compositionRules": [
            "Pair with a visible label and optional description.",
            "Provide clear visual contrast between checked and unchecked states."
          ],
          "compositionRecipes": ["Compose with base/button in a settings form."]
        },
        "demoProps": {
          "Switch": {
            "label": {
              "value": "Airplane Mode"
            },
            "disabled": {
              "value": false
            }
          }
        }
      }
    },
    {
      "name": "base-tooltip",
      "type": "registry:ui",
      "title": "Base Tooltip",
      "description": "An accessible tooltip built on Base UI with spring-based keyframe scale and translation animations powered by Motion.",
      "dependencies": ["@base-ui/react", "motion"],
      "registryDependencies": ["utils", "@soralabs/hooks-use-controlled-state"],
      "meta": {
        "agentMetadata": {
          "intent": "Provide contextual hint or shortcut explanation when hovering or focusing an interactive element.",
          "role": "tooltip",
          "a11yConstraints": [
            "Render accessible name/description without trapping keyboard focus.",
            "Dismiss cleanly on Escape without activating underlying element."
          ],
          "motionEngine": "Motion spring scale, directional translation offset, and presence transition.",
          "compositionRules": [
            "Wrap interactive elements with TooltipTrigger using render prop or semantic button."
          ],
          "compositionRecipes": [
            "Compose with base/button for icon-only action button descriptions."
          ]
        }
      },
      "files": [
        {
          "path": "registry/ui/base/tooltip/index.tsx",
          "type": "registry:ui",
          "target": "components/sora-ui/base/tooltip.tsx"
        }
      ]
    },
    {
      "name": "radix-button",
      "type": "registry:ui",
      "title": "Radix Button",
      "description": "An interactive button component built on Radix UI Slot with Motion hover/tap scaling and shadcn/ui variants.",
      "dependencies": ["radix-ui", "motion", "class-variance-authority"],
      "registryDependencies": ["utils"],
      "files": [
        {
          "path": "registry/ui/radix/button/index.tsx",
          "type": "registry:ui",
          "target": "components/sora-ui/radix/button.tsx"
        }
      ],
      "meta": {
        "agentMetadata": {
          "intent": "Trigger an immediate user action with Radix-compatible composition.",
          "role": "action",
          "a11yConstraints": [
            "Preserve native button keyboard activation and disabled semantics."
          ],
          "motionEngine": "Motion spring scale on hover and tap with reduced-motion bypass.",
          "compositionRules": [
            "Prefer Radix render composition over legacy asChild patterns."
          ],
          "compositionRecipes": [
            "Compose with radix/dialog for modal triggers."
          ]
        },
        "demoProps": {
          "Button": {
            "children": {
              "value": "Button"
            },
            "variant": {
              "value": "default",
              "options": {
                "Default": "default",
                "Secondary": "secondary",
                "Destructive": "destructive",
                "Outline": "outline",
                "Ghost": "ghost",
                "Link": "link"
              }
            },
            "size": {
              "value": "default",
              "options": {
                "Extra Small": "xs",
                "Small": "sm",
                "Default": "default",
                "Large": "lg"
              }
            },
            "hoverScale": {
              "value": 1.05,
              "min": 1,
              "max": 1.3,
              "step": 0.01
            },
            "tapScale": {
              "value": 0.95,
              "min": 0.7,
              "max": 1,
              "step": 0.01
            },
            "disableAnimation": {
              "value": false
            }
          }
        }
      }
    },
    {
      "name": "radix-checkbox",
      "type": "registry:ui",
      "title": "Radix Checkbox",
      "description": "An accessible, stylable checkbox built on Radix UI with a Motion-friendly animated indicator.",
      "dependencies": ["radix-ui", "motion"],
      "registryDependencies": ["utils", "@soralabs/hooks-use-controlled-state"],
      "files": [
        {
          "path": "registry/ui/radix/checkbox/index.tsx",
          "type": "registry:ui",
          "target": "components/sora-ui/radix/checkbox.tsx"
        }
      ],
      "meta": {
        "agentMetadata": {
          "intent": "Toggle an independent boolean setting with Radix state semantics.",
          "role": "input",
          "a11yConstraints": [
            "Preserve the checkbox role, label association, and keyboard toggling."
          ],
          "motionEngine": "Motion checkmark and scale feedback synchronized with checked state.",
          "compositionRules": [
            "Pair with a visible label and explicit form submission semantics."
          ],
          "compositionRecipes": [
            "Compose with radix/button in a preference form."
          ]
        },
        "demoProps": {
          "Checkbox": {
            "label": {
              "value": "Accept terms and conditions"
            },
            "disabled": {
              "value": false
            }
          }
        }
      }
    },
    {
      "name": "radix-dialog",
      "type": "registry:ui",
      "title": "Radix Dialog",
      "description": "An accessible modal dialog built on Radix UI with smooth Motion spring entrance and exit animations.",
      "dependencies": ["radix-ui", "motion", "lucide-react"],
      "registryDependencies": [
        "utils",
        "@soralabs/hooks-use-controlled-state",
        "@soralabs/radix-button"
      ],
      "meta": {
        "agentMetadata": {
          "intent": "Present focused modal content with Radix focus and portal semantics.",
          "role": "overlay",
          "a11yConstraints": [
            "Keep focus trapped and provide Dialog.Title and Dialog.Description."
          ],
          "motionEngine": "Motion scale, perspective, and backdrop presence transition.",
          "compositionRules": [
            "Use Radix Dialog.Trigger and render one semantic trigger element."
          ],
          "compositionRecipes": [
            "Compose with radix/button for confirmation actions."
          ]
        }
      },
      "files": [
        {
          "path": "registry/ui/radix/dialog/index.tsx",
          "type": "registry:ui",
          "target": "components/sora-ui/radix/dialog.tsx"
        }
      ]
    }
  ]
}
