# Görsel ve metin: ücretsiz Shopify bölümü

> Başlık, metin, en fazla dört ikonlu madde ve iki düğmenin yanında görsel. Görselin genişliği, yönü ve şekli ayarlanır; metin görselle örtüşen kartta durabilir.

Görsel ve metin, bir görseli başlık, zengin metin, kısa bir ikon listesi ve en fazla iki düğmenin yanına yerleştiren ücretsiz bir Shopify bölümüdür. Görsel her iki tarafta genişliğin üçte birini, yarısını ya da üçte ikisini kaplayabilir, metin görselle örtüşen bir kartta durabilir; Online Store 2.0 temalarında uygulama olmadan çalışır.

- **Kategori:** İçerik ve hikâye anlatımı
- **Kullanıldığı yerler:** Ana sayfa, Ürün, Koleksiyon, Hakkımızda, Her sayfa
- **Okuduğu veri:** Yalnızca içerik
- **Boyut:** 3 dosyada 29 KB, JavaScript yok
- **Lisans:** MIT, © 2026 Lintel
- **Sayfa:** https://lintelagency.com/tr/kaynaklar/shopify-bolumleri/gorsel-ve-metin
- **Canlı demo:** https://lintelagency.com/resources/shopify-sections/demo/lib-image-with-text.html
- **Eklenme tarihi:** 2026-10-02

## Ne işe yarar

- Ana sayfada ya da Hakkımızda sayfasında marka hikâyesi veya atölye tanıtımı
- Malzemeyi, bakımı ya da bir ürünün nasıl yapıldığını anlatan ürün sayfası bloğu
- Yaşam tarzı fotoğrafı ve ilgili koleksiyonlara bağlantılarla koleksiyon sayfası girişi

## Tema düzenleyici ayarları

Bölüm tema düzenleyicide “Lib · Image with text” 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 |
| --- | --- | --- | --- | --- |
| `eyebrow` | `text` | Eyebrow | From our studio |  |
| `heading` | `inline_richtext` | Heading | `Slow-made pieces for <em>everyday</em> rituals` |  |
| `heading_tag` | `select` | Heading tag | h2 | `h1`, `h2`, `h3`, `p` |
| `heading_size` | `select` | Heading size | large | `small`, `medium`, `large`, `xlarge` |
| `text` | `richtext` | Text | `<p>Every vase, bowl and cup is thrown by hand in our two-wheel studio, glazed in small batches and fired twice. No two are quite the same, and that is the point.</p>` |  |

### Image

| Kimlik | Tür | Etiket | Varsayılan | Seçenekler ya da aralık |
| --- | --- | --- | --- | --- |
| `image` | `image_picker` | Desktop image | – |  |
| `image_mobile` | `image_picker` | Mobile image | – |  |
| `image_position` | `select` | Image position on desktop | left | `left`, `right` |
| `image_width` | `select` | Image width on desktop | half | `third`, `half`, `two_thirds` |
| `image_ratio` | `select` | Image shape on desktop | portrait | `adapt`, `square`, `portrait`, `landscape`, `arch` |
| `image_ratio_mobile` | `select` | Image shape on mobile | square | `adapt`, `square`, `portrait`, `landscape`, `arch` |
| `image_radius` | `range` | Image and card corner radius | `16` | 0–40 px, step 2 |

### Buttons

| Kimlik | Tür | Etiket | Varsayılan | Seçenekler ya da aralık |
| --- | --- | --- | --- | --- |
| `button_label` | `text` | First button label | Shop ceramics |  |
| `button_url` | `url` | First button link | – |  |
| `button_style` | `select` | First button style | primary | `primary`, `outline`, `text` |
| `button_new_tab` | `checkbox` | Open first link in a new tab | `false` |  |
| `button2_label` | `text` | Second button label | Visit the studio |  |
| `button2_url` | `url` | Second button link | – |  |
| `button2_style` | `select` | Second button style | text | `primary`, `outline`, `text` |
| `button2_new_tab` | `checkbox` | Open second link in a new tab | `false` |  |

### Layout

| Kimlik | Tür | Etiket | Varsayılan | Seçenekler ya da aralık |
| --- | --- | --- | --- | --- |
| `box_style` | `select` | Text box | card | `none`, `card` |
| `card_overlap` | `range` | Card overlaps image on desktop | `80` | 0–160 px, step 8 |
| `vertical_alignment` | `select` | Text position next to the image | center | `start`, `center`, `end` |
| `mobile_order` | `select` | Order on mobile | image_first | `image_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, icons) | #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` | Fade in on scroll | `false` |  |

## Bloklar

Toplamda en fazla 4 blok.

### Icon point (`item`, en fazla 4)

| Kimlik | Tür | Etiket | Varsayılan | Seçenekler ya da aralık |
| --- | --- | --- | --- | --- |
| `icon` | `select` | Icon | check | `check`, `leaf`, `truck`, `return`, `shield`, `star`, `heart`, `hand` |
| `icon_image` | `image_picker` | Custom icon | – |  |
| `text` | `text` | Text | Thrown by hand in small batches |  |

## 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-with-text.liquid` adında yeni bir dosya ekleyin, aşağıdaki kaynak koddan `sections/lib-image-with-text.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 with text** 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-with-text.liquid https://lintelagency.com/resources/shopify-sections/files/lib-image-with-text.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-with-text.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-with-text.liquid](https://lintelagency.com/resources/shopify-sections/files/lib-image-with-text.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

### Mobilde farklı bir görsel gösterebilir miyim?

Evet. Bir mobil görsel ekleyin; 750px altında kendi odak noktasıyla gösterilir ve mobil görsel şekli (uyum, kare, dikey, yatay ya da kemer) masaüstünden ayrı ayarlanır. Mobil görsel yoksa masaüstü görseli her yerde kullanılır.

### Kaç ikonlu madde ekleyebilirim?

En fazla dört. Her birinde sekiz yerleşik çizgi ikondan biri ya da kendi küçük görseliniz ve kısa bir metin satırı vardır. Gövde metninin altında bir liste olarak yazdırılırlar.

### Örtüşen kart nasıl çalışır?

Metin kutusu kart olarak ayarlandığında kart, 990px ve üzeri ekranlarda görselin üzerine 160px’e kadar kayabilir. Bunun altında görsel ve kart alt alta dizilir; mobilde önce görselin mi metnin mi geleceğini siz seçersiniz.

### JavaScript kullanır mı?

Hayır. İsteğe bağlı belirme animasyonu CSS scroll-driven animation kullanır; yalnızca bunu destekleyen tarayıcılarda çalışır ve ziyaretçi azaltılmış hareket tercih ettiğinde atlanır. Bölüm sayfadaki ilk iki bölümden biriyse görseli hemen yüklenir; daha aşağıdaysa lazy-load ile yüklenir.

## Kaynak kod

### sections/lib-image-with-text.liquid

```liquid
{%- comment -%}
  MIT License · (c) 2026 Lintel · https://lintelagency.com/resources/shopify-sections
{%- endcomment -%}
{%- comment -%}
  Image with text: an image beside an eyebrow, heading, rich text, up to two buttons and a short
  icon list. Image left or right at one third, half or two thirds of the width; text plain or in a
  card that can overlap the image on desktop. Separate desktop and mobile image. 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 sizes = '(min-width: 990px) 50vw, 100vw'
  case s.image_width
    when 'third'
      assign sizes = '(min-width: 990px) 34vw, 100vw'
    when 'two_thirds'
      assign sizes = '(min-width: 990px) 66vw, 100vw'
  endcase

  assign overlap = 0
  if s.box_style == 'card'
    assign overlap = s.card_overlap
  endif
-%}

<div
  class="lib-image-text lib-image-text--{{ s.section_width }}"
  {% if s.anchor_id != blank %}
    id="{{ s.anchor_id | handleize }}"
  {% endif %}
  data-show="{{ s.show_on }}"
  data-image-position="{{ s.image_position }}"
  data-image-width="{{ s.image_width }}"
  data-valign="{{ s.vertical_alignment }}"
  data-mobile-order="{{ s.mobile_order }}"
  data-box="{{ s.box_style }}"
  {% if 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: {{ 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-image-text__inner">
    <div class="lib-image-text__media" data-ratio="{{ s.image_ratio }}" data-ratio-m="{{ s.image_ratio_mobile }}">
      {%- render 'lib-image',
        image: s.image,
        image_mobile: s.image_mobile,
        class: 'lib-image-text__img',
        sizes: sizes,
        eager: eager
      -%}
    </div>

    <div class="lib-image-text__copy" data-align="{{ s.text_alignment }}" data-align-m="{{ s.text_alignment_mobile }}">
      {%- if s.eyebrow != blank -%}
        <p class="lib-image-text__eyebrow">{{ s.eyebrow | escape }}</p>
      {%- endif -%}

      {%- if s.heading != blank -%}
        <{{ heading_tag }} class="lib-image-text__heading lib-image-text__heading--{{ s.heading_size }}">
          {{- s.heading -}}
        </{{ heading_tag }}>
      {%- endif -%}

      {%- if s.text != blank -%}
        <div class="lib-image-text__text">{{ s.text }}</div>
      {%- endif -%}

      {%- if section.blocks.size > 0 -%}
        <ul class="lib-image-text__list" role="list">
          {%- for block in section.blocks -%}
            {%- assign b = block.settings -%}
            <li class="lib-image-text__item" {{ block.shopify_attributes }}>
              <span class="lib-image-text__icon" aria-hidden="true">
                {%- if b.icon_image != blank -%}
                  {{ b.icon_image | image_url: width: 96 | image_tag: class: 'lib-image-text__icon-img', loading: 'lazy', alt: '' }}
                {%- else -%}
                  <svg viewBox="0 0 24 24" width="24" height="24" focusable="false" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round">
                    {%- case b.icon -%}
                      {%- when 'leaf' -%}
                        <path d="M5 19c0-8 5-13 14-14 0 9-5 14-13 14M5 19l7-7"/>
                      {%- when 'truck' -%}
                        <path d="M3 6h11v10H3zM14 9h4l3 3v4h-7"/><circle cx="7" cy="17.5" r="1.8"/><circle cx="17" cy="17.5" r="1.8"/>
                      {%- when 'return' -%}
                        <path d="M9 14 5 10l4-4"/><path d="M5 10h9a5 5 0 0 1 0 10h-3"/>
                      {%- when 'shield' -%}
                        <path d="M12 3l7 3v5c0 5-3 8.5-7 10-4-1.5-7-5-7-10V6z"/><path d="m9 12 2 2 4-4"/>
                      {%- when 'star' -%}
                        <path d="m12 3.5 2.6 5.4 5.9.8-4.3 4.1 1 5.8L12 16.9l-5.2 2.7 1-5.8-4.3-4.1 5.9-.8z"/>
                      {%- when 'heart' -%}
                        <path d="M12 20s-7-4.4-7-10a4 4 0 0 1 7-2.6A4 4 0 0 1 19 10c0 5.6-7 10-7 10z"/>
                      {%- when 'hand' -%}
                        <path d="M8 13V6.5a1.5 1.5 0 0 1 3 0V12M11 11V4.5a1.5 1.5 0 0 1 3 0V11M14 11V6a1.5 1.5 0 0 1 3 0v7c0 4-2.5 7-6 7-2.5 0-4-1.2-5.5-3.5L4 13.8a1.5 1.5 0 0 1 2.4-1.7L8 14"/>
                      {%- else -%}
                        <path d="m5 12.5 4.5 4.5L19 7.5"/>
                    {%- endcase -%}
                  </svg>
                {%- endif -%}
              </span>
              <span class="lib-image-text__item-text">{{ b.text | escape }}</span>
            </li>
          {%- endfor -%}
        </ul>
      {%- endif -%}

      {%- if s.button_label != blank or s.button2_label != blank -%}
        <div class="lib-image-text__actions">
          {%- render 'lib-button',
            label: s.button_label,
            url: s.button_url,
            style: s.button_style,
            new_tab: s.button_new_tab
          -%}
          {%- render 'lib-button',
            label: s.button2_label,
            url: s.button2_url,
            style: s.button2_style,
            new_tab: s.button2_new_tab,
            arrow: false
          -%}
        </div>
      {%- endif -%}
    </div>
  </div>
</div>

{% stylesheet %}
  .lib-image-text {
    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-image-text__inner {
    max-width: 1200px;
    margin: 0 auto;
    display: grid;
    --lib-gap: clamp(2rem, 5vw, 4.5rem);
    gap: var(--lib-gap);
  }
  .lib-image-text--full .lib-image-text__inner { max-width: none; }
  .lib-image-text__inner > * { min-width: 0; }
  @media (max-width: 749px) {
    .lib-image-text { padding-top: var(--lib-pt-m); padding-bottom: var(--lib-pb-m); }
    .lib-image-text[data-show='desktop'] { display: none; }
    .lib-image-text[data-mobile-order='text_first'] .lib-image-text__copy { order: -1; }
  }
  @media (min-width: 750px) {
    .lib-image-text[data-show='mobile'] { display: none; }
  }
  .lib-image-text[data-box='card'] .lib-image-text__inner { --lib-gap: clamp(1.5rem, 4vw, 3rem); }

  /* Desktop grid: image column width, side, vertical alignment, optional card overlap. */
  @media (min-width: 990px) {
    .lib-image-text__inner { grid-template-columns: 1fr 1fr; }
    .lib-image-text[data-image-width='third'] .lib-image-text__inner { grid-template-columns: 1fr 2fr; }
    .lib-image-text[data-image-width='two_thirds'] .lib-image-text__inner { grid-template-columns: 2fr 1fr; }
    .lib-image-text[data-image-position='right'] .lib-image-text__media { order: 2; }
    .lib-image-text[data-image-position='right'][data-image-width='third'] .lib-image-text__inner { grid-template-columns: 2fr 1fr; }
    .lib-image-text[data-image-position='right'][data-image-width='two_thirds'] .lib-image-text__inner { grid-template-columns: 1fr 2fr; }
    .lib-image-text[data-valign='start'] .lib-image-text__inner { align-items: start; }
    .lib-image-text[data-valign='center'] .lib-image-text__inner { align-items: center; }
    .lib-image-text[data-valign='end'] .lib-image-text__inner { align-items: end; }
    .lib-image-text[data-box='card'] .lib-image-text__copy { position: relative; z-index: 1; }
    .lib-image-text[data-overlap][data-image-position='left'] .lib-image-text__copy {
      margin-inline-start: calc(-1 * (var(--lib-overlap) + var(--lib-gap)));
    }
    .lib-image-text[data-overlap][data-image-position='right'] .lib-image-text__copy {
      margin-inline-end: calc(-1 * (var(--lib-overlap) + var(--lib-gap)));
    }
  }

  /* Copy and alignment: desktop, then mobile override. */
  .lib-image-text__copy { display: flex; flex-direction: column; align-items: flex-start; text-align: left; }
  .lib-image-text__copy[data-align='center'] { align-items: center; text-align: center; }
  .lib-image-text__copy[data-align='right'] { align-items: flex-end; text-align: right; }
  @media (max-width: 749px) {
    .lib-image-text__copy[data-align-m='left'] { align-items: flex-start; text-align: left; }
    .lib-image-text__copy[data-align-m='center'] { align-items: center; text-align: center; }
    .lib-image-text__copy[data-align-m='right'] { align-items: flex-end; text-align: right; }
  }
  .lib-image-text[data-box='card'] .lib-image-text__copy {
    padding: clamp(1.75rem, 4vw, 3.5rem);
    border-radius: var(--lib-radius-img);
    background: var(--lib-card);
    box-shadow: 0 18px 40px -24px rgb(0 0 0 / 0.25);
  }

  .lib-image-text__eyebrow {
    margin: 0 0 1rem;
    font-size: 0.8rem;
    font-weight: 600;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--lib-accent);
  }
  .lib-image-text__heading {
    margin: 0;
    font-size: clamp(2rem, 4vw, 3.25rem);
    line-height: 1.08;
    letter-spacing: -0.025em;
    text-wrap: balance;
  }
  .lib-image-text__heading--small { font-size: clamp(1.5rem, 2.5vw, 2rem); }
  .lib-image-text__heading--medium { font-size: clamp(1.75rem, 3vw, 2.5rem); }
  .lib-image-text__heading--xlarge { font-size: clamp(2.5rem, 6vw, 4.5rem); }
  .lib-image-text__text {
    margin-top: 1.125rem;
    max-width: 36rem;
    font-size: 1.0625rem;
    line-height: 1.65;
    opacity: 0.8;
  }
  .lib-image-text__text > :first-child { margin-top: 0; }
  .lib-image-text__text > :last-child { margin-bottom: 0; }
  .lib-image-text__text a { color: inherit; text-underline-offset: 0.2em; }

  .lib-image-text__list {
    display: grid;
    gap: 0.75rem;
    margin: 1.75rem 0 0;
    padding: 0;
    list-style: none;
    text-align: left;
  }
  .lib-image-text__item { display: flex; align-items: center; gap: 0.75rem; font-weight: 500; }
  .lib-image-text__icon {
    flex: none;
    display: grid;
    place-items: center;
    width: 2.25rem;
    height: 2.25rem;
    border-radius: 50%;
    background: color-mix(in srgb, var(--lib-accent) 14%, transparent);
    color: var(--lib-accent);
  }
  .lib-image-text__icon svg { width: 1.25rem; height: 1.25rem; }
  .lib-image-text__icon-img { display: block; width: 1.25rem; height: 1.25rem; object-fit: contain; }
  .lib-image-text__actions { display: flex; flex-wrap: wrap; gap: 0.75rem; margin-top: 2rem; }
  .lib-image-text__copy[data-align='center'] .lib-image-text__actions { justify-content: center; }
  .lib-image-text__copy[data-align='right'] .lib-image-text__actions { justify-content: flex-end; }
  @media (max-width: 749px) {
    .lib-image-text__copy[data-align-m='left'] .lib-image-text__actions { justify-content: flex-start; }
    .lib-image-text__copy[data-align-m='center'] .lib-image-text__actions { justify-content: center; }
    .lib-image-text__copy[data-align-m='right'] .lib-image-text__actions { justify-content: flex-end; }
  }

  /* Media: shape per device; "adapt" keeps the image's own proportions. */
  .lib-image-text__media {
    position: relative;
    border-radius: var(--lib-radius-img);
    overflow: hidden;
    background: color-mix(in srgb, var(--lib-text) 6%, transparent);
  }
  .lib-image-text__media[data-ratio='square'] { aspect-ratio: 1; }
  .lib-image-text__media[data-ratio='portrait'] { aspect-ratio: 4 / 5; }
  .lib-image-text__media[data-ratio='landscape'] { aspect-ratio: 3 / 2; }
  .lib-image-text__media[data-ratio='arch'] { aspect-ratio: 4 / 5; border-radius: 999px 999px var(--lib-radius-img) var(--lib-radius-img); }
  @media (max-width: 749px) {
    .lib-image-text__media[data-ratio-m='adapt'] { aspect-ratio: auto; }
    .lib-image-text__media[data-ratio-m='square'] { aspect-ratio: 1; }
    .lib-image-text__media[data-ratio-m='portrait'] { aspect-ratio: 4 / 5; }
    .lib-image-text__media[data-ratio-m='landscape'] { aspect-ratio: 3 / 2; }
    .lib-image-text__media[data-ratio-m='arch'] { aspect-ratio: 4 / 5; border-radius: 999px 999px var(--lib-radius-img) var(--lib-radius-img); }
    .lib-image-text__media[data-ratio='arch']:not([data-ratio-m='arch']) { border-radius: var(--lib-radius-img); }
  }
  .lib-image-text__img { display: block; width: 100%; height: 100%; object-fit: cover; }
  .lib-image-text__media[data-ratio='adapt'] .lib-image-text__img { height: auto; }
  @media (max-width: 749px) {
    .lib-image-text__media[data-ratio-m='adapt'] .lib-image-text__img { height: auto; }
    .lib-image-text__media[data-ratio='adapt']:not([data-ratio-m='adapt']) .lib-image-text__img { height: 100%; }
  }
  .lib-image-text__img:is(svg) { aspect-ratio: 1; fill: color-mix(in srgb, var(--lib-text) 25%, transparent); }

  /* Motion: copy fades up as it scrolls into view (browsers with scroll-driven animations only). */
  @supports (animation-timeline: view()) {
    @media (prefers-reduced-motion: no-preference) {
      .lib-image-text[data-animate] .lib-image-text__copy,
      .lib-image-text[data-animate] .lib-image-text__media {
        animation: lib-image-text-rise linear both;
        animation-timeline: view();
        animation-range: entry 0% entry 60%;
      }
    }
  }
  @keyframes lib-image-text-rise {
    from { opacity: 0; transform: translateY(24px); }
  }
{% endstylesheet %}

{% schema %}
{
  "name": "Lib · Image with text",
  "tag": "section",
  "class": "lib-section",
  "max_blocks": 4,
  "settings": [
    { "type": "header", "content": "Content" },
    { "type": "text", "id": "eyebrow", "label": "Eyebrow", "default": "From our studio" },
    { "type": "inline_richtext", "id": "heading", "label": "Heading", "default": "Slow-made pieces for <em>everyday</em> rituals" },
    {
      "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>Every vase, bowl and cup is thrown by hand in our two-wheel studio, glazed in small batches and fired twice. No two are quite the same, and that is the point.</p>" },

    { "type": "header", "content": "Image" },
    { "type": "image_picker", "id": "image", "label": "Desktop image" },
    { "type": "image_picker", "id": "image_mobile", "label": "Mobile image", "info": "Optional. Shown below 750px." },
    {
      "type": "select",
      "id": "image_position",
      "label": "Image position on desktop",
      "options": [
        { "value": "left", "label": "Left" },
        { "value": "right", "label": "Right" }
      ],
      "default": "left"
    },
    {
      "type": "select",
      "id": "image_width",
      "label": "Image width on desktop",
      "options": [
        { "value": "third", "label": "One third" },
        { "value": "half", "label": "Half" },
        { "value": "two_thirds", "label": "Two thirds" }
      ],
      "default": "half"
    },
    {
      "type": "select",
      "id": "image_ratio",
      "label": "Image shape on desktop",
      "options": [
        { "value": "adapt", "label": "Adapt to image" },
        { "value": "square", "label": "Square" },
        { "value": "portrait", "label": "Portrait" },
        { "value": "landscape", "label": "Landscape" },
        { "value": "arch", "label": "Arch" }
      ],
      "default": "portrait"
    },
    {
      "type": "select",
      "id": "image_ratio_mobile",
      "label": "Image shape on mobile",
      "options": [
        { "value": "adapt", "label": "Adapt to image" },
        { "value": "square", "label": "Square" },
        { "value": "portrait", "label": "Portrait" },
        { "value": "landscape", "label": "Landscape" },
        { "value": "arch", "label": "Arch" }
      ],
      "default": "square"
    },
    { "type": "range", "id": "image_radius", "label": "Image and card corner radius", "min": 0, "max": 40, "step": 2, "unit": "px", "default": 16 },

    { "type": "header", "content": "Buttons" },
    { "type": "text", "id": "button_label", "label": "First button label", "default": "Shop ceramics" },
    { "type": "url", "id": "button_url", "label": "First button link" },
    {
      "type": "select",
      "id": "button_style",
      "label": "First 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 first link in a new tab", "default": false },
    { "type": "text", "id": "button2_label", "label": "Second button label", "default": "Visit the studio" },
    { "type": "url", "id": "button2_url", "label": "Second button link" },
    {
      "type": "select",
      "id": "button2_style",
      "label": "Second button style",
      "options": [
        { "value": "primary", "label": "Solid" },
        { "value": "outline", "label": "Outline" },
        { "value": "text", "label": "Text link" }
      ],
      "default": "text"
    },
    { "type": "checkbox", "id": "button2_new_tab", "label": "Open second link in a new tab", "default": false },

    { "type": "header", "content": "Layout" },
    {
      "type": "select",
      "id": "box_style",
      "label": "Text box",
      "options": [
        { "value": "none", "label": "None" },
        { "value": "card", "label": "Card" }
      ],
      "default": "card"
    },
    { "type": "range", "id": "card_overlap", "label": "Card overlaps image on desktop", "info": "0 keeps the card beside the image.", "min": 0, "max": 160, "step": 8, "unit": "px", "default": 80, "visible_if": "{{ section.settings.box_style == 'card' }}" },
    {
      "type": "select",
      "id": "vertical_alignment",
      "label": "Text position next to the image",
      "options": [
        { "value": "start", "label": "Top" },
        { "value": "center", "label": "Middle" },
        { "value": "end", "label": "Bottom" }
      ],
      "default": "center"
    },
    {
      "type": "select",
      "id": "mobile_order",
      "label": "Order on mobile",
      "options": [
        { "value": "image_first", "label": "Image first" },
        { "value": "text_first", "label": "Text first" }
      ],
      "default": "image_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", "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, icons)", "default": "#7A5A3A" },
    { "type": "color", "id": "color_accent_text", "label": "Text on accent", "default": "#FFFFFF" },
    { "type": "color", "id": "color_card", "label": "Card background", "default": "#FFFDF9", "visible_if": "{{ section.settings.box_style == 'card' }}" },

    { "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": "Fade in on scroll", "info": "Only in browsers that support scroll-driven animations; never when reduced motion is on.", "default": false }
  ],
  "blocks": [
    {
      "type": "item",
      "name": "Icon point",
      "limit": 4,
      "settings": [
        {
          "type": "select",
          "id": "icon",
          "label": "Icon",
          "options": [
            { "value": "check", "label": "Check" },
            { "value": "leaf", "label": "Leaf" },
            { "value": "truck", "label": "Delivery" },
            { "value": "return", "label": "Returns" },
            { "value": "shield", "label": "Shield" },
            { "value": "star", "label": "Star" },
            { "value": "heart", "label": "Heart" },
            { "value": "hand", "label": "Handmade" }
          ],
          "default": "check"
        },
        { "type": "image_picker", "id": "icon_image", "label": "Custom icon", "info": "Optional. Replaces the icon above." },
        { "type": "text", "id": "text", "label": "Text", "default": "Thrown by hand in small batches" }
      ]
    }
  ],
  "presets": [
    {
      "name": "Lib · Image with text",
      "blocks": [
        { "type": "item", "settings": { "icon": "hand", "text": "Thrown by hand in small batches" } },
        { "type": "item", "settings": { "icon": "leaf", "text": "Lead-free glazes, food safe" } },
        { "type": "item", "settings": { "icon": "return", "text": "Free returns within 30 days" } }
      ]
    }
  ]
}
{% 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.
