[
  {
    "path": ".gitignore",
    "content": "# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.\n\n# dependencies\n/node_modules\n/.pnp\n.pnp.*\n.yarn/*\n!.yarn/patches\n!.yarn/plugins\n!.yarn/releases\n!.yarn/versions\n\n# testing\n/coverage\n\n# next.js\n/.next/\n/out/\n\n# production\n/build\n\n# misc\n.DS_Store\n*.pem\n\n# debug\nnpm-debug.log*\nyarn-debug.log*\nyarn-error.log*\n.pnpm-debug.log*\n\n# env files (can opt-in for committing if needed)\n.env*\n\n# vercel\n.vercel\n\n# typescript\n*.tsbuildinfo\nnext-env.d.ts\n"
  },
  {
    "path": ".prettierignore",
    "content": ".next\npackage-lock.json\npnpm-lock.yaml\ncomponents.json\n"
  },
  {
    "path": ".prettierrc.json",
    "content": "{\n  \"semi\": true,\n  \"singleQuote\": false,\n  \"tabWidth\": 2,\n  \"printWidth\": 120,\n  \"bracketSpacing\": true,\n  \"trailingComma\": \"es5\",\n  \"endOfLine\": \"auto\",\n  \"plugins\": [\"@ianvs/prettier-plugin-sort-imports\", \"prettier-plugin-tailwindcss\"],\n  \"importOrder\": [\n    \"^(react/(.*)$)|^(react$)\",\n    \"^(next/(.*)$)|^(next$)\",\n    \"<THIRD_PARTY_MODULES>\",\n    \"\",\n    \"^@base-ui-components/(.*)$\",\n    \"^@radix-ui/(.*)$\",\n    \"^cmdk$\",\n    \"^lucide-react$\",\n    \"^motion$\",\n    \"^next-themes$\",\n    \"^posthog-js$\",\n    \"^posthog-js/(.*)$\",\n    \"^vaul$\",\n    \"^zustand$\",\n    \"^class-variance-authority$\",\n    \"^clsx$\",\n    \"^tailwind-merge$\",\n    \"\",\n    \"^@/app/(.*)$\",\n    \"^@/components/(.*)$\",\n    \"\",\n    \"^@/components/ui/(.*)$\",\n    \"^@/lib/(.*)$\",\n    \"\",\n    \"^@/hooks/(.*)$\",\n    \"\",\n    \"^[./]\"\n  ],\n  \"importOrderParserPlugins\": [\"typescript\", \"jsx\", \"decorators-legacy\"],\n  \"importOrderTypeScriptVersion\": \"5.0.0\",\n  \"importOrderCaseSensitive\": false,\n  \"importOrderSeparation\": true,\n  \"importOrderSortSpecifiers\": true,\n  \"importOrderGroupNamespaceSpecifiers\": true\n}\n"
  },
  {
    "path": ".vscode/settings.json",
    "content": "{\n  \"typescript.tsdk\": \"node_modules\\\\typescript\\\\lib\",\n  \"typescript.preferences.importModuleSpecifier\": \"non-relative\",\n  \"javascript.preferences.importModuleSpecifier\": \"non-relative\",\n  \"typescript.updateImportsOnFileMove.enabled\": \"always\",\n  \"javascript.updateImportsOnFileMove.enabled\": \"always\",\n  \"typescript.tsserver.experimental.enableProjectDiagnostics\": true,\n  \"typescript.preferences.importModuleSpecifierEnding\": \"minimal\",\n  \"javascript.preferences.importModuleSpecifierEnding\": \"minimal\",\n  \"editor.formatOnSave\": true,\n  \"editor.defaultFormatter\": \"esbenp.prettier-vscode\",\n  \"editor.codeActionsOnSave\": {\n    \"source.removeUnusedImports\": \"explicit\"\n  }\n}\n"
  },
  {
    "path": "LICENSE",
    "content": "MIT License\n\nCopyright (c) 2025 Sameer Singh\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "README.md",
    "content": "# Lina\n\nThe Adaptive Scroll Area for Modern UIs\n\nA responsive scroll area that feels native on touch devices, offering custom styling and enhanced interactions where it matters most.\n\nLina is a drop‑in replacement for shadcn/ui's `ScrollArea` with better defaults and a more native feel.\n\n![](/main-mockup.png)\n\n## Features\n\n- **Adaptive mask** - Subtle edge fades appear only when content is scrollable and adapt in real time to scroll position, axis, and container shape.\n- **Micro‑interactions** - Hover/press effects for the custom scrollbar on non‑touch (desktop) devices, with responsive thumb behavior.\n- **Native touch optimization** - Uses the right touch‑action, momentum scrolling, and passive listeners so scrolling feels truly native on iOS/Android while staying precise on desktop.\n- **Drop‑in replacement** - Matches shadcn/ui's `ScrollArea` API, same props, slots, and `className` ergonomics—so you can swap it in with zero extra step.\n- **Radix and Base UI variants** - Choose Radix or Base UI primitives while keeping a consistent API and visual design.\n\n## Installation\n\n```bash\nnpx shadcn@latest add https://lina.sameer.sh/r/lina-radix.json\n```\n\n## Usage\n\n```tsx\nimport { ScrollArea } from \"@/components/ui/scroll-area\";\n\nexport default function Example() {\n  return (\n    <ScrollArea className=\"h-[200px] w-[350px] rounded-md border p-4\">\n      Jokester began sneaking into the castle in the middle of the night and leaving jokes all over the place: under the\n      king's pillow, in his soup, even in the royal toilet. The king was furious, but he couldn't seem to stop Jokester.\n      And then, one day, the people of the kingdom discovered that the jokes left by Jokester were so funny that they\n      couldn't help but laugh. And once they started laughing, they couldn't stop.\n    </ScrollArea>\n  );\n}\n```\n\n## Documentation\n\nVisit [Docs](https://lina.sameer.sh)\n\n## Credits\n\nBuilt on top of:\n\n- [Radix UI's Scroll Area](https://radix-ui.com/primitives/docs/components/scroll-area) by [Radix UI](https://radix-ui.com)\n- [Base UI's Scroll Area](https://base-ui.com/react/components/scroll-area) by [Base UI](https://base-ui.com/)\n\n## License\n\nMIT\n"
  },
  {
    "path": "app/globals.css",
    "content": "@import \"tailwindcss\";\n@import \"tw-animate-css\";\n\n@custom-variant dark (&:is(.dark *));\n\n@theme inline {\n  --breakpoint-3xl: 1600px;\n  --breakpoint-4xl: 2000px;\n\n  --color-background: var(--background);\n  --color-foreground: var(--foreground);\n\n  --font-sans: var(--font-geist-sans);\n  --font-mono: var(--font-geist-mono);\n  --font-inter: var(--font-inter);\n\n  --color-primary: var(--primary);\n  --color-primary-foreground: var(--primary-foreground);\n\n  --color-secondary: var(--secondary);\n  --color-secondary-foreground: var(--secondary-foreground);\n\n  --color-card: var(--card);\n  --color-card-foreground: var(--card-foreground);\n\n  --color-popover: var(--popover);\n  --color-popover-foreground: var(--popover-foreground);\n\n  --color-muted: var(--muted);\n  --color-muted-foreground: var(--muted-foreground);\n\n  --color-accent: var(--accent);\n  --color-accent-foreground: var(--accent-foreground);\n\n  --color-surface: var(--surface);\n  --color-surface-foreground: var(--surface-foreground);\n\n  --color-ring: var(--ring);\n  --color-input: var(--input);\n  --color-border: var(--border);\n  --color-destructive: var(--destructive);\n\n  --radius-sm: calc(var(--radius) - 4px);\n  --radius-md: calc(var(--radius) - 2px);\n  --radius-lg: var(--radius);\n  --radius-xl: calc(var(--radius) + 4px);\n}\n\n:root {\n  --radius: 0.625rem;\n  --background: oklch(1 0 0);\n  --foreground: oklch(0.141 0.005 285.823);\n\n  --primary: oklch(0.21 0.006 285.885);\n  --primary-foreground: oklch(0.985 0 0);\n\n  --secondary: oklch(0.967 0.001 286.375);\n  --secondary-foreground: oklch(0.21 0.006 285.885);\n\n  --card: oklch(1 0 0);\n  --card-foreground: oklch(0.141 0.005 285.823);\n\n  --popover: oklch(1 0 0);\n  --popover-foreground: oklch(0.141 0.005 285.823);\n\n  --muted: oklch(0.967 0.001 286.375);\n  --muted-foreground: oklch(0.552 0.016 285.938);\n\n  --accent: oklch(0.967 0.001 286.375);\n  --accent-foreground: oklch(0.21 0.006 285.885);\n\n  --surface: oklch(0.98 0 0);\n  --surface-foreground: var(--foreground);\n\n  --destructive: oklch(0.577 0.245 27.325);\n  --border: oklch(0.92 0.004 286.32);\n  --input: oklch(0.92 0.004 286.32);\n  --ring: oklch(0.705 0.015 286.067);\n}\n\n.dark {\n  --background: oklch(0.141 0.005 285.823);\n  --foreground: oklch(0.985 0 0);\n\n  --primary: oklch(0.92 0.004 286.32);\n  --primary-foreground: oklch(0.21 0.006 285.885);\n\n  --secondary: oklch(0.274 0.006 286.033);\n  --secondary-foreground: oklch(0.985 0 0);\n\n  --card: oklch(0.21 0.006 285.885);\n  --card-foreground: oklch(0.985 0 0);\n\n  --popover: oklch(0.21 0.006 285.885);\n  --popover-foreground: oklch(0.985 0 0);\n\n  --muted: oklch(0.274 0.006 286.033);\n  --muted-foreground: oklch(0.705 0.015 286.067);\n\n  --accent: oklch(0.274 0.006 286.033);\n  --accent-foreground: oklch(0.985 0 0);\n\n  --surface: oklch(0.2 0 0);\n  --surface-foreground: oklch(0.708 0 0);\n\n  --destructive: oklch(0.704 0.191 22.216);\n  --border: oklch(1 0 0 / 10%);\n  --input: oklch(1 0 0 / 15%);\n  --ring: oklch(0.552 0.016 285.938);\n}\n\n@layer base {\n  * {\n    scrollbar-width: thin;\n    scrollbar-color: var(--border) transparent;\n    @apply border-border outline-ring/50;\n  }\n\n  html {\n    @apply scroll-smooth;\n  }\n\n  body {\n    @apply bg-background selection:bg-primary selection:text-primary-foreground text-foreground font-sans;\n    font-synthesis-weight: none;\n    text-rendering: optimizeLegibility;\n  }\n\n  img {\n    @apply select-none;\n  }\n}\n\n@utility container {\n  @apply 3xl:max-w-screen-2xl mx-auto max-w-[1400px] px-4 lg:px-8;\n}\n\n@utility focus-ring {\n  @apply focus-visible:border-ring focus-visible:ring-ring/50 outline-none focus-visible:ring-[3px];\n}\n\n@layer components {\n  [data-line-numbers] {\n    display: grid;\n    min-width: 100%;\n    white-space: pre;\n    border: 0;\n    background: transparent;\n    padding: 0;\n    counter-reset: line;\n    box-decoration-break: clone;\n  }\n\n  [data-line-numbers] [data-line]::before {\n    font-size: var(--text-sm);\n    counter-increment: line;\n    content: counter(line);\n    display: inline-block;\n    width: calc(var(--spacing) * 16);\n    padding-right: calc(var(--spacing) * 6);\n    text-align: right;\n    color: var(--color-foreground);\n    background-color: var(--color-surface);\n    position: sticky;\n    left: 0;\n  }\n\n  [data-line] {\n    padding-top: calc(var(--spacing) * 0.5);\n    padding-bottom: calc(var(--spacing) * 0.5);\n    min-height: calc(var(--spacing) * 1);\n    width: 100%;\n    display: inline-block;\n  }\n\n  [data-line] span {\n    color: var(--shiki-light);\n    @apply selection:bg-primary/10 selection:text-(--shiki-light) dark:selection:text-(--shiki-dark);\n    @variant dark {\n      color: var(--shiki-dark) !important;\n    }\n  }\n\n  [data-highlighted-line] {\n    &:after {\n      position: absolute;\n      top: 0;\n      left: 0;\n      width: 2px;\n      height: 100%;\n      content: \"\";\n      background-color: var(--border);\n    }\n  }\n}\n\n/* Custom Scrollbar Styling  */\n::-webkit-scrollbar {\n  width: 8px;\n}\n::-webkit-scrollbar-track {\n  width: 10px;\n  margin-block: 0.25rem;\n  background: var(--background);\n}\n::-webkit-scrollbar-thumb {\n  border-radius: 100vw;\n  background: color-mix(in oklab, var(--primary) 25%, transparent);\n  transition: background 0.15s ease-in-out;\n  &:hover {\n    background: color-mix(in oklab, var(--primary) 30%, transparent);\n  }\n  &:active {\n    background: color-mix(in oklab, var(--primary) 50%, transparent);\n  }\n}\n"
  },
  {
    "path": "app/layout.tsx",
    "content": "import type { Metadata } from \"next\";\nimport { Geist, Geist_Mono, Inter } from \"next/font/google\";\n\nimport \"@/app/globals.css\";\n\nimport Navbar from \"@/components/navbar\";\nimport PostHogProvider from \"@/components/posthog-provider\";\nimport { ThemeProvider } from \"@/components/theme-provider\";\n\nimport { META_THEME_COLORS } from \"@/hooks/use-meta-color\";\n\nconst geistSans = Geist({\n  variable: \"--font-geist-sans\",\n  subsets: [\"latin\"],\n});\n\nconst geistMono = Geist_Mono({\n  variable: \"--font-geist-mono\",\n  subsets: [\"latin\"],\n});\n\nconst inter = Inter({\n  variable: \"--font-inter\",\n  subsets: [\"latin\"],\n});\n\nexport const metadata: Metadata = {\n  title: \"Refined & Responsive Scroll Area - Lina\",\n  description: \"A responsive scroll area that feels native on touch, and custom where it matters.\",\n  keywords: [\n    \"radix ui\",\n    \"Next.js\",\n    \"React\",\n    \"Tailwind CSS\",\n    \"Components\",\n    \"shadcn\",\n    \"scroll-area\",\n    \"ScrollArea\",\n    \"base ui\",\n    \"adaptive\",\n    \"responsive\",\n  ],\n  creator: \"SameerJS6\",\n  authors: [\n    {\n      name: \"SameerJS6\",\n      url: \"https://sameer.sh\",\n    },\n  ],\n  openGraph: {\n    title: \"Refined & Responsive Scroll Area - Lina\",\n    description: \"A responsive scroll area that feels native on touch, and custom where it matters.\",\n    type: \"website\",\n    url: process.env.NEXT_PUBLIC_BASE_URL,\n    images: [\n      {\n        url: `${process.env.NEXT_PUBLIC_BASE_URL}/og-image.png`,\n        width: 1280,\n        height: 630,\n        alt: \"Lina\",\n      },\n    ],\n  },\n  twitter: {\n    card: \"summary_large_image\",\n    title: \"Refined & Responsive Scroll Area - Lina\",\n    description: \"A responsive scroll area that feels native on touch, and custom where it matters.\",\n    images: [`${process.env.NEXT_PUBLIC_BASE_URL}/og-image.png`],\n    creator: \"@sameerjs6\",\n  },\n  alternates: {\n    canonical: process.env.NEXT_PUBLIC_BASE_URL,\n  },\n  manifest: `${process.env.NEXT_PUBLIC_BASE_URL}/site.webmanifest`,\n};\n\nexport default function RootLayout({\n  children,\n}: Readonly<{\n  children: React.ReactNode;\n}>) {\n  return (\n    <html lang=\"en\" suppressHydrationWarning>\n      <head>\n        <script\n          dangerouslySetInnerHTML={{\n            __html: `\n              try {\n                if (localStorage.theme === 'dark' || ((!('theme' in localStorage) || localStorage.theme === 'system') && window.matchMedia('(prefers-color-scheme: dark)').matches)) {\n                  document.querySelector('meta[name=\"theme-color\"]').setAttribute('content', '${META_THEME_COLORS.dark}')\n                }\n              } catch (_) {}\n            `,\n          }}\n        />\n        <meta name=\"theme-color\" content={META_THEME_COLORS.light} />\n      </head>\n      <body className={`${geistSans.variable} ${geistMono.variable} ${inter.variable} antialiased`}>\n        <PostHogProvider>\n          <ThemeProvider defaultTheme=\"system\" attribute=\"class\" enableSystem disableTransitionOnChange>\n            <Navbar />\n            {children}\n          </ThemeProvider>\n        </PostHogProvider>\n      </body>\n    </html>\n  );\n}\n"
  },
  {
    "path": "app/manifest.ts",
    "content": "import type { MetadataRoute } from \"next\";\n\nexport default function manifest(): MetadataRoute.Manifest {\n  return {\n    name: \"Lina\",\n    short_name: \"Lina\",\n    description: \"A responsive scroll area that feels native on touch, and custom where it matters.\",\n    start_url: \"/new\",\n    display: \"standalone\",\n    background_color: \"#ffffff\",\n    theme_color: \"#000000\",\n    icons: [\n      {\n        src: \"/android-chrome-192x192.png\",\n        sizes: \"192x192\",\n        type: \"image/png\",\n      },\n      {\n        src: \"/android-chrome-512x512.png\",\n        sizes: \"512x512\",\n        type: \"image/png\",\n      },\n    ],\n  };\n}\n"
  },
  {
    "path": "app/page.tsx",
    "content": "import Link from \"next/link\";\n\nimport Examples from \"@/components/examples\";\nimport Features from \"@/components/features\";\nimport Installation from \"@/components/installation\";\nimport PageWideScrollMask from \"@/components/page-wide-scroll-mask\";\nimport { buttonVariants } from \"@/components/ui/button\";\nimport Usage from \"@/components/usage\";\nimport Why from \"@/components/why\";\n\nexport default async function Home() {\n  return (\n    <main className=\"container space-y-8\">\n      <section className=\"flex flex-col items-center gap-2 py-8 text-center sm:px-6 md:py-16 lg:py-20 xl:gap-4\">\n        <div className=\"bg-card text-card-foreground mb-2 rounded-full border px-4 py-1 lg:mb-0\">\n          <a\n            target=\"_blank\"\n            rel=\"noopener noreferrer\"\n            className=\"focus-ring inline items-center gap-1 rounded\"\n            href=\"https://ui.shadcn.com/docs/components/scroll-area\"\n          >\n            Shadcn UI\n          </a>{\" \"}\n          Drop-in Replacement\n        </div>\n        <h1 className=\"font-inter leading-tighter text-primary w-full text-4xl font-semibold tracking-tight text-balance lg:leading-[1.1] lg:font-semibold xl:text-5xl xl:tracking-tighter\">\n          The Adaptive Scroll Area for Modern UIs\n        </h1>\n\n        <p className=\"text-foreground max-w-4xl text-base text-balance sm:text-lg\">\n          A responsive scroll area that feels native on touch devices, offering custom styling and enhanced interactions\n          where it matters most.\n        </p>\n        <div className=\"flex w-full items-center justify-center gap-2 pt-2 **:data-[slot=button]:shadow-none\">\n          <Link href=\"#examples\" className={buttonVariants({ size: \"sm\" })}>\n            See it in Action\n          </Link>\n          <Link href=\"#installation\" className={buttonVariants({ variant: \"ghost\", size: \"sm\" })}>\n            Install Now\n          </Link>\n        </div>\n      </section>\n      <section className=\"space-y-10 sm:space-y-12 md:space-y-14 lg:space-y-16 xl:space-y-24\">\n        <Features />\n        <section className=\"grid w-full min-w-0 gap-10 lg:grid-cols-2 lg:gap-4\">\n          <Installation />\n          <Usage />\n        </section>\n        <Why />\n        <Examples />\n      </section>\n      <PageWideScrollMask />\n    </main>\n  );\n}\n"
  },
  {
    "path": "app/robots.ts",
    "content": "import type { MetadataRoute } from \"next\";\n\nconst baseUrl = process.env.NEXT_PUBLIC_BASE_URL ?? \"http://localhost:3000\";\nconst siteUrl = baseUrl.endsWith(\"/\") ? baseUrl.slice(0, -1) : baseUrl;\n\nexport default function robots(): MetadataRoute.Robots {\n  return {\n    rules: [{ userAgent: \"*\", allow: \"/\" }],\n    sitemap: `${siteUrl}/sitemap.xml`,\n    host: siteUrl,\n  };\n}\n"
  },
  {
    "path": "app/sitemap.ts",
    "content": "import type { MetadataRoute } from \"next\";\n\nconst baseUrl = process.env.NEXT_PUBLIC_BASE_URL ?? \"http://localhost:3000\";\nconst siteUrl = baseUrl.endsWith(\"/\") ? baseUrl.slice(0, -1) : baseUrl;\n\nexport default function sitemap(): MetadataRoute.Sitemap {\n  const now = new Date();\n\n  const routes: MetadataRoute.Sitemap = [\n    {\n      url: `${siteUrl}/`,\n      lastModified: now,\n      changeFrequency: \"weekly\",\n      priority: 1,\n    },\n  ];\n\n  return routes;\n}\n"
  },
  {
    "path": "components/adaptive-mask.tsx",
    "content": "\"use client\";\n\nimport { useEffect, useRef, useState } from \"react\";\nimport { motion, useMotionValue, useSpring } from \"motion/react\";\n\nimport { Card, CardContent, CardDescription, CardHeader, CardTitle } from \"@/components/ui/card\";\n\nimport {\n  calculateContentPosition,\n  getCurrentPhase,\n  getTotalDuration,\n  SCROLL_CONFIG,\n  springConfigs,\n  updateMasksBasedOnPosition,\n} from \"@/lib/adaptive-mask-animation\";\n\nexport default function AdaptiveMask() {\n  const containerRef = useRef<HTMLDivElement>(null);\n  const [containerWidth, setContainerWidth] = useState(370); // Default fallback\n\n  const contentXTarget = useMotionValue(0);\n  const contentYTarget = useMotionValue(0);\n  const topMaskTarget = useMotionValue(0);\n  const bottomMaskTarget = useMotionValue(1);\n  const leftMaskTarget = useMotionValue(0);\n  const rightMaskTarget = useMotionValue(1);\n\n  const contentX = useSpring(contentXTarget, springConfigs.content);\n  const contentY = useSpring(contentYTarget, springConfigs.content);\n  const topMaskOpacity = useSpring(topMaskTarget, springConfigs.masks);\n  const bottomMaskOpacity = useSpring(bottomMaskTarget, springConfigs.masks);\n  const leftMaskOpacity = useSpring(leftMaskTarget, springConfigs.masks);\n  const rightMaskOpacity = useSpring(rightMaskTarget, springConfigs.masks);\n\n  useEffect(() => {\n    if (!containerRef.current) return;\n\n    const updateContainerWidth = () => {\n      if (containerRef.current) {\n        const rect = containerRef.current.getBoundingClientRect();\n        setContainerWidth(rect.width);\n      }\n    };\n\n    updateContainerWidth();\n\n    const resizeObserver = new ResizeObserver(updateContainerWidth);\n    resizeObserver.observe(containerRef.current);\n\n    return () => {\n      resizeObserver.disconnect();\n    };\n  }, []);\n\n  useEffect(() => {\n    let currentStep = 0;\n    const totalDuration = getTotalDuration();\n\n    const animationInterval = setInterval(() => {\n      currentStep = (currentStep + 1) % totalDuration;\n\n      const { phase: currentPhase, progress: phaseProgress } = getCurrentPhase(currentStep);\n      if (!currentPhase) return;\n\n      const { x: targetX, y: targetY } = calculateContentPosition(currentPhase, phaseProgress, containerWidth);\n\n      contentXTarget.set(targetX);\n      contentYTarget.set(targetY);\n\n      updateMasksBasedOnPosition(\n        targetX,\n        targetY,\n        topMaskTarget,\n        bottomMaskTarget,\n        leftMaskTarget,\n        rightMaskTarget,\n        containerWidth\n      );\n    }, SCROLL_CONFIG.timing.fps);\n\n    return () => clearInterval(animationInterval);\n  }, [\n    contentXTarget,\n    contentYTarget,\n    topMaskTarget,\n    bottomMaskTarget,\n    leftMaskTarget,\n    rightMaskTarget,\n    containerWidth,\n  ]);\n\n  return (\n    <Card className=\"group relative overflow-hidden border border-zinc-200/50 bg-white/50 backdrop-blur-sm transition-all duration-300 hover:bg-white/80 dark:border-zinc-800/50 dark:bg-zinc-900/50\">\n      <CardHeader className=\"relative\">\n        <CardTitle className=\"text-xl font-semibold text-zinc-900 dark:text-zinc-100\">Adaptive Mask</CardTitle>\n        <CardDescription className=\"text-zinc-600 dark:text-zinc-400\">\n          Dynamic masking that responds to content.\n        </CardDescription>\n      </CardHeader>\n      <CardContent className=\"relative space-y-4\">\n        <div ref={containerRef} className=\"bg-secondary dark:bg-card relative h-80 overflow-hidden rounded-lg border\">\n          <motion.div\n            className=\"absolute\"\n            style={{\n              x: contentX,\n              y: contentY,\n              width: \"200%\",\n              height: \"220%\",\n              padding: \"16px\",\n            }}\n          >\n            {/* Content Grid */}\n            <div className=\"space-y-3\">\n              {Array.from({ length: 20 }, (_, i) => (\n                <div key={i} className=\"h-2 flex-1 rounded bg-emerald-300 dark:bg-emerald-600\"></div>\n              ))}\n            </div>\n          </motion.div>\n\n          {/* Adaptive Masks */}\n          <motion.div\n            className=\"from-secondary dark:from-card pointer-events-none absolute inset-x-0 top-0 h-8 bg-gradient-to-b to-transparent\"\n            style={{ opacity: topMaskOpacity }}\n          />\n          <motion.div\n            className=\"from-secondary dark:from-card pointer-events-none absolute inset-x-0 bottom-0 h-8 bg-gradient-to-t to-transparent\"\n            style={{ opacity: bottomMaskOpacity }}\n          />\n          <motion.div\n            className=\"from-secondary dark:from-card pointer-events-none absolute inset-y-0 left-0 w-8 bg-gradient-to-r to-transparent\"\n            style={{ opacity: leftMaskOpacity }}\n          />\n          <motion.div\n            className=\"from-secondary dark:from-card pointer-events-none absolute inset-y-0 right-0 w-8 bg-gradient-to-l to-transparent\"\n            style={{ opacity: rightMaskOpacity }}\n          />\n        </div>\n\n        <p className=\"text-sm leading-relaxed text-zinc-700 dark:text-zinc-300\">\n          Automatic edge masks that appear and fade based on scroll position and direction, creating seamless visual\n          boundaries.\n        </p>\n      </CardContent>\n    </Card>\n  );\n}\n"
  },
  {
    "path": "components/anchor-heading.tsx",
    "content": "import type { ComponentProps } from \"react\";\n\nimport { cn } from \"@/lib/utils\";\n\ntype AnchorHeadingProps = ComponentProps<\"h2\">;\n\nexport default function AnchorHeading({ className, id, children, ...props }: AnchorHeadingProps) {\n  return (\n    <h2 id={id} className={cn(\"group relative scroll-m-20 text-3xl font-medium tracking-tight\", className)} {...props}>\n      <a href={\"#\" + id} className=\"focus-ring inline-block cursor-pointer rounded\">\n        <span className=\"bg-muted pointer-events-none absolute top-1/2 -left-9 -translate-y-1/2 rounded border px-2 font-sans text-base opacity-0 transition-opacity group-hover:opacity-100\">\n          #\n        </span>\n        {children}\n      </a>\n    </h2>\n  );\n}\n"
  },
  {
    "path": "components/cli-block.tsx",
    "content": "\"use client\";\n\nimport { Suspense, useEffect, useMemo } from \"react\";\nimport { ScrollArea, ScrollBar } from \"@/registry/radix-ui/scroll-area\";\nimport { type RegistryKeys } from \"@/registry/registry\";\n\nimport posthog from \"posthog-js\";\n\nimport CopyButton from \"@/components/copy-button\";\nimport { Skeleton } from \"@/components/ui/skeleton\";\nimport { Tabs, TabsContent, TabsIndicator, TabsList, TabsTrigger } from \"@/components/ui/tabs\";\nimport VariantSelect from \"@/components/variant-select\";\n\nimport { usePackageManagerStore, type PackageManager } from \"@/lib/package-manager-store\";\nimport { convertNpmCommand } from \"@/lib/package-manager-utils\";\nimport { cn } from \"@/lib/utils\";\nimport { useVariantStore } from \"@/lib/variant-store\";\n\ntype CLIBlockProps = {\n  name?: RegistryKeys;\n  command?: string;\n  className?: string;\n};\n\nexport default function CLIBlock({ name, command }: CLIBlockProps) {\n  return (\n    <Suspense>\n      <CLIBlockContent name={name} command={command} />\n    </Suspense>\n  );\n}\n\nfunction CLIBlockContent({ name, command }: CLIBlockProps) {\n  const { currentVariant } = useVariantStore();\n  const { selectedPackageManager, setPackageManager, isLoading, setLoading } = usePackageManagerStore();\n\n  useEffect(() => {\n    setLoading(false);\n  }, [setLoading]);\n\n  const componentName = name === \"lina\" ? `${name}-${currentVariant}` : `${name}-demo-${currentVariant}`;\n  const registryURL = `https://lina.sameer.sh/r/${componentName}.json`;\n\n  const commands = useMemo(\n    () => convertNpmCommand(command ? command : `npx shadcn@latest add ${registryURL}`),\n    [registryURL, command]\n  );\n\n  const handleCopy = () => {\n    const text = commands[selectedPackageManager];\n    navigator.clipboard.writeText(text);\n    try {\n      posthog.capture(\"cli_copy\", {\n        component: name,\n        variant: currentVariant,\n        package_manager: selectedPackageManager,\n      });\n    } catch {}\n  };\n\n  return (\n    <Tabs value={selectedPackageManager} onValueChange={setPackageManager} className={cn(\"mt-4 flex flex-col gap-0\")}>\n      <div className=\"bg-surface flex items-center justify-between rounded-t-xl px-4 pt-4 pb-2\">\n        <div className=\"space-y-3\">\n          <div>\n            <VariantSelect size=\"sm\" />\n          </div>\n          <TabsList className=\"relative bg-transparent p-0\">\n            {Object.keys(commands).map((key, index) =>\n              isLoading ? (\n                <Skeleton key={index} className=\"mr-2 h-6 w-16 rounded-sm\" />\n              ) : (\n                <TabsTrigger key={index} value={key} className=\"z-10 flex h-full items-end\">\n                  {key}\n                </TabsTrigger>\n              )\n            )}\n            <TabsIndicator className=\"z-5\" />\n          </TabsList>\n        </div>\n        <CopyButton className=\"z-10 !opacity-100\" onCopy={handleCopy} />\n      </div>\n      {Object.keys(commands).map((key, index) => (\n        <TabsContent key={index} value={key} className=\"mt-0\">\n          <ScrollArea\n            maskClassName=\"after:from-surface before:from-surface\"\n            className=\"bg-surface max-h-[600px] w-full rounded-b-xl border-t\"\n          >\n            <pre className={cn(\"pt-2 pb-4\", isLoading && \"p-4\")}>\n              <code className={cn(\"font-mono text-[13px] leading-tight whitespace-nowrap\", !isLoading && \"px-4\")}>\n                {isLoading ? <Skeleton className=\"h-5 w-full\" /> : commands[key as PackageManager]}\n              </code>\n            </pre>\n            <ScrollBar orientation=\"horizontal\" />\n          </ScrollArea>\n        </TabsContent>\n      ))}\n    </Tabs>\n  );\n}\n"
  },
  {
    "path": "components/code-block.tsx",
    "content": "\"use client\";\n\nimport { useLayoutEffect, useRef, useState, type JSX } from \"react\";\nimport { ScrollArea, ScrollBar } from \"@/registry/radix-ui/scroll-area\";\nimport type { BundledLanguage } from \"shiki/bundle/web\";\n\nimport posthog from \"posthog-js\";\n\nimport CopyButton from \"@/components/copy-button\";\n\nimport { highlight } from \"@/lib/code-highlight\";\nimport { cn } from \"@/lib/utils\";\n\ntype CodeBlockProps = {\n  code: string | null;\n  lang: BundledLanguage;\n  initial?: JSX.Element;\n  preHighlighted?: JSX.Element | null;\n  className?: string;\n};\n\nexport default function CodeBlock({ code, lang, initial, preHighlighted, className }: CodeBlockProps) {\n  const [content, setContent] = useState<JSX.Element | null>(preHighlighted || initial || null);\n  const areaRef = useRef<HTMLDivElement>(null);\n\n  const onCopy = () => {\n    const pre = areaRef.current?.getElementsByTagName(\"pre\").item(0);\n\n    if (!pre) return;\n\n    const clone = pre.cloneNode(true) as HTMLElement;\n    navigator.clipboard.writeText(clone.textContent || \"\");\n    try {\n      posthog.capture(\"code_copy\", { lang, length: (clone.textContent || \"\").length });\n    } catch {}\n  };\n\n  useLayoutEffect(() => {\n    if (preHighlighted) {\n      setContent(preHighlighted);\n      return;\n    }\n\n    let isMounted = true;\n\n    if (code) {\n      highlight(code, lang).then((result) => {\n        if (isMounted) setContent(result);\n      });\n    } else {\n      setContent(<pre className=\"bg-secondary/50 rounded-md p-4\">No code available</pre>);\n    }\n\n    return () => {\n      isMounted = false;\n    };\n  }, [code, lang, preHighlighted]);\n\n  return content ? (\n    <div\n      className={cn(\n        \"group focus-ring bg-surface relative overflow-hidden rounded-xl [&_code]:font-mono [&_code]:text-[13px] [&_pre]:p-4 [&_pre]:!leading-tight\",\n        className\n      )}\n    >\n      <ScrollArea\n        ref={areaRef}\n        dir=\"ltr\"\n        maskClassName=\"after:from-surface before:from-surface\"\n        className=\"focus-ring relative size-full rounded-xl\"\n      >\n        {content}\n        <ScrollBar orientation=\"horizontal\" className=\"focus-ring\" />\n        <CopyButton className=\"absolute top-4 right-4 z-[2] backdrop-blur-md\" onCopy={onCopy} />\n      </ScrollArea>\n    </div>\n  ) : (\n    <div className=\"bg-secondary/50 relative my-6 min-h-[500px] overflow-hidden rounded-xl border text-sm\">\n      <pre className=\"rounded-md p-4 text-center text-sm\">Loading...</pre>\n    </div>\n  );\n}\n"
  },
  {
    "path": "components/code-display-block.tsx",
    "content": "\"use client\";\n\nimport type { JSX } from \"react\";\nimport type { BundledLanguage } from \"shiki/bundle/web\";\n\nimport CodeBlock from \"@/components/code-block\";\n\nimport { useVariantStore } from \"@/lib/variant-store\";\n\ntype CodeData = {\n  code: string;\n  highlightedCode: JSX.Element;\n} | null;\n\ntype VariantData = {\n  base: {\n    code: CodeData;\n  };\n  radix: {\n    code: CodeData;\n  };\n};\n\ntype CodeDisplaySectionProps = {\n  variantData: VariantData;\n  language: BundledLanguage;\n  maxHeight?: string;\n};\n\nexport default function CodeDisplaySection({\n  variantData,\n  language,\n  maxHeight = \"[&_pre]:max-h-[400px]\",\n}: CodeDisplaySectionProps) {\n  const { currentVariant } = useVariantStore();\n  const codeData = variantData[currentVariant]?.code;\n\n  return (\n    <>\n      {!codeData ? (\n        <p className=\"text-muted-foreground text-sm\">\n          No code available. If you think this is an error, please{\" \"}\n          <a\n            target=\"_blank\"\n            rel=\"noopener noreferrer\"\n            href=\"https://github.com/SameerJS6/lina/issues\"\n            className=\"text-foreground font-medium underline hover:no-underline\"\n          >\n            open an issue\n          </a>\n          .\n        </p>\n      ) : (\n        <CodeBlock\n          lang={language}\n          code={codeData.code}\n          preHighlighted={codeData.highlightedCode}\n          className={maxHeight}\n        />\n      )}\n    </>\n  );\n}\n"
  },
  {
    "path": "components/component-preview.tsx",
    "content": "import React from \"react\";\nimport { Index, type RegistryKeys } from \"@/registry/registry\";\nimport type { BundledLanguage } from \"shiki/bundle/web\";\n\nimport { Loader } from \"lucide-react\";\n\nimport CodeDisplaySection from \"@/components/code-display-block\";\nimport RenderPreview from \"@/components/render-preview\";\nimport { Tabs, TabsContent, TabsIndicator, TabsList, TabsTrigger } from \"@/components/ui/tabs\";\nimport VariantSelect from \"@/components/variant-select\";\n\nimport { getComponentCode } from \"@/lib/code-highlight\";\nimport { cn } from \"@/lib/utils\";\n\ntype ComponentDetailsProps = {\n  name: RegistryKeys;\n  hideCode?: boolean;\n  className?: string;\n  lang?: BundledLanguage;\n  align?: \"center\" | \"start\" | \"end\";\n};\n\nexport default async function ComponentPreview({\n  name,\n  className,\n  lang = \"tsx\",\n  hideCode = false,\n  align = \"center\",\n}: ComponentDetailsProps) {\n  const registryEntry = Index[name];\n  const [radixCodeData, baseCodeData] = await Promise.all([\n    getComponentCode(`${registryEntry.name}-radix`, lang),\n    getComponentCode(`${registryEntry.name}-base`, lang),\n  ]);\n\n  const variantData = {\n    base: { code: baseCodeData },\n    radix: { code: radixCodeData },\n  } as const;\n\n  return (\n    <div className={cn(\"group relative flex min-w-0 flex-col space-y-2\", className)}>\n      <Tabs defaultValue=\"preview\" className=\"relative w-full\">\n        <div className=\"flex items-center justify-between pb-3\">\n          {!hideCode && (\n            <TabsList className=\"relative z-0 justify-start bg-transparent p-0\">\n              <TabsTrigger value=\"preview\">Preview</TabsTrigger>\n              <TabsTrigger value=\"code\">Code</TabsTrigger>\n              <TabsIndicator />\n            </TabsList>\n          )}\n        </div>\n        <TabsContent value=\"preview\" className=\"focus-ring relative rounded-xl border p-4\">\n          <VariantSelect />\n          <div\n            className={cn(\"flex min-h-[350px] w-full justify-center p-10\", {\n              \"items-center\": align === \"center\",\n              \"items-start\": align === \"start\",\n              \"items-end\": align === \"end\",\n            })}\n          >\n            <React.Suspense\n              fallback={\n                <div className=\"text-muted-foreground flex w-full items-center justify-center text-sm\">\n                  <Loader className=\"mr-2 h-4 w-4 animate-spin\" />\n                  Loading...\n                </div>\n              }\n            >\n              <RenderPreview name={name} />\n            </React.Suspense>\n          </div>\n        </TabsContent>\n        <TabsContent value=\"code\" className=\"focus-ring rounded-xl\">\n          <CodeDisplaySection variantData={variantData} language={lang} maxHeight=\"[&_pre]:max-h-[435px]\" />\n        </TabsContent>\n      </Tabs>\n    </div>\n  );\n}\n"
  },
  {
    "path": "components/copy-button.tsx",
    "content": "\"use client\";\n\nimport type { ButtonHTMLAttributes } from \"react\";\n\nimport { Check, Copy } from \"lucide-react\";\n\nimport { buttonVariants } from \"@/components/ui/button\";\nimport { Tooltip, TooltipContent, TooltipTrigger } from \"@/components/ui/tooltip\";\n\nimport { cn } from \"@/lib/utils\";\n\nimport { useCopyButton } from \"@/hooks/use-copy-button\";\n\nexport default function CopyButton({\n  className,\n  onCopy,\n  ...props\n}: ButtonHTMLAttributes<HTMLButtonElement> & {\n  onCopy: () => void;\n}) {\n  const [checked, onClick] = useCopyButton(onCopy);\n\n  return (\n    <Tooltip>\n      <TooltipTrigger asChild>\n        <button\n          type=\"button\"\n          className={cn(\n            buttonVariants({\n              variant: \"ghost\",\n              size: \"icon\",\n            }),\n            \"size-[1.875rem] transition-opacity group-hover:opacity-100 [&_svg]:size-3.5\",\n            checked && \"hover:bg-green-600/10 dark:hover:bg-green-500/10\",\n            !checked && \"[@media(hover:hover)]:opacity-0\",\n            className\n          )}\n          aria-label={checked ? \"Copied Text\" : \"Copy Text\"}\n          onClick={onClick}\n          {...props}\n        >\n          <Check className={cn(\"text-green-600 transition-transform dark:text-green-500\", !checked && \"scale-0\")} />\n          <Copy className={cn(\"absolute transition-transform\", checked && \"scale-0\")} />\n        </button>\n      </TooltipTrigger>\n      <TooltipContent>{checked ? \"Copied!\" : \"Copy to clipboard\"}</TooltipContent>\n    </Tooltip>\n  );\n}\n"
  },
  {
    "path": "components/examples.tsx",
    "content": "import AnchorHeading from \"@/components/anchor-heading\";\nimport CLIBlock from \"@/components/cli-block\";\nimport ComponentPreview from \"@/components/component-preview\";\n\nexport default function Examples() {\n  return (\n    <section className=\"space-y-6 sm:space-y-8 sm:px-6 lg:space-y-10\">\n      <div className=\"space-y-1\">\n        <AnchorHeading id=\"examples\" className=\"scroll-m-16\">\n          Examples\n        </AnchorHeading>\n        <p className=\"text-muted-foreground leading-7\">\n          Explore various examples showcasing the capabilities of the Adaptive Scroll Area component.\n        </p>\n      </div>\n      <div className=\"space-y-10 sm:space-y-12 lg:space-y-24\">\n        <div className=\"grid gap-6 lg:grid-cols-2\">\n          <div className=\"flex min-w-0 flex-col justify-between\">\n            <div>\n              <h2 className=\"scroll-m-20 text-2xl font-medium tracking-tight\">Vertical Scroll Demo</h2>\n              <p className=\"text-muted-foreground mt-6 leading-7\">\n                Experience smooth vertical scrolling with customizable scrollbars, perfect for long content sections and\n                lists.\n              </p>\n            </div>\n            <CLIBlock name=\"vertical-scroll\" />\n          </div>\n          <ComponentPreview name=\"vertical-scroll\" className=\"my-0\" />\n        </div>\n        <div className=\"grid gap-6 lg:grid-cols-2\">\n          <div className=\"flex min-w-0 flex-col justify-between\">\n            <div>\n              <h2 className=\"scroll-m-20 text-2xl font-medium tracking-tight\">Horizontal Scroll Demo</h2>\n              <p className=\"text-muted-foreground mt-6 leading-7\">\n                Implement elegant horizontal scrolling for carousels, galleries, and overflow content with intuitive\n                controls.\n              </p>\n            </div>\n            <CLIBlock name=\"horizontal-scroll\" />\n          </div>\n          <ComponentPreview name=\"horizontal-scroll\" className=\"my-0\" />\n        </div>\n        <div className=\"grid gap-6 lg:grid-cols-2\">\n          <div className=\"flex min-w-0 flex-col justify-between\">\n            <div>\n              <h2 className=\"scroll-m-20 text-2xl font-semibold tracking-tight\">Timezone Select Example</h2>\n              <p className=\"text-muted-foreground mt-6 leading-7\">\n                A customizable timezone select component demonstrating advanced scroll functionality with search and\n                filtering capabilities.\n              </p>\n            </div>\n            <CLIBlock name=\"timezone-select\" />\n          </div>\n          <ComponentPreview name=\"timezone-select\" />\n        </div>\n      </div>\n    </section>\n  );\n}\n"
  },
  {
    "path": "components/features.tsx",
    "content": "import AdaptiveMask from \"@/components/adaptive-mask\";\nimport MicroInteractions from \"@/components/micro-interactions\";\nimport NativeTouch from \"@/components/native-touch\";\n\nexport default function Features() {\n  return (\n    <section className=\"grid w-full grid-cols-1 gap-4 sm:p-4 md:grid-cols-2 xl:grid-cols-3 md:[&>*:nth-child(3)]:max-xl:col-span-2\">\n      <MicroInteractions />\n      <AdaptiveMask />\n      <NativeTouch />\n    </section>\n  );\n}\n"
  },
  {
    "path": "components/installation.tsx",
    "content": "import AnchorHeading from \"@/components/anchor-heading\";\nimport CLIBlock from \"@/components/cli-block\";\nimport ManualInstallationSection from \"@/components/manual-installation-block\";\nimport { Tabs, TabsContent, TabsIndicator, TabsList, TabsTrigger } from \"@/components/ui/tabs\";\n\nimport { getComponentCode } from \"@/lib/code-highlight\";\n\nexport default async function Installation() {\n  const pathToPrimaryHook = \"hooks/use-has-primary-touch.tsx\";\n\n  const language = \"tsx\";\n  const name = \"lina\";\n\n  const [radixCodeData, baseCodeData, hookCodeData] = await Promise.all([\n    getComponentCode(`${name}-radix`, language),\n    getComponentCode(`${name}-base`, language),\n    getComponentCode(\"\", \"tsx\", pathToPrimaryHook),\n  ]);\n\n  const variantData = {\n    base: {\n      code: baseCodeData,\n      mainDependency: \"@base-ui-components/react\",\n    },\n    radix: {\n      code: radixCodeData,\n      mainDependency: \"@radix-ui/react-scroll-area\",\n    },\n  } as const;\n\n  return (\n    <section className=\"min-w-0 space-y-6 sm:px-6\">\n      <div className=\"space-y-1\">\n        <AnchorHeading id=\"installation\">Installation</AnchorHeading>\n        <p className=\"text-muted-foreground leading-7\">\n          Add the adaptive scroll area component to your project with ease.\n        </p>\n      </div>\n\n      <div>\n        <Tabs defaultValue=\"cli\" className=\"w-full min-w-0\">\n          <TabsList className=\"relative h-8 bg-transparent p-0\">\n            <TabsTrigger value=\"cli\" className=\"text-base\">\n              CLI\n            </TabsTrigger>\n            <TabsTrigger value=\"manual\" className=\"text-base\">\n              Manual\n            </TabsTrigger>\n            <TabsIndicator />\n          </TabsList>\n\n          <TabsContent value=\"cli\" className=\"mt-6\">\n            <div className=\"space-y-6\">\n              <div className=\"space-y-0\">\n                <h4 className=\"font-heading font- mt-12 scroll-m-28 text-lg font-medium tracking-tight first:mt-0 sm:text-2xl lg:mt-20 [&+p]:!mt-4 *:[code]:text-2xl\">\n                  Quick Installation\n                </h4>\n                <p className=\"text-muted-foreground text-sm\">\n                  Use the CLI to add the component to your project. This will automatically install all dependencies and\n                  copy the necessary files.\n                </p>\n              </div>\n              <CLIBlock name=\"lina\" className=\"mt-0\" />\n            </div>\n          </TabsContent>\n          <TabsContent value=\"manual\" className=\"mt-6\">\n            <ManualInstallationSection variantData={variantData} hookCodeData={hookCodeData} language={language} />\n          </TabsContent>\n        </Tabs>\n      </div>\n    </section>\n  );\n}\n"
  },
  {
    "path": "components/manual-installation-block.tsx",
    "content": "\"use client\";\n\nimport type { JSX } from \"react\";\nimport type { BundledLanguage } from \"shiki/bundle/web\";\n\nimport CLIBlock from \"@/components/cli-block\";\nimport CodeDisplaySection from \"@/components/code-display-block\";\n\nimport { useVariantStore } from \"@/lib/variant-store\";\n\ntype CodeData = {\n  code: string;\n  highlightedCode: JSX.Element;\n} | null;\n\ntype VariantData = {\n  base: {\n    code: CodeData;\n    mainDependency: string;\n  };\n  radix: {\n    code: CodeData;\n    mainDependency: string;\n  };\n};\n\ntype ManualInstallationSectionProps = {\n  variantData: VariantData;\n  hookCodeData: CodeData;\n  language: BundledLanguage;\n};\n\nexport default function ManualInstallationBlock({\n  variantData,\n  hookCodeData,\n  language,\n}: ManualInstallationSectionProps) {\n  const { currentVariant } = useVariantStore();\n\n  const devDependency = \"tw-animate-css\";\n  const mainDependency = variantData[currentVariant]?.mainDependency;\n\n  return (\n    <div className=\"space-y-6 sm:space-y-10 lg:space-y-12\">\n      <div className=\"space-y-6\">\n        <div className=\"space-y-0\">\n          <h4 className=\"mt-12 scroll-m-28 text-lg font-medium tracking-tight first:mt-0 sm:text-2xl lg:mt-20 [&+p]:!mt-4\">\n            Install main dependencies\n          </h4>\n          <p className=\"text-muted-foreground text-sm\">\n            Install the required {currentVariant === \"base\" ? \"Base UI\" : \"Radix UI\"} dependencies for the scroll area\n            component.\n          </p>\n        </div>\n        <CLIBlock command={`npm install ${mainDependency}`} />\n      </div>\n\n      <div className=\"space-y-6\">\n        <div className=\"space-y-2\">\n          <h4 className=\"font-heading font- mt-12 scroll-m-28 text-lg font-medium tracking-tight first:mt-0 sm:text-2xl lg:mt-20 [&+p]:!mt-4 *:[code]:text-2xl\">\n            Install development dependencies\n          </h4>\n          <p className=\"text-muted-foreground text-sm\">Install the animation utilities for smooth transitions.</p>\n        </div>\n        <CLIBlock command={`npm install -D ${devDependency}`} />\n      </div>\n\n      <div className=\"space-y-6\">\n        <div className=\"space-y-2\">\n          <h4 className=\"font-heading font- mt-12 scroll-m-28 text-lg font-medium tracking-tight first:mt-0 sm:text-2xl lg:mt-20 [&+p]:!mt-4 *:[code]:text-2xl\">\n            Copy the touch detection hook\n          </h4>\n          <p className=\"text-muted-foreground text-sm\">\n            Add the hook that detects touch-primary devices for adaptive behavior.\n          </p>\n        </div>\n        <CodeDisplaySection\n          variantData={{\n            base: { code: hookCodeData },\n            radix: { code: hookCodeData },\n          }}\n          language={language}\n          maxHeight=\"[&_pre]:max-h-[400px]\"\n        />\n      </div>\n\n      <div className=\"space-y-6\">\n        <div className=\"space-y-2\">\n          <h4 className=\"font-heading font- mt-12 scroll-m-28 text-lg font-medium tracking-tight first:mt-0 sm:text-2xl lg:mt-20 [&+p]:!mt-4 *:[code]:text-2xl\">\n            Copy the component\n          </h4>\n          <p className=\"text-muted-foreground text-sm\">\n            Add the main scroll area component with adaptive masking and touch-optimized behavior.\n          </p>\n        </div>\n        <CodeDisplaySection variantData={variantData} language={language} maxHeight=\"[&_pre]:max-h-[400px]\" />\n      </div>\n    </div>\n  );\n}\n"
  },
  {
    "path": "components/micro-interactions.tsx",
    "content": "\"use client\";\n\nimport { useEffect, useState } from \"react\";\nimport { motion } from \"motion/react\";\n\nimport { Card, CardContent, CardDescription, CardHeader, CardTitle } from \"@/components/ui/card\";\n\nexport default function MicroInteractions() {\n  const [animationPhase, setAnimationPhase] = useState(0);\n\n  const CURSOR_POSITION = {\n    INITIAL: { x: 140, y: 140, scale: 1 },\n    HOVER_ON_PILL: { x: 13, y: -100, scale: 1 },\n    PRESS_ON_PILL: { x: 13, y: -90, scale: 0.8 },\n    END_POSITION_FOR_PILL: { x: 13, y: 50, scale: 0.8 },\n    INITIAL_POSITION_FOR_PILL: { x: 13, y: -100, scale: 0.8 },\n  };\n\n  useEffect(() => {\n    const interval = setInterval(() => {\n      setAnimationPhase((prev) => (prev + 1) % 7);\n    }, 1200);\n    return () => clearInterval(interval);\n  }, []);\n\n  const getCursorPosition = () => {\n    switch (animationPhase) {\n      case 0:\n        return CURSOR_POSITION.INITIAL;\n      case 1:\n        return CURSOR_POSITION.HOVER_ON_PILL;\n      case 2:\n        return CURSOR_POSITION.PRESS_ON_PILL;\n      case 3:\n        return CURSOR_POSITION.END_POSITION_FOR_PILL;\n      case 4:\n      case 5:\n        return CURSOR_POSITION.INITIAL_POSITION_FOR_PILL;\n      default:\n        return CURSOR_POSITION.INITIAL;\n    }\n  };\n\n  const THUMB_SCALE = {\n    INITIAL: 1,\n    HOVER: 1.1,\n    PRESS: 0.95,\n  };\n\n  const getThumbScale = () => {\n    switch (animationPhase) {\n      case 1:\n        return THUMB_SCALE.HOVER;\n      case 2:\n        return THUMB_SCALE.PRESS;\n      case 5:\n        return THUMB_SCALE.INITIAL;\n      default:\n        return THUMB_SCALE.INITIAL;\n    }\n  };\n\n  const THUMB_Y_POSITION = {\n    INITIAL: -42,\n    PRE_INITIAL: -40,\n    END_POSITION: 90,\n  };\n\n  const getThumbY = () => {\n    switch (animationPhase) {\n      case 3:\n        return THUMB_Y_POSITION.END_POSITION;\n      case 4:\n      case 5:\n        return THUMB_Y_POSITION.PRE_INITIAL;\n      default:\n        return THUMB_Y_POSITION.INITIAL;\n    }\n  };\n\n  const getBarOpacity = () => {\n    switch (animationPhase) {\n      case 1:\n      case 2:\n        return 1;\n      case 3:\n        return 1;\n      case 4:\n        return 1;\n      case 5:\n        return 1;\n      default:\n        return 0;\n    }\n  };\n\n  return (\n    <Card className=\"group relative overflow-hidden border border-zinc-200/50 bg-white/50 backdrop-blur-sm transition-all duration-300 hover:bg-white/80 dark:border-zinc-800/50 dark:bg-zinc-900/50\">\n      <CardHeader className=\"relative\">\n        <CardTitle className=\"text-xl font-semibold text-zinc-900 dark:text-zinc-100\">Micro Interactions</CardTitle>\n        <CardDescription className=\"text-zinc-600 dark:text-zinc-400\">\n          Polished interactions that enhance usability.\n        </CardDescription>\n      </CardHeader>\n      <CardContent className=\"space-y-4\">\n        <div className=\"bg-secondary dark:bg-card relative flex h-80 items-center justify-center rounded-xl border\">\n          <motion.div\n            className=\"bar bg-card dark:bg-secondary absolute h-[310px] w-6 rounded-full\"\n            initial={false}\n            animate={{\n              opacity: getBarOpacity(),\n            }}\n            transition={{ duration: 0.6, ease: \"easeInOut\" }}\n          />\n\n          <motion.div\n            className=\"bg-primary relative z-10 h-20 w-4 rounded-full shadow-lg\"\n            animate={{\n              scaleY: getThumbScale(),\n              y: getThumbY(),\n            }}\n            initial={false}\n            transition={{ duration: 1.5, type: \"spring\", bounce: 0.25 }}\n            style={{ marginTop: \"-130px\" }}\n          />\n\n          <motion.div\n            className=\"pointer-events-none absolute z-20\"\n            initial={false}\n            animate={getCursorPosition()}\n            transition={{ duration: 1.55, type: \"spring\", bounce: 0.25 }}\n            style={{\n              transformOrigin: \"center center\",\n              marginLeft: \"-10px\",\n              marginTop: \"-12px\",\n            }}\n          >\n            <svg\n              width=\"24\"\n              height=\"30\"\n              viewBox=\"0 0 30 38\"\n              fill=\"none\"\n              xmlns=\"http://www.w3.org/2000/svg\"\n              className=\"stroke-secondary fill-primary size-6\"\n            >\n              <path\n                d=\"M3.58385 1.69742C2.57836 0.865603 1.05859 1.58076 1.05859 2.88572V35.6296C1.05859 37.1049 2.93111 37.7381 3.8265 36.5656L12.5863 25.0943C12.6889 24.96 12.8483 24.8812 13.0173 24.8812H27.3245C28.7697 24.8812 29.4211 23.0719 28.3076 22.1507L3.58385 1.69742Z\"\n                strokeLinejoin=\"round\"\n              />\n            </svg>\n          </motion.div>\n        </div>\n\n        <p className=\"text-sm leading-relaxed text-zinc-700 dark:text-zinc-300\">\n          Refined micro-interactions including scrollbar fade effects, hover states, and thumb interactions for polished\n          desktop experience.\n        </p>\n      </CardContent>\n    </Card>\n  );\n}\n"
  },
  {
    "path": "components/native-touch.tsx",
    "content": "\"use client\";\n\nimport { useEffect, useState } from \"react\";\nimport { motion } from \"motion/react\";\n\nimport { Card, CardContent, CardDescription, CardHeader, CardTitle } from \"@/components/ui/card\";\n\nexport default function NativeTouch() {\n  const [isTouch, setIsTouch] = useState(false);\n\n  useEffect(() => {\n    const interval = setInterval(() => {\n      setIsTouch((prev) => !prev);\n    }, 5000);\n\n    return () => clearInterval(interval);\n  }, []);\n\n  return (\n    <Card className=\"group relative overflow-hidden border border-zinc-200/50 bg-white/50 backdrop-blur-sm transition-all duration-300 hover:bg-white/80 dark:border-zinc-800/50 dark:bg-zinc-900/50\">\n      <CardHeader className=\"relative\">\n        <CardTitle className=\"text-xl font-semibold text-zinc-900 dark:text-zinc-100\">Adaptive Scrollbars</CardTitle>\n        <CardDescription className=\"text-zinc-600 dark:text-zinc-400\">\n          Native experience that adapts to devices.\n        </CardDescription>\n      </CardHeader>\n      <CardContent className=\"relative space-y-4\">\n        <div className=\"bg-secondary dark:bg-card relative flex h-80 items-center justify-center overflow-hidden rounded-lg border\">\n          {/* Desktop mockup */}\n          <motion.div\n            className=\"relative\"\n            animate={{\n              opacity: isTouch ? 0 : 1,\n              scale: isTouch ? 0.8 : 1,\n              x: isTouch ? -80 : 0,\n            }}\n            transition={{\n              type: \"spring\",\n              stiffness: 120,\n              damping: 25,\n              duration: 2,\n            }}\n          >\n            <div className=\"relative h-28 w-48 rounded-lg border border-zinc-300 bg-zinc-200 p-0.5 sm:h-32 sm:w-60 md:h-40 md:w-72 dark:border-zinc-600 dark:bg-zinc-700\">\n              {/* Screen bezel */}\n              <div className=\"relative h-full w-full overflow-hidden rounded-md bg-zinc-900 p-0.5 dark:bg-zinc-800\">\n                {/* Actual screen */}\n                <div className=\"relative h-full w-full overflow-hidden rounded-sm bg-white dark:bg-zinc-900\">\n                  <div className=\"absolute top-1 right-1 bottom-1 w-1.5 rounded-full bg-zinc-200 dark:bg-zinc-700\">\n                    {/* Desktop scrollbar thumb */}\n                    <motion.div\n                      className=\"absolute top-1 h-8 w-full rounded-full bg-zinc-400 dark:bg-zinc-500\"\n                      animate={{\n                        y: [0, 50, 0],\n                      }}\n                      transition={{\n                        duration: 4,\n                        repeat: Number.POSITIVE_INFINITY,\n                        ease: \"easeInOut\",\n                        repeatDelay: 1,\n                      }}\n                    />\n                  </div>\n                </div>\n              </div>\n            </div>\n            <div className=\"mx-auto -mt-0.5 h-1 w-full rounded-b-lg bg-zinc-300 lg:h-1.5 dark:bg-zinc-600\" />\n          </motion.div>\n\n          {/* Mobile mockup */}\n          <motion.div\n            className=\"absolute\"\n            animate={{\n              opacity: isTouch ? 1 : 0,\n              scale: isTouch ? 1 : 0.8,\n              x: isTouch ? 0 : 80,\n            }}\n            transition={{\n              type: \"spring\",\n              stiffness: 120,\n              damping: 25,\n              duration: 2,\n            }}\n          >\n            <div className=\"relative aspect-[8/16] h-56 w-28 overflow-hidden\">\n              <div\n                className=\"relative h-full w-full rounded-[24px] border border-black bg-black p-[1.5px]\"\n                style={{\n                  background: \"linear-gradient(180deg, #EEEAE1 0%, #D1CCC2 100%)\",\n                  boxShadow: \"0px 0px 1px 1px rgba(0, 0, 0, 0.20) inset, 0px 0px 2px 1px rgba(0, 0, 0, 0.40) inset\",\n                }}\n              >\n                <div\n                  className=\"h-full w-full rounded-[21px] border border-black bg-black p-[3px]\"\n                  style={{\n                    boxShadow: \"0px 0px 2px 1px rgba(255, 255, 255, 0.25), 0px 0px 0.5px 2px #3C3C3C inset\",\n                  }}\n                >\n                  <div className=\"relative h-full w-full overflow-hidden rounded-[18px] bg-white dark:bg-zinc-900\">\n                    {/* Screen content area */}\n                    <div className=\"relative h-full\">\n                      <motion.div\n                        className=\"absolute top-1 right-0.5 bottom-1 w-0.5 rounded-sm\"\n                        animate={{\n                          opacity: [0, 1, 1, 0],\n                        }}\n                        transition={{\n                          duration: 4,\n                          repeat: Number.POSITIVE_INFINITY,\n                          times: [0, 0.1, 0.9, 1],\n                          repeatDelay: 1,\n                        }}\n                      >\n                        {/* Mobile scrollbar thumb */}\n                        <motion.div\n                          className=\"absolute top-0 h-6 w-full rounded-sm bg-zinc-500/80 dark:bg-zinc-400/80\"\n                          animate={{\n                            y: [0, 100, 0],\n                          }}\n                          transition={{\n                            duration: 4,\n                            repeat: Number.POSITIVE_INFINITY,\n                            ease: \"easeInOut\",\n                            repeatDelay: 1,\n                          }}\n                        />\n                      </motion.div>\n                    </div>\n                  </div>\n                </div>\n              </div>\n            </div>\n          </motion.div>\n        </div>\n\n        <p className=\"text-sm leading-relaxed text-zinc-700 md:max-w-[45ch] dark:text-zinc-300\">\n          Automatic scrollbar adaptation between native and custom styles based on device type and touch capabilities.\n        </p>\n      </CardContent>\n    </Card>\n  );\n}\n"
  },
  {
    "path": "components/navbar.tsx",
    "content": "import Link from \"next/link\";\n\nimport ThemeToggle from \"@/components/theme-toggle\";\nimport { Button, buttonVariants } from \"@/components/ui/button\";\nimport { Separator } from \"@/components/ui/separator\";\n\nexport default function Navbar() {\n  return (\n    <header className=\"container\">\n      <nav className=\"flex items-center justify-between gap-4 py-4\">\n        <Link href=\"/\" className={buttonVariants({ variant: \"ghost\", size: \"sm\", className: \"h-10 max-lg:-ml-4\" })}>\n          <svg\n            width=\"270\"\n            height=\"270\"\n            viewBox=\"0 0 270 270\"\n            fill=\"none\"\n            className=\"size-8\"\n            xmlns=\"http://www.w3.org/2000/svg\"\n          >\n            <rect width=\"270\" height=\"270\" />\n            <rect x=\"109\" y=\"35\" width=\"20\" height=\"200\" rx=\"10\" fill=\"currentColor\" />\n            <rect x=\"149\" y=\"85\" width=\"13\" height=\"100\" rx=\"6.5\" fill=\"currentColor\" />\n          </svg>\n          <span className=\"sr-only\">Home</span>\n        </Link>\n        <div className=\"flex h-5 items-center\">\n          <Button variant=\"ghost\" size=\"icon\" asChild>\n            <Link\n              target=\"_blank\"\n              href=\"https://github.com/SameerJS6/lina\"\n              rel=\"noopener noreferrer\"\n              aria-label=\"View project on GitHub\"\n            >\n              <svg\n                width=\"1024\"\n                height=\"1024\"\n                viewBox=\"0 0 1024 1024\"\n                fill=\"none\"\n                xmlns=\"http://www.w3.org/2000/svg\"\n                className=\"fill-primary size-4\"\n              >\n                <path\n                  fillRule=\"evenodd\"\n                  clipRule=\"evenodd\"\n                  d=\"M8 0C3.58 0 0 3.58 0 8C0 11.54 2.29 14.53 5.47 15.59C5.87 15.66 6.02 15.42 6.02 15.21C6.02 15.02 6.01 14.39 6.01 13.72C4 14.09 3.48 13.23 3.32 12.78C3.23 12.55 2.84 11.84 2.5 11.65C2.22 11.5 1.82 11.13 2.49 11.12C3.12 11.11 3.57 11.7 3.72 11.94C4.44 13.15 5.59 12.81 6.05 12.6C6.12 12.08 6.33 11.73 6.56 11.53C4.78 11.33 2.92 10.64 2.92 7.58C2.92 6.71 3.23 5.99 3.74 5.43C3.66 5.23 3.38 4.41 3.82 3.31C3.82 3.31 4.49 3.1 6.02 4.13C6.66 3.95 7.34 3.86 8.02 3.86C8.7 3.86 9.38 3.95 10.02 4.13C11.55 3.09 12.22 3.31 12.22 3.31C12.66 4.41 12.38 5.23 12.3 5.43C12.81 5.99 13.12 6.7 13.12 7.58C13.12 10.65 11.25 11.33 9.47 11.53C9.76 11.78 10.01 12.26 10.01 13.01C10.01 14.08 10 14.94 10 15.21C10 15.42 10.15 15.67 10.55 15.59C13.71 14.53 16 11.53 16 8C16 3.58 12.42 0 8 0Z\"\n                  transform=\"scale(64)\"\n                />\n              </svg>\n            </Link>\n          </Button>\n          <div className=\"h-4\">\n            <Separator orientation=\"vertical\" className=\"mx-2\" />\n          </div>\n          <ThemeToggle />\n        </div>\n      </nav>\n    </header>\n  );\n}\n"
  },
  {
    "path": "components/page-wide-scroll-mask.tsx",
    "content": "\"use client\";\n\nimport { useEffect, useState } from \"react\";\nimport { motion } from \"motion/react\";\n\nexport default function PageWideScrollMask() {\n  const [showTopMask, setShowTopMask] = useState(false);\n  const [showBottomMask, setShowBottomMask] = useState(false);\n\n  useEffect(() => {\n    const handleScroll = () => {\n      const scrollTop = window.scrollY;\n      const windowHeight = window.innerHeight;\n      const documentHeight = document.documentElement.scrollHeight;\n\n      const isScrollable = documentHeight > windowHeight;\n\n      if (!isScrollable) {\n        setShowTopMask(false);\n        setShowBottomMask(false);\n        return;\n      }\n\n      const topThreshold = 50;\n      setShowTopMask(scrollTop > topThreshold);\n\n      const bottomThreshold = 50;\n      const distanceFromBottom = documentHeight - (scrollTop + windowHeight);\n      setShowBottomMask(distanceFromBottom > bottomThreshold);\n    };\n\n    handleScroll();\n\n    window.addEventListener(\"scroll\", handleScroll, { passive: true });\n    return () => {\n      window.removeEventListener(\"scroll\", handleScroll);\n    };\n  }, []);\n\n  return (\n    <>\n      <motion.div\n        aria-hidden=\"true\"\n        className=\"from-background pointer-events-none fixed top-0 z-50 h-16 w-full bg-gradient-to-b to-transparent\"\n        initial={{\n          opacity: 0,\n          y: -16,\n        }}\n        animate={{\n          opacity: showTopMask ? 1 : 0,\n          y: showTopMask ? 0 : -16,\n        }}\n        transition={{\n          duration: 0.3,\n          ease: \"easeInOut\",\n        }}\n        style={{\n          pointerEvents: \"none\",\n        }}\n      />\n      <motion.div\n        aria-hidden=\"true\"\n        className=\"from-background pointer-events-none fixed bottom-0 z-50 h-16 w-full bg-gradient-to-t to-transparent\"\n        initial={{\n          opacity: 0,\n          y: 16,\n        }}\n        animate={{\n          opacity: showBottomMask ? 1 : 0,\n          y: showBottomMask ? 0 : 16,\n        }}\n        transition={{\n          duration: 0.3,\n          ease: \"easeInOut\",\n        }}\n        style={{\n          pointerEvents: \"none\",\n        }}\n      />\n    </>\n  );\n}\n"
  },
  {
    "path": "components/posthog-provider.tsx",
    "content": "\"use client\";\n\nimport { useEffect } from \"react\";\n\nimport posthog from \"posthog-js\";\nimport { PostHogProvider as PHProvider } from \"posthog-js/react\";\n\nexport default function PostHogProvider({ children }: { children: React.ReactNode }) {\n  useEffect(() => {\n    if (process.env.NODE_ENV === \"development\") return;\n\n    if (typeof window === \"undefined\") return;\n\n    const key = \"phc_if0JhFzod0CXwQO92EQ0z5fjQgGT2xXPLPVJmu43nZl\";\n    if (!key) return;\n\n    posthog.init(key, {\n      api_host: process.env.NEXT_PUBLIC_POSTHOG_HOST || \"https://us.i.posthog.com\",\n      capture_pageview: true,\n      capture_pageleave: true,\n      name: \"Lina\",\n      defaults: \"2025-05-24\",\n      person_profiles: \"always\",\n    });\n  }, []);\n\n  return <PHProvider client={posthog}>{children}</PHProvider>;\n}\n"
  },
  {
    "path": "components/render-preview.tsx",
    "content": "\"use client\";\n\nimport React from \"react\";\nimport { Index, type RegistryKeys } from \"@/registry/registry\";\n\nimport { useVariantStore } from \"@/lib/variant-store\";\n\ntype RenderPreviewProps = {\n  name: RegistryKeys;\n};\n\nexport default function RenderPreview({ name }: RenderPreviewProps) {\n  const { currentVariant } = useVariantStore();\n  const registryEntry = Index[name];\n\n  return (\n    <>\n      {!registryEntry ? (\n        <p className=\"text-muted-foreground text-sm\">\n          Component <code className=\"bg-muted relative rounded px-[0.3rem] py-[0.2rem] font-mono text-sm\">{name}</code>{\" \"}\n          not found in special registry.\n        </p>\n      ) : (\n        React.createElement(registryEntry.variants[currentVariant])\n      )}\n    </>\n  );\n}\n"
  },
  {
    "path": "components/theme-provider.tsx",
    "content": "\"use client\";\n\nimport * as React from \"react\";\n\nimport { ThemeProvider as NextThemesProvider } from \"next-themes\";\n\nexport function ThemeProvider({ children, ...props }: React.ComponentProps<typeof NextThemesProvider>) {\n  return <NextThemesProvider {...props}>{children}</NextThemesProvider>;\n}\n"
  },
  {
    "path": "components/theme-toggle.tsx",
    "content": "\"use client\";\n\nimport * as React from \"react\";\n\nimport { useTheme } from \"next-themes\";\n\nimport { Button } from \"@/components/ui/button\";\n\nimport { useMetaColor } from \"@/hooks/use-meta-color\";\n\nexport default function ThemeToggle() {\n  const { setTheme, resolvedTheme } = useTheme();\n  const { metaColor, setMetaColor } = useMetaColor();\n\n  React.useEffect(() => {\n    setMetaColor(metaColor);\n  }, [metaColor, setMetaColor]);\n\n  const toggleTheme = React.useCallback(() => {\n    setTheme(resolvedTheme === \"dark\" ? \"light\" : \"dark\");\n  }, [resolvedTheme, setTheme]);\n\n  return (\n    <Button variant=\"ghost\" size=\"icon\" className=\"group/toggle size-8\" onClick={toggleTheme} title=\"Toggle theme\">\n      <div className=\"border-primary aspect-square size-4 rounded-full border-2 [background:linear-gradient(90deg,var(--background)_50%,var(--primary)_50%)]\" />\n      <span className=\"sr-only\">Toggle theme</span>\n    </Button>\n  );\n}\n"
  },
  {
    "path": "components/ui/button.tsx",
    "content": "import * as React from \"react\";\n\nimport { Slot } from \"@radix-ui/react-slot\";\nimport { cva, type VariantProps } from \"class-variance-authority\";\n\nimport { cn } from \"@/lib/utils\";\n\nconst buttonVariants = cva(\n  \"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring select-none focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive\",\n  {\n    variants: {\n      variant: {\n        default: \"bg-primary text-primary-foreground shadow-xs hover:bg-primary/90\",\n        destructive:\n          \"bg-destructive text-white shadow-xs hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60\",\n        outline:\n          \"border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50\",\n        secondary: \"bg-secondary text-secondary-foreground shadow-xs hover:bg-secondary/80\",\n        ghost: \"hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50\",\n        link: \"text-primary underline-offset-4 hover:underline\",\n      },\n      size: {\n        default: \"h-9 px-4 py-2 has-[>svg]:px-3\",\n        sm: \"h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5\",\n        lg: \"h-10 rounded-md px-6 has-[>svg]:px-4\",\n        icon: \"size-9\",\n      },\n    },\n    defaultVariants: {\n      variant: \"default\",\n      size: \"default\",\n    },\n  }\n);\n\nfunction Button({\n  className,\n  variant,\n  size,\n  asChild = false,\n  ...props\n}: React.ComponentProps<\"button\"> &\n  VariantProps<typeof buttonVariants> & {\n    asChild?: boolean;\n  }) {\n  const Comp = asChild ? Slot : \"button\";\n\n  return <Comp data-slot=\"button\" className={cn(buttonVariants({ variant, size, className }))} {...props} />;\n}\n\nexport { Button, buttonVariants };\n"
  },
  {
    "path": "components/ui/card.tsx",
    "content": "import * as React from \"react\";\n\nimport { cn } from \"@/lib/utils\";\n\nfunction Card({ className, ...props }: React.ComponentProps<\"div\">) {\n  return (\n    <div\n      data-slot=\"card\"\n      className={cn(\"bg-card text-card-foreground flex flex-col gap-6 rounded-xl border py-6 shadow-sm\", className)}\n      {...props}\n    />\n  );\n}\n\nfunction CardHeader({ className, ...props }: React.ComponentProps<\"div\">) {\n  return (\n    <div\n      data-slot=\"card-header\"\n      className={cn(\n        \"@container/card-header grid auto-rows-min grid-rows-[auto_auto] items-start gap-1.5 px-6 has-data-[slot=card-action]:grid-cols-[1fr_auto] [.border-b]:pb-6\",\n        className\n      )}\n      {...props}\n    />\n  );\n}\n\nfunction CardTitle({ className, ...props }: React.ComponentProps<\"div\">) {\n  return <div data-slot=\"card-title\" className={cn(\"leading-none font-semibold\", className)} {...props} />;\n}\n\nfunction CardDescription({ className, ...props }: React.ComponentProps<\"div\">) {\n  return <div data-slot=\"card-description\" className={cn(\"text-muted-foreground text-sm\", className)} {...props} />;\n}\n\nfunction CardAction({ className, ...props }: React.ComponentProps<\"div\">) {\n  return (\n    <div\n      data-slot=\"card-action\"\n      className={cn(\"col-start-2 row-span-2 row-start-1 self-start justify-self-end\", className)}\n      {...props}\n    />\n  );\n}\n\nfunction CardContent({ className, ...props }: React.ComponentProps<\"div\">) {\n  return <div data-slot=\"card-content\" className={cn(\"px-6\", className)} {...props} />;\n}\n\nfunction CardFooter({ className, ...props }: React.ComponentProps<\"div\">) {\n  return (\n    <div data-slot=\"card-footer\" className={cn(\"flex items-center px-6 [.border-t]:pt-6\", className)} {...props} />\n  );\n}\n\nexport { Card, CardHeader, CardFooter, CardTitle, CardAction, CardDescription, CardContent };\n"
  },
  {
    "path": "components/ui/dialog.tsx",
    "content": "\"use client\";\n\nimport * as React from \"react\";\n\nimport * as DialogPrimitive from \"@radix-ui/react-dialog\";\nimport { XIcon } from \"lucide-react\";\n\nimport { cn } from \"@/lib/utils\";\n\nfunction Dialog({ ...props }: React.ComponentProps<typeof DialogPrimitive.Root>) {\n  return <DialogPrimitive.Root data-slot=\"dialog\" {...props} />;\n}\n\nfunction DialogTrigger({ ...props }: React.ComponentProps<typeof DialogPrimitive.Trigger>) {\n  return <DialogPrimitive.Trigger data-slot=\"dialog-trigger\" {...props} />;\n}\n\nfunction DialogPortal({ ...props }: React.ComponentProps<typeof DialogPrimitive.Portal>) {\n  return <DialogPrimitive.Portal data-slot=\"dialog-portal\" {...props} />;\n}\n\nfunction DialogClose({ ...props }: React.ComponentProps<typeof DialogPrimitive.Close>) {\n  return <DialogPrimitive.Close data-slot=\"dialog-close\" {...props} />;\n}\n\nfunction DialogOverlay({ className, ...props }: React.ComponentProps<typeof DialogPrimitive.Overlay>) {\n  return (\n    <DialogPrimitive.Overlay\n      data-slot=\"dialog-overlay\"\n      className={cn(\n        \"data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/50\",\n        className\n      )}\n      {...props}\n    />\n  );\n}\n\nfunction DialogContent({\n  className,\n  children,\n  showCloseButton = true,\n  ...props\n}: React.ComponentProps<typeof DialogPrimitive.Content> & {\n  showCloseButton?: boolean;\n}) {\n  return (\n    <DialogPortal data-slot=\"dialog-portal\">\n      <DialogOverlay />\n      <DialogPrimitive.Content\n        data-slot=\"dialog-content\"\n        className={cn(\n          \"bg-background data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 fixed top-[50%] left-[50%] z-50 grid w-full max-w-[calc(100%-2rem)] translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border p-6 shadow-lg duration-200 sm:max-w-lg\",\n          className\n        )}\n        {...props}\n      >\n        {children}\n        {showCloseButton && (\n          <DialogPrimitive.Close\n            data-slot=\"dialog-close\"\n            className=\"ring-offset-background focus:ring-ring data-[state=open]:bg-accent data-[state=open]:text-muted-foreground absolute top-4 right-4 rounded-xs opacity-70 transition-opacity hover:opacity-100 focus:ring-2 focus:ring-offset-2 focus:outline-hidden disabled:pointer-events-none [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\"\n          >\n            <XIcon />\n            <span className=\"sr-only\">Close</span>\n          </DialogPrimitive.Close>\n        )}\n      </DialogPrimitive.Content>\n    </DialogPortal>\n  );\n}\n\nfunction DialogHeader({ className, ...props }: React.ComponentProps<\"div\">) {\n  return (\n    <div\n      data-slot=\"dialog-header\"\n      className={cn(\"flex flex-col gap-2 text-center sm:text-left\", className)}\n      {...props}\n    />\n  );\n}\n\nfunction DialogFooter({ className, ...props }: React.ComponentProps<\"div\">) {\n  return (\n    <div\n      data-slot=\"dialog-footer\"\n      className={cn(\"flex flex-col-reverse gap-2 sm:flex-row sm:justify-end\", className)}\n      {...props}\n    />\n  );\n}\n\nfunction DialogTitle({ className, ...props }: React.ComponentProps<typeof DialogPrimitive.Title>) {\n  return (\n    <DialogPrimitive.Title\n      data-slot=\"dialog-title\"\n      className={cn(\"text-lg leading-none font-semibold\", className)}\n      {...props}\n    />\n  );\n}\n\nfunction DialogDescription({ className, ...props }: React.ComponentProps<typeof DialogPrimitive.Description>) {\n  return (\n    <DialogPrimitive.Description\n      data-slot=\"dialog-description\"\n      className={cn(\"text-muted-foreground text-sm\", className)}\n      {...props}\n    />\n  );\n}\n\nexport {\n  Dialog,\n  DialogClose,\n  DialogContent,\n  DialogDescription,\n  DialogFooter,\n  DialogHeader,\n  DialogOverlay,\n  DialogPortal,\n  DialogTitle,\n  DialogTrigger,\n};\n"
  },
  {
    "path": "components/ui/label.tsx",
    "content": "\"use client\";\n\nimport * as React from \"react\";\nimport { Label as LabelPrimitive } from \"radix-ui\";\n\nimport { cn } from \"@/lib/utils\";\n\nfunction Label({ className, ...props }: React.ComponentProps<typeof LabelPrimitive.Root>) {\n  return (\n    <LabelPrimitive.Root\n      data-slot=\"label\"\n      className={cn(\n        \"text-foreground text-sm leading-4 font-medium select-none group-data-[disabled=true]:pointer-events-none group-data-[disabled=true]:opacity-50 peer-disabled:cursor-not-allowed peer-disabled:opacity-50\",\n        className\n      )}\n      {...props}\n    />\n  );\n}\n\nexport { Label };\n"
  },
  {
    "path": "components/ui/popover.tsx",
    "content": "\"use client\";\n\nimport * as React from \"react\";\nimport { Popover as PopoverPrimitive } from \"radix-ui\";\n\nimport { cn } from \"@/lib/utils\";\n\nfunction Popover({ ...props }: React.ComponentProps<typeof PopoverPrimitive.Root>) {\n  return <PopoverPrimitive.Root data-slot=\"popover\" {...props} />;\n}\n\nfunction PopoverTrigger({ ...props }: React.ComponentProps<typeof PopoverPrimitive.Trigger>) {\n  return <PopoverPrimitive.Trigger data-slot=\"popover-trigger\" {...props} />;\n}\n\nfunction PopoverContent({\n  className,\n  align = \"center\",\n  sideOffset = 4,\n  showArrow = false,\n  ...props\n}: React.ComponentProps<typeof PopoverPrimitive.Content> & {\n  showArrow?: boolean;\n}) {\n  return (\n    <PopoverPrimitive.Portal>\n      <PopoverPrimitive.Content\n        data-slot=\"popover-content\"\n        align={align}\n        sideOffset={sideOffset}\n        className={cn(\n          \"bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 w-72 rounded-md border p-4 shadow-md outline-hidden\",\n          className\n        )}\n        {...props}\n      >\n        {props.children}\n        {showArrow && <PopoverPrimitive.Arrow className=\"fill-popover -my-px drop-shadow-[0_1px_0_var(--border)]\" />}\n      </PopoverPrimitive.Content>\n    </PopoverPrimitive.Portal>\n  );\n}\n\nfunction PopoverAnchor({ ...props }: React.ComponentProps<typeof PopoverPrimitive.Anchor>) {\n  return <PopoverPrimitive.Anchor data-slot=\"popover-anchor\" {...props} />;\n}\n\nexport { Popover, PopoverAnchor, PopoverContent, PopoverTrigger };\n"
  },
  {
    "path": "components/ui/revola.tsx",
    "content": "\"use client\";\n\nimport * as React from \"react\";\n\nimport * as DialogPrimitive from \"@radix-ui/react-dialog\";\nimport { X } from \"lucide-react\";\nimport { Drawer as DrawerPrimitive, Content as VaulDrawerContent } from \"vaul\";\nimport { cva } from \"class-variance-authority\";\n\nimport { cn } from \"@/lib/utils\";\n\nimport useMediaQuery from \"@/hooks/use-media-query\";\n\nexport type ResponsiveDialogProps = React.ComponentProps<typeof DrawerPrimitive.Root>;\n\ntype ResponsiveDialogContextProps = {\n  modal?: boolean;\n  dismissible?: boolean;\n  direction?: \"top\" | \"right\" | \"bottom\" | \"left\";\n  onlyDrawer?: boolean;\n  onlyDialog?: boolean;\n  alert?: boolean;\n};\n\ntype ResponsiveDialogProviderProps = {\n  children: React.ReactNode;\n} & ResponsiveDialogContextProps;\n\nconst ResponsiveDialogContext = React.createContext<ResponsiveDialogContextProps | null>(null);\nconst MOBILE_BREAKPOINT = \"(min-width: 640px)\";\n\nconst ResponsiveDialogProvider = ({\n  modal = true,\n  dismissible = true,\n  direction = \"bottom\",\n  onlyDrawer = false,\n  onlyDialog = false,\n  alert = false,\n  children,\n}: ResponsiveDialogProviderProps) => {\n  return (\n    <ResponsiveDialogContext.Provider value={{ modal, dismissible, direction, onlyDrawer, onlyDialog, alert }}>\n      {children}\n    </ResponsiveDialogContext.Provider>\n  );\n};\n\nexport const useResponsiveDialog = () => {\n  const context = React.useContext(ResponsiveDialogContext);\n\n  if (!context) {\n    throw new Error(\"useResponsiveDialog must be used within a <ResponsiveDialog />\");\n  }\n\n  return context;\n};\n\nconst ResponsiveDialog = ({\n  modal = true,\n  dismissible = true,\n  direction = \"bottom\",\n  onlyDrawer = false,\n  onlyDialog = false,\n  alert = false,\n  shouldScaleBackground = true,\n  open: controlledOpen,\n  onOpenChange: controlledOnOpenChange,\n  ...props\n}: ResponsiveDialogProps & { onlyDrawer?: boolean; onlyDialog?: boolean; alert?: boolean }) => {\n  const [internalState, setInternalState] = React.useState<boolean>(false);\n\n  const isControlledOpen = typeof controlledOpen === \"undefined\";\n  const toggleInternalState = () => setInternalState((prev) => !prev);\n\n  const open = isControlledOpen ? internalState : controlledOpen;\n  const onOpenChange = isControlledOpen ? toggleInternalState : controlledOnOpenChange;\n\n  const isDesktop = useMediaQuery(MOBILE_BREAKPOINT);\n\n  const shouldUseDialog = onlyDialog || (!onlyDrawer && isDesktop);\n  const ResponsiveDialog = shouldUseDialog ? DialogPrimitive.Root : DrawerPrimitive.Root;\n\n  const effectiveModal = alert ? true : modal;\n  const effectiveDismissible = alert ? true : dismissible;\n\n  return (\n    <ResponsiveDialogProvider\n      modal={effectiveModal}\n      dismissible={effectiveDismissible}\n      direction={direction}\n      onlyDrawer={onlyDrawer}\n      onlyDialog={onlyDialog}\n      alert={alert}\n    >\n      <ResponsiveDialog\n        modal={effectiveModal}\n        direction={direction}\n        dismissible={effectiveDismissible}\n        shouldScaleBackground={shouldScaleBackground}\n        open={open}\n        onOpenChange={onOpenChange}\n        {...props}\n      />\n    </ResponsiveDialogProvider>\n  );\n};\nResponsiveDialog.displayName = \"ResponsiveDialog\";\n\nconst ResponsiveDialogTrigger = ({ ...props }: React.ComponentProps<typeof DialogPrimitive.Trigger>) => {\n  const { onlyDrawer, onlyDialog } = useResponsiveDialog();\n  const isDesktop = useMediaQuery(MOBILE_BREAKPOINT);\n\n  const shouldUseDialog = onlyDialog || (!onlyDrawer && isDesktop);\n  const ResponsiveDialogTrigger = shouldUseDialog ? DialogPrimitive.Trigger : DrawerPrimitive.Trigger;\n  return <ResponsiveDialogTrigger {...props} />;\n};\nResponsiveDialogTrigger.displayName = \"ResponsiveDialogTrigger\";\n\nconst ResponsiveDialogPortal = ({ ...props }: React.ComponentProps<typeof DialogPrimitive.Portal>) => {\n  const { onlyDrawer, onlyDialog } = useResponsiveDialog();\n  const isDesktop = useMediaQuery(MOBILE_BREAKPOINT);\n\n  const shouldUseDialog = onlyDialog || (!onlyDrawer && isDesktop);\n  const ResponsiveDialogPortal = shouldUseDialog ? DialogPrimitive.Portal : DrawerPrimitive.Portal;\n  return <ResponsiveDialogPortal {...props} />;\n};\nResponsiveDialogPortal.displayName = \"ResponsiveDialogPortal\";\n\nconst ResponsiveDialogOverlay = ({ className, ...props }: React.ComponentProps<typeof DialogPrimitive.Overlay>) => {\n  const { onlyDrawer, onlyDialog } = useResponsiveDialog();\n  const isDesktop = useMediaQuery(MOBILE_BREAKPOINT);\n\n  const shouldUseDialog = onlyDialog || (!onlyDrawer && isDesktop);\n  const ResponsiveDialogOverlay = shouldUseDialog ? DialogPrimitive.Overlay : DrawerPrimitive.Overlay;\n  return (\n    <ResponsiveDialogOverlay\n      {...props}\n      className={cn(\n        \"sm:data-[state=open]:animate-in sm:data-[state=closed]:animate-out sm:data-[state=closed]:fade-out-0 sm:data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/50\",\n        className\n      )}\n    />\n  );\n};\nResponsiveDialogOverlay.displayName = \"ResponsiveDialogOverlay\";\n\nconst ResponsiveDialogClose = ({ ...props }: React.ComponentProps<typeof DialogPrimitive.Close>) => {\n  const { dismissible, alert, onlyDrawer, onlyDialog } = useResponsiveDialog();\n  const isDesktop = useMediaQuery(MOBILE_BREAKPOINT);\n\n  const shouldUseDialog = onlyDialog || (!onlyDrawer && isDesktop);\n  const ResponsiveDialogClose = shouldUseDialog ? DialogPrimitive.Close : DrawerPrimitive.Close;\n\n  const shouldPreventClose = !dismissible && !alert;\n\n  return (\n    <ResponsiveDialogClose\n      aria-label=\"Close\"\n      {...(shouldPreventClose && { onClick: (e) => e.preventDefault() })}\n      {...props}\n    />\n  );\n};\nResponsiveDialogClose.displayName = \"ResponsiveDialogClose\";\n\nconst ResponsiveDialogContentVariants = cva(\"fixed z-[9999] bg-background\", {\n  variants: {\n    device: {\n      desktop:\n        \"left-1/2 top-1/2 grid max-h-[calc(100%-4rem)] w-full max-w-[calc(100%-2rem)] translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:max-w-lg\",\n      mobile: \"flex \",\n    },\n    direction: {\n      bottom: \"\",\n      top: \"\",\n      left: \"\",\n      right: \"\",\n    },\n  },\n  defaultVariants: {\n    device: \"desktop\",\n    direction: \"bottom\",\n  },\n  compoundVariants: [\n    {\n      device: \"mobile\",\n      direction: \"bottom\",\n      className:\n        \"inset-x-0 bottom-0 mt-24 h-fit max-h-[65%] flex-col rounded-t-[10px] border border-b-0 border-primary/10\",\n    },\n    {\n      device: \"mobile\",\n      direction: \"top\",\n      className:\n        \"inset-x-0 top-0 mb-24 h-fit max-h-[65%] flex-col rounded-b-[10px] border border-b-0 border-primary/10\",\n    },\n    {\n      device: \"mobile\",\n      direction: \"left\",\n      className:\n        \"bottom-2 left-2 top-2 flex w-[310px] bg-transparent outline-none [--initial-transform:calc(100%+8px)]\",\n    },\n    {\n      device: \"mobile\",\n      direction: \"right\",\n      className: \"bottom-2 right-2 top-2 w-[310px] bg-transparent outline-none [--initial-transform:calc(100%+8px)]\",\n    },\n  ],\n});\n\nconst ResponsiveDialogContent = React.forwardRef<\n  HTMLDivElement,\n  React.ComponentPropsWithoutRef<typeof DialogPrimitive.Content> & {\n    showCloseButton?: boolean;\n    /** Styles for the built in close button */\n    closeButtonClassName?: string;\n    /** Styles for the drag handle */\n    dragHandleClassName?: string;\n  }\n>(({ className, children, showCloseButton = true, closeButtonClassName, dragHandleClassName, ...props }, ref) => {\n  const { direction, modal, dismissible, alert, onlyDrawer, onlyDialog } = useResponsiveDialog();\n\n  const isDesktop = useMediaQuery(MOBILE_BREAKPOINT);\n  const shouldUseDialog = onlyDialog || (!onlyDrawer && isDesktop);\n  const ResponsiveDialogContent = shouldUseDialog ? DialogPrimitive.Content : VaulDrawerContent;\n\n  const shouldShowCloseButton = !alert && showCloseButton;\n  const shouldPreventEscape = !dismissible && !alert;\n  const shouldPreventOutsideInteraction = !modal || (!dismissible && !alert) || alert;\n\n  return (\n    <ResponsiveDialogPortal>\n      <ResponsiveDialogOverlay />\n      <ResponsiveDialogContent\n        ref={ref}\n        {...props}\n        {...(shouldPreventEscape && shouldUseDialog && { onEscapeKeyDown: (e) => e.preventDefault() })}\n        {...(shouldPreventOutsideInteraction &&\n          shouldUseDialog && {\n            onInteractOutside: (e) => e.preventDefault(),\n          })}\n        {...(!shouldUseDialog &&\n          shouldPreventOutsideInteraction && {\n            onPointerDownOutside: (e) => e.preventDefault(),\n            onInteractOutside: (e) => e.preventDefault(),\n          })}\n        className={cn(\n          ResponsiveDialogContentVariants({\n            device: shouldUseDialog ? \"desktop\" : \"mobile\",\n            direction,\n          }),\n          className\n        )}\n      >\n        {!shouldUseDialog && direction === \"bottom\" && (\n          <div\n            className={cn(\n              \"bg-muted-foreground/25 dark:bg-muted mx-auto my-4 h-1.5 w-14 rounded-full pb-1.5 data-[vaul-handle]:h-1.5 data-[vaul-handle]:w-14 data-[vaul-handle]:pb-1.5\",\n              dragHandleClassName\n            )}\n          />\n        )}\n        {children}\n        {shouldShowCloseButton && (\n          <ResponsiveDialogClose\n            className={cn(\n              \"ring-offset-background focus-visible:ring-ring data-[state=open]:bg-accent absolute top-4 right-4 rounded-sm opacity-70 backdrop-blur-sm transition-opacity hover:opacity-100 focus:ring-offset-2 focus:outline-none focus-visible:ring-2 disabled:pointer-events-none data-[state=open]:text-white\",\n              closeButtonClassName\n            )}\n          >\n            <X className=\"size-4\" />\n            <span className=\"sr-only\">close</span>\n          </ResponsiveDialogClose>\n        )}\n      </ResponsiveDialogContent>\n    </ResponsiveDialogPortal>\n  );\n});\nResponsiveDialogContent.displayName = \"ResponsiveDialogContent\";\n\nconst ResponsiveDialogHeader = ({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) => {\n  return <div className={cn(\"flex flex-col gap-1.5 text-center sm:text-left\", className)} {...props} />;\n};\nResponsiveDialogHeader.displayName = \"ResponsiveDialogHeader\";\n\nconst ResponsiveDialogFooter = ({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) => {\n  return <footer className={cn(\"flex flex-col-reverse gap-2 sm:flex-row sm:justify-end\", className)} {...props} />;\n};\nResponsiveDialogFooter.displayName = \"ResponsiveDialogFooter\";\n\nconst ResponsiveDialogTitle = React.forwardRef<\n  React.ComponentRef<typeof DialogPrimitive.Title>,\n  React.ComponentPropsWithoutRef<typeof DialogPrimitive.Title>\n>(({ className, ...props }, ref) => {\n  const { onlyDrawer, onlyDialog } = useResponsiveDialog();\n  const isDesktop = useMediaQuery(MOBILE_BREAKPOINT);\n\n  const shouldUseDialog = onlyDialog || (!onlyDrawer && isDesktop);\n  const ResponsiveDialogTitle = shouldUseDialog ? DialogPrimitive.Title : DrawerPrimitive.Title;\n  return (\n    <ResponsiveDialogTitle\n      ref={ref}\n      className={cn(\"text-lg leading-none font-semibold tracking-tight\", className)}\n      {...props}\n    />\n  );\n});\n\nResponsiveDialogTitle.displayName = \"ResponsiveDialogTitle\";\n\nconst ResponsiveDialogDescription = React.forwardRef<\n  React.ComponentRef<typeof DialogPrimitive.Description>,\n  React.ComponentPropsWithoutRef<typeof DialogPrimitive.Description>\n>(({ className, ...props }, ref) => {\n  const { onlyDrawer, onlyDialog } = useResponsiveDialog();\n  const isDesktop = useMediaQuery(MOBILE_BREAKPOINT);\n\n  const shouldUseDialog = onlyDialog || (!onlyDrawer && isDesktop);\n  const ResponsiveDialogDescription = shouldUseDialog ? DialogPrimitive.Description : DrawerPrimitive.Description;\n  return (\n    <ResponsiveDialogDescription ref={ref} className={cn(\"text-muted-foreground text-sm\", className)} {...props} />\n  );\n});\n\nResponsiveDialogDescription.displayName = \"ResponsiveDialogDescription\";\n\nexport {\n  ResponsiveDialog,\n  ResponsiveDialogClose,\n  ResponsiveDialogContent,\n  ResponsiveDialogDescription,\n  ResponsiveDialogFooter,\n  ResponsiveDialogHeader,\n  ResponsiveDialogOverlay,\n  ResponsiveDialogPortal,\n  ResponsiveDialogTitle,\n  ResponsiveDialogTrigger,\n};\n"
  },
  {
    "path": "components/ui/select.tsx",
    "content": "\"use client\";\n\nimport * as React from \"react\";\n\nimport * as SelectPrimitive from \"@radix-ui/react-select\";\nimport { CheckIcon, ChevronDownIcon, ChevronUpIcon } from \"lucide-react\";\n\nimport { cn } from \"@/lib/utils\";\n\nfunction Select({ ...props }: React.ComponentProps<typeof SelectPrimitive.Root>) {\n  return <SelectPrimitive.Root data-slot=\"select\" {...props} />;\n}\n\nfunction SelectGroup({ ...props }: React.ComponentProps<typeof SelectPrimitive.Group>) {\n  return <SelectPrimitive.Group data-slot=\"select-group\" {...props} />;\n}\n\nfunction SelectValue({ ...props }: React.ComponentProps<typeof SelectPrimitive.Value>) {\n  return <SelectPrimitive.Value data-slot=\"select-value\" {...props} />;\n}\n\nfunction SelectTrigger({\n  className,\n  size = \"default\",\n  children,\n  ...props\n}: React.ComponentProps<typeof SelectPrimitive.Trigger> & {\n  size?: \"sm\" | \"default\";\n}) {\n  return (\n    <SelectPrimitive.Trigger\n      data-slot=\"select-trigger\"\n      data-size={size}\n      className={cn(\n        \"border-input data-[placeholder]:text-muted-foreground [&_svg:not([class*='text-'])]:text-muted-foreground focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:bg-input/30 dark:hover:bg-input/50 flex w-fit items-center justify-between gap-2 rounded-md border bg-transparent px-3 py-2 text-sm whitespace-nowrap shadow-xs transition-[color,box-shadow] outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50 data-[size=default]:h-9 data-[size=sm]:h-8 *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center *:data-[slot=select-value]:gap-2 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n        className\n      )}\n      {...props}\n    >\n      {children}\n      <SelectPrimitive.Icon asChild>\n        <ChevronDownIcon className=\"size-4 opacity-50\" />\n      </SelectPrimitive.Icon>\n    </SelectPrimitive.Trigger>\n  );\n}\n\nfunction SelectContent({\n  className,\n  children,\n  position = \"popper\",\n  ...props\n}: React.ComponentProps<typeof SelectPrimitive.Content>) {\n  return (\n    <SelectPrimitive.Portal>\n      <SelectPrimitive.Content\n        data-slot=\"select-content\"\n        className={cn(\n          \"bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 relative z-50 max-h-(--radix-select-content-available-height) min-w-[8rem] origin-(--radix-select-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-md border shadow-md\",\n          position === \"popper\" &&\n            \"data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1\",\n          className\n        )}\n        position={position}\n        {...props}\n      >\n        <SelectScrollUpButton />\n        <SelectPrimitive.Viewport\n          className={cn(\n            \"p-1\",\n            position === \"popper\" &&\n              \"h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)] scroll-my-1\"\n          )}\n        >\n          {children}\n        </SelectPrimitive.Viewport>\n        <SelectScrollDownButton />\n      </SelectPrimitive.Content>\n    </SelectPrimitive.Portal>\n  );\n}\n\nfunction SelectLabel({ className, ...props }: React.ComponentProps<typeof SelectPrimitive.Label>) {\n  return (\n    <SelectPrimitive.Label\n      data-slot=\"select-label\"\n      className={cn(\"text-muted-foreground px-2 py-1.5 text-xs\", className)}\n      {...props}\n    />\n  );\n}\n\nfunction SelectItem({ className, children, ...props }: React.ComponentProps<typeof SelectPrimitive.Item>) {\n  return (\n    <SelectPrimitive.Item\n      data-slot=\"select-item\"\n      className={cn(\n        \"focus:bg-accent focus:text-accent-foreground [&_svg:not([class*='text-'])]:text-muted-foreground relative flex w-full cursor-default items-center gap-2 rounded-sm py-1.5 pr-8 pl-2 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 *:[span]:last:flex *:[span]:last:items-center *:[span]:last:gap-2\",\n        className\n      )}\n      {...props}\n    >\n      <span className=\"absolute right-2 flex size-3.5 items-center justify-center\">\n        <SelectPrimitive.ItemIndicator>\n          <CheckIcon className=\"size-4\" />\n        </SelectPrimitive.ItemIndicator>\n      </span>\n      <SelectPrimitive.ItemText>{children}</SelectPrimitive.ItemText>\n    </SelectPrimitive.Item>\n  );\n}\n\nfunction SelectSeparator({ className, ...props }: React.ComponentProps<typeof SelectPrimitive.Separator>) {\n  return (\n    <SelectPrimitive.Separator\n      data-slot=\"select-separator\"\n      className={cn(\"bg-border pointer-events-none -mx-1 my-1 h-px\", className)}\n      {...props}\n    />\n  );\n}\n\nfunction SelectScrollUpButton({ className, ...props }: React.ComponentProps<typeof SelectPrimitive.ScrollUpButton>) {\n  return (\n    <SelectPrimitive.ScrollUpButton\n      data-slot=\"select-scroll-up-button\"\n      className={cn(\"flex cursor-default items-center justify-center py-1\", className)}\n      {...props}\n    >\n      <ChevronUpIcon className=\"size-4\" />\n    </SelectPrimitive.ScrollUpButton>\n  );\n}\n\nfunction SelectScrollDownButton({\n  className,\n  ...props\n}: React.ComponentProps<typeof SelectPrimitive.ScrollDownButton>) {\n  return (\n    <SelectPrimitive.ScrollDownButton\n      data-slot=\"select-scroll-down-button\"\n      className={cn(\"flex cursor-default items-center justify-center py-1\", className)}\n      {...props}\n    >\n      <ChevronDownIcon className=\"size-4\" />\n    </SelectPrimitive.ScrollDownButton>\n  );\n}\n\nexport {\n  Select,\n  SelectContent,\n  SelectGroup,\n  SelectItem,\n  SelectLabel,\n  SelectScrollDownButton,\n  SelectScrollUpButton,\n  SelectSeparator,\n  SelectTrigger,\n  SelectValue,\n};\n"
  },
  {
    "path": "components/ui/separator.tsx",
    "content": "\"use client\";\n\nimport * as React from \"react\";\n\nimport * as SeparatorPrimitive from \"@radix-ui/react-separator\";\n\nimport { cn } from \"@/lib/utils\";\n\nfunction Separator({\n  className,\n  orientation = \"horizontal\",\n  decorative = true,\n  ...props\n}: React.ComponentProps<typeof SeparatorPrimitive.Root>) {\n  return (\n    <SeparatorPrimitive.Root\n      data-slot=\"separator\"\n      decorative={decorative}\n      orientation={orientation}\n      className={cn(\n        \"bg-border shrink-0 data-[orientation=horizontal]:h-px data-[orientation=horizontal]:w-full data-[orientation=vertical]:h-full data-[orientation=vertical]:w-px\",\n        className\n      )}\n      {...props}\n    />\n  );\n}\n\nexport { Separator };\n"
  },
  {
    "path": "components/ui/skeleton.tsx",
    "content": "import { cn } from \"@/lib/utils\";\n\nfunction Skeleton({ className, ...props }: React.ComponentProps<\"div\">) {\n  return <div data-slot=\"skeleton\" className={cn(\"bg-accent animate-pulse rounded-md\", className)} {...props} />;\n}\n\nexport { Skeleton };\n"
  },
  {
    "path": "components/ui/tabs.tsx",
    "content": "\"use client\";\n\nimport * as React from \"react\";\n\nimport { Tabs as TabsPrimitive } from \"@base-ui-components/react/tabs\";\nimport posthog from \"posthog-js\";\n\nimport { cn } from \"@/lib/utils\";\n\nfunction Tabs({ className, ...props }: React.ComponentProps<typeof TabsPrimitive.Root>) {\n  return <TabsPrimitive.Root data-slot=\"tabs\" className={cn(\"flex flex-col gap-2\", className)} {...props} />;\n}\n\nfunction TabsList({ className, ...props }: React.ComponentProps<typeof TabsPrimitive.List>) {\n  return (\n    <TabsPrimitive.List\n      data-slot=\"tabs-list\"\n      className={cn(\n        \"bg-muted text-muted-foreground inline-flex h-7 w-fit items-center justify-center rounded-lg p-[3px]\",\n        className\n      )}\n      {...props}\n    />\n  );\n}\n\nfunction TabsTrigger({ className, onClick, value, ...props }: React.ComponentProps<typeof TabsPrimitive.Tab>) {\n  return (\n    <TabsPrimitive.Tab\n      data-slot=\"tabs-trigger\"\n      className={cn(\n        \"dark:data-[selected]:text-foreground focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:outline-ring text-foreground dark:text-muted-foreground inline-flex h-[calc(100%-1px)] flex-1 items-center justify-center gap-1.5 rounded border border-transparent px-2 py-1 text-sm font-medium whitespace-nowrap transition-colors focus-visible:ring-[3px] focus-visible:outline-1 disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n        className\n      )}\n      onClick={(e) => {\n        try {\n          if (value) {\n            posthog.capture(\"tabs_select\", { value });\n          }\n        } catch {}\n        onClick?.(e);\n      }}\n      value={value}\n      {...props}\n    />\n  );\n}\n\nfunction TabsIndicator({ className, ...props }: React.ComponentProps<typeof TabsPrimitive.Indicator>) {\n  return (\n    <TabsPrimitive.Indicator\n      data-slot=\"tabs-indicator\"\n      className={cn(\n        \"border-border bg-surface absolute top-1/2 left-0 z-[-1] h-[calc(100%-1px)] w-(--active-tab-width) translate-x-(--active-tab-left) -translate-y-1/2 rounded border transition-all duration-200 ease-in-out\",\n        className\n      )}\n      {...props}\n    />\n  );\n}\n\nfunction TabsContent({ className, ...props }: React.ComponentProps<typeof TabsPrimitive.Panel>) {\n  return <TabsPrimitive.Panel data-slot=\"tabs-content\" className={cn(\"flex-1 outline-none\", className)} {...props} />;\n}\n\nexport { Tabs, TabsList, TabsTrigger, TabsIndicator, TabsContent };\n"
  },
  {
    "path": "components/ui/tooltip.tsx",
    "content": "\"use client\";\n\nimport * as React from \"react\";\n\nimport * as TooltipPrimitive from \"@radix-ui/react-tooltip\";\n\nimport { cn } from \"@/lib/utils\";\n\nfunction TooltipProvider({ delayDuration = 0, ...props }: React.ComponentProps<typeof TooltipPrimitive.Provider>) {\n  return <TooltipPrimitive.Provider data-slot=\"tooltip-provider\" delayDuration={delayDuration} {...props} />;\n}\n\nfunction Tooltip({ ...props }: React.ComponentProps<typeof TooltipPrimitive.Root>) {\n  return (\n    <TooltipProvider>\n      <TooltipPrimitive.Root data-slot=\"tooltip\" {...props} />\n    </TooltipProvider>\n  );\n}\n\nfunction TooltipTrigger({ ...props }: React.ComponentProps<typeof TooltipPrimitive.Trigger>) {\n  return <TooltipPrimitive.Trigger data-slot=\"tooltip-trigger\" {...props} />;\n}\n\nfunction TooltipContent({\n  className,\n  sideOffset = 0,\n  children,\n  ...props\n}: React.ComponentProps<typeof TooltipPrimitive.Content>) {\n  return (\n    <TooltipPrimitive.Portal>\n      <TooltipPrimitive.Content\n        data-slot=\"tooltip-content\"\n        sideOffset={sideOffset}\n        className={cn(\n          \"bg-primary text-primary-foreground animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 w-fit origin-(--radix-tooltip-content-transform-origin) rounded-md px-3 py-1.5 text-xs text-balance\",\n          className\n        )}\n        {...props}\n      >\n        {children}\n        <TooltipPrimitive.Arrow className=\"bg-primary fill-primary z-50 size-2.5 translate-y-[calc(-50%_-_2px)] rotate-45 rounded-[2px]\" />\n      </TooltipPrimitive.Content>\n    </TooltipPrimitive.Portal>\n  );\n}\n\nexport { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider };\n"
  },
  {
    "path": "components/usage.tsx",
    "content": "import AnchorHeading from \"@/components/anchor-heading\";\nimport CodeDisplaySection from \"@/components/code-display-block\";\n\nimport { getComponentCode } from \"@/lib/code-highlight\";\n\nexport default async function Usage() {\n  const language = \"tsx\";\n\n  const [radixCodeData, baseCodeData] = await Promise.all([\n    getComponentCode(\"\", language, \"registry/radix-ui/examples/usage-demo.tsx\"),\n    getComponentCode(\"\", language, \"registry/base-ui/examples/usage-demo.tsx\"),\n  ]);\n\n  const variantData = {\n    base: {\n      code: baseCodeData,\n    },\n    radix: {\n      code: radixCodeData,\n    },\n  } as const;\n\n  return (\n    <section className=\"min-w-0 space-y-6 sm:px-6\">\n      <div className=\"space-y-1\">\n        <AnchorHeading id=\"usage\">Usage</AnchorHeading>\n        <p className=\"text-muted-foreground leading-7\">\n          Add the adaptive scroll area component to your project with ease.\n        </p>\n      </div>\n      <CodeDisplaySection variantData={variantData} language={language} maxHeight=\"[&_pre]:max-h-[400px]\" />\n    </section>\n  );\n}\n"
  },
  {
    "path": "components/variant-select.tsx",
    "content": "\"use client\";\n\nimport { useEffect, useState } from \"react\";\n\nimport posthog from \"posthog-js\";\n\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from \"@/components/ui/select\";\nimport { Skeleton } from \"@/components/ui/skeleton\";\n\nimport { cn } from \"@/lib/utils\";\nimport { useVariantStore, type Variant } from \"@/lib/variant-store\";\n\ntype VariantSelectProps = {\n  size?: \"sm\" | \"default\";\n};\n\nexport default function VariantSelect({ size = \"default\" }: VariantSelectProps) {\n  const { setVariant, currentVariant } = useVariantStore();\n  const [isHydrated, setIsHydrated] = useState(false);\n\n  useEffect(() => {\n    setIsHydrated(true);\n  }, []);\n\n  const handleVariantChange = (value: Variant) => {\n    try {\n      setVariant(value);\n      posthog.capture(\"variant_change\", { to: value });\n    } catch {}\n  };\n\n  return (\n    <Select value={isHydrated ? currentVariant : undefined} onValueChange={handleVariantChange}>\n      <SelectTrigger size={size} className={cn(\"h-7 text-sm font-medium [&_svg]:h-4 [&_svg]:w-4\")}>\n        <span className=\"text-muted-foreground font-normal\">Variant: </span>\n        {isHydrated ? <SelectValue placeholder=\"Configuration:\" /> : <Skeleton className=\"h-4 w-16\" />}\n      </SelectTrigger>\n      <SelectContent>\n        <SelectItem value=\"radix\" aria-label=\"Switch to Radix UI variant\">\n          Radix UI\n        </SelectItem>\n        <SelectItem value=\"base\" aria-label=\"Switch to Base UI variant\">\n          Base UI\n        </SelectItem>\n      </SelectContent>\n    </Select>\n  );\n}\n"
  },
  {
    "path": "components/why.tsx",
    "content": "import AnchorHeading from \"@/components/anchor-heading\";\n\nexport default function Why() {\n  return (\n    <section className=\"sm:px-6 lg:max-w-[750px]\">\n      <div className=\"space-y-6\">\n        <div className=\"space-y-1\">\n          <AnchorHeading id=\"why\" className=\"scroll-m-12\">\n            Why\n          </AnchorHeading>\n          <p className=\"text-muted-foreground leading-7\">Why did I create Lina in the first place?</p>\n        </div>\n        <div className=\"space-y-8\">\n          <div>\n            <h3 className=\"scroll-m-20 text-2xl font-semibold tracking-tight\">The Problem</h3>\n            <p className=\"leading-7 [&:not(:first-child)]:mt-6\">\n              The main reason behind it was that custom scrollbar/scrollarea components looked amazing on desktop, but\n              on mobile or general touch devices, the native scrollbars were just better, and I wanted to use those\n              instead of a custom scrollbar.\n            </p>\n          </div>\n\n          <div>\n            <h3 className=\"scroll-m-20 text-2xl font-semibold tracking-tight\">From Quick Fix to Full Component</h3>\n            <p className=\"leading-7 [&:not(:first-child)]:mt-6\">\n              So I wrote a simple version back at the end of 2024 while working on one of our office projects. Fast\n              forward to now, while building scrollable examples for{\" \"}\n              <a href=\"https://revola.sameerjs.com\" target=\"_blank\" rel=\"\" className=\"underline underline-offset-2\">\n                Revola\n              </a>\n              , I decided to turn that simple version into a full-fledged separate component. So I did.\n            </p>\n          </div>\n\n          <div>\n            <h3 className=\"scroll-m-20 text-2xl font-semibold tracking-tight\">The Details</h3>\n            <p className=\"leading-7 [&:not(:first-child)]:mt-6\">\n              The initial version of Lina only had micro-interactions and native scrollable adaptation. But then I\n              started noticing the details that make interfaces feel premium.\n            </p>\n            <p className=\"leading-7 [&:not(:first-child)]:mt-4\">\n              While using{\" \"}\n              <a href=\"https://v0.app\" target=\"_blank\" className=\"underline underline-offset-2\">\n                v0\n              </a>\n              , I spotted this smooth mask just above the chat input, content would fade in so elegantly. That visual\n              caught my eye, and I knew I had to add it. These little touches make all the difference.\n            </p>\n          </div>\n\n          <div>\n            <h3 className=\"scroll-m-20 text-2xl font-semibold tracking-tight\">The Goal</h3>\n            <blockquote className=\"mt-6 border-l-2 pl-6 italic\">\n              &quot;If wer&rsquo;e going the custom ScrollArea route, why not make it look and feel purely custom,\n              refined and detailed?.&quot;\n            </blockquote>\n            <p className=\"leading-7 [&:not(:first-child)]:mt-6\">\n              That&rsquo;s the philosophy behind Lina. No half-measures, no compromises, just a scrolling experience\n              that feels intentionally well crafted.\n            </p>\n          </div>\n        </div>\n      </div>\n    </section>\n  );\n}\n"
  },
  {
    "path": "components.json",
    "content": "{\n  \"$schema\": \"https://ui.shadcn.com/schema.json\",\n  \"style\": \"new-york\",\n  \"rsc\": true,\n  \"tsx\": true,\n  \"tailwind\": {\n    \"config\": \"\",\n    \"css\": \"app/globals.css\",\n    \"baseColor\": \"zinc\",\n    \"cssVariables\": true,\n    \"prefix\": \"\"\n  },\n  \"aliases\": {\n    \"components\": \"@/components\",\n    \"utils\": \"@/lib/utils\",\n    \"ui\": \"@/components/ui\",\n    \"lib\": \"@/lib\",\n    \"hooks\": \"@/hooks\"\n  },\n  \"iconLibrary\": \"lucide\"\n}"
  },
  {
    "path": "eslint.config.mjs",
    "content": "import { dirname } from \"path\";\nimport { fileURLToPath } from \"url\";\nimport { FlatCompat } from \"@eslint/eslintrc\";\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\nconst compat = new FlatCompat({\n  baseDirectory: __dirname,\n});\n\nconst eslintConfig = [\n  ...compat.extends(\"next/core-web-vitals\", \"next/typescript\"),\n];\n\nexport default eslintConfig;\n"
  },
  {
    "path": "hooks/use-copy-button.ts",
    "content": "\"use client\";\n\nimport { useCallback, useEffect, useRef, useState, type MouseEventHandler } from \"react\";\n\nexport function useCopyButton(onCopy: () => void): [checked: boolean, onClick: MouseEventHandler] {\n  const [checked, setChecked] = useState(false);\n  const timeoutRef = useRef<number | null>(null);\n  const callbackRef = useRef(onCopy);\n  callbackRef.current = onCopy;\n\n  const onClick: MouseEventHandler = useCallback(() => {\n    if (timeoutRef.current) window.clearTimeout(timeoutRef.current);\n    timeoutRef.current = window.setTimeout(() => {\n      setChecked(false);\n    }, 1500);\n    callbackRef.current();\n    setChecked(true);\n  }, []);\n\n  // Avoid updates after being unmounted\n  useEffect(() => {\n    return () => {\n      if (timeoutRef.current) window.clearTimeout(timeoutRef.current);\n    };\n  }, []);\n\n  return [checked, onClick];\n}\n"
  },
  {
    "path": "hooks/use-has-primary-touch.tsx",
    "content": "import { useEffect, useState } from \"react\";\n\nexport function useTouchPrimary() {\n  const [isTouchPrimary, setIsTouchPrimary] = useState(false);\n\n  useEffect(() => {\n    if (typeof window === \"undefined\") return;\n\n    const controller = new AbortController();\n    const { signal } = controller;\n\n    const handleTouch = () => {\n      const hasTouch = \"ontouchstart\" in window || navigator.maxTouchPoints > 0;\n      const prefersTouch = window.matchMedia(\"(pointer: coarse)\").matches;\n      setIsTouchPrimary(hasTouch && prefersTouch);\n    };\n\n    const mq = window.matchMedia(\"(pointer: coarse)\");\n    mq.addEventListener(\"change\", handleTouch, { signal });\n    window.addEventListener(\"pointerdown\", handleTouch, { signal });\n\n    handleTouch();\n\n    return () => controller.abort();\n  }, []);\n\n  return isTouchPrimary;\n}\n"
  },
  {
    "path": "hooks/use-media-query.tsx",
    "content": "\"use client\";\n\nimport { useEffect, useState } from \"react\";\n\nconst useMediaQuery = (query: string) => {\n  const [matches, setMatches] = useState<boolean | null>(null);\n\n  useEffect(() => {\n    const media = window.matchMedia(query);\n\n    if (media.matches !== matches) setMatches(media.matches);\n\n    const listener = () => setMatches(media.matches);\n\n    window.addEventListener(\"resize\", listener);\n    return () => window.removeEventListener(\"resize\", listener);\n  }, [query, matches]);\n\n  return matches;\n};\n\nexport default useMediaQuery;\n"
  },
  {
    "path": "hooks/use-meta-color.ts",
    "content": "import * as React from \"react\";\n\nimport { useTheme } from \"next-themes\";\n\nexport const META_THEME_COLORS = {\n  light: \"#ffffff\",\n  dark: \"#0a0a0a\",\n};\n\nexport function useMetaColor() {\n  const { resolvedTheme } = useTheme();\n\n  const metaColor = React.useMemo(() => {\n    return resolvedTheme !== \"dark\" ? META_THEME_COLORS.light : META_THEME_COLORS.dark;\n  }, [resolvedTheme]);\n\n  const setMetaColor = React.useCallback((color: string) => {\n    document.querySelector('meta[name=\"theme-color\"]')?.setAttribute(\"content\", color);\n  }, []);\n\n  return {\n    metaColor,\n    setMetaColor,\n  };\n}\n"
  },
  {
    "path": "lib/adaptive-mask-animation.ts",
    "content": "import { MotionValue } from \"motion/react\";\n\n// Configuration constants\nexport const SCROLL_CONFIG = {\n  vertical: { max: 105, hold: 105, return: 40 },\n  horizontal: { max: 370, curve: 10 },\n  timing: { cycle: 280, fps: 16 },\n} as const;\n\n// Content bounds for mask calculations\nexport const getContentBounds = (containerWidth: number = SCROLL_CONFIG.horizontal.max) => ({\n  top: 0,\n  bottom: -SCROLL_CONFIG.vertical.max,\n  left: 0,\n  right: -containerWidth,\n});\n\n// Animation phases configuration\nexport type AnimationPhase = {\n  name: string;\n  duration: number;\n};\n\nexport const animationPhases: AnimationPhase[] = [\n  { name: \"scrollDown\", duration: 50 },\n  { name: \"holdBottom\", duration: 10 },\n  { name: \"scrollUp\", duration: 20 },\n  { name: \"scrollRight\", duration: 50 },\n  { name: \"holdRight\", duration: 10 },\n  { name: \"scrollLeft\", duration: 50 },\n  { name: \"holdLeft\", duration: 10 },\n  { name: \"scrollUp\", duration: 40 },\n  { name: \"reset\", duration: 40 },\n];\n\n// Easing functions\nexport const easeOut = (t: number) => 1 - Math.pow(1 - t, 2.5);\nexport const curvedEasing = (t: number) => {\n  const spring = 1 - Math.pow(1 - t, 1.8);\n  return spring * (1 + 0.15 * Math.sin(t * Math.PI));\n};\n\n// Spring configurations\nexport const springConfigs = {\n  content: { stiffness: 180, damping: 25, mass: 0.6 },\n  masks: { stiffness: 400, damping: 30, mass: 0.3 },\n} as const;\n\n// Position-based mask logic\nexport const updateMasksBasedOnPosition = (\n  x: number,\n  y: number,\n  topMaskTarget: MotionValue<number>,\n  bottomMaskTarget: MotionValue<number>,\n  leftMaskTarget: MotionValue<number>,\n  rightMaskTarget: MotionValue<number>,\n  containerWidth: number = SCROLL_CONFIG.horizontal.max\n) => {\n  const threshold = 2; // Smaller threshold for faster mask response\n  const contentBounds = getContentBounds(containerWidth);\n\n  // Top mask: visible when scrolled down (y is negative)\n  const topMaskVisible = y < contentBounds.top - threshold;\n  topMaskTarget.set(topMaskVisible ? 1 : 0);\n\n  // Bottom mask: visible when NOT at bottom (can scroll down more)\n  const bottomMaskVisible = y > contentBounds.bottom + threshold;\n  bottomMaskTarget.set(bottomMaskVisible ? 1 : 0);\n\n  // Left mask: visible when scrolled right (x is negative)\n  const leftMaskVisible = x < contentBounds.left - threshold;\n  leftMaskTarget.set(leftMaskVisible ? 1 : 0);\n\n  // Right mask: visible when NOT at right edge (can scroll right more)\n  const rightMaskVisible = x > contentBounds.right + threshold;\n  rightMaskTarget.set(rightMaskVisible ? 1 : 0);\n};\n\n// Calculate content position for current animation phase\nexport const calculateContentPosition = (\n  currentPhase: AnimationPhase,\n  phaseProgress: number,\n  containerWidth: number = SCROLL_CONFIG.horizontal.max\n): { x: number; y: number } => {\n  const easeProgress = easeOut(phaseProgress);\n  let targetX = 0;\n  let targetY = 0;\n\n  switch (currentPhase.name) {\n    case \"scrollDown\":\n      targetX = 0;\n      targetY = -easeProgress * SCROLL_CONFIG.vertical.max;\n      break;\n    case \"holdBottom\":\n      targetX = 0;\n      targetY = -SCROLL_CONFIG.vertical.hold;\n      break;\n    case \"scrollUp\":\n      targetX = 0;\n      targetY = -SCROLL_CONFIG.vertical.return;\n      break;\n    case \"scrollRight\":\n      const curvedProgress = curvedEasing(phaseProgress);\n      const verticalCurve = Math.sin(phaseProgress * Math.PI) * SCROLL_CONFIG.horizontal.curve;\n      targetX = -curvedProgress * containerWidth;\n      targetY = -SCROLL_CONFIG.vertical.return - verticalCurve;\n      break;\n    case \"holdRight\":\n      targetX = -containerWidth;\n      targetY = -SCROLL_CONFIG.vertical.return;\n      break;\n    case \"scrollLeft\":\n      const leftProgress = curvedEasing(phaseProgress);\n      const leftCurve = Math.sin(phaseProgress * Math.PI) * (SCROLL_CONFIG.horizontal.curve * 0.75);\n      targetX = -containerWidth + leftProgress * containerWidth;\n      targetY = -SCROLL_CONFIG.vertical.return + leftCurve;\n      break;\n    case \"holdLeft\":\n      targetX = 0;\n      targetY = -SCROLL_CONFIG.vertical.return;\n      break;\n    case \"scrollUp\":\n      targetX = 0;\n      targetY = -180 + easeProgress * 180;\n      break;\n    case \"reset\":\n      targetX = 0;\n      targetY = 0;\n      break;\n  }\n\n  return { x: targetX, y: targetY };\n};\n\n// Find current animation phase based on step\nexport const getCurrentPhase = (currentStep: number): { phase: AnimationPhase | null; progress: number } => {\n  let accumulatedDuration = 0;\n  let currentPhase = null;\n  let phaseStart = 0;\n\n  for (const phase of animationPhases) {\n    const phaseEnd = accumulatedDuration + phase.duration;\n    if (currentStep >= accumulatedDuration && currentStep < phaseEnd) {\n      currentPhase = phase;\n      phaseStart = accumulatedDuration;\n      break;\n    }\n    accumulatedDuration = phaseEnd;\n  }\n\n  if (!currentPhase) {\n    return { phase: null, progress: 0 };\n  }\n\n  const phaseProgress = (currentStep - phaseStart) / currentPhase.duration;\n  return { phase: currentPhase, progress: phaseProgress };\n};\n\n// Get total animation duration\nexport const getTotalDuration = () => animationPhases.reduce((sum, phase) => sum + phase.duration, 0);\n"
  },
  {
    "path": "lib/code-highlight.ts",
    "content": "\"use server\";\n\nimport \"server-only\";\n\nimport fs from \"fs/promises\";\nimport path from \"path\";\nimport type { JSX } from \"react\";\nimport { Fragment, jsx, jsxs } from \"react/jsx-runtime\";\nimport { toJsxRuntime } from \"hast-util-to-jsx-runtime\";\nimport { codeToHast, type BundledLanguage } from \"shiki/bundle/web\";\n\nasync function highlight(code: string, lang: BundledLanguage) {\n  const hast = await codeToHast(code, {\n    lang,\n    defaultColor: false,\n    themes: {\n      light: \"github-light\",\n      dark: \"github-dark\",\n    },\n    transformers: [\n      {\n        pre(node) {\n          node.properties[\"class\"] =\n            \"min-w-0 px-4 py-3.5 outline-none has-[[data-highlighted-line]]:px-0 has-[[data-line-numbers]]:px-0 has-[[data-slot=tabs]]:p-0 !bg-transparent\";\n        },\n        code(node) {\n          node.properties[\"data-line-numbers\"] = \"\";\n        },\n        line(node) {\n          node.properties[\"data-line\"] = \"\";\n        },\n      },\n    ],\n  });\n\n  return toJsxRuntime(hast, {\n    Fragment,\n    jsx,\n    jsxs,\n  }) as JSX.Element;\n}\n\n// Simple in-memory cache for component code\nconst codeCache = new Map<string, { code: string; highlightedCode: JSX.Element } | null>();\n\nasync function getComponentCode(\n  name: string,\n  lang: BundledLanguage,\n  customFilePath?: string\n): Promise<{ code: string; highlightedCode: JSX.Element } | null> {\n  const cacheKey = `${name}-${lang}-${customFilePath || \"\"}`;\n\n  // Check cache first\n  if (codeCache.has(cacheKey)) {\n    return codeCache.get(cacheKey)!;\n  }\n\n  try {\n    let rawContent = \"\";\n\n    if (customFilePath) {\n      const filePath = path.join(process.cwd(), customFilePath);\n      rawContent = await fs.readFile(filePath, \"utf-8\");\n    } else {\n      const publicPath = path.join(\"public\", \"r\", `${name}.json`);\n      const filePath = path.join(process.cwd(), publicPath);\n      const fileContent = await fs.readFile(filePath, \"utf-8\");\n      const data = JSON.parse(fileContent);\n      rawContent = data.files[0].content || \"\";\n    }\n\n    if (!rawContent.trim()) {\n      codeCache.set(cacheKey, null);\n      return null;\n    }\n\n    const highlightedCode = await highlight(rawContent, lang);\n    const result = { code: rawContent, highlightedCode };\n\n    // Cache the result\n    codeCache.set(cacheKey, result);\n\n    return result;\n  } catch (error) {\n    console.error(\"Error getting component code\", error);\n    codeCache.set(cacheKey, null);\n    return null;\n  }\n}\n\nexport { highlight, getComponentCode };\n"
  },
  {
    "path": "lib/package-manager-store.ts",
    "content": "\"use client\";\n\nimport { persist } from \"zustand/middleware\";\n\nimport { create } from \"zustand\";\n\ntype PackageManager = \"pnpm\" | \"npm\" | \"bun\" | \"yarn\";\n\ntype PackageManagerState = {\n  selectedPackageManager: PackageManager;\n  isLoading: boolean;\n  setPackageManager: (pm: PackageManager) => void;\n  setLoading: (loading: boolean) => void;\n};\n\nconst usePackageManagerStore = create<PackageManagerState>()(\n  persist(\n    (set) => ({\n      selectedPackageManager: \"pnpm\",\n      isLoading: true,\n      setPackageManager: (pm) => set({ selectedPackageManager: pm }),\n      setLoading: (loading) => set({ isLoading: loading }),\n    }),\n    {\n      name: \"package-manager-store\",\n    }\n  )\n);\n\nexport { usePackageManagerStore, type PackageManager };\n"
  },
  {
    "path": "lib/package-manager-utils.ts",
    "content": "import type { PackageManager } from \"@/lib/package-manager-store\";\n\ntype CommandMapping = {\n  npm: string[];\n  pnpm: string[];\n  yarn: string[];\n  bun: string[];\n};\n\nconst NPX_COMMAND_MAPPINGS: CommandMapping = {\n  npm: [\"npx\"],\n  pnpm: [\"pnpm\", \"dlx\"],\n  yarn: [\"yarn\", \"dlx\"],\n  bun: [\"bun\", \"x\"],\n};\n\nconst PACKAGE_COMMAND_MAPPINGS: CommandMapping = {\n  npm: [\"npm\", \"install\"],\n  pnpm: [\"pnpm\", \"add\"],\n  yarn: [\"yarn\", \"add\"],\n  bun: [\"bun\", \"install\"],\n};\n\nfunction isNpxCommand(command: string): boolean {\n  return command.startsWith(\"npx \");\n}\n\nexport function convertNpmCommand(npmCommand: string): Record<PackageManager, string> {\n  const parts = npmCommand.split(\" \");\n  const isNpx = isNpxCommand(npmCommand);\n\n  if (isNpx) {\n    return convertNpxStyle(parts);\n  }\n\n  const mappings = PACKAGE_COMMAND_MAPPINGS;\n\n  if (!mappings) {\n    // If we don't have specific mappings, keep the command as is for all managers\n    return {\n      npm: npmCommand,\n      pnpm: npmCommand.replace(\"npm\", \"pnpm\"),\n      yarn: npmCommand.replace(\"npm\", \"yarn\"),\n      bun: npmCommand.replace(\"npm\", \"bun\"),\n    };\n  }\n\n  const commands: Record<PackageManager, string> = {} as Record<PackageManager, string>;\n\n  Object.entries(mappings).forEach(([pm, prefixParts]) => {\n    commands[pm as PackageManager] = [...prefixParts, ...parts.slice(2)].join(\" \");\n  });\n\n  return commands;\n}\n\nfunction convertNpxStyle(parts: string[]): Record<PackageManager, string> {\n  const commands: Record<PackageManager, string> = {\n    npm: parts.join(\" \"),\n    pnpm: \"\",\n    yarn: \"\",\n    bun: \"\",\n  };\n\n  Object.entries(NPX_COMMAND_MAPPINGS).forEach(([pm, prefixParts]) => {\n    if (pm === \"npm\") return;\n\n    commands[pm as PackageManager] = [...prefixParts, ...parts.slice(1)].join(\" \");\n  });\n\n  return commands;\n}\n"
  },
  {
    "path": "lib/utils.ts",
    "content": "import { clsx, type ClassValue } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs));\n}\n"
  },
  {
    "path": "lib/variant-store.ts",
    "content": "\"use client\";\n\nimport { persist } from \"zustand/middleware\";\n\nimport { create } from \"zustand\";\n\ntype Variant = \"base\" | \"radix\";\n\ntype VariantState = {\n  currentVariant: Variant;\n  setVariant: (variant: Variant) => void;\n};\n\nconst useVariantStore = create<VariantState>()(\n  persist(\n    (set) => ({\n      currentVariant: \"radix\",\n      setVariant: (variant) =>\n        set({\n          currentVariant: variant,\n        }),\n    }),\n    {\n      name: \"variant-store\",\n    }\n  )\n);\n\nexport { useVariantStore, type Variant };\n"
  },
  {
    "path": "next.config.ts",
    "content": "import type { NextConfig } from \"next\";\n\nconst nextConfig: NextConfig = {\n  images: {\n    remotePatterns: [{ hostname: \"images.unsplash.com\" }],\n  },\n  // Ensure non-imported files read at runtime (e.g. with fs) are included in the output\n  // so they are available on Vercel's serverless filesystem.\n  outputFileTracingIncludes: {\n    \"/(app|pages|api)/**\": [\"./registry/**\", \"./hooks/**\"],\n  },\n};\n\nexport default nextConfig;\n"
  },
  {
    "path": "package.json",
    "content": "{\n  \"name\": \"lina\",\n  \"version\": \"1.0.0\",\n  \"description\": \"Lina is a drop‑in replacement for shadcn/ui's `ScrollArea` with better defaults and a more native feel.\",\n  \"private\": true,\n  \"scripts\": {\n    \"dev\": \"next dev --turbopack\",\n    \"build\": \"next build\",\n    \"start\": \"next start\",\n    \"lint\": \"next lint\",\n    \"lint:fix\": \"next lint --fix\",\n    \"typecheck\": \"tsc --noEmit\",\n    \"registry:build\": \"shadcn build\",\n    \"changeset\": \"changeset\",\n    \"changeset:version\": \"changeset version\",\n    \"changeset:publish\": \"changeset publish\",\n    \"format:write\": \"prettier --write \\\"**/*.{ts,tsx,mdx}\\\" --cache\",\n    \"format:check\": \"prettier --check \\\"**/*.{ts,tsx,mdx}\\\" --cache\"\n  },\n  \"dependencies\": {\n    \"@base-ui-components/react\": \"1.0.0-beta.2\",\n    \"@radix-ui/react-dialog\": \"^1.1.14\",\n    \"@radix-ui/react-scroll-area\": \"^1.2.9\",\n    \"@radix-ui/react-select\": \"^2.2.6\",\n    \"@radix-ui/react-separator\": \"^1.1.7\",\n    \"@radix-ui/react-slot\": \"^1.2.3\",\n    \"@radix-ui/react-tooltip\": \"^1.2.7\",\n    \"class-variance-authority\": \"^0.7.1\",\n    \"clsx\": \"^2.1.1\",\n    \"cmdk\": \"^1.1.1\",\n    \"hast-util-to-jsx-runtime\": \"^2.3.6\",\n    \"lucide-react\": \"^0.536.0\",\n    \"motion\": \"^12.23.12\",\n    \"next\": \"15.4.5\",\n    \"next-themes\": \"^0.4.6\",\n    \"posthog-js\": \"^1.260.2\",\n    \"radix-ui\": \"^1.4.3\",\n    \"react\": \"19.1.0\",\n    \"react-dom\": \"19.1.0\",\n    \"server-only\": \"^0.0.1\",\n    \"shadcn\": \"2.9.3-canary.0\",\n    \"shiki\": \"^3.9.1\",\n    \"tailwind-merge\": \"^3.3.1\",\n    \"vaul\": \"^1.1.2\",\n    \"zustand\": \"^5.0.7\"\n  },\n  \"devDependencies\": {\n    \"@changesets/cli\": \"^2.29.5\",\n    \"@eslint/eslintrc\": \"^3\",\n    \"@ianvs/prettier-plugin-sort-imports\": \"^4.5.1\",\n    \"@tailwindcss/postcss\": \"^4\",\n    \"@types/node\": \"^20\",\n    \"@types/react\": \"^19\",\n    \"@types/react-dom\": \"^19\",\n    \"eslint\": \"^9\",\n    \"eslint-config-next\": \"15.4.5\",\n    \"postcss\": \"^8.5.6\",\n    \"prettier\": \"^3.6.2\",\n    \"prettier-plugin-tailwindcss\": \"^0.6.14\",\n    \"tailwindcss\": \"^4\",\n    \"tw-animate-css\": \"^1.3.6\",\n    \"typescript\": \"^5\"\n  }\n}\n"
  },
  {
    "path": "postcss.config.mjs",
    "content": "const config = {\n  plugins: [\"@tailwindcss/postcss\"],\n};\n\nexport default config;\n"
  },
  {
    "path": "public/r/command-base.json",
    "content": "{\n  \"$schema\": \"https://ui.shadcn.com/schema/registry-item.json\",\n  \"name\": \"command-base\",\n  \"type\": \"registry:ui\",\n  \"title\": \"Command based on Lina's Base UI variant\",\n  \"description\": \"A command component built using Lina's Base UI\",\n  \"dependencies\": [\n    \"lucide-react\",\n    \"cmdk\"\n  ],\n  \"registryDependencies\": [\n    \"button\",\n    \"dialog\",\n    \"https://lina.sameer.sh/r/lina-base.json\"\n  ],\n  \"files\": [\n    {\n      \"path\": \"registry/base-ui/examples/command.tsx\",\n      \"content\": \"\\\"use client\\\";\\r\\n\\r\\nimport * as React from \\\"react\\\";\\r\\nimport { ScrollArea } from \\\"@/registry/base-ui/scroll-area\\\";\\r\\n\\r\\nimport { Command as CommandPrimitive } from \\\"cmdk\\\";\\r\\nimport { SearchIcon } from \\\"lucide-react\\\";\\r\\n\\r\\nimport { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle } from \\\"@/components/ui/dialog\\\";\\r\\n\\r\\nimport { cn } from \\\"@/lib/utils\\\";\\r\\n\\r\\nfunction Command({ className, ...props }: React.ComponentProps<typeof CommandPrimitive>) {\\r\\n  return (\\r\\n    <CommandPrimitive\\r\\n      data-slot=\\\"command\\\"\\r\\n      className={cn(\\\"bg-popover text-popover-foreground flex size-full flex-col overflow-hidden rounded-md\\\", className)}\\r\\n      {...props}\\r\\n    />\\r\\n  );\\r\\n}\\r\\n\\r\\nfunction CommandDialog({\\r\\n  title = \\\"Command Palette\\\",\\r\\n  description = \\\"Search for a command to run...\\\",\\r\\n  children,\\r\\n  ...props\\r\\n}: React.ComponentProps<typeof Dialog> & {\\r\\n  title?: string;\\r\\n  description?: string;\\r\\n}) {\\r\\n  return (\\r\\n    <Dialog {...props}>\\r\\n      <DialogHeader className=\\\"sr-only\\\">\\r\\n        <DialogTitle>{title}</DialogTitle>\\r\\n        <DialogDescription>{description}</DialogDescription>\\r\\n      </DialogHeader>\\r\\n      <DialogContent className=\\\"overflow-hidden p-0 sm:max-w-lg [&>button:last-child]:hidden\\\">\\r\\n        <Command className=\\\"[&_[cmdk-group-heading]]:text-muted-foreground max-h-[100svh] **:data-[slot=command-input-wrapper]:h-12 [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group]]:px-2 [&_[cmdk-input]]:h-12 [&_[cmdk-item]]:px-3 [&_[cmdk-item]]:py-2\\\">\\r\\n          {children}\\r\\n        </Command>\\r\\n      </DialogContent>\\r\\n    </Dialog>\\r\\n  );\\r\\n}\\r\\n\\r\\nfunction CommandInput({ className, ...props }: React.ComponentProps<typeof CommandPrimitive.Input>) {\\r\\n  return (\\r\\n    <div className=\\\"border-input flex items-center border-b px-5\\\" cmdk-input-wrapper=\\\"\\\">\\r\\n      <SearchIcon size={20} className=\\\"text-muted-foreground/80 me-3\\\" />\\r\\n      <CommandPrimitive.Input\\r\\n        data-slot=\\\"command-input-wrapper\\\"\\r\\n        className={cn(\\r\\n          \\\"placeholder:text-muted-foreground/70 flex h-10 w-full rounded-md bg-transparent py-3 text-sm outline-hidden disabled:cursor-not-allowed disabled:opacity-50\\\",\\r\\n          className\\r\\n        )}\\r\\n        {...props}\\r\\n      />\\r\\n    </div>\\r\\n  );\\r\\n}\\r\\n\\r\\nfunction CommandList({ className, ...props }: React.ComponentProps<typeof CommandPrimitive.List>) {\\r\\n  return (\\r\\n    <ScrollArea\\r\\n      maskClassName=\\\"before:from-popover after:from-popover\\\"\\r\\n      className=\\\"flex max-h-full flex-col overflow-hidden\\\"\\r\\n    >\\r\\n      <CommandPrimitive.List data-slot=\\\"command-list\\\" className={cn(\\\"max-h-80 flex-1\\\", className)} {...props} />\\r\\n    </ScrollArea>\\r\\n  );\\r\\n}\\r\\n\\r\\nfunction CommandEmpty({ ...props }: React.ComponentProps<typeof CommandPrimitive.Empty>) {\\r\\n  return <CommandPrimitive.Empty data-slot=\\\"command-empty\\\" className=\\\"py-6 text-center text-sm\\\" {...props} />;\\r\\n}\\r\\n\\r\\nfunction CommandGroup({ className, ...props }: React.ComponentProps<typeof CommandPrimitive.Group>) {\\r\\n  return (\\r\\n    <CommandPrimitive.Group\\r\\n      data-slot=\\\"command-group\\\"\\r\\n      className={cn(\\r\\n        \\\"text-foreground [&_[cmdk-group-heading]]:text-muted-foreground overflow-hidden p-2 [&_[cmdk-group-heading]]:px-3 [&_[cmdk-group-heading]]:py-2 [&_[cmdk-group-heading]]:text-xs [&_[cmdk-group-heading]]:font-medium\\\",\\r\\n        className\\r\\n      )}\\r\\n      {...props}\\r\\n    />\\r\\n  );\\r\\n}\\r\\n\\r\\nfunction CommandSeparator({ className, ...props }: React.ComponentProps<typeof CommandPrimitive.Separator>) {\\r\\n  return (\\r\\n    <CommandPrimitive.Separator\\r\\n      data-slot=\\\"command-separator\\\"\\r\\n      className={cn(\\\"bg-border -mx-1 h-px\\\", className)}\\r\\n      {...props}\\r\\n    />\\r\\n  );\\r\\n}\\r\\n\\r\\nfunction CommandItem({ className, ...props }: React.ComponentProps<typeof CommandPrimitive.Item>) {\\r\\n  return (\\r\\n    <CommandPrimitive.Item\\r\\n      data-slot=\\\"command-item\\\"\\r\\n      className={cn(\\r\\n        \\\"data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground relative flex cursor-default items-center gap-3 rounded-md px-2 py-1.5 text-sm outline-hidden select-none data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0\\\",\\r\\n        className\\r\\n      )}\\r\\n      {...props}\\r\\n    />\\r\\n  );\\r\\n}\\r\\n\\r\\nfunction CommandShortcut({ className, ...props }: React.ComponentProps<\\\"span\\\">) {\\r\\n  return (\\r\\n    <kbd\\r\\n      data-slot=\\\"command-shortcut\\\"\\r\\n      className={cn(\\r\\n        \\\"bg-background text-muted-foreground/70 ms-auto -me-1 inline-flex h-5 max-h-full items-center rounded border px-1 font-[inherit] text-[0.625rem] font-medium\\\",\\r\\n        className\\r\\n      )}\\r\\n      {...props}\\r\\n    />\\r\\n  );\\r\\n}\\r\\n\\r\\nexport {\\r\\n  Command,\\r\\n  CommandDialog,\\r\\n  CommandEmpty,\\r\\n  CommandGroup,\\r\\n  CommandInput,\\r\\n  CommandItem,\\r\\n  CommandList,\\r\\n  CommandSeparator,\\r\\n  CommandShortcut,\\r\\n};\\r\\n\",\n      \"type\": \"registry:ui\"\n    }\n  ]\n}"
  },
  {
    "path": "public/r/command-radix.json",
    "content": "{\n  \"$schema\": \"https://ui.shadcn.com/schema/registry-item.json\",\n  \"name\": \"command-radix\",\n  \"type\": \"registry:ui\",\n  \"title\": \"Command based on Lina's Radix UI variant\",\n  \"description\": \"A command component built using Lina's Radix UI\",\n  \"dependencies\": [\n    \"lucide-react\",\n    \"cmdk\"\n  ],\n  \"registryDependencies\": [\n    \"button\",\n    \"dialog\",\n    \"https://lina.sameer.sh/r/lina-radix.json\"\n  ],\n  \"files\": [\n    {\n      \"path\": \"registry/radix-ui/examples/command.tsx\",\n      \"content\": \"\\\"use client\\\";\\r\\n\\r\\nimport * as React from \\\"react\\\";\\r\\nimport { ScrollArea } from \\\"@/registry/radix-ui/scroll-area\\\";\\r\\n\\r\\nimport { Command as CommandPrimitive } from \\\"cmdk\\\";\\r\\nimport { SearchIcon } from \\\"lucide-react\\\";\\r\\n\\r\\nimport { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle } from \\\"@/components/ui/dialog\\\";\\r\\n\\r\\nimport { cn } from \\\"@/lib/utils\\\";\\r\\n\\r\\nfunction Command({ className, ...props }: React.ComponentProps<typeof CommandPrimitive>) {\\r\\n  return (\\r\\n    <CommandPrimitive\\r\\n      data-slot=\\\"command\\\"\\r\\n      className={cn(\\\"bg-popover text-popover-foreground flex size-full flex-col overflow-hidden rounded-md\\\", className)}\\r\\n      {...props}\\r\\n    />\\r\\n  );\\r\\n}\\r\\n\\r\\nfunction CommandDialog({\\r\\n  title = \\\"Command Palette\\\",\\r\\n  description = \\\"Search for a command to run...\\\",\\r\\n  children,\\r\\n  ...props\\r\\n}: React.ComponentProps<typeof Dialog> & {\\r\\n  title?: string;\\r\\n  description?: string;\\r\\n}) {\\r\\n  return (\\r\\n    <Dialog {...props}>\\r\\n      <DialogHeader className=\\\"sr-only\\\">\\r\\n        <DialogTitle>{title}</DialogTitle>\\r\\n        <DialogDescription>{description}</DialogDescription>\\r\\n      </DialogHeader>\\r\\n      <DialogContent className=\\\"overflow-hidden p-0 sm:max-w-lg [&>button:last-child]:hidden\\\">\\r\\n        <Command className=\\\"[&_[cmdk-group-heading]]:text-muted-foreground max-h-[100svh] **:data-[slot=command-input-wrapper]:h-12 [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group]]:px-2 [&_[cmdk-input]]:h-12 [&_[cmdk-item]]:px-3 [&_[cmdk-item]]:py-2\\\">\\r\\n          {children}\\r\\n        </Command>\\r\\n      </DialogContent>\\r\\n    </Dialog>\\r\\n  );\\r\\n}\\r\\n\\r\\nfunction CommandInput({ className, ...props }: React.ComponentProps<typeof CommandPrimitive.Input>) {\\r\\n  return (\\r\\n    <div className=\\\"border-input flex items-center border-b px-5\\\" cmdk-input-wrapper=\\\"\\\">\\r\\n      <SearchIcon size={20} className=\\\"text-muted-foreground/80 me-3\\\" />\\r\\n      <CommandPrimitive.Input\\r\\n        data-slot=\\\"command-input-wrapper\\\"\\r\\n        className={cn(\\r\\n          \\\"placeholder:text-muted-foreground/70 flex h-10 w-full rounded-md bg-transparent py-3 text-sm outline-hidden disabled:cursor-not-allowed disabled:opacity-50\\\",\\r\\n          className\\r\\n        )}\\r\\n        {...props}\\r\\n      />\\r\\n    </div>\\r\\n  );\\r\\n}\\r\\n\\r\\nfunction CommandList({ className, ...props }: React.ComponentProps<typeof CommandPrimitive.List>) {\\r\\n  return (\\r\\n    <ScrollArea\\r\\n      maskClassName=\\\"before:from-popover after:from-popover\\\"\\r\\n      className=\\\"flex max-h-full flex-col overflow-hidden\\\"\\r\\n    >\\r\\n      <CommandPrimitive.List data-slot=\\\"command-list\\\" className={cn(\\\"max-h-80 flex-1\\\", className)} {...props} />\\r\\n    </ScrollArea>\\r\\n  );\\r\\n}\\r\\n\\r\\nfunction CommandEmpty({ ...props }: React.ComponentProps<typeof CommandPrimitive.Empty>) {\\r\\n  return <CommandPrimitive.Empty data-slot=\\\"command-empty\\\" className=\\\"py-6 text-center text-sm\\\" {...props} />;\\r\\n}\\r\\n\\r\\nfunction CommandGroup({ className, ...props }: React.ComponentProps<typeof CommandPrimitive.Group>) {\\r\\n  return (\\r\\n    <CommandPrimitive.Group\\r\\n      data-slot=\\\"command-group\\\"\\r\\n      className={cn(\\r\\n        \\\"text-foreground [&_[cmdk-group-heading]]:text-muted-foreground overflow-hidden p-2 [&_[cmdk-group-heading]]:px-3 [&_[cmdk-group-heading]]:py-2 [&_[cmdk-group-heading]]:text-xs [&_[cmdk-group-heading]]:font-medium\\\",\\r\\n        className\\r\\n      )}\\r\\n      {...props}\\r\\n    />\\r\\n  );\\r\\n}\\r\\n\\r\\nfunction CommandSeparator({ className, ...props }: React.ComponentProps<typeof CommandPrimitive.Separator>) {\\r\\n  return (\\r\\n    <CommandPrimitive.Separator\\r\\n      data-slot=\\\"command-separator\\\"\\r\\n      className={cn(\\\"bg-border -mx-1 h-px\\\", className)}\\r\\n      {...props}\\r\\n    />\\r\\n  );\\r\\n}\\r\\n\\r\\nfunction CommandItem({ className, ...props }: React.ComponentProps<typeof CommandPrimitive.Item>) {\\r\\n  return (\\r\\n    <CommandPrimitive.Item\\r\\n      data-slot=\\\"command-item\\\"\\r\\n      className={cn(\\r\\n        \\\"data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground relative flex cursor-default items-center gap-3 rounded-md px-2 py-1.5 text-sm outline-hidden select-none data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0\\\",\\r\\n        className\\r\\n      )}\\r\\n      {...props}\\r\\n    />\\r\\n  );\\r\\n}\\r\\n\\r\\nfunction CommandShortcut({ className, ...props }: React.ComponentProps<\\\"span\\\">) {\\r\\n  return (\\r\\n    <kbd\\r\\n      data-slot=\\\"command-shortcut\\\"\\r\\n      className={cn(\\r\\n        \\\"bg-background text-muted-foreground/70 ms-auto -me-1 inline-flex h-5 max-h-full items-center rounded border px-1 font-[inherit] text-[0.625rem] font-medium\\\",\\r\\n        className\\r\\n      )}\\r\\n      {...props}\\r\\n    />\\r\\n  );\\r\\n}\\r\\n\\r\\nexport {\\r\\n  Command,\\r\\n  CommandDialog,\\r\\n  CommandEmpty,\\r\\n  CommandGroup,\\r\\n  CommandInput,\\r\\n  CommandItem,\\r\\n  CommandList,\\r\\n  CommandSeparator,\\r\\n  CommandShortcut,\\r\\n};\\r\\n\",\n      \"type\": \"registry:ui\"\n    }\n  ]\n}"
  },
  {
    "path": "public/r/horizontal-scroll-demo-base.json",
    "content": "{\n  \"$schema\": \"https://ui.shadcn.com/schema/registry-item.json\",\n  \"name\": \"horizontal-scroll-demo-base\",\n  \"type\": \"registry:component\",\n  \"title\": \"Horizontal Scroll Area Base Demo\",\n  \"description\": \"A demo showcasing the horizontal scroll area component using Lina's Base UI\",\n  \"registryDependencies\": [\n    \"https://lina.sameer.sh/r/lina-base.json\"\n  ],\n  \"files\": [\n    {\n      \"path\": \"registry/base-ui/examples/horizontal-scroll.tsx\",\n      \"content\": \"import Image from \\\"next/image\\\";\\r\\nimport { ScrollArea, ScrollBar } from \\\"@/registry/base-ui/scroll-area\\\";\\r\\n\\r\\nexport interface Artwork {\\r\\n  artist: string;\\r\\n  art: string;\\r\\n}\\r\\n\\r\\nconst works: Artwork[] = [\\r\\n  {\\r\\n    artist: \\\"Ornella Binni\\\",\\r\\n    art: \\\"https://images.unsplash.com/photo-1465869185982-5a1a7522cbcb?auto=format&fit=crop&w=300&q=80\\\",\\r\\n  },\\r\\n  {\\r\\n    artist: \\\"Tom Byrom\\\",\\r\\n    art: \\\"https://images.unsplash.com/photo-1548516173-3cabfa4607e9?auto=format&fit=crop&w=300&q=80\\\",\\r\\n  },\\r\\n  {\\r\\n    artist: \\\"Vladimir Malyavko\\\",\\r\\n    art: \\\"https://images.unsplash.com/photo-1494337480532-3725c85fd2ab?auto=format&fit=crop&w=300&q=80\\\",\\r\\n  },\\r\\n];\\r\\n\\r\\nexport function ScrollAreaHorizontalDemo() {\\r\\n  return (\\r\\n    <ScrollArea className=\\\"bg-background w-96 rounded-md border whitespace-nowrap\\\">\\r\\n      <div className=\\\"flex w-max space-x-4 p-4\\\">\\r\\n        {works.map((artwork) => (\\r\\n          <figure key={artwork.artist} className=\\\"shrink-0\\\">\\r\\n            <div className=\\\"overflow-hidden rounded-md\\\">\\r\\n              <Image\\r\\n                src={artwork.art}\\r\\n                alt={`Photo by ${artwork.artist}`}\\r\\n                className=\\\"aspect-[3/4] h-fit w-fit object-cover\\\"\\r\\n                width={300}\\r\\n                height={400}\\r\\n              />\\r\\n            </div>\\r\\n            <figcaption className=\\\"text-muted-foreground pt-2 text-xs\\\">\\r\\n              Photo by <span className=\\\"text-foreground font-semibold\\\">{artwork.artist}</span>\\r\\n            </figcaption>\\r\\n          </figure>\\r\\n        ))}\\r\\n      </div>\\r\\n      <ScrollBar orientation=\\\"horizontal\\\" />\\r\\n    </ScrollArea>\\r\\n  );\\r\\n}\\r\\n\",\n      \"type\": \"registry:component\"\n    }\n  ]\n}"
  },
  {
    "path": "public/r/horizontal-scroll-demo-radix.json",
    "content": "{\n  \"$schema\": \"https://ui.shadcn.com/schema/registry-item.json\",\n  \"name\": \"horizontal-scroll-demo-radix\",\n  \"type\": \"registry:component\",\n  \"title\": \"Horizontal Scroll Area Radix Demo\",\n  \"description\": \"A demo showcasing the horizontal scroll area component using Lina's Radix UI\",\n  \"registryDependencies\": [\n    \"https://lina.sameer.sh/r/lina-radix.json\"\n  ],\n  \"files\": [\n    {\n      \"path\": \"registry/radix-ui/examples/horizontal-scroll.tsx\",\n      \"content\": \"import Image from \\\"next/image\\\";\\r\\nimport { ScrollArea, ScrollBar } from \\\"@/registry/radix-ui/scroll-area\\\";\\r\\n\\r\\nexport interface Artwork {\\r\\n  artist: string;\\r\\n  art: string;\\r\\n}\\r\\n\\r\\nconst works: Artwork[] = [\\r\\n  {\\r\\n    artist: \\\"Ornella Binni\\\",\\r\\n    art: \\\"https://images.unsplash.com/photo-1465869185982-5a1a7522cbcb?auto=format&fit=crop&w=300&q=80\\\",\\r\\n  },\\r\\n  {\\r\\n    artist: \\\"Tom Byrom\\\",\\r\\n    art: \\\"https://images.unsplash.com/photo-1548516173-3cabfa4607e9?auto=format&fit=crop&w=300&q=80\\\",\\r\\n  },\\r\\n  {\\r\\n    artist: \\\"Vladimir Malyavko\\\",\\r\\n    art: \\\"https://images.unsplash.com/photo-1494337480532-3725c85fd2ab?auto=format&fit=crop&w=300&q=80\\\",\\r\\n  },\\r\\n];\\r\\n\\r\\nexport function ScrollAreaHorizontalDemo() {\\r\\n  return (\\r\\n    <ScrollArea className=\\\"bg-background w-96 rounded-md border whitespace-nowrap\\\">\\r\\n      <div className=\\\"flex w-max space-x-4 p-4\\\">\\r\\n        {works.map((artwork) => (\\r\\n          <figure key={artwork.artist} className=\\\"shrink-0\\\">\\r\\n            <div className=\\\"overflow-hidden rounded-md\\\">\\r\\n              <Image\\r\\n                src={artwork.art}\\r\\n                alt={`Photo by ${artwork.artist}`}\\r\\n                className=\\\"aspect-[3/4] h-fit w-fit object-cover\\\"\\r\\n                width={300}\\r\\n                height={400}\\r\\n              />\\r\\n            </div>\\r\\n            <figcaption className=\\\"text-muted-foreground pt-2 text-xs\\\">\\r\\n              Photo by <span className=\\\"text-foreground font-semibold\\\">{artwork.artist}</span>\\r\\n            </figcaption>\\r\\n          </figure>\\r\\n        ))}\\r\\n      </div>\\r\\n      <ScrollBar orientation=\\\"horizontal\\\" />\\r\\n    </ScrollArea>\\r\\n  );\\r\\n}\\r\\n\",\n      \"type\": \"registry:component\"\n    }\n  ]\n}"
  },
  {
    "path": "public/r/lina-base.json",
    "content": "{\n  \"$schema\": \"https://ui.shadcn.com/schema/registry-item.json\",\n  \"name\": \"lina-base\",\n  \"type\": \"registry:ui\",\n  \"title\": \"Base UI Adaptive Scroll Area\",\n  \"description\": \"A responsive scroll area that feel native on touch devices, offereing custom styling and enchanced interactions where it matter most.\",\n  \"dependencies\": [\n    \"@base-ui-components/react\"\n  ],\n  \"devDependencies\": [\n    \"tw-animate-css\"\n  ],\n  \"files\": [\n    {\n      \"path\": \"registry/base-ui/scroll-area.tsx\",\n      \"content\": \"\\\"use client\\\";\\r\\n\\r\\nimport * as React from \\\"react\\\";\\r\\n\\r\\nimport { ScrollArea as ScrollAreaPrimitive } from \\\"@base-ui-components/react/scroll-area\\\";\\r\\n\\r\\nimport { cn } from \\\"@/lib/utils\\\";\\r\\n\\r\\nimport { useTouchPrimary } from \\\"@/hooks/use-has-primary-touch\\\";\\r\\n\\r\\ntype Mask = {\\r\\n  top: boolean;\\r\\n  bottom: boolean;\\r\\n  left: boolean;\\r\\n  right: boolean;\\r\\n};\\r\\n\\r\\nexport type ScrollAreaContextProps = {\\r\\n  isTouch: boolean;\\r\\n  type: \\\"auto\\\" | \\\"always\\\" | \\\"scroll\\\" | \\\"hover\\\";\\r\\n};\\r\\n\\r\\nconst ScrollAreaContext = React.createContext<ScrollAreaContextProps>({\\r\\n  isTouch: false,\\r\\n  type: \\\"hover\\\",\\r\\n});\\r\\n\\r\\nconst ScrollArea = React.forwardRef<\\r\\n  React.ComponentRef<typeof ScrollAreaPrimitive.Root>,\\r\\n  React.ComponentPropsWithoutRef<typeof ScrollAreaPrimitive.Root> & {\\r\\n    type?: \\\"auto\\\" | \\\"always\\\" | \\\"scroll\\\" | \\\"hover\\\";\\r\\n    viewportClassName?: string;\\r\\n    /**\\r\\n     * `maskHeight` is the height of the mask in pixels.\\r\\n     * pass `0` to disable the mask\\r\\n     * @default 30\\r\\n     */\\r\\n    maskHeight?: number;\\r\\n    maskClassName?: string;\\r\\n  }\\r\\n>(({ className, children, type = \\\"hover\\\", maskHeight = 30, maskClassName, viewportClassName, ...props }, ref) => {\\r\\n  const [showMask, setShowMask] = React.useState<Mask>({\\r\\n    top: false,\\r\\n    bottom: false,\\r\\n    left: false,\\r\\n    right: false,\\r\\n  });\\r\\n\\r\\n  const viewportRef = React.useRef<HTMLDivElement>(null);\\r\\n  const isTouch = useTouchPrimary();\\r\\n\\r\\n  const checkScrollability = React.useCallback(() => {\\r\\n    const element = viewportRef.current;\\r\\n    if (!element) return;\\r\\n\\r\\n    const { scrollTop, scrollLeft, scrollWidth, clientWidth, scrollHeight, clientHeight } = element;\\r\\n    setShowMask((prev) => ({\\r\\n      ...prev,\\r\\n      top: scrollTop > 0,\\r\\n      bottom: scrollTop + clientHeight < scrollHeight - 1,\\r\\n      left: scrollLeft > 0,\\r\\n      right: scrollLeft + clientWidth < scrollWidth - 1,\\r\\n    }));\\r\\n  }, []);\\r\\n\\r\\n  React.useEffect(() => {\\r\\n    if (typeof window === \\\"undefined\\\") return;\\r\\n\\r\\n    const element = viewportRef.current;\\r\\n    if (!element) return;\\r\\n\\r\\n    const controller = new AbortController();\\r\\n    const { signal } = controller;\\r\\n\\r\\n    const resizeObserver = new ResizeObserver(checkScrollability);\\r\\n    resizeObserver.observe(element);\\r\\n\\r\\n    element.addEventListener(\\\"scroll\\\", checkScrollability, { signal });\\r\\n    window.addEventListener(\\\"resize\\\", checkScrollability, { signal });\\r\\n\\r\\n    // Run an initial check whenever dependencies change (including pointer mode)\\r\\n    checkScrollability();\\r\\n\\r\\n    return () => {\\r\\n      controller.abort();\\r\\n      resizeObserver.disconnect();\\r\\n    };\\r\\n  }, [checkScrollability, isTouch]);\\r\\n\\r\\n  return (\\r\\n    <ScrollAreaContext.Provider value={{ isTouch, type }}>\\r\\n      {isTouch ? (\\r\\n        <div\\r\\n          ref={ref}\\r\\n          {...props}\\r\\n          role=\\\"group\\\"\\r\\n          data-slot=\\\"scroll-area\\\"\\r\\n          aria-roledescription=\\\"scroll area\\\"\\r\\n          className={cn(\\\"relative overflow-hidden\\\", className)}\\r\\n        >\\r\\n          <div ref={viewportRef} className={cn(\\\"size-full overflow-auto\\\", viewportClassName)} tabIndex={0}>\\r\\n            {children}\\r\\n          </div>\\r\\n          {maskHeight > 0 && <ScrollMask showMask={showMask} className={maskClassName} maskHeight={maskHeight} />}\\r\\n        </div>\\r\\n      ) : (\\r\\n        <ScrollAreaPrimitive.Root\\r\\n          ref={ref}\\r\\n          data-slot=\\\"scroll-area\\\"\\r\\n          className={cn(\\\"relative overflow-hidden\\\", viewportClassName, className)}\\r\\n          {...props}\\r\\n        >\\r\\n          <ScrollAreaPrimitive.Viewport\\r\\n            ref={viewportRef}\\r\\n            data-slot=\\\"scroll-area-viewport\\\"\\r\\n            className={cn(\\\"focus-ring size-full rounded-[inherit]\\\", viewportClassName)}\\r\\n          >\\r\\n            {children}\\r\\n          </ScrollAreaPrimitive.Viewport>\\r\\n          <ScrollBar />\\r\\n          <ScrollAreaPrimitive.Corner />\\r\\n          {maskHeight > 0 && <ScrollMask showMask={showMask} className={maskClassName} maskHeight={maskHeight} />}\\r\\n        </ScrollAreaPrimitive.Root>\\r\\n      )}\\r\\n    </ScrollAreaContext.Provider>\\r\\n  );\\r\\n});\\r\\n\\r\\nScrollArea.displayName = ScrollAreaPrimitive.Root.displayName;\\r\\n\\r\\nconst ScrollBar = React.forwardRef<\\r\\n  React.ComponentRef<typeof ScrollAreaPrimitive.Scrollbar>,\\r\\n  React.ComponentPropsWithoutRef<typeof ScrollAreaPrimitive.Scrollbar>\\r\\n>(({ className, orientation = \\\"vertical\\\", ...props }, ref) => {\\r\\n  const { isTouch, type } = React.useContext(ScrollAreaContext);\\r\\n\\r\\n  if (isTouch) return null;\\r\\n\\r\\n  return (\\r\\n    <ScrollAreaPrimitive.Scrollbar\\r\\n      ref={ref}\\r\\n      orientation={orientation}\\r\\n      data-slot=\\\"scroll-area-scrollbar\\\"\\r\\n      className={cn(\\r\\n        \\\"hover:bg-muted dark:hover:bg-muted/50 flex touch-none p-px transition-[colors,opacity] duration-150 ease-out select-none\\\",\\r\\n        orientation === \\\"vertical\\\" && \\\"h-full w-2.5 border-l border-l-transparent\\\",\\r\\n        orientation === \\\"horizontal\\\" && \\\"h-2.5 flex-col border-t border-t-transparent px-1 pr-1.25\\\",\\r\\n        type === \\\"hover\\\" && \\\"opacity-0 data-[hovering]:opacity-100\\\",\\r\\n        type === \\\"scroll\\\" && \\\"opacity-0 data-[scrolling]:opacity-100\\\",\\r\\n        className\\r\\n      )}\\r\\n      {...props}\\r\\n    >\\r\\n      <ScrollAreaPrimitive.Thumb\\r\\n        data-slot=\\\"scroll-area-thumb\\\"\\r\\n        className={cn(\\r\\n          \\\"bg-border relative flex-1 rounded-full transition-[scale]\\\",\\r\\n          orientation === \\\"vertical\\\" && \\\"my-1 active:scale-y-95\\\",\\r\\n          orientation === \\\"horizontal\\\" && \\\"active:scale-x-98\\\"\\r\\n        )}\\r\\n      />\\r\\n    </ScrollAreaPrimitive.Scrollbar>\\r\\n  );\\r\\n});\\r\\n\\r\\nScrollBar.displayName = ScrollAreaPrimitive.Scrollbar.displayName;\\r\\n\\r\\nconst ScrollMask = ({\\r\\n  showMask,\\r\\n  maskHeight,\\r\\n  className,\\r\\n  ...props\\r\\n}: React.ComponentProps<\\\"div\\\"> & {\\r\\n  showMask: Mask;\\r\\n  maskHeight: number;\\r\\n}) => {\\r\\n  return (\\r\\n    <>\\r\\n      <div\\r\\n        {...props}\\r\\n        aria-hidden=\\\"true\\\"\\r\\n        style={\\r\\n          {\\r\\n            \\\"--top-fade-height\\\": showMask.top ? `${maskHeight}px` : \\\"0px\\\",\\r\\n            \\\"--bottom-fade-height\\\": showMask.bottom ? `${maskHeight}px` : \\\"0px\\\",\\r\\n          } as React.CSSProperties\\r\\n        }\\r\\n        className={cn(\\r\\n          \\\"pointer-events-none absolute inset-0 z-10\\\",\\r\\n          \\\"before:absolute before:inset-x-0 before:top-0 before:transition-[height,opacity] before:duration-300 before:content-['']\\\",\\r\\n          \\\"after:absolute after:inset-x-0 after:bottom-0 after:transition-[height,opacity] after:duration-300 after:content-['']\\\",\\r\\n          \\\"before:h-(--top-fade-height) after:h-(--bottom-fade-height)\\\",\\r\\n          showMask.top ? \\\"before:opacity-100\\\" : \\\"before:opacity-0\\\",\\r\\n          showMask.bottom ? \\\"after:opacity-100\\\" : \\\"after:opacity-0\\\",\\r\\n          \\\"before:from-background before:bg-gradient-to-b before:to-transparent\\\",\\r\\n          \\\"after:from-background after:bg-gradient-to-t after:to-transparent\\\",\\r\\n          className\\r\\n        )}\\r\\n      />\\r\\n      <div\\r\\n        {...props}\\r\\n        aria-hidden=\\\"true\\\"\\r\\n        style={\\r\\n          {\\r\\n            \\\"--left-fade-width\\\": showMask.left ? `${maskHeight}px` : \\\"0px\\\",\\r\\n            \\\"--right-fade-width\\\": showMask.right ? `${maskHeight}px` : \\\"0px\\\",\\r\\n          } as React.CSSProperties\\r\\n        }\\r\\n        className={cn(\\r\\n          \\\"pointer-events-none absolute inset-0 z-10\\\",\\r\\n          \\\"before:absolute before:inset-y-0 before:left-0 before:transition-[width,opacity] before:duration-300 before:content-['']\\\",\\r\\n          \\\"after:absolute after:inset-y-0 after:right-0 after:transition-[width,opacity] after:duration-300 after:content-['']\\\",\\r\\n          \\\"before:w-(--left-fade-width) after:w-(--right-fade-width)\\\",\\r\\n          showMask.left ? \\\"before:opacity-100\\\" : \\\"before:opacity-0\\\",\\r\\n          showMask.right ? \\\"after:opacity-100\\\" : \\\"after:opacity-0\\\",\\r\\n          \\\"before:from-background before:bg-gradient-to-r before:to-transparent\\\",\\r\\n          \\\"after:from-background after:bg-gradient-to-l after:to-transparent\\\",\\r\\n          className\\r\\n        )}\\r\\n      />\\r\\n    </>\\r\\n  );\\r\\n};\\r\\n\\r\\nexport { ScrollArea, ScrollBar };\\r\\n\",\n      \"type\": \"registry:ui\"\n    },\n    {\n      \"path\": \"hooks/use-has-primary-touch.tsx\",\n      \"content\": \"import { useEffect, useState } from \\\"react\\\";\\r\\n\\r\\nexport function useTouchPrimary() {\\r\\n  const [isTouchPrimary, setIsTouchPrimary] = useState(false);\\r\\n\\r\\n  useEffect(() => {\\r\\n    if (typeof window === \\\"undefined\\\") return;\\r\\n\\r\\n    const controller = new AbortController();\\r\\n    const { signal } = controller;\\r\\n\\r\\n    const handleTouch = () => {\\r\\n      const hasTouch = \\\"ontouchstart\\\" in window || navigator.maxTouchPoints > 0;\\r\\n      const prefersTouch = window.matchMedia(\\\"(pointer: coarse)\\\").matches;\\r\\n      setIsTouchPrimary(hasTouch && prefersTouch);\\r\\n    };\\r\\n\\r\\n    const mq = window.matchMedia(\\\"(pointer: coarse)\\\");\\r\\n    mq.addEventListener(\\\"change\\\", handleTouch, { signal });\\r\\n    window.addEventListener(\\\"pointerdown\\\", handleTouch, { signal });\\r\\n\\r\\n    handleTouch();\\r\\n\\r\\n    return () => controller.abort();\\r\\n  }, []);\\r\\n\\r\\n  return isTouchPrimary;\\r\\n}\\r\\n\",\n      \"type\": \"registry:ui\"\n    }\n  ]\n}"
  },
  {
    "path": "public/r/lina-radix.json",
    "content": "{\n  \"$schema\": \"https://ui.shadcn.com/schema/registry-item.json\",\n  \"name\": \"lina-radix\",\n  \"type\": \"registry:ui\",\n  \"title\": \"Radix Adaptive Scroll Area\",\n  \"description\": \"A responsive scroll area that feels native on touch devices, offering custom styling and enhanced interactions where it matters most.\",\n  \"dependencies\": [\n    \"@radix-ui/react-scroll-area\"\n  ],\n  \"devDependencies\": [\n    \"tw-animate-css\"\n  ],\n  \"files\": [\n    {\n      \"path\": \"registry/radix-ui/scroll-area.tsx\",\n      \"content\": \"\\\"use client\\\";\\r\\n\\r\\nimport * as React from \\\"react\\\";\\r\\n\\r\\nimport * as ScrollAreaPrimitive from \\\"@radix-ui/react-scroll-area\\\";\\r\\n\\r\\nimport { cn } from \\\"@/lib/utils\\\";\\r\\n\\r\\nimport { useTouchPrimary } from \\\"@/hooks/use-has-primary-touch\\\";\\r\\n\\r\\nconst ScrollAreaContext = React.createContext<boolean>(false);\\r\\ntype Mask = {\\r\\n  top: boolean;\\r\\n  bottom: boolean;\\r\\n  left: boolean;\\r\\n  right: boolean;\\r\\n};\\r\\n\\r\\nconst ScrollArea = React.forwardRef<\\r\\n  React.ComponentRef<typeof ScrollAreaPrimitive.Root>,\\r\\n  React.ComponentPropsWithoutRef<typeof ScrollAreaPrimitive.Root> & {\\r\\n    viewportClassName?: string;\\r\\n    /**\\r\\n     * `maskHeight` is the height of the mask in pixels.\\r\\n     * pass `0` to disable the mask\\r\\n     * @default 30\\r\\n     */\\r\\n    maskHeight?: number;\\r\\n    maskClassName?: string;\\r\\n  }\\r\\n>(({ className, children, scrollHideDelay = 0, viewportClassName, maskClassName, maskHeight = 30, ...props }, ref) => {\\r\\n  const [showMask, setShowMask] = React.useState<Mask>({\\r\\n    top: false,\\r\\n    bottom: false,\\r\\n    left: false,\\r\\n    right: false,\\r\\n  });\\r\\n  const viewportRef = React.useRef<HTMLDivElement>(null);\\r\\n  const isTouch = useTouchPrimary();\\r\\n\\r\\n  const checkScrollability = React.useCallback(() => {\\r\\n    const element = viewportRef.current;\\r\\n    if (!element) return;\\r\\n\\r\\n    const { scrollTop, scrollLeft, scrollWidth, clientWidth, scrollHeight, clientHeight } = element;\\r\\n    setShowMask((prev) => ({\\r\\n      ...prev,\\r\\n      top: scrollTop > 0,\\r\\n      bottom: scrollTop + clientHeight < scrollHeight - 1,\\r\\n      left: scrollLeft > 0,\\r\\n      right: scrollLeft + clientWidth < scrollWidth - 1,\\r\\n    }));\\r\\n  }, []);\\r\\n\\r\\n  React.useEffect(() => {\\r\\n    if (typeof window === \\\"undefined\\\") return;\\r\\n\\r\\n    const element = viewportRef.current;\\r\\n    if (!element) return;\\r\\n\\r\\n    const controller = new AbortController();\\r\\n    const { signal } = controller;\\r\\n\\r\\n    const resizeObserver = new ResizeObserver(checkScrollability);\\r\\n    resizeObserver.observe(element);\\r\\n\\r\\n    element.addEventListener(\\\"scroll\\\", checkScrollability, { signal });\\r\\n    window.addEventListener(\\\"resize\\\", checkScrollability, { signal });\\r\\n\\r\\n    // Run an initial check whenever dependencies change (including pointer mode)\\r\\n    checkScrollability();\\r\\n\\r\\n    return () => {\\r\\n      controller.abort();\\r\\n      resizeObserver.disconnect();\\r\\n    };\\r\\n  }, [checkScrollability, isTouch]);\\r\\n\\r\\n  return (\\r\\n    <ScrollAreaContext.Provider value={isTouch}>\\r\\n      {isTouch ? (\\r\\n        <div\\r\\n          ref={ref}\\r\\n          role=\\\"group\\\"\\r\\n          data-slot=\\\"scroll-area\\\"\\r\\n          aria-roledescription=\\\"scroll area\\\"\\r\\n          className={cn(\\\"relative overflow-hidden\\\", className)}\\r\\n          {...props}\\r\\n        >\\r\\n          <div\\r\\n            ref={viewportRef}\\r\\n            data-slot=\\\"scroll-area-viewport\\\"\\r\\n            className={cn(\\\"size-full overflow-auto rounded-[inherit]\\\", viewportClassName)}\\r\\n            tabIndex={0}\\r\\n          >\\r\\n            {children}\\r\\n          </div>\\r\\n\\r\\n          {maskHeight > 0 && <ScrollMask showMask={showMask} className={maskClassName} maskHeight={maskHeight} />}\\r\\n        </div>\\r\\n      ) : (\\r\\n        <ScrollAreaPrimitive.Root\\r\\n          ref={ref}\\r\\n          data-slot=\\\"scroll-area\\\"\\r\\n          scrollHideDelay={scrollHideDelay}\\r\\n          className={cn(\\\"relative overflow-hidden\\\", className)}\\r\\n          {...props}\\r\\n        >\\r\\n          <ScrollAreaPrimitive.Viewport\\r\\n            ref={viewportRef}\\r\\n            data-slot=\\\"scroll-area-viewport\\\"\\r\\n            className={cn(\\\"size-full rounded-[inherit]\\\", viewportClassName)}\\r\\n          >\\r\\n            {children}\\r\\n          </ScrollAreaPrimitive.Viewport>\\r\\n\\r\\n          {maskHeight > 0 && <ScrollMask showMask={showMask} className={maskClassName} maskHeight={maskHeight} />}\\r\\n          <ScrollBar />\\r\\n          <ScrollAreaPrimitive.Corner />\\r\\n        </ScrollAreaPrimitive.Root>\\r\\n      )}\\r\\n    </ScrollAreaContext.Provider>\\r\\n  );\\r\\n});\\r\\n\\r\\nScrollArea.displayName = ScrollAreaPrimitive.Root.displayName;\\r\\n\\r\\nconst ScrollBar = React.forwardRef<\\r\\n  React.ComponentRef<typeof ScrollAreaPrimitive.ScrollAreaScrollbar>,\\r\\n  React.ComponentPropsWithoutRef<typeof ScrollAreaPrimitive.ScrollAreaScrollbar>\\r\\n>(({ className, orientation = \\\"vertical\\\", ...props }, ref) => {\\r\\n  const isTouch = React.useContext(ScrollAreaContext);\\r\\n\\r\\n  if (isTouch) return null;\\r\\n\\r\\n  return (\\r\\n    <ScrollAreaPrimitive.ScrollAreaScrollbar\\r\\n      ref={ref}\\r\\n      orientation={orientation}\\r\\n      data-slot=\\\"scroll-area-scrollbar\\\"\\r\\n      className={cn(\\r\\n        \\\"hover:bg-muted dark:hover:bg-muted/50 data-[state=visible]:fade-in-0 data-[state=hidden]:fade-out-0 data-[state=visible]:animate-in data-[state=hidden]:animate-out flex touch-none p-px transition-[colors] duration-150 select-none\\\",\\r\\n        orientation === \\\"vertical\\\" && \\\"h-full w-2.5 border-l border-l-transparent\\\",\\r\\n        orientation === \\\"horizontal\\\" && \\\"h-2.5 flex-col border-t border-t-transparent px-1 pr-1.25\\\",\\r\\n        className\\r\\n      )}\\r\\n      {...props}\\r\\n    >\\r\\n      <ScrollAreaPrimitive.ScrollAreaThumb\\r\\n        data-slot=\\\"scroll-area-thumb\\\"\\r\\n        className={cn(\\r\\n          \\\"bg-border relative flex-1 origin-center rounded-full transition-[scale]\\\",\\r\\n          orientation === \\\"vertical\\\" && \\\"my-1 active:scale-y-95\\\",\\r\\n          orientation === \\\"horizontal\\\" && \\\"active:scale-x-98\\\"\\r\\n        )}\\r\\n      />\\r\\n    </ScrollAreaPrimitive.ScrollAreaScrollbar>\\r\\n  );\\r\\n});\\r\\n\\r\\nScrollBar.displayName = ScrollAreaPrimitive.ScrollAreaScrollbar.displayName;\\r\\n\\r\\nconst ScrollMask = ({\\r\\n  showMask,\\r\\n  maskHeight,\\r\\n  className,\\r\\n  ...props\\r\\n}: React.ComponentProps<\\\"div\\\"> & {\\r\\n  showMask: Mask;\\r\\n  maskHeight: number;\\r\\n}) => {\\r\\n  return (\\r\\n    <>\\r\\n      <div\\r\\n        {...props}\\r\\n        aria-hidden=\\\"true\\\"\\r\\n        style={\\r\\n          {\\r\\n            \\\"--top-fade-height\\\": showMask.top ? `${maskHeight}px` : \\\"0px\\\",\\r\\n            \\\"--bottom-fade-height\\\": showMask.bottom ? `${maskHeight}px` : \\\"0px\\\",\\r\\n          } as React.CSSProperties\\r\\n        }\\r\\n        className={cn(\\r\\n          \\\"pointer-events-none absolute inset-0 z-10\\\",\\r\\n          \\\"before:absolute before:inset-x-0 before:top-0 before:transition-[height,opacity] before:duration-300 before:content-['']\\\",\\r\\n          \\\"after:absolute after:inset-x-0 after:bottom-0 after:transition-[height,opacity] after:duration-300 after:content-['']\\\",\\r\\n          \\\"before:h-(--top-fade-height) after:h-(--bottom-fade-height)\\\",\\r\\n          showMask.top ? \\\"before:opacity-100\\\" : \\\"before:opacity-0\\\",\\r\\n          showMask.bottom ? \\\"after:opacity-100\\\" : \\\"after:opacity-0\\\",\\r\\n          \\\"before:from-background before:bg-gradient-to-b before:to-transparent\\\",\\r\\n          \\\"after:from-background after:bg-gradient-to-t after:to-transparent\\\",\\r\\n          className\\r\\n        )}\\r\\n      />\\r\\n      <div\\r\\n        {...props}\\r\\n        aria-hidden=\\\"true\\\"\\r\\n        style={\\r\\n          {\\r\\n            \\\"--left-fade-width\\\": showMask.left ? `${maskHeight}px` : \\\"0px\\\",\\r\\n            \\\"--right-fade-width\\\": showMask.right ? `${maskHeight}px` : \\\"0px\\\",\\r\\n          } as React.CSSProperties\\r\\n        }\\r\\n        className={cn(\\r\\n          \\\"pointer-events-none absolute inset-0 z-10\\\",\\r\\n          \\\"before:absolute before:inset-y-0 before:left-0 before:transition-[width,opacity] before:duration-300 before:content-['']\\\",\\r\\n          \\\"after:absolute after:inset-y-0 after:right-0 after:transition-[width,opacity] after:duration-300 after:content-['']\\\",\\r\\n          \\\"before:w-(--left-fade-width) after:w-(--right-fade-width)\\\",\\r\\n          showMask.left ? \\\"before:opacity-100\\\" : \\\"before:opacity-0\\\",\\r\\n          showMask.right ? \\\"after:opacity-100\\\" : \\\"after:opacity-0\\\",\\r\\n          \\\"before:from-background before:bg-gradient-to-r before:to-transparent\\\",\\r\\n          \\\"after:from-background after:bg-gradient-to-l after:to-transparent\\\",\\r\\n          className\\r\\n        )}\\r\\n      />\\r\\n    </>\\r\\n  );\\r\\n};\\r\\n\\r\\nexport { ScrollArea, ScrollBar };\\r\\n\",\n      \"type\": \"registry:ui\"\n    },\n    {\n      \"path\": \"hooks/use-has-primary-touch.tsx\",\n      \"content\": \"import { useEffect, useState } from \\\"react\\\";\\r\\n\\r\\nexport function useTouchPrimary() {\\r\\n  const [isTouchPrimary, setIsTouchPrimary] = useState(false);\\r\\n\\r\\n  useEffect(() => {\\r\\n    if (typeof window === \\\"undefined\\\") return;\\r\\n\\r\\n    const controller = new AbortController();\\r\\n    const { signal } = controller;\\r\\n\\r\\n    const handleTouch = () => {\\r\\n      const hasTouch = \\\"ontouchstart\\\" in window || navigator.maxTouchPoints > 0;\\r\\n      const prefersTouch = window.matchMedia(\\\"(pointer: coarse)\\\").matches;\\r\\n      setIsTouchPrimary(hasTouch && prefersTouch);\\r\\n    };\\r\\n\\r\\n    const mq = window.matchMedia(\\\"(pointer: coarse)\\\");\\r\\n    mq.addEventListener(\\\"change\\\", handleTouch, { signal });\\r\\n    window.addEventListener(\\\"pointerdown\\\", handleTouch, { signal });\\r\\n\\r\\n    handleTouch();\\r\\n\\r\\n    return () => controller.abort();\\r\\n  }, []);\\r\\n\\r\\n  return isTouchPrimary;\\r\\n}\\r\\n\",\n      \"type\": \"registry:hook\"\n    }\n  ]\n}"
  },
  {
    "path": "public/r/timezone-select-demo-base.json",
    "content": "{\n  \"$schema\": \"https://ui.shadcn.com/schema/registry-item.json\",\n  \"name\": \"timezone-select-demo-base\",\n  \"type\": \"registry:component\",\n  \"title\": \"Timezone Select Base UI Demo\",\n  \"description\": \"A demo showcasing the timezone select component using Lina based on Base UI\",\n  \"dependencies\": [\n    \"lucide-react\"\n  ],\n  \"registryDependencies\": [\n    \"button\",\n    \"label\",\n    \"popover\",\n    \"https://lina.sameer.sh/r/lina-base.json\",\n    \"https://lina.sameer.sh/r/command-base.json\"\n  ],\n  \"files\": [\n    {\n      \"path\": \"registry/base-ui/examples/timezone-select.tsx\",\n      \"content\": \"\\\"use client\\\";\\r\\n\\r\\nimport { useId, useMemo, useState } from \\\"react\\\";\\r\\nimport {\\r\\n  Command,\\r\\n  CommandEmpty,\\r\\n  CommandGroup,\\r\\n  CommandInput,\\r\\n  CommandItem,\\r\\n  CommandList,\\r\\n} from \\\"@/registry/base-ui/examples/command\\\";\\r\\n\\r\\nimport { CheckIcon, ChevronDownIcon } from \\\"lucide-react\\\";\\r\\n\\r\\nimport { Button } from \\\"@/components/ui/button\\\";\\r\\nimport { Label } from \\\"@/components/ui/label\\\";\\r\\nimport { Popover, PopoverContent, PopoverTrigger } from \\\"@/components/ui/popover\\\";\\r\\n\\r\\nimport { cn } from \\\"@/lib/utils\\\";\\r\\n\\r\\nexport function TimezonSelectExample() {\\r\\n  const id = useId();\\r\\n  const [open, setOpen] = useState<boolean>(false);\\r\\n  const [value, setValue] = useState<string>(\\\"Asia/Calcutta\\\");\\r\\n\\r\\n  const timezones = Intl.supportedValuesOf(\\\"timeZone\\\");\\r\\n\\r\\n  const formattedTimezones = useMemo(() => {\\r\\n    return timezones\\r\\n      .map((timezone) => {\\r\\n        const formatter = new Intl.DateTimeFormat(\\\"en\\\", {\\r\\n          timeZone: timezone,\\r\\n          timeZoneName: \\\"shortOffset\\\",\\r\\n        });\\r\\n        const parts = formatter.formatToParts(new Date());\\r\\n        const offset = parts.find((part) => part.type === \\\"timeZoneName\\\")?.value || \\\"\\\";\\r\\n        const modifiedOffset = offset === \\\"GMT\\\" ? \\\"GMT+0\\\" : offset;\\r\\n\\r\\n        return {\\r\\n          value: timezone,\\r\\n          label: `(${modifiedOffset}) ${timezone.replace(/_/g, \\\" \\\")}`,\\r\\n          numericOffset: parseInt(offset.replace(\\\"GMT\\\", \\\"\\\").replace(\\\"+\\\", \\\"\\\") || \\\"0\\\"),\\r\\n        };\\r\\n      })\\r\\n      .sort((a, b) => a.numericOffset - b.numericOffset);\\r\\n  }, [timezones]);\\r\\n\\r\\n  return (\\r\\n    <div className=\\\"*:not-first:mt-2\\\">\\r\\n      <Label htmlFor={id}>Timezone select with search</Label>\\r\\n      <Popover open={open} onOpenChange={setOpen}>\\r\\n        <PopoverTrigger asChild>\\r\\n          <Button\\r\\n            id={id}\\r\\n            variant=\\\"outline\\\"\\r\\n            role=\\\"combobox\\\"\\r\\n            aria-expanded={open}\\r\\n            className=\\\"bg-background hover:bg-background border-input w-full justify-between px-3 font-normal outline-offset-0 outline-none focus-visible:outline-[3px]\\\"\\r\\n          >\\r\\n            <span className={cn(\\\"truncate\\\", !value && \\\"text-muted-foreground\\\")}>\\r\\n              {value ? formattedTimezones.find((timezone) => timezone.value === value)?.label : \\\"Select timezone\\\"}\\r\\n            </span>\\r\\n            <ChevronDownIcon size={16} className=\\\"text-muted-foreground/80 shrink-0\\\" aria-hidden=\\\"true\\\" />\\r\\n          </Button>\\r\\n        </PopoverTrigger>\\r\\n        <PopoverContent className=\\\"border-input w-full min-w-[var(--radix-popper-anchor-width)] p-0\\\" align=\\\"start\\\">\\r\\n          <Command\\r\\n            filter={(value, search) => {\\r\\n              const normalizedValue = value.toLowerCase();\\r\\n              const normalizedSearch = search.toLowerCase().replace(/\\\\s+/g, \\\"\\\");\\r\\n              return normalizedValue.includes(normalizedSearch) ? 1 : 0;\\r\\n            }}\\r\\n          >\\r\\n            <CommandInput placeholder=\\\"Search timezone...\\\" />\\r\\n            <CommandList>\\r\\n              <CommandEmpty>No timezone found.</CommandEmpty>\\r\\n              <CommandGroup>\\r\\n                {formattedTimezones.map(({ value: itemValue, label }) => (\\r\\n                  <CommandItem\\r\\n                    key={itemValue}\\r\\n                    value={itemValue}\\r\\n                    onSelect={(currentValue) => {\\r\\n                      setValue(currentValue === value ? \\\"\\\" : currentValue);\\r\\n                      setOpen(false);\\r\\n                    }}\\r\\n                  >\\r\\n                    {label}\\r\\n                    {value === itemValue && <CheckIcon size={16} className=\\\"ml-auto\\\" />}\\r\\n                  </CommandItem>\\r\\n                ))}\\r\\n              </CommandGroup>\\r\\n            </CommandList>\\r\\n          </Command>\\r\\n        </PopoverContent>\\r\\n      </Popover>\\r\\n    </div>\\r\\n  );\\r\\n}\\r\\n\",\n      \"type\": \"registry:component\"\n    }\n  ]\n}"
  },
  {
    "path": "public/r/timezone-select-demo-radix.json",
    "content": "{\n  \"$schema\": \"https://ui.shadcn.com/schema/registry-item.json\",\n  \"name\": \"timezone-select-demo-radix\",\n  \"type\": \"registry:component\",\n  \"title\": \"Timezone Select Radix Demo\",\n  \"description\": \"A demo showcasing the timezone select component using Lina based on Radix UI\",\n  \"dependencies\": [\n    \"lucide-react\"\n  ],\n  \"registryDependencies\": [\n    \"button\",\n    \"label\",\n    \"popover\",\n    \"https://lina.sameer.sh/r/lina-radix.json\",\n    \"https://lina.sameer.sh/r/command-radix.json\"\n  ],\n  \"files\": [\n    {\n      \"path\": \"registry/radix-ui/examples/timezone-select.tsx\",\n      \"content\": \"\\\"use client\\\";\\r\\n\\r\\nimport { useId, useMemo, useState } from \\\"react\\\";\\r\\nimport {\\r\\n  Command,\\r\\n  CommandEmpty,\\r\\n  CommandGroup,\\r\\n  CommandInput,\\r\\n  CommandItem,\\r\\n  CommandList,\\r\\n} from \\\"@/registry/radix-ui/examples/command\\\";\\r\\n\\r\\nimport { CheckIcon, ChevronDownIcon } from \\\"lucide-react\\\";\\r\\n\\r\\nimport { Button } from \\\"@/components/ui/button\\\";\\r\\nimport { Label } from \\\"@/components/ui/label\\\";\\r\\nimport { Popover, PopoverContent, PopoverTrigger } from \\\"@/components/ui/popover\\\";\\r\\n\\r\\nimport { cn } from \\\"@/lib/utils\\\";\\r\\n\\r\\nexport function TimezoneSelectExample() {\\r\\n  const id = useId();\\r\\n  const [open, setOpen] = useState<boolean>(false);\\r\\n  const [value, setValue] = useState<string>(\\\"Asia/Calcutta\\\");\\r\\n\\r\\n  const timezones = Intl.supportedValuesOf(\\\"timeZone\\\");\\r\\n\\r\\n  const formattedTimezones = useMemo(() => {\\r\\n    return timezones\\r\\n      .map((timezone) => {\\r\\n        const formatter = new Intl.DateTimeFormat(\\\"en\\\", {\\r\\n          timeZone: timezone,\\r\\n          timeZoneName: \\\"shortOffset\\\",\\r\\n        });\\r\\n        const parts = formatter.formatToParts(new Date());\\r\\n        const offset = parts.find((part) => part.type === \\\"timeZoneName\\\")?.value || \\\"\\\";\\r\\n        const modifiedOffset = offset === \\\"GMT\\\" ? \\\"GMT+0\\\" : offset;\\r\\n\\r\\n        return {\\r\\n          value: timezone,\\r\\n          label: `(${modifiedOffset}) ${timezone.replace(/_/g, \\\" \\\")}`,\\r\\n          numericOffset: parseInt(offset.replace(\\\"GMT\\\", \\\"\\\").replace(\\\"+\\\", \\\"\\\") || \\\"0\\\"),\\r\\n        };\\r\\n      })\\r\\n      .sort((a, b) => a.numericOffset - b.numericOffset);\\r\\n  }, [timezones]);\\r\\n\\r\\n  return (\\r\\n    <div className=\\\"*:not-first:mt-2\\\">\\r\\n      <Label htmlFor={id}>Timezone select with search</Label>\\r\\n      <Popover open={open} onOpenChange={setOpen}>\\r\\n        <PopoverTrigger asChild>\\r\\n          <Button\\r\\n            id={id}\\r\\n            variant=\\\"outline\\\"\\r\\n            role=\\\"combobox\\\"\\r\\n            aria-expanded={open}\\r\\n            className=\\\"bg-background hover:bg-background border-input w-full justify-between px-3 font-normal outline-offset-0 outline-none focus-visible:outline-[3px]\\\"\\r\\n          >\\r\\n            <span className={cn(\\\"truncate\\\", !value && \\\"text-muted-foreground\\\")}>\\r\\n              {value ? formattedTimezones.find((timezone) => timezone.value === value)?.label : \\\"Select timezone\\\"}\\r\\n            </span>\\r\\n            <ChevronDownIcon size={16} className=\\\"text-muted-foreground/80 shrink-0\\\" aria-hidden=\\\"true\\\" />\\r\\n          </Button>\\r\\n        </PopoverTrigger>\\r\\n        <PopoverContent className=\\\"border-input w-full min-w-[var(--radix-popper-anchor-width)] p-0\\\" align=\\\"start\\\">\\r\\n          <Command\\r\\n            filter={(value, search) => {\\r\\n              const normalizedValue = value.toLowerCase();\\r\\n              const normalizedSearch = search.toLowerCase().replace(/\\\\s+/g, \\\"\\\");\\r\\n              return normalizedValue.includes(normalizedSearch) ? 1 : 0;\\r\\n            }}\\r\\n          >\\r\\n            <CommandInput placeholder=\\\"Search timezone...\\\" />\\r\\n            <CommandList>\\r\\n              <CommandEmpty>No timezone found.</CommandEmpty>\\r\\n              <CommandGroup>\\r\\n                {formattedTimezones.map(({ value: itemValue, label }) => (\\r\\n                  <CommandItem\\r\\n                    key={itemValue}\\r\\n                    value={itemValue}\\r\\n                    onSelect={(currentValue) => {\\r\\n                      setValue(currentValue === value ? \\\"\\\" : currentValue);\\r\\n                      setOpen(false);\\r\\n                    }}\\r\\n                  >\\r\\n                    {label}\\r\\n                    {value === itemValue && <CheckIcon size={16} className=\\\"ml-auto\\\" />}\\r\\n                  </CommandItem>\\r\\n                ))}\\r\\n              </CommandGroup>\\r\\n            </CommandList>\\r\\n          </Command>\\r\\n        </PopoverContent>\\r\\n      </Popover>\\r\\n    </div>\\r\\n  );\\r\\n}\\r\\n\",\n      \"type\": \"registry:component\"\n    }\n  ]\n}"
  },
  {
    "path": "public/r/vertical-scroll-demo-base.json",
    "content": "{\n  \"$schema\": \"https://ui.shadcn.com/schema/registry-item.json\",\n  \"name\": \"vertical-scroll-demo-base\",\n  \"type\": \"registry:component\",\n  \"title\": \"Vertical Scroll Area Base Demo\",\n  \"description\": \"A demo showcasing the vertical scroll area component using Lina's Base UI\",\n  \"registryDependencies\": [\n    \"https://lina.sameer.sh/r/lina-base.json\"\n  ],\n  \"files\": [\n    {\n      \"path\": \"registry/base-ui/examples/vertical-scroll.tsx\",\n      \"content\": \"import * as React from \\\"react\\\";\\r\\nimport { ScrollArea } from \\\"@/registry/base-ui/scroll-area\\\";\\r\\n\\r\\nimport { Separator } from \\\"@/components/ui/separator\\\";\\r\\n\\r\\nconst tags = Array.from({ length: 50 }).map((_, i, a) => `v1.2.0-beta.${a.length - i}`);\\r\\n\\r\\nexport function ScrollAreaDemo() {\\r\\n  return (\\r\\n    <ScrollArea className=\\\"bg-background h-72 w-48 rounded-md border\\\">\\r\\n      <div className=\\\"p-4\\\">\\r\\n        <h4 className=\\\"mb-4 text-sm leading-none font-medium\\\">Tags</h4>\\r\\n        {tags.map((tag) => (\\r\\n          <React.Fragment key={tag}>\\r\\n            <div className=\\\"text-sm\\\">{tag}</div>\\r\\n            <Separator className=\\\"my-2\\\" />\\r\\n          </React.Fragment>\\r\\n        ))}\\r\\n      </div>\\r\\n    </ScrollArea>\\r\\n  );\\r\\n}\\r\\n\",\n      \"type\": \"registry:component\"\n    }\n  ]\n}"
  },
  {
    "path": "public/r/vertical-scroll-demo-radix.json",
    "content": "{\n  \"$schema\": \"https://ui.shadcn.com/schema/registry-item.json\",\n  \"name\": \"vertical-scroll-demo-radix\",\n  \"type\": \"registry:component\",\n  \"title\": \"Vertical Scroll Area Radix Demo\",\n  \"description\": \"A demo showcasing the vertical scroll area component using Lina's Radix UI\",\n  \"registryDependencies\": [\n    \"https://lina.sameer.sh/r/lina-radix.json\"\n  ],\n  \"files\": [\n    {\n      \"path\": \"registry/radix-ui/examples/vertical-scroll.tsx\",\n      \"content\": \"import * as React from \\\"react\\\";\\r\\nimport { ScrollArea } from \\\"@/registry/radix-ui/scroll-area\\\";\\r\\n\\r\\nimport { Separator } from \\\"@/components/ui/separator\\\";\\r\\n\\r\\nconst tags = Array.from({ length: 50 }).map((_, i, a) => `v1.2.0-beta.${a.length - i}`);\\r\\n\\r\\nexport function ScrollAreaDemo() {\\r\\n  return (\\r\\n    <ScrollArea className=\\\"bg-background h-72 w-48 rounded-md border\\\">\\r\\n      <div className=\\\"p-4\\\">\\r\\n        <h4 className=\\\"mb-4 text-sm leading-none font-medium\\\">Tags</h4>\\r\\n        {tags.map((tag) => (\\r\\n          <React.Fragment key={tag}>\\r\\n            <div className=\\\"text-sm\\\">{tag}</div>\\r\\n            <Separator className=\\\"my-2\\\" />\\r\\n          </React.Fragment>\\r\\n        ))}\\r\\n      </div>\\r\\n    </ScrollArea>\\r\\n  );\\r\\n}\\r\\n\",\n      \"type\": \"registry:component\"\n    }\n  ]\n}"
  },
  {
    "path": "public/site.webmanifest",
    "content": "{\n  \"name2\": \"Lina\",\n  \"short_name\": \"Lina\",\n  \"icons\": [\n    {\n      \"src\": \"/android-chrome-192x192.png\",\n      \"sizes\": \"192x192\",\n      \"type\": \"image/png\",\n      \"purpose\": \"maskable\"\n    },\n    {\n      \"src\": \"/android-chrome-512x512.png\",\n      \"sizes\": \"512x512\",\n      \"type\": \"image/png\",\n      \"purpose\": \"maskable\"\n    }\n  ],\n  \"theme_color\": \"#ffffff\",\n  \"background_color\": \"#000000\",\n  \"display\": \"standalone\"\n}\n"
  },
  {
    "path": "registry/base-ui/examples/command.tsx",
    "content": "\"use client\";\n\nimport * as React from \"react\";\nimport { ScrollArea } from \"@/registry/base-ui/scroll-area\";\n\nimport { Command as CommandPrimitive } from \"cmdk\";\nimport { SearchIcon } from \"lucide-react\";\n\nimport { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle } from \"@/components/ui/dialog\";\n\nimport { cn } from \"@/lib/utils\";\n\nfunction Command({ className, ...props }: React.ComponentProps<typeof CommandPrimitive>) {\n  return (\n    <CommandPrimitive\n      data-slot=\"command\"\n      className={cn(\"bg-popover text-popover-foreground flex size-full flex-col overflow-hidden rounded-md\", className)}\n      {...props}\n    />\n  );\n}\n\nfunction CommandDialog({\n  title = \"Command Palette\",\n  description = \"Search for a command to run...\",\n  children,\n  ...props\n}: React.ComponentProps<typeof Dialog> & {\n  title?: string;\n  description?: string;\n}) {\n  return (\n    <Dialog {...props}>\n      <DialogHeader className=\"sr-only\">\n        <DialogTitle>{title}</DialogTitle>\n        <DialogDescription>{description}</DialogDescription>\n      </DialogHeader>\n      <DialogContent className=\"overflow-hidden p-0 sm:max-w-lg [&>button:last-child]:hidden\">\n        <Command className=\"[&_[cmdk-group-heading]]:text-muted-foreground max-h-[100svh] **:data-[slot=command-input-wrapper]:h-12 [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group]]:px-2 [&_[cmdk-input]]:h-12 [&_[cmdk-item]]:px-3 [&_[cmdk-item]]:py-2\">\n          {children}\n        </Command>\n      </DialogContent>\n    </Dialog>\n  );\n}\n\nfunction CommandInput({ className, ...props }: React.ComponentProps<typeof CommandPrimitive.Input>) {\n  return (\n    <div className=\"border-input flex items-center border-b px-5\" cmdk-input-wrapper=\"\">\n      <SearchIcon size={20} className=\"text-muted-foreground/80 me-3\" />\n      <CommandPrimitive.Input\n        data-slot=\"command-input-wrapper\"\n        className={cn(\n          \"placeholder:text-muted-foreground/70 flex h-10 w-full rounded-md bg-transparent py-3 text-sm outline-hidden disabled:cursor-not-allowed disabled:opacity-50\",\n          className\n        )}\n        {...props}\n      />\n    </div>\n  );\n}\n\nfunction CommandList({ className, ...props }: React.ComponentProps<typeof CommandPrimitive.List>) {\n  return (\n    <ScrollArea\n      maskClassName=\"before:from-popover after:from-popover\"\n      className=\"flex max-h-full flex-col overflow-hidden\"\n    >\n      <CommandPrimitive.List data-slot=\"command-list\" className={cn(\"max-h-80 flex-1\", className)} {...props} />\n    </ScrollArea>\n  );\n}\n\nfunction CommandEmpty({ ...props }: React.ComponentProps<typeof CommandPrimitive.Empty>) {\n  return <CommandPrimitive.Empty data-slot=\"command-empty\" className=\"py-6 text-center text-sm\" {...props} />;\n}\n\nfunction CommandGroup({ className, ...props }: React.ComponentProps<typeof CommandPrimitive.Group>) {\n  return (\n    <CommandPrimitive.Group\n      data-slot=\"command-group\"\n      className={cn(\n        \"text-foreground [&_[cmdk-group-heading]]:text-muted-foreground overflow-hidden p-2 [&_[cmdk-group-heading]]:px-3 [&_[cmdk-group-heading]]:py-2 [&_[cmdk-group-heading]]:text-xs [&_[cmdk-group-heading]]:font-medium\",\n        className\n      )}\n      {...props}\n    />\n  );\n}\n\nfunction CommandSeparator({ className, ...props }: React.ComponentProps<typeof CommandPrimitive.Separator>) {\n  return (\n    <CommandPrimitive.Separator\n      data-slot=\"command-separator\"\n      className={cn(\"bg-border -mx-1 h-px\", className)}\n      {...props}\n    />\n  );\n}\n\nfunction CommandItem({ className, ...props }: React.ComponentProps<typeof CommandPrimitive.Item>) {\n  return (\n    <CommandPrimitive.Item\n      data-slot=\"command-item\"\n      className={cn(\n        \"data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground relative flex cursor-default items-center gap-3 rounded-md px-2 py-1.5 text-sm outline-hidden select-none data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0\",\n        className\n      )}\n      {...props}\n    />\n  );\n}\n\nfunction CommandShortcut({ className, ...props }: React.ComponentProps<\"span\">) {\n  return (\n    <kbd\n      data-slot=\"command-shortcut\"\n      className={cn(\n        \"bg-background text-muted-foreground/70 ms-auto -me-1 inline-flex h-5 max-h-full items-center rounded border px-1 font-[inherit] text-[0.625rem] font-medium\",\n        className\n      )}\n      {...props}\n    />\n  );\n}\n\nexport {\n  Command,\n  CommandDialog,\n  CommandEmpty,\n  CommandGroup,\n  CommandInput,\n  CommandItem,\n  CommandList,\n  CommandSeparator,\n  CommandShortcut,\n};\n"
  },
  {
    "path": "registry/base-ui/examples/horizontal-scroll.tsx",
    "content": "import Image from \"next/image\";\nimport { ScrollArea, ScrollBar } from \"@/registry/base-ui/scroll-area\";\n\nexport interface Artwork {\n  artist: string;\n  art: string;\n}\n\nconst works: Artwork[] = [\n  {\n    artist: \"Ornella Binni\",\n    art: \"https://images.unsplash.com/photo-1465869185982-5a1a7522cbcb?auto=format&fit=crop&w=300&q=80\",\n  },\n  {\n    artist: \"Tom Byrom\",\n    art: \"https://images.unsplash.com/photo-1548516173-3cabfa4607e9?auto=format&fit=crop&w=300&q=80\",\n  },\n  {\n    artist: \"Vladimir Malyavko\",\n    art: \"https://images.unsplash.com/photo-1494337480532-3725c85fd2ab?auto=format&fit=crop&w=300&q=80\",\n  },\n];\n\nexport function ScrollAreaHorizontalDemo() {\n  return (\n    <ScrollArea className=\"bg-background w-96 rounded-md border whitespace-nowrap\">\n      <div className=\"flex w-max space-x-4 p-4\">\n        {works.map((artwork) => (\n          <figure key={artwork.artist} className=\"shrink-0\">\n            <div className=\"overflow-hidden rounded-md\">\n              <Image\n                src={artwork.art}\n                alt={`Photo by ${artwork.artist}`}\n                className=\"aspect-[3/4] h-fit w-fit object-cover\"\n                width={300}\n                height={400}\n              />\n            </div>\n            <figcaption className=\"text-muted-foreground pt-2 text-xs\">\n              Photo by <span className=\"text-foreground font-semibold\">{artwork.artist}</span>\n            </figcaption>\n          </figure>\n        ))}\n      </div>\n      <ScrollBar orientation=\"horizontal\" />\n    </ScrollArea>\n  );\n}\n"
  },
  {
    "path": "registry/base-ui/examples/timezone-select.tsx",
    "content": "\"use client\";\n\nimport { useId, useMemo, useState } from \"react\";\nimport {\n  Command,\n  CommandEmpty,\n  CommandGroup,\n  CommandInput,\n  CommandItem,\n  CommandList,\n} from \"@/registry/base-ui/examples/command\";\n\nimport { CheckIcon, ChevronDownIcon } from \"lucide-react\";\n\nimport { Button } from \"@/components/ui/button\";\nimport { Label } from \"@/components/ui/label\";\nimport { Popover, PopoverContent, PopoverTrigger } from \"@/components/ui/popover\";\n\nimport { cn } from \"@/lib/utils\";\n\nexport function TimezonSelectExample() {\n  const id = useId();\n  const [open, setOpen] = useState<boolean>(false);\n  const [value, setValue] = useState<string>(\"Asia/Calcutta\");\n\n  const timezones = Intl.supportedValuesOf(\"timeZone\");\n\n  const formattedTimezones = useMemo(() => {\n    return timezones\n      .map((timezone) => {\n        const formatter = new Intl.DateTimeFormat(\"en\", {\n          timeZone: timezone,\n          timeZoneName: \"shortOffset\",\n        });\n        const parts = formatter.formatToParts(new Date());\n        const offset = parts.find((part) => part.type === \"timeZoneName\")?.value || \"\";\n        const modifiedOffset = offset === \"GMT\" ? \"GMT+0\" : offset;\n\n        return {\n          value: timezone,\n          label: `(${modifiedOffset}) ${timezone.replace(/_/g, \" \")}`,\n          numericOffset: parseInt(offset.replace(\"GMT\", \"\").replace(\"+\", \"\") || \"0\"),\n        };\n      })\n      .sort((a, b) => a.numericOffset - b.numericOffset);\n  }, [timezones]);\n\n  return (\n    <div className=\"*:not-first:mt-2\">\n      <Label htmlFor={id}>Timezone select with search</Label>\n      <Popover open={open} onOpenChange={setOpen}>\n        <PopoverTrigger asChild>\n          <Button\n            id={id}\n            variant=\"outline\"\n            role=\"combobox\"\n            aria-expanded={open}\n            className=\"bg-background hover:bg-background border-input w-full justify-between px-3 font-normal outline-offset-0 outline-none focus-visible:outline-[3px]\"\n          >\n            <span className={cn(\"truncate\", !value && \"text-muted-foreground\")}>\n              {value ? formattedTimezones.find((timezone) => timezone.value === value)?.label : \"Select timezone\"}\n            </span>\n            <ChevronDownIcon size={16} className=\"text-muted-foreground/80 shrink-0\" aria-hidden=\"true\" />\n          </Button>\n        </PopoverTrigger>\n        <PopoverContent className=\"border-input w-full min-w-[var(--radix-popper-anchor-width)] p-0\" align=\"start\">\n          <Command\n            filter={(value, search) => {\n              const normalizedValue = value.toLowerCase();\n              const normalizedSearch = search.toLowerCase().replace(/\\s+/g, \"\");\n              return normalizedValue.includes(normalizedSearch) ? 1 : 0;\n            }}\n          >\n            <CommandInput placeholder=\"Search timezone...\" />\n            <CommandList>\n              <CommandEmpty>No timezone found.</CommandEmpty>\n              <CommandGroup>\n                {formattedTimezones.map(({ value: itemValue, label }) => (\n                  <CommandItem\n                    key={itemValue}\n                    value={itemValue}\n                    onSelect={(currentValue) => {\n                      setValue(currentValue === value ? \"\" : currentValue);\n                      setOpen(false);\n                    }}\n                  >\n                    {label}\n                    {value === itemValue && <CheckIcon size={16} className=\"ml-auto\" />}\n                  </CommandItem>\n                ))}\n              </CommandGroup>\n            </CommandList>\n          </Command>\n        </PopoverContent>\n      </Popover>\n    </div>\n  );\n}\n"
  },
  {
    "path": "registry/base-ui/examples/usage-demo.tsx",
    "content": "import { ScrollArea } from \"@/registry/base-ui/scroll-area\";\n\nexport default function Example() {\n  return (\n    <ScrollArea className=\"h-[200px] w-[350px] rounded-md border p-4\">\n      Jokester began sneaking into the castle in the middle of the night and leaving jokes all over the place: under the\n      king's pillow, in his soup, even in the royal toilet. The king was furious, but he couldn't seem to stop Jokester.\n      And then, one day, the people of the kingdom discovered that the jokes left by Jokester were so funny that they\n      couldn't help but laugh. And once they started laughing, they couldn't stop.\n    </ScrollArea>\n  );\n}\n"
  },
  {
    "path": "registry/base-ui/examples/vertical-scroll.tsx",
    "content": "import * as React from \"react\";\nimport { ScrollArea } from \"@/registry/base-ui/scroll-area\";\n\nimport { Separator } from \"@/components/ui/separator\";\n\nconst tags = Array.from({ length: 50 }).map((_, i, a) => `v1.2.0-beta.${a.length - i}`);\n\nexport function ScrollAreaDemo() {\n  return (\n    <ScrollArea className=\"bg-background h-72 w-48 rounded-md border\">\n      <div className=\"p-4\">\n        <h4 className=\"mb-4 text-sm leading-none font-medium\">Tags</h4>\n        {tags.map((tag) => (\n          <React.Fragment key={tag}>\n            <div className=\"text-sm\">{tag}</div>\n            <Separator className=\"my-2\" />\n          </React.Fragment>\n        ))}\n      </div>\n    </ScrollArea>\n  );\n}\n"
  },
  {
    "path": "registry/base-ui/scroll-area.tsx",
    "content": "\"use client\";\n\nimport * as React from \"react\";\n\nimport { ScrollArea as ScrollAreaPrimitive } from \"@base-ui-components/react/scroll-area\";\n\nimport { cn } from \"@/lib/utils\";\n\nimport { useTouchPrimary } from \"@/hooks/use-has-primary-touch\";\n\ntype Mask = {\n  top: boolean;\n  bottom: boolean;\n  left: boolean;\n  right: boolean;\n};\n\nexport type ScrollAreaContextProps = {\n  isTouch: boolean;\n  type: \"auto\" | \"always\" | \"scroll\" | \"hover\";\n};\n\nconst ScrollAreaContext = React.createContext<ScrollAreaContextProps>({\n  isTouch: false,\n  type: \"hover\",\n});\n\nconst ScrollArea = React.forwardRef<\n  React.ComponentRef<typeof ScrollAreaPrimitive.Root>,\n  React.ComponentPropsWithoutRef<typeof ScrollAreaPrimitive.Root> & {\n    type?: \"auto\" | \"always\" | \"scroll\" | \"hover\";\n    viewportClassName?: string;\n    /**\n     * `maskHeight` is the height of the mask in pixels.\n     * pass `0` to disable the mask\n     * @default 30\n     */\n    maskHeight?: number;\n    maskClassName?: string;\n  }\n>(({ className, children, type = \"hover\", maskHeight = 30, maskClassName, viewportClassName, ...props }, ref) => {\n  const [showMask, setShowMask] = React.useState<Mask>({\n    top: false,\n    bottom: false,\n    left: false,\n    right: false,\n  });\n\n  const viewportRef = React.useRef<HTMLDivElement>(null);\n  const isTouch = useTouchPrimary();\n\n  const checkScrollability = React.useCallback(() => {\n    const element = viewportRef.current;\n    if (!element) return;\n\n    const { scrollTop, scrollLeft, scrollWidth, clientWidth, scrollHeight, clientHeight } = element;\n    setShowMask((prev) => ({\n      ...prev,\n      top: scrollTop > 0,\n      bottom: scrollTop + clientHeight < scrollHeight - 1,\n      left: scrollLeft > 0,\n      right: scrollLeft + clientWidth < scrollWidth - 1,\n    }));\n  }, []);\n\n  React.useEffect(() => {\n    if (typeof window === \"undefined\") return;\n\n    const element = viewportRef.current;\n    if (!element) return;\n\n    const controller = new AbortController();\n    const { signal } = controller;\n\n    const resizeObserver = new ResizeObserver(checkScrollability);\n    resizeObserver.observe(element);\n\n    element.addEventListener(\"scroll\", checkScrollability, { signal });\n    window.addEventListener(\"resize\", checkScrollability, { signal });\n\n    // Run an initial check whenever dependencies change (including pointer mode)\n    checkScrollability();\n\n    return () => {\n      controller.abort();\n      resizeObserver.disconnect();\n    };\n  }, [checkScrollability, isTouch]);\n\n  return (\n    <ScrollAreaContext.Provider value={{ isTouch, type }}>\n      {isTouch ? (\n        <div\n          ref={ref}\n          {...props}\n          role=\"group\"\n          data-slot=\"scroll-area\"\n          aria-roledescription=\"scroll area\"\n          className={cn(\"relative overflow-hidden\", className)}\n        >\n          <div ref={viewportRef} className={cn(\"size-full overflow-auto\", viewportClassName)} tabIndex={0}>\n            {children}\n          </div>\n          {maskHeight > 0 && <ScrollMask showMask={showMask} className={maskClassName} maskHeight={maskHeight} />}\n        </div>\n      ) : (\n        <ScrollAreaPrimitive.Root\n          ref={ref}\n          data-slot=\"scroll-area\"\n          className={cn(\"relative overflow-hidden\", viewportClassName, className)}\n          {...props}\n        >\n          <ScrollAreaPrimitive.Viewport\n            ref={viewportRef}\n            data-slot=\"scroll-area-viewport\"\n            className={cn(\"focus-ring size-full rounded-[inherit]\", viewportClassName)}\n          >\n            {children}\n          </ScrollAreaPrimitive.Viewport>\n          <ScrollBar />\n          <ScrollAreaPrimitive.Corner />\n          {maskHeight > 0 && <ScrollMask showMask={showMask} className={maskClassName} maskHeight={maskHeight} />}\n        </ScrollAreaPrimitive.Root>\n      )}\n    </ScrollAreaContext.Provider>\n  );\n});\n\nScrollArea.displayName = ScrollAreaPrimitive.Root.displayName;\n\nconst ScrollBar = React.forwardRef<\n  React.ComponentRef<typeof ScrollAreaPrimitive.Scrollbar>,\n  React.ComponentPropsWithoutRef<typeof ScrollAreaPrimitive.Scrollbar>\n>(({ className, orientation = \"vertical\", ...props }, ref) => {\n  const { isTouch, type } = React.useContext(ScrollAreaContext);\n\n  if (isTouch) return null;\n\n  return (\n    <ScrollAreaPrimitive.Scrollbar\n      ref={ref}\n      orientation={orientation}\n      data-slot=\"scroll-area-scrollbar\"\n      className={cn(\n        \"hover:bg-muted dark:hover:bg-muted/50 flex touch-none p-px transition-[colors,opacity] duration-150 ease-out select-none\",\n        orientation === \"vertical\" && \"h-full w-2.5 border-l border-l-transparent\",\n        orientation === \"horizontal\" && \"h-2.5 flex-col border-t border-t-transparent px-1 pr-1.25\",\n        type === \"hover\" && \"opacity-0 data-[hovering]:opacity-100\",\n        type === \"scroll\" && \"opacity-0 data-[scrolling]:opacity-100\",\n        className\n      )}\n      {...props}\n    >\n      <ScrollAreaPrimitive.Thumb\n        data-slot=\"scroll-area-thumb\"\n        className={cn(\n          \"bg-border relative flex-1 rounded-full transition-[scale]\",\n          orientation === \"vertical\" && \"my-1 active:scale-y-95\",\n          orientation === \"horizontal\" && \"active:scale-x-98\"\n        )}\n      />\n    </ScrollAreaPrimitive.Scrollbar>\n  );\n});\n\nScrollBar.displayName = ScrollAreaPrimitive.Scrollbar.displayName;\n\nconst ScrollMask = ({\n  showMask,\n  maskHeight,\n  className,\n  ...props\n}: React.ComponentProps<\"div\"> & {\n  showMask: Mask;\n  maskHeight: number;\n}) => {\n  return (\n    <>\n      <div\n        {...props}\n        aria-hidden=\"true\"\n        style={\n          {\n            \"--top-fade-height\": showMask.top ? `${maskHeight}px` : \"0px\",\n            \"--bottom-fade-height\": showMask.bottom ? `${maskHeight}px` : \"0px\",\n          } as React.CSSProperties\n        }\n        className={cn(\n          \"pointer-events-none absolute inset-0 z-10\",\n          \"before:absolute before:inset-x-0 before:top-0 before:transition-[height,opacity] before:duration-300 before:content-['']\",\n          \"after:absolute after:inset-x-0 after:bottom-0 after:transition-[height,opacity] after:duration-300 after:content-['']\",\n          \"before:h-(--top-fade-height) after:h-(--bottom-fade-height)\",\n          showMask.top ? \"before:opacity-100\" : \"before:opacity-0\",\n          showMask.bottom ? \"after:opacity-100\" : \"after:opacity-0\",\n          \"before:from-background before:bg-gradient-to-b before:to-transparent\",\n          \"after:from-background after:bg-gradient-to-t after:to-transparent\",\n          className\n        )}\n      />\n      <div\n        {...props}\n        aria-hidden=\"true\"\n        style={\n          {\n            \"--left-fade-width\": showMask.left ? `${maskHeight}px` : \"0px\",\n            \"--right-fade-width\": showMask.right ? `${maskHeight}px` : \"0px\",\n          } as React.CSSProperties\n        }\n        className={cn(\n          \"pointer-events-none absolute inset-0 z-10\",\n          \"before:absolute before:inset-y-0 before:left-0 before:transition-[width,opacity] before:duration-300 before:content-['']\",\n          \"after:absolute after:inset-y-0 after:right-0 after:transition-[width,opacity] after:duration-300 after:content-['']\",\n          \"before:w-(--left-fade-width) after:w-(--right-fade-width)\",\n          showMask.left ? \"before:opacity-100\" : \"before:opacity-0\",\n          showMask.right ? \"after:opacity-100\" : \"after:opacity-0\",\n          \"before:from-background before:bg-gradient-to-r before:to-transparent\",\n          \"after:from-background after:bg-gradient-to-l after:to-transparent\",\n          className\n        )}\n      />\n    </>\n  );\n};\n\nexport { ScrollArea, ScrollBar };\n"
  },
  {
    "path": "registry/radix-ui/examples/command.tsx",
    "content": "\"use client\";\n\nimport * as React from \"react\";\nimport { ScrollArea } from \"@/registry/radix-ui/scroll-area\";\n\nimport { Command as CommandPrimitive } from \"cmdk\";\nimport { SearchIcon } from \"lucide-react\";\n\nimport { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle } from \"@/components/ui/dialog\";\n\nimport { cn } from \"@/lib/utils\";\n\nfunction Command({ className, ...props }: React.ComponentProps<typeof CommandPrimitive>) {\n  return (\n    <CommandPrimitive\n      data-slot=\"command\"\n      className={cn(\"bg-popover text-popover-foreground flex size-full flex-col overflow-hidden rounded-md\", className)}\n      {...props}\n    />\n  );\n}\n\nfunction CommandDialog({\n  title = \"Command Palette\",\n  description = \"Search for a command to run...\",\n  children,\n  ...props\n}: React.ComponentProps<typeof Dialog> & {\n  title?: string;\n  description?: string;\n}) {\n  return (\n    <Dialog {...props}>\n      <DialogHeader className=\"sr-only\">\n        <DialogTitle>{title}</DialogTitle>\n        <DialogDescription>{description}</DialogDescription>\n      </DialogHeader>\n      <DialogContent className=\"overflow-hidden p-0 sm:max-w-lg [&>button:last-child]:hidden\">\n        <Command className=\"[&_[cmdk-group-heading]]:text-muted-foreground max-h-[100svh] **:data-[slot=command-input-wrapper]:h-12 [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group]]:px-2 [&_[cmdk-input]]:h-12 [&_[cmdk-item]]:px-3 [&_[cmdk-item]]:py-2\">\n          {children}\n        </Command>\n      </DialogContent>\n    </Dialog>\n  );\n}\n\nfunction CommandInput({ className, ...props }: React.ComponentProps<typeof CommandPrimitive.Input>) {\n  return (\n    <div className=\"border-input flex items-center border-b px-5\" cmdk-input-wrapper=\"\">\n      <SearchIcon size={20} className=\"text-muted-foreground/80 me-3\" />\n      <CommandPrimitive.Input\n        data-slot=\"command-input-wrapper\"\n        className={cn(\n          \"placeholder:text-muted-foreground/70 flex h-10 w-full rounded-md bg-transparent py-3 text-sm outline-hidden disabled:cursor-not-allowed disabled:opacity-50\",\n          className\n        )}\n        {...props}\n      />\n    </div>\n  );\n}\n\nfunction CommandList({ className, ...props }: React.ComponentProps<typeof CommandPrimitive.List>) {\n  return (\n    <ScrollArea\n      maskClassName=\"before:from-popover after:from-popover\"\n      className=\"flex max-h-full flex-col overflow-hidden\"\n    >\n      <CommandPrimitive.List data-slot=\"command-list\" className={cn(\"max-h-80 flex-1\", className)} {...props} />\n    </ScrollArea>\n  );\n}\n\nfunction CommandEmpty({ ...props }: React.ComponentProps<typeof CommandPrimitive.Empty>) {\n  return <CommandPrimitive.Empty data-slot=\"command-empty\" className=\"py-6 text-center text-sm\" {...props} />;\n}\n\nfunction CommandGroup({ className, ...props }: React.ComponentProps<typeof CommandPrimitive.Group>) {\n  return (\n    <CommandPrimitive.Group\n      data-slot=\"command-group\"\n      className={cn(\n        \"text-foreground [&_[cmdk-group-heading]]:text-muted-foreground overflow-hidden p-2 [&_[cmdk-group-heading]]:px-3 [&_[cmdk-group-heading]]:py-2 [&_[cmdk-group-heading]]:text-xs [&_[cmdk-group-heading]]:font-medium\",\n        className\n      )}\n      {...props}\n    />\n  );\n}\n\nfunction CommandSeparator({ className, ...props }: React.ComponentProps<typeof CommandPrimitive.Separator>) {\n  return (\n    <CommandPrimitive.Separator\n      data-slot=\"command-separator\"\n      className={cn(\"bg-border -mx-1 h-px\", className)}\n      {...props}\n    />\n  );\n}\n\nfunction CommandItem({ className, ...props }: React.ComponentProps<typeof CommandPrimitive.Item>) {\n  return (\n    <CommandPrimitive.Item\n      data-slot=\"command-item\"\n      className={cn(\n        \"data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground relative flex cursor-default items-center gap-3 rounded-md px-2 py-1.5 text-sm outline-hidden select-none data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0\",\n        className\n      )}\n      {...props}\n    />\n  );\n}\n\nfunction CommandShortcut({ className, ...props }: React.ComponentProps<\"span\">) {\n  return (\n    <kbd\n      data-slot=\"command-shortcut\"\n      className={cn(\n        \"bg-background text-muted-foreground/70 ms-auto -me-1 inline-flex h-5 max-h-full items-center rounded border px-1 font-[inherit] text-[0.625rem] font-medium\",\n        className\n      )}\n      {...props}\n    />\n  );\n}\n\nexport {\n  Command,\n  CommandDialog,\n  CommandEmpty,\n  CommandGroup,\n  CommandInput,\n  CommandItem,\n  CommandList,\n  CommandSeparator,\n  CommandShortcut,\n};\n"
  },
  {
    "path": "registry/radix-ui/examples/horizontal-scroll.tsx",
    "content": "import Image from \"next/image\";\nimport { ScrollArea, ScrollBar } from \"@/registry/radix-ui/scroll-area\";\n\nexport interface Artwork {\n  artist: string;\n  art: string;\n}\n\nconst works: Artwork[] = [\n  {\n    artist: \"Ornella Binni\",\n    art: \"https://images.unsplash.com/photo-1465869185982-5a1a7522cbcb?auto=format&fit=crop&w=300&q=80\",\n  },\n  {\n    artist: \"Tom Byrom\",\n    art: \"https://images.unsplash.com/photo-1548516173-3cabfa4607e9?auto=format&fit=crop&w=300&q=80\",\n  },\n  {\n    artist: \"Vladimir Malyavko\",\n    art: \"https://images.unsplash.com/photo-1494337480532-3725c85fd2ab?auto=format&fit=crop&w=300&q=80\",\n  },\n];\n\nexport function ScrollAreaHorizontalDemo() {\n  return (\n    <ScrollArea className=\"bg-background w-96 rounded-md border whitespace-nowrap\">\n      <div className=\"flex w-max space-x-4 p-4\">\n        {works.map((artwork) => (\n          <figure key={artwork.artist} className=\"shrink-0\">\n            <div className=\"overflow-hidden rounded-md\">\n              <Image\n                src={artwork.art}\n                alt={`Photo by ${artwork.artist}`}\n                className=\"aspect-[3/4] h-fit w-fit object-cover\"\n                width={300}\n                height={400}\n              />\n            </div>\n            <figcaption className=\"text-muted-foreground pt-2 text-xs\">\n              Photo by <span className=\"text-foreground font-semibold\">{artwork.artist}</span>\n            </figcaption>\n          </figure>\n        ))}\n      </div>\n      <ScrollBar orientation=\"horizontal\" />\n    </ScrollArea>\n  );\n}\n"
  },
  {
    "path": "registry/radix-ui/examples/timezone-select.tsx",
    "content": "\"use client\";\n\nimport { useId, useMemo, useState } from \"react\";\nimport {\n  Command,\n  CommandEmpty,\n  CommandGroup,\n  CommandInput,\n  CommandItem,\n  CommandList,\n} from \"@/registry/radix-ui/examples/command\";\n\nimport { CheckIcon, ChevronDownIcon } from \"lucide-react\";\n\nimport { Button } from \"@/components/ui/button\";\nimport { Label } from \"@/components/ui/label\";\nimport { Popover, PopoverContent, PopoverTrigger } from \"@/components/ui/popover\";\n\nimport { cn } from \"@/lib/utils\";\n\nexport function TimezoneSelectExample() {\n  const id = useId();\n  const [open, setOpen] = useState<boolean>(false);\n  const [value, setValue] = useState<string>(\"Asia/Calcutta\");\n\n  const timezones = Intl.supportedValuesOf(\"timeZone\");\n\n  const formattedTimezones = useMemo(() => {\n    return timezones\n      .map((timezone) => {\n        const formatter = new Intl.DateTimeFormat(\"en\", {\n          timeZone: timezone,\n          timeZoneName: \"shortOffset\",\n        });\n        const parts = formatter.formatToParts(new Date());\n        const offset = parts.find((part) => part.type === \"timeZoneName\")?.value || \"\";\n        const modifiedOffset = offset === \"GMT\" ? \"GMT+0\" : offset;\n\n        return {\n          value: timezone,\n          label: `(${modifiedOffset}) ${timezone.replace(/_/g, \" \")}`,\n          numericOffset: parseInt(offset.replace(\"GMT\", \"\").replace(\"+\", \"\") || \"0\"),\n        };\n      })\n      .sort((a, b) => a.numericOffset - b.numericOffset);\n  }, [timezones]);\n\n  return (\n    <div className=\"*:not-first:mt-2\">\n      <Label htmlFor={id}>Timezone select with search</Label>\n      <Popover open={open} onOpenChange={setOpen}>\n        <PopoverTrigger asChild>\n          <Button\n            id={id}\n            variant=\"outline\"\n            role=\"combobox\"\n            aria-expanded={open}\n            className=\"bg-background hover:bg-background border-input w-full justify-between px-3 font-normal outline-offset-0 outline-none focus-visible:outline-[3px]\"\n          >\n            <span className={cn(\"truncate\", !value && \"text-muted-foreground\")}>\n              {value ? formattedTimezones.find((timezone) => timezone.value === value)?.label : \"Select timezone\"}\n            </span>\n            <ChevronDownIcon size={16} className=\"text-muted-foreground/80 shrink-0\" aria-hidden=\"true\" />\n          </Button>\n        </PopoverTrigger>\n        <PopoverContent className=\"border-input w-full min-w-[var(--radix-popper-anchor-width)] p-0\" align=\"start\">\n          <Command\n            filter={(value, search) => {\n              const normalizedValue = value.toLowerCase();\n              const normalizedSearch = search.toLowerCase().replace(/\\s+/g, \"\");\n              return normalizedValue.includes(normalizedSearch) ? 1 : 0;\n            }}\n          >\n            <CommandInput placeholder=\"Search timezone...\" />\n            <CommandList>\n              <CommandEmpty>No timezone found.</CommandEmpty>\n              <CommandGroup>\n                {formattedTimezones.map(({ value: itemValue, label }) => (\n                  <CommandItem\n                    key={itemValue}\n                    value={itemValue}\n                    onSelect={(currentValue) => {\n                      setValue(currentValue === value ? \"\" : currentValue);\n                      setOpen(false);\n                    }}\n                  >\n                    {label}\n                    {value === itemValue && <CheckIcon size={16} className=\"ml-auto\" />}\n                  </CommandItem>\n                ))}\n              </CommandGroup>\n            </CommandList>\n          </Command>\n        </PopoverContent>\n      </Popover>\n    </div>\n  );\n}\n"
  },
  {
    "path": "registry/radix-ui/examples/usage-demo.tsx",
    "content": "import { ScrollArea } from \"@/registry/radix-ui/scroll-area\";\n\nexport default function Example() {\n  return (\n    <ScrollArea className=\"h-[200px] w-[350px] rounded-md border p-4\">\n      Jokester began sneaking into the castle in the middle of the night and leaving jokes all over the place: under the\n      king's pillow, in his soup, even in the royal toilet. The king was furious, but he couldn't seem to stop Jokester.\n      And then, one day, the people of the kingdom discovered that the jokes left by Jokester were so funny that they\n      couldn't help but laugh. And once they started laughing, they couldn't stop.\n    </ScrollArea>\n  );\n}\n"
  },
  {
    "path": "registry/radix-ui/examples/vertical-scroll.tsx",
    "content": "import * as React from \"react\";\nimport { ScrollArea } from \"@/registry/radix-ui/scroll-area\";\n\nimport { Separator } from \"@/components/ui/separator\";\n\nconst tags = Array.from({ length: 50 }).map((_, i, a) => `v1.2.0-beta.${a.length - i}`);\n\nexport function ScrollAreaDemo() {\n  return (\n    <ScrollArea className=\"bg-background h-72 w-48 rounded-md border\">\n      <div className=\"p-4\">\n        <h4 className=\"mb-4 text-sm leading-none font-medium\">Tags</h4>\n        {tags.map((tag) => (\n          <React.Fragment key={tag}>\n            <div className=\"text-sm\">{tag}</div>\n            <Separator className=\"my-2\" />\n          </React.Fragment>\n        ))}\n      </div>\n    </ScrollArea>\n  );\n}\n"
  },
  {
    "path": "registry/radix-ui/scroll-area.tsx",
    "content": "\"use client\";\n\nimport * as React from \"react\";\n\nimport * as ScrollAreaPrimitive from \"@radix-ui/react-scroll-area\";\n\nimport { cn } from \"@/lib/utils\";\n\nimport { useTouchPrimary } from \"@/hooks/use-has-primary-touch\";\n\nconst ScrollAreaContext = React.createContext<boolean>(false);\ntype Mask = {\n  top: boolean;\n  bottom: boolean;\n  left: boolean;\n  right: boolean;\n};\n\nconst ScrollArea = React.forwardRef<\n  React.ComponentRef<typeof ScrollAreaPrimitive.Root>,\n  React.ComponentPropsWithoutRef<typeof ScrollAreaPrimitive.Root> & {\n    viewportClassName?: string;\n    /**\n     * `maskHeight` is the height of the mask in pixels.\n     * pass `0` to disable the mask\n     * @default 30\n     */\n    maskHeight?: number;\n    maskClassName?: string;\n  }\n>(({ className, children, scrollHideDelay = 0, viewportClassName, maskClassName, maskHeight = 30, ...props }, ref) => {\n  const [showMask, setShowMask] = React.useState<Mask>({\n    top: false,\n    bottom: false,\n    left: false,\n    right: false,\n  });\n  const viewportRef = React.useRef<HTMLDivElement>(null);\n  const isTouch = useTouchPrimary();\n\n  const checkScrollability = React.useCallback(() => {\n    const element = viewportRef.current;\n    if (!element) return;\n\n    const { scrollTop, scrollLeft, scrollWidth, clientWidth, scrollHeight, clientHeight } = element;\n    setShowMask((prev) => ({\n      ...prev,\n      top: scrollTop > 0,\n      bottom: scrollTop + clientHeight < scrollHeight - 1,\n      left: scrollLeft > 0,\n      right: scrollLeft + clientWidth < scrollWidth - 1,\n    }));\n  }, []);\n\n  React.useEffect(() => {\n    if (typeof window === \"undefined\") return;\n\n    const element = viewportRef.current;\n    if (!element) return;\n\n    const controller = new AbortController();\n    const { signal } = controller;\n\n    const resizeObserver = new ResizeObserver(checkScrollability);\n    resizeObserver.observe(element);\n\n    element.addEventListener(\"scroll\", checkScrollability, { signal });\n    window.addEventListener(\"resize\", checkScrollability, { signal });\n\n    // Run an initial check whenever dependencies change (including pointer mode)\n    checkScrollability();\n\n    return () => {\n      controller.abort();\n      resizeObserver.disconnect();\n    };\n  }, [checkScrollability, isTouch]);\n\n  return (\n    <ScrollAreaContext.Provider value={isTouch}>\n      {isTouch ? (\n        <div\n          ref={ref}\n          role=\"group\"\n          data-slot=\"scroll-area\"\n          aria-roledescription=\"scroll area\"\n          className={cn(\"relative overflow-hidden\", className)}\n          {...props}\n        >\n          <div\n            ref={viewportRef}\n            data-slot=\"scroll-area-viewport\"\n            className={cn(\"size-full overflow-auto rounded-[inherit]\", viewportClassName)}\n            tabIndex={0}\n          >\n            {children}\n          </div>\n\n          {maskHeight > 0 && <ScrollMask showMask={showMask} className={maskClassName} maskHeight={maskHeight} />}\n        </div>\n      ) : (\n        <ScrollAreaPrimitive.Root\n          ref={ref}\n          data-slot=\"scroll-area\"\n          scrollHideDelay={scrollHideDelay}\n          className={cn(\"relative overflow-hidden\", className)}\n          {...props}\n        >\n          <ScrollAreaPrimitive.Viewport\n            ref={viewportRef}\n            data-slot=\"scroll-area-viewport\"\n            className={cn(\"size-full rounded-[inherit]\", viewportClassName)}\n          >\n            {children}\n          </ScrollAreaPrimitive.Viewport>\n\n          {maskHeight > 0 && <ScrollMask showMask={showMask} className={maskClassName} maskHeight={maskHeight} />}\n          <ScrollBar />\n          <ScrollAreaPrimitive.Corner />\n        </ScrollAreaPrimitive.Root>\n      )}\n    </ScrollAreaContext.Provider>\n  );\n});\n\nScrollArea.displayName = ScrollAreaPrimitive.Root.displayName;\n\nconst ScrollBar = React.forwardRef<\n  React.ComponentRef<typeof ScrollAreaPrimitive.ScrollAreaScrollbar>,\n  React.ComponentPropsWithoutRef<typeof ScrollAreaPrimitive.ScrollAreaScrollbar>\n>(({ className, orientation = \"vertical\", ...props }, ref) => {\n  const isTouch = React.useContext(ScrollAreaContext);\n\n  if (isTouch) return null;\n\n  return (\n    <ScrollAreaPrimitive.ScrollAreaScrollbar\n      ref={ref}\n      orientation={orientation}\n      data-slot=\"scroll-area-scrollbar\"\n      className={cn(\n        \"hover:bg-muted dark:hover:bg-muted/50 data-[state=visible]:fade-in-0 data-[state=hidden]:fade-out-0 data-[state=visible]:animate-in data-[state=hidden]:animate-out flex touch-none p-px transition-[colors] duration-150 select-none\",\n        orientation === \"vertical\" && \"h-full w-2.5 border-l border-l-transparent\",\n        orientation === \"horizontal\" && \"h-2.5 flex-col border-t border-t-transparent px-1 pr-1.25\",\n        className\n      )}\n      {...props}\n    >\n      <ScrollAreaPrimitive.ScrollAreaThumb\n        data-slot=\"scroll-area-thumb\"\n        className={cn(\n          \"bg-border relative flex-1 origin-center rounded-full transition-[scale]\",\n          orientation === \"vertical\" && \"my-1 active:scale-y-95\",\n          orientation === \"horizontal\" && \"active:scale-x-98\"\n        )}\n      />\n    </ScrollAreaPrimitive.ScrollAreaScrollbar>\n  );\n});\n\nScrollBar.displayName = ScrollAreaPrimitive.ScrollAreaScrollbar.displayName;\n\nconst ScrollMask = ({\n  showMask,\n  maskHeight,\n  className,\n  ...props\n}: React.ComponentProps<\"div\"> & {\n  showMask: Mask;\n  maskHeight: number;\n}) => {\n  return (\n    <>\n      <div\n        {...props}\n        aria-hidden=\"true\"\n        style={\n          {\n            \"--top-fade-height\": showMask.top ? `${maskHeight}px` : \"0px\",\n            \"--bottom-fade-height\": showMask.bottom ? `${maskHeight}px` : \"0px\",\n          } as React.CSSProperties\n        }\n        className={cn(\n          \"pointer-events-none absolute inset-0 z-10\",\n          \"before:absolute before:inset-x-0 before:top-0 before:transition-[height,opacity] before:duration-300 before:content-['']\",\n          \"after:absolute after:inset-x-0 after:bottom-0 after:transition-[height,opacity] after:duration-300 after:content-['']\",\n          \"before:h-(--top-fade-height) after:h-(--bottom-fade-height)\",\n          showMask.top ? \"before:opacity-100\" : \"before:opacity-0\",\n          showMask.bottom ? \"after:opacity-100\" : \"after:opacity-0\",\n          \"before:from-background before:bg-gradient-to-b before:to-transparent\",\n          \"after:from-background after:bg-gradient-to-t after:to-transparent\",\n          className\n        )}\n      />\n      <div\n        {...props}\n        aria-hidden=\"true\"\n        style={\n          {\n            \"--left-fade-width\": showMask.left ? `${maskHeight}px` : \"0px\",\n            \"--right-fade-width\": showMask.right ? `${maskHeight}px` : \"0px\",\n          } as React.CSSProperties\n        }\n        className={cn(\n          \"pointer-events-none absolute inset-0 z-10\",\n          \"before:absolute before:inset-y-0 before:left-0 before:transition-[width,opacity] before:duration-300 before:content-['']\",\n          \"after:absolute after:inset-y-0 after:right-0 after:transition-[width,opacity] after:duration-300 after:content-['']\",\n          \"before:w-(--left-fade-width) after:w-(--right-fade-width)\",\n          showMask.left ? \"before:opacity-100\" : \"before:opacity-0\",\n          showMask.right ? \"after:opacity-100\" : \"after:opacity-0\",\n          \"before:from-background before:bg-gradient-to-r before:to-transparent\",\n          \"after:from-background after:bg-gradient-to-l after:to-transparent\",\n          className\n        )}\n      />\n    </>\n  );\n};\n\nexport { ScrollArea, ScrollBar };\n"
  },
  {
    "path": "registry/registry.ts",
    "content": "import * as React from \"react\";\nimport { ScrollAreaHorizontalDemo as ScrollAreaHorizontalBaseUIDemo } from \"@/registry/base-ui/examples/horizontal-scroll\";\nimport { TimezonSelectExample as TimezoneSelectBaseUIExample } from \"@/registry/base-ui/examples/timezone-select\";\nimport { ScrollAreaDemo as ScrollAreaVerticalBaseUIDemo } from \"@/registry/base-ui/examples/vertical-scroll\";\nimport { ScrollAreaHorizontalDemo as ScrollAreaHorizontalRadixDemo } from \"@/registry/radix-ui/examples/horizontal-scroll\";\nimport { TimezoneSelectExample as TimezoneSelectRadixExample } from \"@/registry/radix-ui/examples/timezone-select\";\nimport { ScrollAreaDemo as ScrollAreaVerticalRadixDemo } from \"@/registry/radix-ui/examples/vertical-scroll\";\n\nconst registryKeys = [\"lina\", \"vertical-scroll\", \"horizontal-scroll\", \"timezone-select\"] as const;\ntype RegistryKeys = (typeof registryKeys)[number];\n\ninterface Registry {\n  name: string;\n  description: string;\n  variants: {\n    radix: React.ComponentType<() => React.JSX.Element>;\n    base: React.ComponentType<() => React.JSX.Element>;\n  };\n  categories?: string[];\n  meta?: string;\n}\n\nconst Index: Record<RegistryKeys, Registry> = {\n  lina: {\n    name: \"scroll-area\",\n    description:\n      \"A responsive scroll area that feels native on touch devices, offering custom styling and enhanced interactions where it matters most.\",\n    variants: {\n      radix: ScrollAreaVerticalRadixDemo,\n      base: ScrollAreaVerticalBaseUIDemo,\n    },\n  },\n  \"vertical-scroll\": {\n    name: \"vertical-scroll-demo\",\n    description: \"Adaptive Vertical Scroll Area Demo\",\n    variants: {\n      radix: ScrollAreaVerticalRadixDemo,\n      base: ScrollAreaVerticalBaseUIDemo,\n    },\n    categories: [\"scroll-area\"],\n    meta: \"Special component that uses source.ts\",\n  },\n  \"horizontal-scroll\": {\n    name: \"horizontal-scroll-demo\",\n    description: \"Adaptive Horizontal Scroll Area Demo\",\n    variants: {\n      radix: ScrollAreaHorizontalRadixDemo,\n      base: ScrollAreaHorizontalBaseUIDemo,\n    },\n  },\n  \"timezone-select\": {\n    name: \"timezone-select-demo\",\n    description: \"Adaptive Timezone Select Demo\",\n    variants: {\n      radix: TimezoneSelectRadixExample,\n      base: TimezoneSelectBaseUIExample,\n    },\n  },\n};\n\nexport { Index, type RegistryKeys, type Registry };\n"
  },
  {
    "path": "registry.json",
    "content": "{\n  \"name\": \"lina\",\n  \"homepage\": \"https://lina.sameer.sh\",\n  \"$schema\": \"https://ui.shadcn.com/schema/registry.json\",\n  \"items\": [\n    {\n      \"name\": \"lina-radix\",\n      \"type\": \"registry:ui\",\n      \"title\": \"Radix Adaptive Scroll Area\",\n      \"description\": \"A responsive scroll area that feels native on touch devices, offering custom styling and enhanced interactions where it matters most.\",\n      \"dependencies\": [\"@radix-ui/react-scroll-area\"],\n      \"devDependencies\": [\"tw-animate-css\"],\n      \"files\": [\n        {\n          \"path\": \"registry/radix-ui/scroll-area.tsx\",\n          \"type\": \"registry:ui\"\n        },\n        {\n          \"path\": \"hooks/use-has-primary-touch.tsx\",\n          \"type\": \"registry:hook\"\n        }\n      ]\n    },\n    {\n      \"name\": \"lina-base\",\n      \"type\": \"registry:ui\",\n      \"title\": \"Base UI Adaptive Scroll Area\",\n      \"description\": \"A responsive scroll area that feel native on touch devices, offereing custom styling and enchanced interactions where it matter most.\",\n      \"dependencies\": [\"@base-ui-components/react\"],\n      \"devDependencies\": [\"tw-animate-css\"],\n      \"files\": [\n        {\n          \"path\": \"registry/base-ui/scroll-area.tsx\",\n          \"type\": \"registry:ui\"\n        },\n        { \"path\": \"hooks/use-has-primary-touch.tsx\", \"type\": \"registry:ui\" }\n      ]\n    },\n    {\n      \"name\": \"vertical-scroll-demo-radix\",\n      \"type\": \"registry:component\",\n      \"title\": \"Vertical Scroll Area Radix Demo\",\n      \"description\": \"A demo showcasing the vertical scroll area component using Lina's Radix UI\",\n      \"registryDependencies\": [\"https://lina.sameer.sh/r/lina-radix.json\"],\n      \"files\": [{ \"path\": \"registry/radix-ui/examples/vertical-scroll.tsx\", \"type\": \"registry:component\" }]\n    },\n    {\n      \"name\": \"vertical-scroll-demo-base\",\n      \"type\": \"registry:component\",\n      \"title\": \"Vertical Scroll Area Base Demo\",\n      \"description\": \"A demo showcasing the vertical scroll area component using Lina's Base UI\",\n      \"registryDependencies\": [\"https://lina.sameer.sh/r/lina-base.json\"],\n      \"files\": [{ \"path\": \"registry/base-ui/examples/vertical-scroll.tsx\", \"type\": \"registry:component\" }]\n    },\n    {\n      \"name\": \"horizontal-scroll-demo-radix\",\n      \"type\": \"registry:component\",\n      \"title\": \"Horizontal Scroll Area Radix Demo\",\n      \"description\": \"A demo showcasing the horizontal scroll area component using Lina's Radix UI\",\n      \"registryDependencies\": [\"https://lina.sameer.sh/r/lina-radix.json\"],\n      \"files\": [{ \"path\": \"registry/radix-ui/examples/horizontal-scroll.tsx\", \"type\": \"registry:component\" }]\n    },\n    {\n      \"name\": \"horizontal-scroll-demo-base\",\n      \"type\": \"registry:component\",\n      \"title\": \"Horizontal Scroll Area Base Demo\",\n      \"description\": \"A demo showcasing the horizontal scroll area component using Lina's Base UI\",\n      \"registryDependencies\": [\"https://lina.sameer.sh/r/lina-base.json\"],\n      \"files\": [{ \"path\": \"registry/base-ui/examples/horizontal-scroll.tsx\", \"type\": \"registry:component\" }]\n    },\n    {\n      \"name\": \"timezone-select-demo-radix\",\n      \"type\": \"registry:component\",\n      \"title\": \"Timezone Select Radix Demo\",\n      \"description\": \"A demo showcasing the timezone select component using Lina based on Radix UI\",\n      \"registryDependencies\": [\n        \"button\",\n        \"label\",\n        \"popover\",\n        \"https://lina.sameer.sh/r/lina-radix.json\",\n        \"https://lina.sameer.sh/r/command-radix.json\"\n      ],\n      \"dependencies\": [\"lucide-react\"],\n      \"files\": [{ \"path\": \"registry/radix-ui/examples/timezone-select.tsx\", \"type\": \"registry:component\" }]\n    },\n    {\n      \"name\": \"timezone-select-demo-base\",\n      \"type\": \"registry:component\",\n      \"title\": \"Timezone Select Base UI Demo\",\n      \"description\": \"A demo showcasing the timezone select component using Lina based on Base UI\",\n      \"registryDependencies\": [\n        \"button\",\n        \"label\",\n        \"popover\",\n        \"https://lina.sameer.sh/r/lina-base.json\",\n        \"https://lina.sameer.sh/r/command-base.json\"\n      ],\n      \"dependencies\": [\"lucide-react\"],\n      \"files\": [{ \"path\": \"registry/base-ui/examples/timezone-select.tsx\", \"type\": \"registry:component\" }]\n    },\n    {\n      \"name\": \"command-radix\",\n      \"type\": \"registry:ui\",\n      \"title\": \"Command based on Lina's Radix UI variant\",\n      \"description\": \"A command component built using Lina's Radix UI\",\n      \"registryDependencies\": [\"button\", \"dialog\", \"https://lina.sameer.sh/r/lina-radix.json\"],\n      \"dependencies\": [\"lucide-react\", \"cmdk\"],\n      \"files\": [{ \"path\": \"registry/radix-ui/examples/command.tsx\", \"type\": \"registry:ui\" }]\n    },\n    {\n      \"name\": \"command-base\",\n      \"type\": \"registry:ui\",\n      \"title\": \"Command based on Lina's Base UI variant\",\n      \"description\": \"A command component built using Lina's Base UI\",\n      \"registryDependencies\": [\"button\", \"dialog\", \"https://lina.sameer.sh/r/lina-base.json\"],\n      \"dependencies\": [\"lucide-react\", \"cmdk\"],\n      \"files\": [{ \"path\": \"registry/base-ui/examples/command.tsx\", \"type\": \"registry:ui\" }]\n    }\n  ]\n}\n"
  },
  {
    "path": "tsconfig.json",
    "content": "{\n  \"compilerOptions\": {\n    \"target\": \"ES2017\",\n    \"lib\": [\"dom\", \"dom.iterable\", \"esnext\"],\n    \"allowJs\": true,\n    \"skipLibCheck\": true,\n    \"strict\": true,\n    \"noEmit\": true,\n    \"verbatimModuleSyntax\": true,\n    \"esModuleInterop\": true,\n    \"module\": \"esnext\",\n    \"baseUrl\": \".\",\n    \"moduleResolution\": \"bundler\",\n    \"resolveJsonModule\": true,\n    \"isolatedModules\": true,\n    \"jsx\": \"preserve\",\n    \"incremental\": true,\n    \"plugins\": [\n      {\n        \"name\": \"next\"\n      }\n    ],\n    \"paths\": {\n      \"@/*\": [\"./*\"]\n    }\n  },\n  \"include\": [\"next-env.d.ts\", \"**/*.ts\", \"**/*.tsx\", \".next/types/**/*.ts\"],\n  \"exclude\": [\"node_modules\"]\n}\n"
  }
]