{
  "name": "feature/carousel",
  "type": "registry:component",
  "description": "Feature carousel with Tabs-driven content",
  "files": [
    {
      "path": "example/Feature/SectionFeature_Carousel.astro",
      "type": "registry:component",
      "content": "---\nimport Card from '@@/components/ui/Card.astro';\nimport { Icon } from 'astro-icon/components';\nimport image1 from '@/assets/placeholder.png';\nimport image2 from '@/assets/placeholder.png';\nimport image3 from '@/assets/placeholder.png';\nimport image4 from '@/assets/placeholder.png';\n---\n\n<section class=\"py-24 sm:py-32\" data-scheme=\"shift\">\n  <div class=\"container\">\n    <div class=\"mb-10 text-center\">\n      <div\n        class=\"rounded-card mb-4 inline-flex items-center gap-2 px-4 py-2 text-sm\"\n        data-scheme=\"shift\"\n      >\n        <span class=\"bg-accent h-2 w-2 rounded-full\"></span>\n        Deploy faster\n      </div>\n      <h2 class=\"h2 mb-4\">\n        Everything you need to <span class=\"sp-emphasis\">deploy</span> your app\n      </h2>\n      <p class=\"text-fg-sub mx-auto max-w-3xl text-lg md:text-xl\">\n        Modern workflow, integrations, security, and performance—ready to ship\n      </p>\n    </div>\n  </div>\n\n  <!-- Carousel (full-bleed like testimonials) -->\n  <div\n    class=\"relative -ml-[calc(50vw-50%)] mt-10 w-screen sm:mt-16\"\n    data-carousel=\"root\"\n  >\n    <div\n      data-carousel=\"scroller\"\n      class=\"flex w-full snap-x snap-mandatory items-stretch gap-6 overflow-x-auto scroll-smooth px-6 [-ms-overflow-style:none] [scroll-padding-left:1.5rem] [scrollbar-width:none] lg:px-8 lg:[scroll-padding-left:2rem] [&::-webkit-scrollbar]:hidden\"\n    >\n      <!-- Leading spacer -->\n      <div\n        aria-hidden=\"true\"\n        class=\"w-6 shrink-0 [scroll-snap-align:none] lg:w-8\"\n      >\n      </div>\n      <!-- Slide 1 -->\n      <div\n        data-slide\n        class=\"flex w-[88%] min-w-[88%] shrink-0 snap-start sm:w-[66%] sm:min-w-[66%] lg:w-[43%] lg:min-w-[43%]\"\n      >\n        <Card className=\"shadow-8 h-full w-full flex-1 lg:rounded-2xl\">\n          <div class=\"w-full\">\n            <img\n              src={image1.src}\n              width={image1.width}\n              height={image1.height}\n              alt=\"\"\n              class=\"w-full object-cover\"\n              style=\"aspect-ratio: 4/3;\"\n            />\n          </div>\n          <div class=\"p-5 md:p-7\">\n            <h3 class=\"typography-ui-12-regular color-text-secondary\">\n              Releases\n            </h3>\n            <p class=\"text-fg-sub mt-2 max-w-[42rem]\">\n              Lorem ipsum dolor sit amet, consectetur adipiscing elit. In\n              gravida justo et nulla efficitur, maximus egestas sem\n              pellentesque.\n            </p>\n          </div>\n        </Card>\n      </div>\n\n      <!-- Slide 2 -->\n      <div\n        data-slide\n        class=\"flex w-[88%] min-w-[88%] shrink-0 snap-start sm:w-[66%] sm:min-w-[66%] lg:w-[43%] lg:min-w-[43%]\"\n      >\n        <Card className=\"shadow-8 h-full w-full flex-1 lg:rounded-2xl\">\n          <div class=\"w-full\">\n            <img\n              src={image2.src}\n              width={image2.width}\n              height={image2.height}\n              alt=\"\"\n              class=\"w-full object-cover\"\n              style=\"aspect-ratio: 4/3;\"\n            />\n          </div>\n          <div class=\"p-5 md:p-7\">\n            <h3 class=\"typography-ui-12-regular color-text-secondary\">\n              Integrations\n            </h3>\n            <p class=\"text-fg-sub mt-2 max-w-[42rem]\">\n              Curabitur auctor, ex quis auctor venenatis, eros arcu rhoncus\n              massa.\n            </p>\n          </div>\n        </Card>\n      </div>\n\n      <!-- Slide 3 -->\n      <div\n        data-slide\n        class=\"flex w-[88%] min-w-[88%] shrink-0 snap-start sm:w-[66%] sm:min-w-[66%] lg:w-[43%] lg:min-w-[43%]\"\n      >\n        <Card className=\"shadow-8 h-full w-full flex-1 lg:rounded-2xl\">\n          <div class=\"w-full\">\n            <img\n              src={image3.src}\n              width={image3.width}\n              height={image3.height}\n              alt=\"\"\n              class=\"w-full object-cover\"\n              style=\"aspect-ratio: 4/3;\"\n            />\n          </div>\n          <div class=\"p-5 md:p-7\">\n            <h3 class=\"typography-ui-12-regular color-text-secondary\">\n              Security\n            </h3>\n            <p class=\"text-fg-sub mt-2 max-w-[42rem]\">\n              Vestibulum ante ipsum primis in faucibus orci luctus et ultrices\n              posuere cubilia.\n            </p>\n          </div>\n        </Card>\n      </div>\n\n      <!-- Slide 4 -->\n      <div\n        data-slide\n        class=\"flex w-[88%] min-w-[88%] shrink-0 snap-start sm:w-[66%] sm:min-w-[66%] lg:w-[43%] lg:min-w-[43%]\"\n      >\n        <Card className=\"shadow-8 h-full w-full flex-1 lg:rounded-2xl\">\n          <div class=\"w-full\">\n            <img\n              src={image4.src}\n              width={image4.width}\n              height={image4.height}\n              alt=\"\"\n              class=\"w-full object-cover\"\n              style=\"aspect-ratio: 4/3;\"\n            />\n          </div>\n          <div class=\"p-5 md:p-7\">\n            <h3 class=\"typography-ui-12-regular color-text-secondary\">\n              Performance\n            </h3>\n            <p class=\"text-fg-sub mt-2 max-w-[42rem]\">\n              Sed congue eros non finibus molestie. Vestibulum euismod augue vel\n              commodo vulputate. Maecenas at augue sed elit dictum vulputate.\n            </p>\n          </div>\n        </Card>\n      </div>\n      <!-- Trailing spacer -->\n      <div\n        aria-hidden=\"true\"\n        class=\"w-6 shrink-0 [scroll-snap-align:none] lg:w-8\"\n      >\n      </div>\n    </div>\n\n    <!-- Controls -->\n    <div class=\"mt-6 flex items-center justify-end gap-2 px-6 lg:px-8\">\n      <button\n        type=\"button\"\n        data-action=\"prev\"\n        aria-label=\"Previous\"\n        class=\"carousel-btn group\"\n      >\n        <span\n          data-scheme=\"bg\"\n          class=\"shadow-2 inline-flex h-10 w-10 items-center justify-center rounded-full\"\n        >\n          <Icon name=\"lucide:chevron-left\" size={18} />\n        </span>\n      </button>\n      <button type=\"button\" data-action=\"next\" aria-label=\"Next\" class=\"carousel-btn group\">\n        <span\n          data-scheme=\"bg\"\n          class=\"shadow-2 inline-flex h-10 w-10 items-center justify-center rounded-full\"\n        >\n          <Icon name=\"lucide:chevron-right\" size={18} />\n        </span>\n      </button>\n    </div>\n  </div>\n</section>\n\n<style>\n  .carousel-btn {\n    cursor: pointer;\n    transition: transform 0.15s cubic-bezier(0.4, 0, 0.2, 1), opacity 0.15s cubic-bezier(0.4, 0, 0.2, 1);\n  }\n\n  .carousel-btn:hover:not(:disabled) {\n    transform: translateY(1px) scale(0.99);\n    opacity: 0.9;\n  }\n\n  .carousel-btn:active:not(:disabled) {\n    transform: translateY(2px) scale(0.98);\n    opacity: 0.8;\n  }\n\n  .carousel-btn:disabled {\n    opacity: 0.5;\n    cursor: not-allowed;\n    pointer-events: none;\n  }\n</style>\n\n<script>\n  const root = document.querySelector('[data-carousel=\"root\"]');\n  if (root) {\n    const scroller = root.querySelector('[data-carousel=\"scroller\"]');\n    const prev = root.querySelector('[data-action=\"prev\"]') as HTMLButtonElement | null;\n    const next = root.querySelector('[data-action=\"next\"]') as HTMLButtonElement | null;\n\n    const updateButtonStates = () => {\n      if (!scroller || !prev || !next) return;\n\n      const isAtStart = scroller.scrollLeft <= 1;\n      const isAtEnd = scroller.scrollLeft + scroller.clientWidth >= scroller.scrollWidth - 1;\n\n      prev.disabled = isAtStart;\n      next.disabled = isAtEnd;\n    };\n\n    const animateScrollTo = (targetLeft, duration = 320) => {\n      if (!scroller) return;\n      const startLeft = scroller.scrollLeft;\n      const delta = targetLeft - startLeft;\n      if (delta === 0) return;\n\n      const easeOutCubic = (t) => 1 - Math.pow(1 - t, 3);\n      const start = performance.now();\n\n      const step = (now) => {\n        const elapsed = now - start;\n        const t = Math.min(1, elapsed / duration);\n        const eased = easeOutCubic(t);\n        scroller.scrollLeft = startLeft + delta * eased;\n        if (t < 1) requestAnimationFrame(step);\n        else updateButtonStates();\n      };\n      requestAnimationFrame(step);\n    };\n\n    const scrollPage = (dir) => {\n      if (!scroller) return;\n      const slide = scroller.querySelector(\"[data-slide]\");\n      const slideWidth =\n        slide instanceof HTMLElement\n          ? slide.clientWidth\n          : scroller.clientWidth / 3;\n      const amount = slideWidth + 24; // slide + gap\n      animateScrollTo(scroller.scrollLeft + dir * amount, 280);\n    };\n\n    prev && prev.addEventListener(\"click\", () => scrollPage(-1));\n    next && next.addEventListener(\"click\", () => scrollPage(1));\n\n    // Update button states on scroll and resize\n    scroller && scroller.addEventListener(\"scroll\", updateButtonStates);\n    window.addEventListener(\"resize\", updateButtonStates);\n\n    // Initial state\n    updateButtonStates();\n  }\n</script>\n"
    }
  ],
  "category": "example",
  "registryDependencies": [
    "tabs",
    "tabs-list",
    "tabs-trigger",
    "tabs-content",
    "carousel"
  ]
}