# Görsel kolaj: ücretsiz Shopify bölümü

> Başlık, metin ve düğmeli bir kartın yanında üst üste binen iki ya da üç fotoğraf; Hakkımızda sayfalarına uygun. Mobilde düzenli ızgara, Liquid ve CSS.

Görsel kolaj, iki ya da üç fotoğrafı üst üste bindirerek bir kolaj oluşturan ve yanına üst başlık, başlık, metin ve düğmeden oluşan bir metin kartı yerleştiren ücretsiz bir Shopify bölümüdür. Görseller solda ya da sağda durur, masaüstünde kart görsellerin üzerine taşabilir; mobilde fotoğraflar kartın üstünde ya da altında düzenli bir ızgaraya dizilir (ilki tam genişlikte, diğerleri yan yana). Her görselin kendi mobil sürümü ve odak noktası vardır. Online Store 2.0 temaları için JavaScript kullanmadan, yalnızca Liquid ve CSS ile yazılmıştır.

- **Kategori:** İçerik ve hikâye anlatımı
- **Kullanıldığı yerler:** Hakkımızda, Ana sayfa, Açılış sayfaları
- **Okuduğu veri:** Yalnızca içerik
- **Boyut:** 3 dosyada 22 KB, JavaScript yok
- **Lisans:** MIT, © 2026 Lintel
- **Sayfa:** https://lintelagency.com/tr/kaynaklar/shopify-bolumleri/gorsel-kolaj
- **Canlı demo:** https://lintelagency.com/resources/shopify-sections/demo/lib-image-collage.html
- **Eklenme tarihi:** 2026-11-02

## Ne işe yarar

- Hakkımızda sayfasında atölyeyi, malzemeleri ve paketleme masasını marka hikâyesinin yanında gösteren bir alan
- Ana sayfada birkaç yaşam tarzı fotoğrafı ve bir bağlantıyla yeni bir koleksiyonu tanıtmak
- Açılış sayfasında, tam bir galeriye gerek kalmadan bir ürünün nasıl yapıldığını anlatmak

## Tema düzenleyici ayarları

Bölüm tema düzenleyicide “Lib · Image collage” 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.

### Text card

| Kimlik | Tür | Etiket | Varsayılan | Seçenekler ya da aralık |
| --- | --- | --- | --- | --- |
| `eyebrow` | `text` | Eyebrow | Our story |  |
| `heading` | `inline_richtext` | Heading | `A small studio, <em>slowly</em> grown` |  |
| `heading_tag` | `select` | Heading tag | h2 | `h1`, `h2`, `h3`, `p` |
| `heading_size` | `select` | Heading size | large | `small`, `medium`, `large`, `xlarge` |
| `text` | `richtext` | Text | `<p>What started at a kitchen table is now a two-wheel studio. We still glaze in small batches, pack every order by hand and answer every email ourselves.</p>` |  |
| `button_label` | `text` | Button label | Read our story |  |
| `button_url` | `url` | Button link | – |  |
| `button_style` | `select` | Button style | primary | `primary`, `outline`, `text` |
| `button_new_tab` | `checkbox` | Open link in a new tab | `false` |  |

### Layout

| Kimlik | Tür | Etiket | Varsayılan | Seçenekler ya da aralık |
| --- | --- | --- | --- | --- |
| `images_position` | `select` | Images on desktop | left | `left`, `right` |
| `card_overlap` | `range` | Card overlaps images on desktop | `48` | 0–160 px, step 8 |
| `image_radius` | `range` | Image and card corner radius | `12` | 0–40 px, step 2 |
| `mobile_order` | `select` | Order on mobile | images_first | `images_first`, `text_first` |
| `section_width` | `select` | Width | page | `page`, `full` |
| `text_alignment` | `text_alignment` | Text alignment on desktop | left |  |
| `text_alignment_mobile` | `select` | Text alignment on mobile | left | `left`, `center`, `right` |

### Colors

| Kimlik | Tür | Etiket | Varsayılan | Seçenekler ya da aralık |
| --- | --- | --- | --- | --- |
| `color_bg` | `color` | Background | #F4EFE8 |  |
| `color_bg_gradient` | `color_background` | Background gradient | – |  |
| `color_text` | `color` | Text | #2A2420 |  |
| `color_accent` | `color` | Accent (solid button, eyebrow) | #7A5A3A |  |
| `color_accent_text` | `color` | Text on accent | #FFFFFF |  |
| `color_card` | `color` | Card background | #FFFDF9 |  |

### Spacing and visibility

| Kimlik | Tür | Etiket | Varsayılan | Seçenekler ya da aralık |
| --- | --- | --- | --- | --- |
| `padding_top` | `range` | Top padding on desktop | `88` | 0–200 px, step 4 |
| `padding_bottom` | `range` | Bottom padding on desktop | `88` | 0–200 px, step 4 |
| `padding_top_mobile` | `range` | Top padding on mobile | `48` | 0–160 px, step 4 |
| `padding_bottom_mobile` | `range` | Bottom padding on mobile | `56` | 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` | Rise in on scroll | `false` |  |

## Bloklar

Toplamda en fazla 3 blok.

### Image (`image`, en fazla 3)

| Kimlik | Tür | Etiket | Varsayılan | Seçenekler ya da aralık |
| --- | --- | --- | --- | --- |
| `image` | `image_picker` | Desktop image | – |  |
| `image_mobile` | `image_picker` | Mobile image | – |  |

## 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-image-collage.liquid` adında yeni bir dosya ekleyin, aşağıdaki kaynak koddan `sections/lib-image-collage.liquid` içeriğini yapıştırıp kaydedin.
4. `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 · Image collage** 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-image-collage.liquid https://lintelagency.com/resources/shopify-sections/files/lib-image-collage.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-image-collage.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-image-collage.liquid](https://lintelagency.com/resources/shopify-sections/files/lib-image-collage.liquid): `sections/` 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ç görsel ekleyebilirim?

Birden üçe kadar; her biri tema düzenleyicide sırasını değiştirebileceğiniz bir bloktur. Üç görselde ilki en büyüğüdür, diğer ikisi onun üzerine biner; iki görselde çapraz olarak üst üste gelirler; tek görsel ise görsel alanının tamamını doldurur.

### Kolaj telefonlarda da çalışıyor mu?

Evet, ama üst üste binme olmadan: 750px’in altında ilk görsel tam genişlikte, diğerleri altında yan yana durur; küçük ekranda hiçbir öğe diğerini örtmez. Metin kartını görsellerden önce ya da sonra gösterebilir, her görsele ayrı bir mobil sürüm verebilirsiniz.

### Alternatif metin (alt) nereden geliyor?

Shopify’ın Dosyalar bölümünde her görsele girdiğiniz metinden; bir kez yazmanız yeterlidir. Ekran okuyucular görselleri blok sırasıyla, ardından metin kartını okur.

### Kart görsellerin üzerine binebilir mi?

Evet. "Card overlaps images on desktop" ayarı kartı kolajın üzerine 160px’e kadar kaydırır; 0 ise kartı görsellerin yanında tutar. Kart fotoğrafların önünde durur ve kendi arka plan rengini korur, böylece metin her zaman okunaklı kalır.

## Kaynak kod

### sections/lib-image-collage.liquid

```liquid
{%- comment -%}
  MIT License · (c) 2026 Lintel · https://lintelagency.com/resources/shopify-sections
{%- endcomment -%}
{%- comment -%}
  Image collage: two or three overlapping images (one block each, with a separate mobile image and
  focal points) beside a text card with eyebrow, heading, text and a button. Images left or right;
  the card can overlap the collage on desktop. On mobile the images sit in a tidy grid (the first
  full width, the others side by side) above or below the card, without overlaps. No JavaScript.
  Depends on: snippets/lib-image.liquid, snippets/lib-button.liquid
{%- endcomment -%}

{%- liquid
  assign s = section.settings
  assign heading_tag = s.heading_tag | default: 'h2'
  assign eager = false
  if section.index <= 2
    assign eager = true
  endif
  assign image_count = section.blocks.size
  if image_count > 3
    assign image_count = 3
  endif
-%}

<div
  class="lib-collage lib-collage--{{ s.section_width }}"
  {% if s.anchor_id != blank %}
    id="{{ s.anchor_id | handleize }}"
  {% endif %}
  data-show="{{ s.show_on }}"
  data-images="{{ s.images_position }}"
  data-count="{{ image_count }}"
  data-mobile-order="{{ s.mobile_order }}"
  {% if s.card_overlap > 0 %}
    data-overlap
  {% endif %}
  {% 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-radius-img: {{ s.image_radius }}px;
    --lib-overlap: {{ s.card_overlap }}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-collage__inner">
    <div class="lib-collage__images">
      {%- for block in section.blocks limit: 3 -%}
        {%- assign b = block.settings -%}
        <div class="lib-collage__frame lib-collage__frame--{{ forloop.index }}" {{ block.shopify_attributes }}>
          {%- liquid
            assign placeholder = 'lifestyle-' | append: forloop.index
            if forloop.index == 3
              assign placeholder = 'image'
            endif
            assign sizes = '(min-width: 990px) 30vw, 50vw'
            if forloop.first
              assign sizes = '(min-width: 990px) 35vw, 100vw'
            endif
            assign img_eager = false
            if eager and forloop.first
              assign img_eager = true
            endif
          -%}
          {%- render 'lib-image',
            image: b.image,
            image_mobile: b.image_mobile,
            class: 'lib-collage__img',
            sizes: sizes,
            eager: img_eager,
            placeholder: placeholder
          -%}
        </div>
      {%- endfor -%}
    </div>

    <div class="lib-collage__card" data-align="{{ s.text_alignment }}" data-align-m="{{ s.text_alignment_mobile }}">
      {%- if s.eyebrow != blank -%}
        <p class="lib-collage__eyebrow">{{ s.eyebrow | escape }}</p>
      {%- endif -%}
      {%- if s.heading != blank -%}
        <{{ heading_tag }} class="lib-collage__heading lib-collage__heading--{{ s.heading_size }}">
          {{- s.heading -}}
        </{{ heading_tag }}>
      {%- endif -%}
      {%- if s.text != blank -%}
        <div class="lib-collage__text">{{ s.text }}</div>
      {%- endif -%}
      {%- if s.button_label != blank -%}
        <div class="lib-collage__actions">
          {%- render 'lib-button',
            label: s.button_label,
            url: s.button_url,
            style: s.button_style,
            new_tab: s.button_new_tab
          -%}
        </div>
      {%- endif -%}
    </div>
  </div>
</div>

{% stylesheet %}
  .lib-collage {
    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-collage__inner {
    max-width: 1200px;
    margin: 0 auto;
    display: grid;
    gap: clamp(1.5rem, 4vw, 3rem);
  }
  .lib-collage--full .lib-collage__inner { max-width: none; }
  .lib-collage__inner > * { min-width: 0; }

  /* Mobile: a tidy grid, first image full width, the others side by side; no overlaps. */
  .lib-collage__images { display: grid; grid-template-columns: 1fr 1fr; gap: 0.75rem; }
  .lib-collage__frame {
    position: relative;
    overflow: hidden;
    border-radius: var(--lib-radius-img);
    background: color-mix(in srgb, var(--lib-text) 6%, transparent);
    aspect-ratio: 1;
  }
  .lib-collage__frame--1 { grid-column: 1 / -1; aspect-ratio: 4 / 3; }
  .lib-collage[data-count='2'] .lib-collage__frame--2 { grid-column: 1 / -1; aspect-ratio: 3 / 2; }
  .lib-collage__img { display: block; width: 100%; height: 100%; object-fit: cover; }
  .lib-collage__img:is(svg) { fill: color-mix(in srgb, var(--lib-text) 25%, transparent); }

  @media (max-width: 749px) {
    .lib-collage { padding-top: var(--lib-pt-m); padding-bottom: var(--lib-pb-m); }
    .lib-collage[data-show='desktop'] { display: none; }
    .lib-collage[data-mobile-order='text_first'] .lib-collage__card { order: -1; }
  }
  @media (min-width: 750px) {
    .lib-collage[data-show='mobile'] { display: none; }
  }

  /* Desktop: images overlap on a 12 × 12 grid; each later image sits on top with a ring in the
     background color, so the edges read clearly. */
  @media (min-width: 990px) {
    .lib-collage__inner { --lib-gap: clamp(2rem, 5vw, 4.5rem); grid-template-columns: 7fr 5fr; align-items: center; gap: var(--lib-gap); }
    .lib-collage[data-images='right'] .lib-collage__inner { grid-template-columns: 5fr 7fr; }
    .lib-collage[data-images='right'] .lib-collage__images { order: 2; }
    .lib-collage__images {
      grid-template-columns: repeat(12, 1fr);
      grid-template-rows: repeat(12, 1fr);
      gap: 0;
      aspect-ratio: 1 / 0.92;
    }
    .lib-collage__frame { aspect-ratio: auto; box-shadow: 0 0 0 8px var(--lib-bg), 0 24px 48px -28px rgb(0 0 0 / 0.35); }
    .lib-collage__frame--1 { grid-area: 1 / 1 / 13 / 13; aspect-ratio: auto; box-shadow: none; }
    .lib-collage[data-count='2'] .lib-collage__frame--1 { grid-area: 1 / 1 / 11 / 9; }
    .lib-collage[data-count='2'] .lib-collage__frame--2 { grid-area: 5 / 6 / 13 / 13; aspect-ratio: auto; z-index: 1; }
    .lib-collage[data-count='3'] .lib-collage__frame--1 { grid-area: 1 / 1 / 9 / 8; }
    .lib-collage[data-count='3'] .lib-collage__frame--2 { grid-area: 2 / 8 / 7 / 13; z-index: 1; }
    .lib-collage[data-count='3'] .lib-collage__frame--3 { grid-area: 7 / 4 / 13 / 11; z-index: 2; }
    .lib-collage[data-images='right'][data-count='3'] .lib-collage__frame--1 { grid-area: 1 / 6 / 9 / 13; }
    .lib-collage[data-images='right'][data-count='3'] .lib-collage__frame--2 { grid-area: 2 / 1 / 7 / 6; }
    .lib-collage[data-images='right'][data-count='3'] .lib-collage__frame--3 { grid-area: 7 / 3 / 13 / 10; }
    .lib-collage[data-images='right'][data-count='2'] .lib-collage__frame--1 { grid-area: 1 / 5 / 11 / 13; }
    .lib-collage[data-images='right'][data-count='2'] .lib-collage__frame--2 { grid-area: 5 / 1 / 13 / 8; }
    .lib-collage__card { position: relative; z-index: 3; }
    .lib-collage[data-overlap][data-images='left'] .lib-collage__card { margin-inline-start: calc(-1 * (var(--lib-overlap) + var(--lib-gap))); }
    .lib-collage[data-overlap][data-images='right'] .lib-collage__card { margin-inline-end: calc(-1 * (var(--lib-overlap) + var(--lib-gap))); }
  }

  .lib-collage__card {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    text-align: left;
    padding: clamp(1.75rem, 4vw, 3.25rem);
    border-radius: var(--lib-radius-img);
    background: var(--lib-card);
    box-shadow: 0 18px 40px -24px rgb(0 0 0 / 0.25);
  }
  .lib-collage__card[data-align='center'] { align-items: center; text-align: center; }
  .lib-collage__card[data-align='right'] { align-items: flex-end; text-align: right; }
  @media (max-width: 749px) {
    .lib-collage__card[data-align-m='left'] { align-items: flex-start; text-align: left; }
    .lib-collage__card[data-align-m='center'] { align-items: center; text-align: center; }
    .lib-collage__card[data-align-m='right'] { align-items: flex-end; text-align: right; }
  }
  .lib-collage__eyebrow {
    margin: 0 0 1rem;
    font-size: 0.8rem;
    font-weight: 600;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--lib-accent);
  }
  .lib-collage__heading {
    margin: 0;
    font-size: clamp(1.75rem, 3.4vw, 2.75rem);
    line-height: 1.1;
    letter-spacing: -0.02em;
    text-wrap: balance;
  }
  .lib-collage__heading--small { font-size: clamp(1.375rem, 2.2vw, 1.75rem); }
  .lib-collage__heading--medium { font-size: clamp(1.5rem, 2.8vw, 2.25rem); }
  .lib-collage__heading--xlarge { font-size: clamp(2.25rem, 5vw, 3.75rem); }
  .lib-collage__text { margin-top: 1rem; max-width: 34rem; font-size: 1.0625rem; line-height: 1.65; opacity: 0.82; }
  .lib-collage__text > :first-child { margin-top: 0; }
  .lib-collage__text > :last-child { margin-bottom: 0; }
  .lib-collage__text a { color: inherit; text-underline-offset: 0.2em; }
  .lib-collage__actions { margin-top: 1.75rem; }

  /* Motion: images and card rise in as they scroll into view, the later images a little later. */
  @supports (animation-timeline: view()) {
    @media (prefers-reduced-motion: no-preference) {
      .lib-collage[data-animate] .lib-collage__frame,
      .lib-collage[data-animate] .lib-collage__card {
        animation: lib-collage-rise linear both;
        animation-timeline: view();
        animation-range: entry 0% entry 55%;
      }
      .lib-collage[data-animate] .lib-collage__frame--2 { animation-range: entry 10% entry 70%; }
      .lib-collage[data-animate] .lib-collage__frame--3 { animation-range: entry 20% entry 85%; }
    }
  }
  @keyframes lib-collage-rise {
    from { opacity: 0; transform: translateY(28px); }
  }
{% endstylesheet %}

{% schema %}
{
  "name": "Lib · Image collage",
  "tag": "section",
  "class": "lib-section",
  "max_blocks": 3,
  "settings": [
    { "type": "header", "content": "Text card" },
    { "type": "text", "id": "eyebrow", "label": "Eyebrow", "default": "Our story" },
    { "type": "inline_richtext", "id": "heading", "label": "Heading", "default": "A small studio, <em>slowly</em> grown" },
    {
      "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" },
        { "value": "xlarge", "label": "Extra large" }
      ],
      "default": "large"
    },
    { "type": "richtext", "id": "text", "label": "Text", "default": "<p>What started at a kitchen table is now a two-wheel studio. We still glaze in small batches, pack every order by hand and answer every email ourselves.</p>" },
    { "type": "text", "id": "button_label", "label": "Button label", "default": "Read our story" },
    { "type": "url", "id": "button_url", "label": "Button link" },
    {
      "type": "select",
      "id": "button_style",
      "label": "Button style",
      "options": [
        { "value": "primary", "label": "Solid" },
        { "value": "outline", "label": "Outline" },
        { "value": "text", "label": "Text link" }
      ],
      "default": "primary"
    },
    { "type": "checkbox", "id": "button_new_tab", "label": "Open link in a new tab", "default": false },

    { "type": "header", "content": "Layout" },
    {
      "type": "select",
      "id": "images_position",
      "label": "Images on desktop",
      "options": [
        { "value": "left", "label": "Left" },
        { "value": "right", "label": "Right" }
      ],
      "default": "left"
    },
    { "type": "range", "id": "card_overlap", "label": "Card overlaps images on desktop", "info": "0 keeps the card beside the images.", "min": 0, "max": 160, "step": 8, "unit": "px", "default": 48 },
    { "type": "range", "id": "image_radius", "label": "Image and card corner radius", "min": 0, "max": 40, "step": 2, "unit": "px", "default": 12 },
    {
      "type": "select",
      "id": "mobile_order",
      "label": "Order on mobile",
      "options": [
        { "value": "images_first", "label": "Images first" },
        { "value": "text_first", "label": "Text first" }
      ],
      "default": "images_first"
    },
    {
      "type": "select",
      "id": "section_width",
      "label": "Width",
      "options": [
        { "value": "page", "label": "Page width" },
        { "value": "full", "label": "Full width" }
      ],
      "default": "page"
    },
    { "type": "text_alignment", "id": "text_alignment", "label": "Text alignment on desktop", "default": "left" },
    {
      "type": "select",
      "id": "text_alignment_mobile",
      "label": "Text alignment on mobile",
      "options": [
        { "value": "left", "label": "Left" },
        { "value": "center", "label": "Center" },
        { "value": "right", "label": "Right" }
      ],
      "default": "left"
    },

    { "type": "header", "content": "Colors" },
    { "type": "color", "id": "color_bg", "label": "Background", "info": "Also the thin ring between overlapping images.", "default": "#F4EFE8" },
    { "type": "color_background", "id": "color_bg_gradient", "label": "Background gradient", "info": "Optional. Covers the background color." },
    { "type": "color", "id": "color_text", "label": "Text", "default": "#2A2420" },
    { "type": "color", "id": "color_accent", "label": "Accent (solid button, eyebrow)", "default": "#7A5A3A" },
    { "type": "color", "id": "color_accent_text", "label": "Text on accent", "default": "#FFFFFF" },
    { "type": "color", "id": "color_card", "label": "Card background", "default": "#FFFDF9" },

    { "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": 88 },
    { "type": "range", "id": "padding_bottom", "label": "Bottom padding on desktop", "min": 0, "max": 200, "step": 4, "unit": "px", "default": 88 },
    { "type": "range", "id": "padding_top_mobile", "label": "Top padding on mobile", "min": 0, "max": 160, "step": 4, "unit": "px", "default": 48 },
    { "type": "range", "id": "padding_bottom_mobile", "label": "Bottom padding on mobile", "min": 0, "max": 160, "step": 4, "unit": "px", "default": 56 },
    {
      "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": "Rise in on scroll", "info": "Only in browsers that support scroll-driven animations; never when reduced motion is on.", "default": false }
  ],
  "blocks": [
    {
      "type": "image",
      "name": "Image",
      "limit": 3,
      "settings": [
        { "type": "image_picker", "id": "image", "label": "Desktop image", "info": "The first image is the largest. Alt text comes from the image in Files." },
        { "type": "image_picker", "id": "image_mobile", "label": "Mobile image", "info": "Optional. Shown below 750px." }
      ]
    }
  ],
  "presets": [
    {
      "name": "Lib · Image collage",
      "blocks": [
        { "type": "image" },
        { "type": "image" },
        { "type": "image" }
      ]
    }
  ]
}
{% endschema %}
```

### 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.
