# Sekmeli koleksiyonlar: ücretsiz Shopify bölümü

> Yeni gelenler, Çok satanlar, İndirim ya da istediğiniz koleksiyonlar tek bölümde, sekmeli ızgarada; her sekmede Tümünü gör bağlantısı. Erişilebilir sekmeler.

Sekmeli koleksiyonlar, birkaç koleksiyonu Yeni gelenler, Çok satanlar ve İndirim gibi sekmelerle tek bir ürün ızgarasında toplayan ücretsiz bir Shopify bölümüdür. Her sekme, bir koleksiyon seçip isteğe bağlı olarak etiket verdiğiniz bir bloktur; fiyat, rozetler ve isteğe bağlı hızlı sepete ekle düğmesi olan kartlarla en çok 16 ürün gösterir, sonuna da koleksiyona giden bir Tümünü gör bağlantısı eklenebilir. Tüm ürünler Liquid ile oluşturulur; arama motorları ve JavaScript’i kapalı müşteriler grupları alt alta görür, küçük bir betik de bunları klavyeyle kullanılabilen sekmelere dönüştürür. Online Store 2.0 temalarında uygulama olmadan çalışır.

- **Kategori:** Ürün ve koleksiyon keşfi
- **Kullanıldığı yerler:** Ana sayfa, Açılış sayfaları, Koleksiyon
- **Okuduğu veri:** Koleksiyonlar ve ürünleri
- **Boyut:** 4 dosyada 39 KB, küçük bir betikle
- **Lisans:** MIT, © 2026 Lintel
- **Sayfa:** https://lintelagency.com/tr/kaynaklar/shopify-bolumleri/sekmeli-koleksiyonlar
- **Canlı demo:** https://lintelagency.com/resources/shopify-sections/demo/lib-collection-tabs.html
- **Eklenme tarihi:** 2026-11-02

## Ne işe yarar

- Üç ayrı öne çıkan koleksiyon bölümü yerine Yeni gelenler, Çok satanlar ve İndirim sekmelerinden oluşan tek bir ana sayfa bölümü
- Her bütçe ya da hediye alınacak kişi için ayrı bir sekmesi olan hediye rehberi açılış sayfası
- Alt grupları sekmelere ayrılmış bir koleksiyon sayfası (Kupalar, Tabaklar, Kaseler)

## Tema düzenleyici ayarları

Bölüm tema düzenleyicide “Lib · Collection tabs” adıyla görünür. Kimlikler, türler, etiketler ve varsayılan değerler bölümün şemasından gelir. Etiketler tema düzenleyicide göründüğü gibi İngilizcedir.

### Content

| Kimlik | Tür | Etiket | Varsayılan | Seçenekler ya da aralık |
| --- | --- | --- | --- | --- |
| `heading` | `inline_richtext` | Heading | Shop the range |  |
| `heading_tag` | `select` | Heading tag | h2 | `h1`, `h2`, `h3`, `p` |
| `heading_size` | `select` | Heading size | medium | `small`, `medium`, `large` |
| `text` | `richtext` | Intro text | – |  |
| `tabs_label` | `text` | Tab list name (screen readers) | Collections |  |
| `tab_style` | `select` | Tab style | pill | `pill`, `underline` |
| `view_all_label` | `text` | View all link | View all |  |
| `view_all_style` | `select` | View all style | outline | `primary`, `outline`, `text` |

### Products

| Kimlik | Tür | Etiket | Varsayılan | Seçenekler ya da aralık |
| --- | --- | --- | --- | --- |
| `products_per_tab` | `range` | Products per tab | `4` | 2–16, step 1 |
| `image_ratio` | `select` | Image shape | portrait | `square`, `portrait`, `tall`, `landscape` |
| `card_style` | `select` | Card style | plain | `plain`, `card` |
| `card_radius` | `range` | Corner radius | `12` | 0–24 px, step 2 |
| `show_vendor` | `checkbox` | Show vendor | `false` |  |
| `show_second_image` | `checkbox` | Show second image on hover | `true` |  |
| `show_quick_add` | `checkbox` | Show quick add | `false` |  |
| `quick_add_label` | `text` | Quick add button | Add to cart |  |
| `choose_label` | `text` | Link for products with options | Choose options |  |
| `sale_label` | `text` | Sale badge | Sale |  |
| `sold_out_label` | `text` | Sold out badge | Sold out |  |
| `sale_price_label` | `text` | Sale price label (screen readers) | Sale price |  |
| `regular_price_label` | `text` | Regular price label (screen readers) | Regular price |  |

### Layout

| Kimlik | Tür | Etiket | Varsayılan | Seçenekler ya da aralık |
| --- | --- | --- | --- | --- |
| `columns` | `range` | Columns on desktop | `4` | 2–6, step 1 |
| `columns_mobile` | `range` | Columns on mobile | `2` | 1–2, step 1 |
| `layout_mobile` | `select` | Layout on mobile | grid | `grid`, `row` |
| `section_width` | `select` | Width | page | `page`, `full` |
| `text_alignment` | `select` | Heading and tabs alignment on desktop | center | `left`, `center` |
| `text_alignment_mobile` | `select` | Heading and tabs alignment on mobile | left | `left`, `center` |

### Colors

| Kimlik | Tür | Etiket | Varsayılan | Seçenekler ya da aralık |
| --- | --- | --- | --- | --- |
| `color_bg` | `color` | Background | #FFFFFF |  |
| `color_bg_gradient` | `color_background` | Background gradient | – |  |
| `color_text` | `color` | Text | #1F1B17 |  |
| `color_accent` | `color` | Accent (buttons, badges) | #7A5A3A |  |
| `color_accent_text` | `color` | Text on accent | #FFFFFF |  |
| `color_card` | `color` | Card background | #FAF6F1 |  |

### Spacing and visibility

| Kimlik | Tür | Etiket | Varsayılan | Seçenekler ya da aralık |
| --- | --- | --- | --- | --- |
| `padding_top` | `range` | Top padding on desktop | `64` | 0–200 px, step 4 |
| `padding_bottom` | `range` | Bottom padding on desktop | `64` | 0–200 px, step 4 |
| `padding_top_mobile` | `range` | Top padding on mobile | `40` | 0–160 px, step 4 |
| `padding_bottom_mobile` | `range` | Bottom padding on mobile | `40` | 0–160 px, step 4 |
| `show_on` | `select` | Show on | all | `all`, `desktop`, `mobile` |
| `anchor_id` | `text` | Anchor ID | – |  |

### Motion

| Kimlik | Tür | Etiket | Varsayılan | Seçenekler ya da aralık |
| --- | --- | --- | --- | --- |
| `animate` | `checkbox` | Fade products in when switching tabs | `true` |  |

## Bloklar

Toplamda en fazla 6 blok.

### Tab (`tab`)

| Kimlik | Tür | Etiket | Varsayılan | Seçenekler ya da aralık |
| --- | --- | --- | --- | --- |
| `collection` | `collection` | Collection | – |  |
| `label` | `text` | Tab label | – |  |

## Kurulum

### Shopify yönetim panelinde

1. Canlı temanızda değil, bir kopyasında çalışın: Shopify yönetim panelinde **Online Mağaza > Temalar** sayfasına gidin, mevcut temanızın **…** menüsünü açın ve **Kopya oluştur**’u seçin.
2. Kopyada **…** menüsünü açın ve **Kodu düzenle**’yi seçin.
3. `sections` klasörüne `lib-collection-tabs.liquid` adında yeni bir dosya ekleyin, aşağıdaki kaynak koddan `sections/lib-collection-tabs.liquid` içeriğini yapıştırıp kaydedin.
4. `lib-product-card.liquid` ve `lib-image.liquid` ve `lib-button.liquid` dosyalarını da aynı şekilde `snippets` klasörüne ekleyin. Başka bir Lib bölümünden gelen aynı adlı bir snippet zaten varsa aynı dosyadır; tek kopya yeterli.
5. Kopyada **Özelleştir**’i açın, **Bölüm ekle**’yi seçin ve **Lib · Collection tabs** bölümünü ekleyin. Örnek içeriği kendi içeriğinizle değiştirin, renkleri ayarlayın.
6. Kopyayı önizleyin, her şey doğru göründüğünde yayınlayın.

### Shopify CLI ile

Yerel tema klasörünüzde dosyaları indirin ve yalnızca bunları yayında olmayan bir temaya gönderin (temanın kimliğini `shopify theme list` gösterir):

```sh
curl -fsSL -o sections/lib-collection-tabs.liquid https://lintelagency.com/resources/shopify-sections/files/lib-collection-tabs.liquid
curl -fsSL -o snippets/lib-product-card.liquid https://lintelagency.com/resources/shopify-sections/files/lib-product-card.liquid
curl -fsSL -o snippets/lib-image.liquid https://lintelagency.com/resources/shopify-sections/files/lib-image.liquid
curl -fsSL -o snippets/lib-button.liquid https://lintelagency.com/resources/shopify-sections/files/lib-button.liquid
shopify theme push --theme <unpublished-theme-id> --only sections/lib-collection-tabs.liquid --only snippets/lib-product-card.liquid --only snippets/lib-image.liquid --only snippets/lib-button.liquid
```

Canlı temaya asla göndermeyin: her zaman yayında olmayan bir temanın kimliğini verin, `--live` ya da `--allow-live` kullanmayın. Ardından bölümü yukarıdaki gibi tema düzenleyicide ekleyin.

## Dosyalar

- [sections/lib-collection-tabs.liquid](https://lintelagency.com/resources/shopify-sections/files/lib-collection-tabs.liquid): `sections/` klasörüne
- [snippets/lib-product-card.liquid](https://lintelagency.com/resources/shopify-sections/files/lib-product-card.liquid): `snippets/` klasörüne
- [snippets/lib-image.liquid](https://lintelagency.com/resources/shopify-sections/files/lib-image.liquid): `snippets/` klasörüne
- [snippets/lib-button.liquid](https://lintelagency.com/resources/shopify-sections/files/lib-button.liquid): `snippets/` klasörüne

## Sık sorulan sorular

### Kaç sekme ekleyebilirim?

En çok altı. Her sekme, bir koleksiyon seçtiğiniz bir bloktur; kendi etiketinizi yazmazsanız koleksiyonun adı kullanılır. Yalnızca bir sekme eklerseniz bölüm, sekme listesi olmadan düz bir ürün ızgarası gösterir.

### Sekmeler erişilebilir mi?

Evet. WAI-ARIA sekme kalıbını izler: sekme listesinde gerçek düğmeler vardır, ok tuşları, Home ve End ile sekmeler arasında gezinilir, seçili sekme ekran okuyucuya bildirilir ve her panel kendi sekmesiyle etiketlenir. Odak her zaman görünür.

### Arama motorları gizli sekmelerdeki ürünleri görür mü?

Evet. Her sekmenin ürünleri sayfanın HTML’indedir; betik yalnızca seçili olmayan panelleri gizler. JavaScript olmadan gruplar kendi başlıklarıyla art arda görünür.

### Müşteriler ızgaradan sepete ekleyebilir mi?

Evet, hızlı sepete ekle seçeneğini açmanız yeterli: tek varyantlı ürünlerde sepete ekle düğmesi (Shopify’ın kendi ürün formu) görünür; seçenekli ürünlerde "Seçenekleri belirle" bağlantısı ürün sayfasına götürür.

## Kaynak kod

### sections/lib-collection-tabs.liquid

```liquid
{%- comment -%}
  MIT License · (c) 2026 Lintel · https://lintelagency.com/resources/shopify-sections
{%- endcomment -%}
{%- comment -%}
  Collection tabs: a product grid with tabs, one tab per collection (New in, Best sellers, Sale…),
  in a single section. Every tab's products are rendered by Liquid, so search engines and shoppers
  without JavaScript see all of them, one titled group after another; a small custom element turns
  the groups into tabs (WAI-ARIA tabs pattern: arrow keys, Home, End). Each tab can end with a
  "view all" link to its collection. Cards show price, badges and an optional quick add.
  Depends on: snippets/lib-product-card.liquid, snippets/lib-image.liquid, snippets/lib-button.liquid
{%- endcomment -%}

{%- liquid
  assign s = section.settings
  assign heading_tag = s.heading_tag | default: 'h2'
  assign panel_tag = 'h3'
  assign card_tag = 'h3'
  if heading_tag == 'h3' or heading_tag == 'p'
    assign panel_tag = 'h4'
    assign card_tag = 'h4'
  endif
  assign cols = s.columns | plus: 0
  assign cols_m = s.columns_mobile | plus: 0
  assign limit = s.products_per_tab | plus: 0
  assign img_vw = 100 | divided_by: cols
  assign img_sizes = '(min-width: 990px) ' | append: img_vw | append: 'vw, (min-width: 750px) 33vw, 50vw'
-%}

<lib-collection-tabs
  class="lib-tabs lib-tabs--{{ s.section_width }}"
  {% if s.anchor_id != blank %}
    id="{{ s.anchor_id | handleize }}"
  {% endif %}
  data-show="{{ s.show_on }}"
  data-card="{{ s.card_style }}"
  data-layout-m="{{ s.layout_mobile }}"
  data-tab-style="{{ s.tab_style }}"
  {% if s.animate %}
    data-animate
  {% endif %}
  style="
    --lib-bg: {{ s.color_bg }};
    {% if s.color_bg_gradient != blank %}--lib-bg-image: {{ s.color_bg_gradient }};{% endif %}
    --lib-text: {{ s.color_text }};
    --lib-accent: {{ s.color_accent }};
    --lib-accent-text: {{ s.color_accent_text }};
    --lib-card: {{ s.color_card }};
    --lib-cols: {{ cols }};
    --lib-cols-m: {{ cols_m }};
    --lib-radius-card: {{ s.card_radius }}px;
    --lib-pt: {{ s.padding_top }}px;
    --lib-pb: {{ s.padding_bottom }}px;
    --lib-pt-m: {{ s.padding_top_mobile }}px;
    --lib-pb-m: {{ s.padding_bottom_mobile }}px;
  "
>
  <div class="lib-tabs__inner">
    <header class="lib-tabs__header" data-align="{{ s.text_alignment }}" data-align-m="{{ s.text_alignment_mobile }}">
      {%- if s.heading != blank -%}
        <{{ heading_tag }} class="lib-tabs__heading lib-tabs__heading--{{ s.heading_size }}">
          {{- s.heading -}}
        </{{ heading_tag }}>
      {%- endif -%}
      {%- if s.text != blank -%}
        <div class="lib-tabs__text">{{ s.text }}</div>
      {%- endif -%}

      {%- if section.blocks.size > 1 -%}
        {%- comment -%} The script shows the tab list; without it every group shows with its own title. {%- endcomment -%}
        <div class="lib-tabs__tablist" role="tablist" aria-label="{{ s.tabs_label | escape }}" hidden data-tablist>
          {%- for block in section.blocks -%}
            {%- assign label = block.settings.label | default: block.settings.collection.title | default: 'Collection' -%}
            <button
              type="button"
              role="tab"
              class="lib-tabs__tab"
              id="LibTab-{{ block.id }}"
              aria-controls="LibPanel-{{ block.id }}"
              aria-selected="{% if forloop.first %}true{% else %}false{% endif %}"
              {% unless forloop.first %}
                tabindex="-1"
              {% endunless %}
              {{ block.shopify_attributes }}
            >
              {{- label | escape -}}
            </button>
          {%- endfor -%}
        </div>
      {%- endif -%}
    </header>

    {%- for block in section.blocks -%}
      {%- liquid
        assign b = block.settings
        assign c = b.collection
        assign label = b.label | default: c.title | default: 'Collection'
        assign id_prefix = 'LibTabs-' | append: block.id
        assign first_tab = forloop.first
      -%}
      <div class="lib-tabs__panel" id="LibPanel-{{ block.id }}" data-panel data-tab="LibTab-{{ block.id }}">
        <{{ panel_tag }} class="lib-tabs__panel-title">{{ label | escape }}</{{ panel_tag }}>
        <ul class="lib-tabs__grid" role="list">
          {%- if c != blank and c.products.size > 0 -%}
            {%- for item in c.products limit: limit -%}
              {%- liquid
                assign eager = false
                if section.index <= 2 and first_tab and forloop.index <= cols
                  assign eager = true
                endif
              -%}
              <li class="lib-tabs__item">
                {%- render 'lib-product-card',
                  product: item,
                  title_tag: card_tag,
                  ratio: s.image_ratio,
                  sizes: img_sizes,
                  eager: eager,
                  show_vendor: s.show_vendor,
                  show_second_image: s.show_second_image,
                  show_quick_add: s.show_quick_add,
                  quick_add_label: s.quick_add_label,
                  choose_label: s.choose_label,
                  sold_out_label: s.sold_out_label,
                  sale_label: s.sale_label,
                  sale_price_label: s.sale_price_label,
                  regular_price_label: s.regular_price_label,
                  id_prefix: id_prefix
                -%}
              </li>
            {%- endfor -%}
          {%- elsif request.design_mode -%}
            {%- for i in (1..cols) -%}
              <li class="lib-tabs__item">{%- render 'lib-product-card', title_tag: card_tag, ratio: s.image_ratio -%}</li>
            {%- endfor -%}
          {%- endif -%}
        </ul>
        {%- if s.view_all_label != blank and c != blank -%}
          <div class="lib-tabs__more">
            {%- render 'lib-button', label: s.view_all_label, url: c.url, style: s.view_all_style -%}
          </div>
        {%- endif -%}
      </div>
    {%- endfor -%}
  </div>
</lib-collection-tabs>

{% stylesheet %}
  .lib-tabs {
    display: block;
    background-color: var(--lib-bg);
    background-image: var(--lib-bg-image, none);
    color: var(--lib-text);
    padding: var(--lib-pt) 1rem var(--lib-pb);
  }
  .lib-tabs__inner { max-width: 1200px; margin: 0 auto; }
  .lib-tabs--full .lib-tabs__inner { max-width: none; }
  @media (max-width: 749px) {
    .lib-tabs { padding-top: var(--lib-pt-m); padding-bottom: var(--lib-pb-m); }
    .lib-tabs[data-show='desktop'] { display: none; }
  }
  @media (min-width: 750px) {
    .lib-tabs[data-show='mobile'] { display: none; }
  }

  .lib-tabs__header { display: grid; gap: 0.75rem; margin-bottom: clamp(1.25rem, 3vw, 2rem); }
  .lib-tabs__heading {
    margin: 0;
    font-size: clamp(1.75rem, 3vw, 2.5rem);
    line-height: 1.15;
    letter-spacing: -0.02em;
    text-wrap: balance;
  }
  .lib-tabs__heading--small { font-size: clamp(1.25rem, 1.8vw, 1.5rem); }
  .lib-tabs__heading--large { font-size: clamp(2rem, 4vw, 3.25rem); }
  .lib-tabs__text { max-width: 40rem; font-size: 1rem; line-height: 1.6; opacity: 0.85; }
  .lib-tabs__text > :first-child { margin-top: 0; }
  .lib-tabs__text > :last-child { margin-bottom: 0; }
  .lib-tabs__header[data-align='center'] { justify-items: center; text-align: center; }
  @media (max-width: 749px) {
    .lib-tabs__header[data-align-m='left'] { justify-items: start; text-align: left; }
    .lib-tabs__header[data-align-m='center'] { justify-items: center; text-align: center; }
  }

  /* Tabs: a row that scrolls sideways when the labels don't fit. */
  .lib-tabs__tablist {
    display: flex;
    gap: 0.5rem;
    max-width: 100%;
    margin-top: 0.5rem;
    padding: 0.25rem;
    overflow-x: auto;
    scrollbar-width: none;
  }
  .lib-tabs__tablist[hidden] { display: none; }
  .lib-tabs__tab {
    flex: none;
    min-height: 2.75rem;
    padding: 0.55rem 1.1rem;
    border: 1.5px solid color-mix(in srgb, var(--lib-text) 22%, transparent);
    border-radius: 999px;
    background: transparent;
    color: inherit;
    font: inherit;
    font-size: 0.9375rem;
    font-weight: 600;
    line-height: 1.2;
    white-space: nowrap;
    cursor: pointer;
    transition: background-color 0.2s ease, color 0.2s ease, border-color 0.2s ease;
  }
  .lib-tabs__tab:hover { border-color: var(--lib-text); }
  .lib-tabs__tab[aria-selected='true'] { background: var(--lib-text); border-color: var(--lib-text); color: var(--lib-bg); }
  .lib-tabs__tab:focus-visible { outline: 2px solid var(--lib-accent); outline-offset: 2px; }
  .lib-tabs[data-tab-style='underline'] .lib-tabs__tablist { gap: 1.5rem; padding-inline: 0; }
  .lib-tabs[data-tab-style='underline'] .lib-tabs__tab {
    padding-inline: 0;
    border: 0;
    border-bottom: 2px solid transparent;
    border-radius: 0;
    opacity: 0.7;
  }
  .lib-tabs[data-tab-style='underline'] .lib-tabs__tab[aria-selected='true'] {
    background: none;
    color: inherit;
    border-bottom-color: currentColor;
    opacity: 1;
  }

  .lib-tabs__panel + .lib-tabs__panel { margin-top: clamp(2rem, 5vw, 3.5rem); }
  .lib-tabs[data-ready] .lib-tabs__panel + .lib-tabs__panel { margin-top: 0; }
  .lib-tabs__panel[hidden] { display: none; }
  .lib-tabs__panel:focus-visible { outline: 2px solid var(--lib-accent); outline-offset: 6px; border-radius: 4px; }
  .lib-tabs__panel-title { margin: 0 0 1rem; font-size: 1.25rem; line-height: 1.3; }
  .lib-tabs[data-ready] .lib-tabs__panel-title {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }

  .lib-tabs__grid {
    display: grid;
    grid-template-columns: repeat(var(--lib-cols), minmax(0, 1fr));
    gap: clamp(1rem, 2vw, 1.5rem);
    margin: 0;
    padding: 0;
    list-style: none;
  }
  .lib-tabs__item { display: flex; min-width: 0; }
  @media (max-width: 749px) {
    .lib-tabs__grid { grid-template-columns: repeat(var(--lib-cols-m), minmax(0, 1fr)); }
    .lib-tabs[data-layout-m='row'] .lib-tabs__grid {
      grid-auto-flow: column;
      grid-template-columns: none;
      grid-auto-columns: calc((100% - 1rem) / var(--lib-cols-m) - 2.5rem);
      overflow-x: auto;
      scroll-snap-type: x mandatory;
      scrollbar-width: none;
      padding-bottom: 0.25rem;
    }
    .lib-tabs[data-layout-m='row'] .lib-tabs__item { scroll-snap-align: start; }
  }
  .lib-tabs__more { display: flex; justify-content: center; margin-top: clamp(1.5rem, 3vw, 2.25rem); }

  @media (prefers-reduced-motion: no-preference) {
    .lib-tabs[data-animate] .lib-tabs__panel[data-shown] .lib-tabs__item { animation: lib-tabs-in 0.45s cubic-bezier(0.2, 0.7, 0.2, 1) both; }
    .lib-tabs[data-animate] .lib-tabs__panel[data-shown] .lib-tabs__item:nth-child(2) { animation-delay: 40ms; }
    .lib-tabs[data-animate] .lib-tabs__panel[data-shown] .lib-tabs__item:nth-child(3) { animation-delay: 80ms; }
    .lib-tabs[data-animate] .lib-tabs__panel[data-shown] .lib-tabs__item:nth-child(n + 4) { animation-delay: 120ms; }
  }
  @media (prefers-reduced-motion: reduce) {
    .lib-tabs__tab { transition: none; }
  }
  @keyframes lib-tabs-in {
    from { opacity: 0; transform: translateY(10px); }
  }
{% endstylesheet %}

{% javascript %}
  (() => {
    if (customElements.get('lib-collection-tabs')) return;

    class LibCollectionTabs extends HTMLElement {
      connectedCallback() {
        this.tablist = this.querySelector('[data-tablist]');
        if (!this.tablist) return;
        this.tabs = [...this.tablist.querySelectorAll('[role="tab"]')];
        this.panels = this.tabs.map((tab) => this.querySelector(`#${CSS.escape(tab.getAttribute('aria-controls'))}`));
        this.panels.forEach((panel, i) => {
          panel.setAttribute('role', 'tabpanel');
          panel.setAttribute('aria-labelledby', this.tabs[i].id);
          panel.tabIndex = 0;
        });
        this.tablist.hidden = false;
        this.toggleAttribute('data-ready', true);
        this.select(Math.max(0, this.tabs.findIndex((t) => t.getAttribute('aria-selected') === 'true')), false);

        this.tablist.addEventListener('click', (event) => {
          const tab = event.target.closest('[role="tab"]');
          if (tab) this.select(this.tabs.indexOf(tab), true);
        });
        this.tablist.addEventListener('keydown', (event) => this.onKey(event));
        // Theme editor: selecting a tab's block shows its panel.
        this.addEventListener('shopify:block:select', (event) => {
          const index = this.tabs.findIndex((t) => t.id === `LibTab-${event.detail.blockId}`);
          if (index >= 0) this.select(index, false);
        });
      }

      onKey(event) {
        const current = this.tabs.indexOf(document.activeElement);
        if (current < 0) return;
        const last = this.tabs.length - 1;
        const moves = {ArrowRight: current + 1, ArrowLeft: current - 1, Home: 0, End: last};
        if (!(event.key in moves)) return;
        event.preventDefault();
        const next = (moves[event.key] + this.tabs.length) % this.tabs.length;
        this.select(next, true);
      }

      select(index, focus) {
        this.tabs.forEach((tab, i) => {
          const active = i === index;
          tab.setAttribute('aria-selected', String(active));
          tab.tabIndex = active ? 0 : -1;
          this.panels[i].hidden = !active;
          this.panels[i].toggleAttribute('data-shown', active && focus);
        });
        if (focus) {
          this.tabs[index].focus();
          this.tabs[index].scrollIntoView({block: 'nearest', inline: 'nearest'});
        }
      }
    }
    customElements.define('lib-collection-tabs', LibCollectionTabs);
  })();
{% endjavascript %}

{% schema %}
{
  "name": "Lib · Collection tabs",
  "tag": "section",
  "class": "lib-section",
  "max_blocks": 6,
  "settings": [
    { "type": "header", "content": "Content" },
    { "type": "inline_richtext", "id": "heading", "label": "Heading", "default": "Shop the range" },
    {
      "type": "select",
      "id": "heading_tag",
      "label": "Heading tag",
      "info": "Use H1 only when this is the page's main heading.",
      "options": [
        { "value": "h1", "label": "H1" },
        { "value": "h2", "label": "H2" },
        { "value": "h3", "label": "H3" },
        { "value": "p", "label": "Paragraph" }
      ],
      "default": "h2"
    },
    {
      "type": "select",
      "id": "heading_size",
      "label": "Heading size",
      "options": [
        { "value": "small", "label": "Small" },
        { "value": "medium", "label": "Medium" },
        { "value": "large", "label": "Large" }
      ],
      "default": "medium"
    },
    { "type": "richtext", "id": "text", "label": "Intro text" },
    { "type": "text", "id": "tabs_label", "label": "Tab list name (screen readers)", "default": "Collections" },
    {
      "type": "select",
      "id": "tab_style",
      "label": "Tab style",
      "options": [
        { "value": "pill", "label": "Pills" },
        { "value": "underline", "label": "Underline" }
      ],
      "default": "pill"
    },
    { "type": "text", "id": "view_all_label", "label": "View all link", "info": "Shown under each tab, linking to its collection. Leave empty to hide.", "default": "View all" },
    {
      "type": "select",
      "id": "view_all_style",
      "label": "View all style",
      "options": [
        { "value": "primary", "label": "Solid" },
        { "value": "outline", "label": "Outline" },
        { "value": "text", "label": "Text link" }
      ],
      "default": "outline"
    },

    { "type": "header", "content": "Products" },
    { "type": "range", "id": "products_per_tab", "label": "Products per tab", "min": 2, "max": 16, "step": 1, "default": 4 },
    {
      "type": "select",
      "id": "image_ratio",
      "label": "Image shape",
      "options": [
        { "value": "square", "label": "Square" },
        { "value": "portrait", "label": "Portrait" },
        { "value": "tall", "label": "Tall" },
        { "value": "landscape", "label": "Landscape" }
      ],
      "default": "portrait"
    },
    {
      "type": "select",
      "id": "card_style",
      "label": "Card style",
      "options": [
        { "value": "plain", "label": "Plain" },
        { "value": "card", "label": "Card" }
      ],
      "default": "plain"
    },
    { "type": "range", "id": "card_radius", "label": "Corner radius", "min": 0, "max": 24, "step": 2, "unit": "px", "default": 12 },
    { "type": "checkbox", "id": "show_vendor", "label": "Show vendor", "default": false },
    { "type": "checkbox", "id": "show_second_image", "label": "Show second image on hover", "default": true },
    { "type": "checkbox", "id": "show_quick_add", "label": "Show quick add", "info": "Products with options link to their page instead.", "default": false },
    { "type": "text", "id": "quick_add_label", "label": "Quick add button", "default": "Add to cart" },
    { "type": "text", "id": "choose_label", "label": "Link for products with options", "default": "Choose options" },
    { "type": "text", "id": "sale_label", "label": "Sale badge", "default": "Sale" },
    { "type": "text", "id": "sold_out_label", "label": "Sold out badge", "default": "Sold out" },
    { "type": "text", "id": "sale_price_label", "label": "Sale price label (screen readers)", "default": "Sale price" },
    { "type": "text", "id": "regular_price_label", "label": "Regular price label (screen readers)", "default": "Regular price" },

    { "type": "header", "content": "Layout" },
    { "type": "range", "id": "columns", "label": "Columns on desktop", "min": 2, "max": 6, "step": 1, "default": 4 },
    { "type": "range", "id": "columns_mobile", "label": "Columns on mobile", "min": 1, "max": 2, "step": 1, "default": 2 },
    {
      "type": "select",
      "id": "layout_mobile",
      "label": "Layout on mobile",
      "options": [
        { "value": "grid", "label": "Grid" },
        { "value": "row", "label": "Swipeable row" }
      ],
      "default": "grid"
    },
    {
      "type": "select",
      "id": "section_width",
      "label": "Width",
      "options": [
        { "value": "page", "label": "Page width" },
        { "value": "full", "label": "Full width" }
      ],
      "default": "page"
    },
    {
      "type": "select",
      "id": "text_alignment",
      "label": "Heading and tabs alignment on desktop",
      "options": [
        { "value": "left", "label": "Left" },
        { "value": "center", "label": "Center" }
      ],
      "default": "center"
    },
    {
      "type": "select",
      "id": "text_alignment_mobile",
      "label": "Heading and tabs alignment on mobile",
      "options": [
        { "value": "left", "label": "Left" },
        { "value": "center", "label": "Center" }
      ],
      "default": "left"
    },

    { "type": "header", "content": "Colors" },
    { "type": "color", "id": "color_bg", "label": "Background", "default": "#FFFFFF" },
    { "type": "color_background", "id": "color_bg_gradient", "label": "Background gradient", "info": "Optional. Covers the background color." },
    { "type": "color", "id": "color_text", "label": "Text", "default": "#1F1B17" },
    { "type": "color", "id": "color_accent", "label": "Accent (buttons, badges)", "default": "#7A5A3A" },
    { "type": "color", "id": "color_accent_text", "label": "Text on accent", "default": "#FFFFFF" },
    { "type": "color", "id": "color_card", "label": "Card background", "default": "#FAF6F1" },

    { "type": "header", "content": "Spacing and visibility" },
    { "type": "range", "id": "padding_top", "label": "Top padding on desktop", "min": 0, "max": 200, "step": 4, "unit": "px", "default": 64 },
    { "type": "range", "id": "padding_bottom", "label": "Bottom padding on desktop", "min": 0, "max": 200, "step": 4, "unit": "px", "default": 64 },
    { "type": "range", "id": "padding_top_mobile", "label": "Top padding on mobile", "min": 0, "max": 160, "step": 4, "unit": "px", "default": 40 },
    { "type": "range", "id": "padding_bottom_mobile", "label": "Bottom padding on mobile", "min": 0, "max": 160, "step": 4, "unit": "px", "default": 40 },
    {
      "type": "select",
      "id": "show_on",
      "label": "Show on",
      "options": [
        { "value": "all", "label": "All devices" },
        { "value": "desktop", "label": "Desktop only" },
        { "value": "mobile", "label": "Mobile only" }
      ],
      "default": "all"
    },
    { "type": "text", "id": "anchor_id", "label": "Anchor ID", "info": "Optional. Link to this section with #your-id." },

    { "type": "header", "content": "Motion" },
    { "type": "checkbox", "id": "animate", "label": "Fade products in when switching tabs", "info": "Never when reduced motion is on.", "default": true }
  ],
  "blocks": [
    {
      "type": "tab",
      "name": "Tab",
      "settings": [
        { "type": "collection", "id": "collection", "label": "Collection" },
        { "type": "text", "id": "label", "label": "Tab label", "info": "Optional. Uses the collection's title when empty." }
      ]
    }
  ],
  "presets": [
    {
      "name": "Lib · Collection tabs",
      "blocks": [
        { "type": "tab", "settings": { "label": "New in" } },
        { "type": "tab", "settings": { "label": "Best sellers" } },
        { "type": "tab", "settings": { "label": "Sale" } }
      ]
    }
  ]
}
{% endschema %}
```

### snippets/lib-product-card.liquid

```liquid
{%- comment -%}
  MIT License · (c) 2026 Lintel · https://lintelagency.com/resources/shopify-sections
{%- endcomment -%}
{% doc %}
  Product card shared by the library's product sections: image (second image on hover), optional
  vendor, price with compare-at price, sale and sold-out badges, and an optional quick add. Quick add
  is a plain Shopify product form that posts the only variant to /cart/add; products with options
  link to the product page. Colors come from the parent section's --lib-* custom properties.
  With `template: true` it prints empty slots (data-slot) for a script to fill from product JSON,
  so cards built in the browser look exactly like cards built in Liquid.
  @param {product} [product] - The product; blank prints a placeholder card (theme editor only)
  @param {boolean} [template] - Print empty slots for a script instead of a product
  @param {string} [title_tag] - Tag for the product title (default 'h3')
  @param {string} [ratio] - Image shape: 'square' (default), 'portrait', 'tall' or 'landscape'
  @param {string} [sizes] - sizes attribute for the image
  @param {boolean} [eager] - Load the image immediately
  @param {boolean} [show_vendor] - Show the vendor above the title
  @param {boolean} [show_second_image] - Show the second image on hover
  @param {boolean} [show_quick_add] - Show the quick add button or the choose options link
  @param {string} [quick_add_label] - Quick add button text
  @param {string} [choose_label] - Link text for products with options
  @param {string} [sold_out_label] - Badge and button text for sold-out products
  @param {string} [sale_label] - Badge text for products on sale
  @param {string} [sale_price_label] - Screen-reader label before the sale price
  @param {string} [regular_price_label] - Screen-reader label before the compare-at price
  @param {string} [id_prefix] - Unique prefix for the title id (the quick add button points at it)
  @example
  {% render 'lib-product-card', product: product, ratio: 'portrait', show_quick_add: true, quick_add_label: 'Add to cart', id_prefix: section.id %}
{% enddoc %}
{%- liquid
  assign tag = title_tag | default: 'h3'
  assign shape = ratio | default: 'square'
  assign title_id = id_prefix | append: '-' | append: product.id
  assign on_sale = false
  if product.compare_at_price > product.price
    assign on_sale = true
  endif
  assign has_img2 = false
  if show_second_image and product.media.size > 1 and product.media[1].preview_image != blank
    assign has_img2 = true
  endif
-%}

{%- if template -%}
  <article class="lib-card">
    <div class="lib-card__media" data-ratio="{{ shape }}">
      <img class="lib-card__img" data-slot="image" alt="" loading="lazy" width="600" height="600" hidden>
      <span class="lib-card__badge lib-card__badge--sold-out" data-slot="sold-out" hidden>{{ sold_out_label | escape }}</span>
      <span class="lib-card__badge" data-slot="sale" hidden>{{ sale_label | escape }}</span>
    </div>
    <div class="lib-card__body">
      {%- if show_vendor -%}
        <p class="lib-card__vendor" data-slot="vendor"></p>
      {%- endif -%}
      <{{ tag }} class="lib-card__title"><a class="lib-card__link" data-slot="link" href=""></a></{{ tag }}>
      <p class="lib-card__price">
        <span class="lib-card__sr" data-slot="sale-label" hidden>{{ sale_price_label | escape }}</span>
        <span class="lib-card__price-now" data-slot="price"></span>
        <span class="lib-card__sr" data-slot="regular-label" hidden>{{ regular_price_label | escape }}</span>
        <s class="lib-card__price-was" data-slot="compare" hidden></s>
      </p>
    </div>
  </article>
{%- elsif product != blank -%}
  <article class="lib-card{% if product.available == false %} is-sold-out{% endif %}">
    <div class="lib-card__media" data-ratio="{{ shape }}">
      {%- render 'lib-image', image: product.featured_image, class: 'lib-card__img', sizes: sizes, eager: eager, placeholder: 'product-1' -%}
      {%- if has_img2 -%}
        <div class="lib-card__img2" aria-hidden="true">
          {%- render 'lib-image', image: product.media[1].preview_image, class: 'lib-card__img', sizes: sizes -%}
        </div>
      {%- endif -%}
      {%- if product.available == false and sold_out_label != blank -%}
        <span class="lib-card__badge lib-card__badge--sold-out">{{ sold_out_label | escape }}</span>
      {%- elsif on_sale and sale_label != blank -%}
        <span class="lib-card__badge">{{ sale_label | escape }}</span>
      {%- endif -%}
    </div>

    <div class="lib-card__body">
      {%- if show_vendor and product.vendor != blank -%}
        <p class="lib-card__vendor">{{ product.vendor | escape }}</p>
      {%- endif -%}
      <{{ tag }} class="lib-card__title" id="{{ title_id }}">
        <a class="lib-card__link" href="{{ product.url }}">{{ product.title | escape }}</a>
      </{{ tag }}>
      <p class="lib-card__price">
        {%- if on_sale -%}
          <span class="lib-card__sr">{{ sale_price_label | escape }}</span>
          <span class="lib-card__price-now lib-card__price-now--sale">{{ product.price | money }}</span>
          <span class="lib-card__sr">{{ regular_price_label | escape }}</span>
          <s class="lib-card__price-was">{{ product.compare_at_price | money }}</s>
        {%- else -%}
          <span class="lib-card__price-now">{{ product.price | money }}</span>
        {%- endif -%}
      </p>

      {%- if show_quick_add -%}
        <div class="lib-card__cta">
          {%- if product.has_only_default_variant -%}
            {%- form 'product', product, class: 'lib-card__form' -%}
              <input type="hidden" name="id" value="{{ product.selected_or_first_available_variant.id }}">
              <input type="hidden" name="quantity" value="1">
              <button
                type="submit"
                name="add"
                class="lib-card__add"
                aria-describedby="{{ title_id }}"
                {% if product.available == false %}
                  disabled
                {% endif %}
              >
                {%- if product.available -%}
                  {{- quick_add_label | escape -}}
                {%- else -%}
                  {{- sold_out_label | default: quick_add_label | escape -}}
                {%- endif -%}
              </button>
            {%- endform -%}
          {%- else -%}
            <a class="lib-card__add" href="{{ product.url }}" aria-describedby="{{ title_id }}">
              {{- choose_label | escape -}}
            </a>
          {%- endif -%}
        </div>
      {%- endif -%}
    </div>
  </article>
{%- else -%}
  <article class="lib-card">
    <div class="lib-card__media" data-ratio="{{ shape }}">
      {{ 'product-1' | placeholder_svg_tag: 'lib-card__img' }}
    </div>
    <div class="lib-card__body">
      <{{ tag }} class="lib-card__title">Example product title</{{ tag }}>
      <p class="lib-card__price"><span class="lib-card__price-now">{{ 4800 | money }}</span></p>
    </div>
  </article>
{%- endif -%}

{% stylesheet %}
  .lib-card {
    position: relative;
    display: flex;
    flex: 1;
    flex-direction: column;
    min-width: 0;
    border-radius: var(--lib-radius-card, 12px);
    color: var(--lib-text, #1f1b17);
  }
  [data-card='card'] .lib-card { background: var(--lib-card, #faf6f1); }
  .lib-card__media {
    position: relative;
    overflow: hidden;
    aspect-ratio: 1;
    border-radius: var(--lib-radius-card, 12px);
    background: color-mix(in srgb, var(--lib-text, #1f1b17) 6%, transparent);
  }
  .lib-card__media[data-ratio='portrait'] { aspect-ratio: 4 / 5; }
  .lib-card__media[data-ratio='tall'] { aspect-ratio: 2 / 3; }
  .lib-card__media[data-ratio='landscape'] { aspect-ratio: 4 / 3; }
  [data-card='card'] .lib-card__media { border-end-start-radius: 0; border-end-end-radius: 0; }
  .lib-card__img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
    transition: transform 0.6s cubic-bezier(0.2, 0.7, 0.2, 1);
  }
  svg.lib-card__img { fill: color-mix(in srgb, var(--lib-text, #1f1b17) 22%, transparent); }
  .lib-card__img2 { position: absolute; inset: 0; opacity: 0; transition: opacity 0.4s ease; }
  @media (hover: hover) {
    .lib-card:hover .lib-card__img2 { opacity: 1; }
    .lib-card:hover .lib-card__img { transform: scale(1.03); }
  }
  .lib-card:focus-within .lib-card__img2 { opacity: 1; }
  .lib-card.is-sold-out .lib-card__media img { opacity: 0.6; }

  .lib-card__badge {
    position: absolute;
    z-index: 2;
    top: 0.75rem;
    left: 0.75rem;
    padding: 0.3rem 0.7rem;
    border-radius: 999px;
    background: var(--lib-accent, #1f1b17);
    color: var(--lib-accent-text, #fff);
    font-size: 0.75rem;
    font-weight: 600;
    letter-spacing: 0.03em;
    line-height: 1.2;
    pointer-events: none;
  }
  .lib-card__badge[hidden] { display: none; }
  .lib-card__badge--sold-out {
    background: var(--lib-bg, #fff);
    color: var(--lib-text, #1f1b17);
    box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--lib-text, #1f1b17) 20%, transparent);
  }

  .lib-card__body { display: flex; flex: 1; flex-direction: column; gap: 0.3rem; padding-top: 0.9rem; }
  [data-card='card'] .lib-card__body { padding: 0.9rem 1rem 1rem; }
  .lib-card__vendor { margin: 0; font-size: 0.75rem; letter-spacing: 0.08em; text-transform: uppercase; opacity: 0.7; }
  .lib-card__vendor:empty { display: none; }
  .lib-card__title { margin: 0; font-size: 1rem; font-weight: 600; line-height: 1.3; }
  .lib-card__link { color: inherit; text-decoration: none; }
  /* The title link covers the whole card; the quick add button sits above it. */
  .lib-card__link::after { content: ''; position: absolute; inset: 0; z-index: 1; border-radius: var(--lib-radius-card, 12px); }
  .lib-card__link:hover { text-decoration: underline; text-underline-offset: 0.2em; }
  .lib-card__link:focus-visible { outline: none; }
  .lib-card__link:focus-visible::after { outline: 2px solid var(--lib-accent, #1f1b17); outline-offset: 3px; }
  .lib-card__price { display: flex; flex-wrap: wrap; align-items: baseline; gap: 0.5rem; margin: 0; font-size: 0.9375rem; }
  .lib-card__price-now--sale { font-weight: 600; }
  .lib-card__price-was { opacity: 0.7; font-size: 0.875rem; }
  .lib-card__price-was[hidden] { display: none; }
  .lib-card__sr {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }

  .lib-card__cta { position: relative; z-index: 2; margin-top: auto; padding-top: 0.75rem; }
  .lib-card__form { margin: 0; }
  .lib-card__add {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    min-height: 2.75rem;
    padding: 0.6rem 1rem;
    border: 1.5px solid var(--lib-text, #1f1b17);
    border-radius: min(var(--lib-radius-card, 12px), 999px);
    background: transparent;
    color: var(--lib-text, #1f1b17);
    font: inherit;
    font-size: 0.875rem;
    font-weight: 600;
    line-height: 1.2;
    text-align: center;
    text-decoration: none;
    cursor: pointer;
    transition: background-color 0.2s ease, color 0.2s ease, border-color 0.2s ease;
  }
  .lib-card__add:hover:not(:disabled) {
    background: var(--lib-accent, #1f1b17);
    border-color: var(--lib-accent, #1f1b17);
    color: var(--lib-accent-text, #fff);
  }
  .lib-card__add:focus-visible { outline: 2px solid var(--lib-accent, #1f1b17); outline-offset: 2px; }
  .lib-card__add:disabled { opacity: 0.45; cursor: default; }

  @media (prefers-reduced-motion: reduce) {
    .lib-card__img,
    .lib-card__img2,
    .lib-card__add { transition: none; }
    .lib-card:hover .lib-card__img { transform: none; }
  }
{% endstylesheet %}
```

### snippets/lib-image.liquid

```liquid
{%- comment -%}
  MIT License · (c) 2026 Lintel · https://lintelagency.com/resources/shopify-sections
{%- endcomment -%}
{% doc %}
  Responsive image with optional art direction: a separate mobile image (below 750px),
  each honouring its own focal point from the theme editor. Falls back to a placeholder.

  @param {image} [image] - Desktop image (also used on mobile when no mobile image is set)
  @param {image} [image_mobile] - Mobile image, below 750px
  @param {string} [class] - Class for the img element
  @param {string} [sizes] - sizes attribute for the desktop image (default 100vw)
  @param {boolean} [eager] - Load immediately with high fetch priority (use for the first sections on a page)
  @param {string} [placeholder] - placeholder_svg_tag name when no image is set (default 'lifestyle-1')

  @example
  {% render 'lib-image', image: section.settings.image, image_mobile: section.settings.image_mobile, class: 'lib-hero__img', sizes: '(min-width: 990px) 50vw, 100vw', eager: true %}
{% enddoc %}

{%- liquid
  assign desktop = image
  if desktop == blank
    assign desktop = image_mobile
  endif
  assign img_sizes = sizes | default: '100vw'
  assign img_loading = 'lazy'
  assign img_priority = 'auto'
  if eager
    assign img_loading = 'eager'
    assign img_priority = 'high'
  endif
  assign art = false
  if image != blank and image_mobile != blank
    assign art = true
  endif
-%}

{%- if desktop != blank -%}
  <picture
    class="lib-picture{% if art %} lib-picture--art{% endif %}"
    {% if art %}
      style="--lib-pos-m: {{ image_mobile.presentation.focal_point | default: '50% 50%' }};"
    {% endif %}
  >
    {%- if art -%}
      <source
        media="(max-width: 749px)"
        srcset="
          {{ image_mobile | image_url: width: 375 }} 375w,
          {{ image_mobile | image_url: width: 750 }} 750w,
          {{ image_mobile | image_url: width: 1100 }} 1100w,
          {{ image_mobile | image_url: width: 1500 }} 1500w
        "
        sizes="100vw"
        width="{{ image_mobile.width }}"
        height="{{ image_mobile.height }}"
      >
    {%- endif -%}
    {{
      desktop
      | image_url: width: 2400
      | image_tag:
        class: class,
        loading: img_loading,
        fetchpriority: img_priority,
        sizes: img_sizes,
        widths: '600, 900, 1200, 1600, 2000, 2400'
    }}
  </picture>
{%- else -%}
  {{ placeholder | default: 'lifestyle-1' | placeholder_svg_tag: class }}
{%- endif -%}

{% stylesheet %}
  .lib-picture { display: contents; }
  @media (max-width: 749px) {
    /* image_tag sets the desktop focal point inline; the mobile image needs its own. */
    .lib-picture--art img { object-position: var(--lib-pos-m) !important; }
  }
{% endstylesheet %}
```

### snippets/lib-button.liquid

```liquid
{%- comment -%}
  MIT License · (c) 2026 Lintel · https://lintelagency.com/resources/shopify-sections
{%- endcomment -%}
{% doc %}
  Animated call-to-action link. Light sweep on hover, arrow slides right.
  Colors come from the parent section's --lib-accent / --lib-accent-text / --lib-text vars.
  Inspired by Uiverse.io button patterns; rewritten for themes, no dependencies.

  @param {string} label - Button text
  @param {string} [url] - Link target; renders a disabled-looking span when blank
  @param {string} [style] - 'primary' (default), 'outline' or 'text'
  @param {boolean} [new_tab] - Open the link in a new tab
  @param {boolean} [arrow] - Show the trailing arrow (default true)

  @example
  {% render 'lib-button', label: section.settings.button_label, url: section.settings.button_url, style: 'outline' %}
{% enddoc %}

{%- liquid
  assign btn_style = style | default: 'primary'
  assign show_arrow = true
  if arrow == false
    assign show_arrow = false
  endif
-%}

{%- unless label == blank -%}
{%- capture inner -%}
  <span class="lib-btn__label">{{ label | escape }}</span>
  {%- if show_arrow -%}
    <svg class="lib-btn__arrow" viewBox="0 0 16 16" width="16" height="16" aria-hidden="true" focusable="false">
      <path d="M3 8h9M8.5 4.5 12 8l-3.5 3.5" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/>
    </svg>
  {%- endif -%}
{%- endcapture -%}

{%- if url != blank -%}
  <a
    class="lib-btn lib-btn--{{ btn_style }}"
    href="{{ url }}"
    {% if new_tab %}
      target="_blank" rel="noopener"
    {% endif %}
  >
    {{- inner -}}
  </a>
{%- else -%}
  <span class="lib-btn lib-btn--{{ btn_style }}" aria-disabled="true">{{ inner }}</span>
{%- endif -%}
{%- endunless -%}

{% stylesheet %}
  .lib-btn {
    position: relative;
    display: inline-flex;
    align-items: center;
    gap: 0.5em;
    padding: 0.85em 1.5em;
    border-radius: var(--lib-radius, 999px);
    font: inherit;
    font-weight: 600;
    line-height: 1;
    text-decoration: none;
    overflow: hidden;
    isolation: isolate;
    transition: transform 0.2s ease, box-shadow 0.2s ease, background-color 0.2s ease;
  }
  .lib-btn--primary {
    background: var(--lib-accent, #111);
    color: var(--lib-accent-text, #fff);
    box-shadow: 0 1px 2px rgb(0 0 0 / 0.12);
  }
  .lib-btn--outline {
    background: transparent;
    color: var(--lib-text, #111);
    box-shadow: inset 0 0 0 1.5px currentColor;
  }
  .lib-btn--text {
    padding-inline: 0;
    background: none;
    color: var(--lib-text, #111);
    text-decoration: underline;
    text-underline-offset: 0.3em;
    overflow: visible;
  }
  .lib-btn--text::before { display: none; }
  .lib-btn--text:hover { transform: none; box-shadow: none; }
  .lib-btn::before {
    content: '';
    position: absolute;
    inset: 0;
    z-index: -1;
    background: linear-gradient(110deg, transparent 30%, rgb(255 255 255 / 0.35) 50%, transparent 70%);
    transform: translateX(-120%);
    transition: transform 0.6s ease;
  }
  .lib-btn--outline::before {
    background: linear-gradient(110deg, transparent 30%, rgb(127 127 127 / 0.18) 50%, transparent 70%);
  }
  .lib-btn:hover {
    transform: translateY(-2px);
    box-shadow: 0 8px 20px -8px rgb(0 0 0 / 0.35);
  }
  .lib-btn:hover::before { transform: translateX(120%); }
  .lib-btn__arrow { transition: transform 0.2s ease; }
  .lib-btn:hover .lib-btn__arrow { transform: translateX(3px); }
  .lib-btn:focus-visible {
    outline: 2px solid var(--lib-accent, #111);
    outline-offset: 3px;
  }
  .lib-btn[aria-disabled='true'] { pointer-events: none; }
  @media (prefers-reduced-motion: reduce) {
    .lib-btn, .lib-btn::before, .lib-btn__arrow { transition: none; }
    .lib-btn:hover { transform: none; }
  }
{% endstylesheet %}
```

## Lisans

MIT Lisansı, © 2026 Lintel. Kendi mağazanızda ya da müşteri işlerinde ücretsiz kullanabilir, değiştirebilir ve yayınlayabilirsiniz; her dosyanın başındaki lisans satırını koruyun.
