{
  "name": "feature/grid-tabs",
  "type": "registry:component",
  "description": "Feature section with grid-based tabs",
  "files": [
    {
      "path": "example/Feature/SectionFeature_GridTabs.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\ninterface FeatureBlock {\n  id: string;\n  title: string;\n  description: string;\n  image: ImageMetadata;\n  imageAlt: string;\n}\n\nconst featureBlocks: FeatureBlock[] = [\n  {\n    id: 'knowledge',\n    title: 'Company knowledge',\n    description: \"One home that's organized, searchable, and accurate.\",\n    image: image1,\n    imageAlt: 'Company knowledge dashboard',\n  },\n  {\n    id: 'search',\n    title: 'Enterprise search',\n    description: 'Instantly surface answers across Notion and connected apps.',\n    image: image2,\n    imageAlt: 'Enterprise search interface',\n  },\n  {\n    id: 'projects',\n    title: 'Integrated projects',\n    description: 'Plan tasks, track progress, and align teams.',\n    image: image3,\n    imageAlt: 'Project management view',\n  },\n  {\n    id: 'workflows',\n    title: 'Workflows & integrations',\n    description: 'Automate any process and integrate your tools.',\n    image: image4,\n    imageAlt: 'Workflow automation',\n  },\n];\n---\n\n<section class=\"relative py-12 sm:py-16\" data-scheme=\"bg\">\n  <div class=\"container max-w-5xl\">\n    <div class=\"mb-6 text-left\">\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      >\n        <span class=\"bg-accent h-2 w-2 rounded-full\"></span>\n        Layout Gallery\n      </div>\n      <h2\n        class=\"h2 mb-2 text-2xl sm:text-3xl\"\n\n      >\n        Grid Tabs: Interactive feature showcase\n      </h2>\n      <p\n        class=\"text-fg-sub max-w-2xl text-base sm:text-lg\"\n\n      >\n        Display multiple features with clickable grid tabs that reveal\n        corresponding visuals below.\n      </p>\n    </div>\n\n    <!-- Grid Tab Navigation -->\n    <div\n      data-grid-tabs=\"blocks\"\n      class=\"mb-6 grid grid-cols-2 gap-3 md:grid-cols-4\"\n    >\n      {\n        featureBlocks.map((block, index) => (\n          <button\n            type=\"button\"\n            data-block-id={block.id}\n            data-block-trigger\n            data-scheme=\"shift\"\n            aria-selected={index === 0 ? \"true\" : \"false\"}\n            class=\"group flex cursor-pointer flex-col justify-start overflow-hidden rounded-[var(--sp-radius-card)] border-2 border-transparent p-3 text-left transition-all aria-selected:bg-[color-mix(in_srgb,_var(--sp-fg)_8%,_transparent)] md:p-4\"\n          >\n            <h3 class=\"mb-1 text-base font-semibold text-[color:var(--sp-fg)] transition-colors md:mb-2 md:text-lg\">\n              {block.title}\n            </h3>\n            <p class=\"text-xs text-[color:var(--sp-fg-sub)] md:text-sm\">\n              {block.description}\n            </p>\n          </button>\n        ))\n      }\n    </div>\n\n    <!-- Carousel Container -->\n    <div\n      class=\"relative overflow-hidden rounded-[var(--sp-radius-card)]\"\n      data-grid-tabs=\"carousel\"\n    >\n      <div\n        data-carousel=\"wrapper\"\n        class=\"flex transition-transform duration-500 ease-in-out\"\n        style=\"transform: translateX(0);\"\n      >\n        {\n          featureBlocks.map((block, index) => (\n            <div\n              data-carousel-slide={block.id}\n              data-slide-index={index}\n              class=\"w-full flex-shrink-0\"\n            >\n              <div class=\"relative w-full overflow-hidden rounded-[var(--sp-radius-card)]\">\n                <img\n                  src={block.image.src}\n                  width={block.image.width}\n                  height={block.image.height}\n                  alt={block.imageAlt}\n                  class=\"w-full object-cover\"\n                  style=\"aspect-ratio: 16/10;\"\n                  loading={index === 0 ? \"eager\" : \"lazy\"}\n                />\n              </div>\n            </div>\n          ))\n        }\n      </div>\n\n      <!-- Navigation Buttons -->\n      <div class=\"absolute inset-y-0 left-4 flex items-center\">\n        <button\n          type=\"button\"\n          data-carousel-action=\"prev\"\n          aria-label=\"Previous\"\n          class=\"shadow-4 flex h-9 w-9 items-center justify-center rounded-full bg-[color:var(--sp-bg)] text-[color:var(--sp-fg)] opacity-0 transition-opacity hover:bg-[color-mix(in_srgb,_var(--sp-fg)_6%,_var(--sp-bg))] disabled:cursor-not-allowed disabled:opacity-30\"\n        >\n          <Icon name=\"lucide:chevron-left\" size={18} />\n        </button>\n      </div>\n      <div class=\"absolute inset-y-0 right-4 flex items-center\">\n        <button\n          type=\"button\"\n          data-carousel-action=\"next\"\n          aria-label=\"Next\"\n          class=\"shadow-4 flex h-9 w-9 items-center justify-center rounded-full bg-[color:var(--sp-bg)] text-[color:var(--sp-fg)] opacity-0 transition-opacity hover:bg-[color-mix(in_srgb,_var(--sp-fg)_6%,_var(--sp-bg))] disabled:cursor-not-allowed disabled:opacity-30\"\n        >\n          <Icon name=\"lucide:chevron-right\" size={18} />\n        </button>\n      </div>\n    </div>\n  </div>\n</section>\n\n<script>\n  document.addEventListener(\"DOMContentLoaded\", () => {\n    const carousel = document.querySelector('[data-grid-tabs=\"carousel\"]');\n    if (!carousel) return;\n\n    const wrapper = carousel.querySelector(\n      '[data-carousel=\"wrapper\"]',\n    ) as HTMLElement;\n    const prevBtn = carousel.querySelector(\n      '[data-carousel-action=\"prev\"]',\n    ) as HTMLButtonElement;\n    const nextBtn = carousel.querySelector(\n      '[data-carousel-action=\"next\"]',\n    ) as HTMLButtonElement;\n    const blockTriggers = document.querySelectorAll(\"[data-block-trigger]\");\n    const indicators = document.querySelectorAll(\"[data-indicator]\");\n    const slides = carousel.querySelectorAll(\"[data-carousel-slide]\");\n\n    let currentIndex = 0;\n    const totalSlides = slides.length;\n\n    const updateCarousel = (index: number) => {\n      currentIndex = index;\n      const offset = -100 * index;\n      if (wrapper) {\n        wrapper.style.transform = `translateX(${offset}%)`;\n      }\n\n      // Update block triggers\n      blockTriggers.forEach((trigger, i) => {\n        trigger.setAttribute(\"aria-selected\", i === index ? \"true\" : \"false\");\n      });\n\n      // Update indicators\n      indicators.forEach((indicator, i) => {\n        indicator.setAttribute(\"aria-selected\", i === index ? \"true\" : \"false\");\n      });\n\n      // Update navigation button states\n      if (prevBtn && nextBtn) {\n        prevBtn.disabled = index === 0;\n        nextBtn.disabled = index === totalSlides - 1;\n\n        // Show buttons on hover or when not at edges\n        if (index > 0) {\n          prevBtn.style.opacity = \"1\";\n        } else {\n          prevBtn.style.opacity = \"0.3\";\n        }\n\n        if (index < totalSlides - 1) {\n          nextBtn.style.opacity = \"1\";\n        } else {\n          nextBtn.style.opacity = \"0.3\";\n        }\n      }\n    };\n\n    // Block click handlers\n    blockTriggers.forEach((trigger, index) => {\n      trigger.addEventListener(\"click\", () => {\n        updateCarousel(index);\n      });\n    });\n\n    // Block hover handlers\n    blockTriggers.forEach((trigger, index) => {\n      trigger.addEventListener(\"mouseenter\", () => {\n        updateCarousel(index);\n      });\n    });\n\n    // Indicator click handlers\n    indicators.forEach((indicator, index) => {\n      indicator.addEventListener(\"click\", () => {\n        updateCarousel(index);\n      });\n    });\n\n    // Navigation button handlers\n    prevBtn?.addEventListener(\"click\", () => {\n      if (currentIndex > 0) {\n        updateCarousel(currentIndex - 1);\n      }\n    });\n\n    nextBtn?.addEventListener(\"click\", () => {\n      if (currentIndex < totalSlides - 1) {\n        updateCarousel(currentIndex + 1);\n      }\n    });\n\n    // Keyboard navigation\n    blockTriggers.forEach((trigger, index) => {\n      trigger.addEventListener(\"keydown\", (e) => {\n        const event = e as KeyboardEvent;\n        if (event.key === \"ArrowRight\" && index < totalSlides - 1) {\n          updateCarousel(index + 1);\n          (blockTriggers[index + 1] as HTMLElement)?.focus();\n        } else if (event.key === \"ArrowLeft\" && index > 0) {\n          updateCarousel(index - 1);\n          (blockTriggers[index - 1] as HTMLElement)?.focus();\n        }\n      });\n    });\n\n    // Initialize\n    updateCarousel(0);\n\n    // Hover effects for navigation buttons\n    carousel.addEventListener(\"mouseenter\", () => {\n      if (currentIndex > 0) {\n        prevBtn.style.opacity = \"1\";\n      }\n      if (currentIndex < totalSlides - 1) {\n        nextBtn.style.opacity = \"1\";\n      }\n    });\n\n    carousel.addEventListener(\"mouseleave\", () => {\n      if (prevBtn.disabled) {\n        prevBtn.style.opacity = \"0.3\";\n      }\n      if (nextBtn.disabled) {\n        nextBtn.style.opacity = \"0.3\";\n      }\n    });\n  });\n</script>\n\n<style>\n  [data-carousel-action] {\n    transition: opacity 0.2s ease;\n  }\n\n  [data-grid-tabs=\"carousel\"]:hover [data-carousel-action]:not(:disabled) {\n    opacity: 1;\n  }\n</style>\n"
    }
  ],
  "category": "example",
  "registryDependencies": [
    "tabs",
    "tabs-list",
    "tabs-trigger",
    "tabs-content"
  ]
}