# Ready examples

Recipes to copy. Each block shows the file it goes in and passes the store's
check. After creating a section, add it in **Customize theme > Sections of the
page** or in `templates/<page>.json`.

> [!TIP]
> With the AI connected, you can ask for exactly this: *"Use the category
> showcase example from the Hystore wiki for the kits, with 6 products."*

## Promotion banner

A banner with a title, text and a button, all editable in Customize theme.

```liquid sections/promo-banner.liquid
<section class="promo">
  <div class="promo-in">
    <p class="promo-tag">{{ section.settings.tag }}</p>
    <h2>{{ section.settings.title }}</h2>
    <p>{{ section.settings.text }}</p>
    {%- if section.settings.button_url != blank -%}
      <a class="promo-btn" href="{{ section.settings.button_url }}">{{ section.settings.button_label }}</a>
    {%- endif -%}
  </div>
</section>
{% schema %}
{
  "name": "Promotion banner",
  "settings": [
    { "id": "tag", "type": "text", "label": "Tag", "default": "This week only" },
    { "id": "title", "type": "text", "label": "Title", "default": "Black Friday: up to 50% off" },
    { "id": "text", "type": "textarea", "label": "Text", "default": "Kits, VIPs and cosmetics on sale." },
    { "id": "button_label", "type": "text", "label": "Button text", "default": "See the deals" },
    { "id": "button_url", "type": "url", "label": "Button link", "default": "/loja" }
  ]
}
{% endschema %}
```

```css styles/promo-banner.css
.promo { padding: 48px 20px; background: linear-gradient(120deg, hsl(var(--primary)), #1d4ed8); color: #fff; }
.promo-in { max-width: 960px; margin: 0 auto; }
.promo-tag { display: inline-block; padding: 4px 10px; border-radius: 999px; background: rgba(255, 255, 255, .18); font-weight: 700; font-size: 13px; }
.promo h2 { margin: 12px 0 8px; font-size: clamp(28px, 4vw, 44px); }
.promo-btn { display: inline-block; margin-top: 12px; padding: 12px 22px; border-radius: 12px; background: #f5b544; color: #1c1305; font-weight: 700; text-decoration: none; }
```

## Category showcase

The products of a category, with price, sale and a buy button.

```liquid sections/category-showcase.liquid
{% load products, category: section.settings.category, limit: section.settings.count as items %}
<section class="showcase">
  <h2>{{ section.settings.title }}</h2>
  <div class="showcase-grid">
    {%- for p in items -%}
      <article class="showcase-card">
        <a href="{{ p.url }}">
          {%- if p.image -%}<img src="{{ p.image }}" alt="{{ p.name }}" loading="lazy">{%- endif -%}
          <h3>{{ p.name }}</h3>
        </a>
        <p class="showcase-price">
          {%- if p.on_sale -%}<s>{{ p.original_price | money }}</s> {% endif -%}
          <strong>{{ p.price | money }}</strong>
        </p>
        {%- if p.sold_out -%}
          <span class="showcase-off">{{ 'product.sold_out' | t }}</span>
        {%- else -%}
          <button type="button" data-hystore-add-to-cart="{{ p.id }}">{{ 'product.add' | t }}</button>
        {%- endif -%}
      </article>
    {%- else -%}
      <p>{{ 'showcase.empty' | t }}</p>
    {%- endfor -%}
  </div>
</section>
{% schema %}
{
  "name": "Category showcase",
  "settings": [
    { "id": "title", "type": "text", "label": "Title", "default": "Kits" },
    { "id": "category", "type": "text", "label": "Category slug", "default": "kits" },
    { "id": "count", "type": "range", "label": "How many", "min": 2, "max": 24, "default": 8 }
  ]
}
{% endschema %}
```

The slug is the end of the category's address in the store (`/loja/survival/kits`
has the slug `kits`). The texts `product.add`, `product.sold_out` and
`showcase.empty` live in the language files:

```json locales/en.json
{
  "product": { "add": "Buy", "sold_out": "Sold out" },
  "showcase": { "empty": "No products here yet." }
}
```

## Countdown

The store fills in the numbers by itself, with no JavaScript in the theme.

```liquid sections/countdown.liquid
<section class="countdown" data-hystore-countdown="{{ section.settings.ends_at }}">
  <h2>{{ section.settings.title }}</h2>
  <div class="countdown-row">
    <span><b data-hystore-days>0</b> {{ 'time.days' | t }}</span>
    <span><b data-hystore-hours>0</b> {{ 'time.hours' | t }}</span>
    <span><b data-hystore-minutes>0</b> {{ 'time.minutes' | t }}</span>
    <span><b data-hystore-seconds>0</b> {{ 'time.seconds' | t }}</span>
  </div>
</section>
{% schema %}
{
  "name": "Countdown",
  "settings": [
    { "id": "title", "type": "text", "label": "Title", "default": "The new season starts in" },
    { "id": "ends_at", "type": "text", "label": "Date and time (UTC)", "default": "2026-12-24T23:59:00Z" }
  ]
}
{% endschema %}
```

## Server IP and players online

```liquid sections/server-bar.liquid
{% load server_status as status %}
<section class="server-bar">
  <button type="button" class="server-ip" data-hystore-copy="{{ store.ip }}">{{ store.ip }}</button>
  {%- if status and status.online -%}
    <span class="server-on">{{ status.players_online }}/{{ status.players_max }} {{ 'server.online' | t }}</span>
  {%- else -%}
    <span class="server-off">{{ 'server.offline' | t }}</span>
  {%- endif -%}
  <hystore-online-players></hystore-online-players>
</section>
{% schema %}
{ "name": "Server bar", "settings": [] }
{% endschema %}
```

Clicking the IP copies the address. The store fills `<hystore-online-players>`
with the players online.

## Top buyers of the month

```liquid sections/top-buyers.liquid
{% load ranking, period: 'month', limit: 5 as top %}
<section class="top-buyers">
  <h2>{{ section.settings.title }}</h2>
  <ol>
    {%- for row in top -%}
      <li>
        <img src="{{ row.nick | skin_url: 48 }}" alt="" width="48" height="48">
        <span>{{ row.position }}. {{ row.nick }}</span>
        <b>{{ row.total_spent | money }}</b>
      </li>
    {%- endfor -%}
  </ol>
</section>
{% schema %}
{
  "name": "Top buyers",
  "settings": [{ "id": "title", "type": "text", "label": "Title", "default": "Top of the month" }]
}
{% endschema %}
```

## Frequently asked questions

An accordion with questions the store owner adds as blocks.

```liquid sections/faq.liquid
<section class="faq" data-hystore-accordion="single">
  <h2>{{ section.settings.title }}</h2>
  {%- for block in section.blocks -%}
    <div class="faq-item" data-hystore-accordion-item>
      <button type="button" data-hystore-accordion-toggle>{{ block.settings.question }}</button>
      <div class="faq-answer" data-hystore-accordion-panel>{{ block.settings.answer }}</div>
    </div>
  {%- endfor -%}
</section>
{% schema %}
{
  "name": "FAQ",
  "settings": [{ "id": "title", "type": "text", "label": "Title", "default": "Questions" }],
  "blocks": [
    {
      "type": "question",
      "name": "Question",
      "settings": [
        { "id": "question", "type": "text", "label": "Question" },
        { "id": "answer", "type": "textarea", "label": "Answer" }
      ]
    }
  ]
}
{% endschema %}
```

## Theme colours and options

General settings live in `theme.json` and become fields in Customize theme:

```json theme.json
{
  "name": "My theme",
  "version": "1.0.0",
  "color_modes": ["dark", "light"],
  "settings": [
    { "id": "accent", "type": "color", "label": "Accent colour", "default": "#f5b544" },
    { "id": "radius", "type": "range", "label": "Roundness", "min": 0, "max": 28, "default": 14 }
  ]
}
```

Colours and numbers become CSS variables at the theme's root:

```css styles/theme.css
.button { background: var(--theme-accent); border-radius: calc(var(--theme-radius) * 1px); }
html:not(.dark) .card { background: #fff; color: #0b1526; }
html.dark .card { background: #0d1524; color: #e8eef8; }
```

And any general setting shows in Liquid as `{{ settings.accent }}`.

## Switch colour mode and language

```liquid components/header-tools.liquid
<div class="header-tools">
  <button type="button" data-hystore-color-mode="toggle">{{ 'header.theme' | t }}</button>
  <button type="button" data-hystore-language="pt">PT</button>
  <button type="button" data-hystore-language="en">EN</button>
  <button type="button" data-hystore-language="es">ES</button>
  <button type="button" data-hystore-open="cart">{{ 'header.cart' | t }} (<span data-hystore-cart-count>0</span>)</button>
  <hystore-account></hystore-account>
</div>
```

Use it in the layout with `{% render 'header-tools' %}`.

## More

- The [theme guide](/en/code-theme/guide/) lists every data source, filter,
  ready-made block and interactive piece.
- For JavaScript (wheel, quiz, calculator), see
  [Isolated apps](/en/code-theme/apps/).
- The Base, Aurora, Celeste and Prisma themes are great to learn from: start
  one in the dashboard and open its files in the editor.
