Overview
This guide walks you through integrating the ELFBAR Design System into a Shopify Liquid theme. After completing these steps, you will have:
- Design Tokens — consistent colors, spacing, fonts, and radii across your theme
- CSS Components — pre-styled UI elements matching the design system
- Liquid Snippets — reusable template fragments you can render in any section
Final File Structure
your-shopify-theme/
assets/
ds-tokens.css← Design tokens (colors, spacing, fonts)
ds-components.css← Component styles
ds-components.min.js← Interaction logic (optional)
snippets/
ds-button.liquid
ds-card.liquid
ds-badge.liquid
ds-accordion.liquid
...
layout/
theme.liquid← Add stylesheet/script tags here
Prerequisites
Before you begin, make sure you have:
- Access to your Shopify theme editor — Go to Shopify Admin → Online Store → Themes → Edit code
- The following files (provided by your design system team):
ds-tokens.css— Design token variablesds-components.css— Component stylesds-components.min.js— Interaction script (optional, for accordions, tabs, etc.)
Step 1: Add the Design Token File
Design tokens define all the colors, spacing, fonts, and border-radius values used by the design system. They are delivered as CSS variables.
1.1 Create the token file
- In the theme editor, navigate to Assets
- Click Add a new asset
- Choose Create a blank file, name it
ds-tokens, select.css - Paste the entire contents of the
ds-tokens.cssfile provided by your design system team - Click Save
1.2 Include in your theme layout
Open layout/theme.liquid and add the following line before the closing </head> tag:
{{ 'ds-tokens.css' | asset_url | stylesheet_tag }}```
Place it **after** your theme's main stylesheet so that design system tokens can be accessed by all components.
---
## Step 2: Add Component Styles
Component styles define the visual appearance of each UI element (buttons, cards, badges, etc.).
### 2.1 Create the component stylesheet
1. In **Assets**, click **Add a new asset**
2. Create a blank `.css` file named `ds-components`
3. Paste the contents of `ds-components.css`
4. Click **Save**
### 2.2 Include in your theme layout
In `layout/theme.liquid`, add this line right **after** the token stylesheet:
```liquid
{{ 'ds-components.css' | asset_url | stylesheet_tag }}```
Your `</head>` area should now look like this:
```liquid
{{ 'ds-tokens.css' | asset_url | stylesheet_tag }}
{{ 'ds-components.css' | asset_url | stylesheet_tag }}
</head>```
---
## Step 3: Add the Interaction Script (Optional)
Some components require JavaScript for interactivity (accordion expand/collapse, tab switching, etc.). If you only need static components like buttons and cards, you can skip this step.
### 3.1 Create the script file
1. In **Assets**, click **Add a new asset**
2. Create a blank `.js` file named `ds-components.min`
3. Paste the contents of `ds-components.min.js`
4. Click **Save**
### 3.2 Include in your theme layout
In `layout/theme.liquid`, add this line **before** the closing `</body>` tag:
```liquid
{{ 'ds-components.min.js' | asset_url | script_tag }}```
---
## Step 4: Create Liquid Snippets
Snippets are reusable template fragments. Each component has its own snippet file that you create once and use everywhere.
### How to create a snippet
1. In the theme editor, navigate to **Snippets**
2. Click **Add a new snippet**
3. Name it (e.g., `ds-button`)
4. Paste the code shown below
5. Click **Save**
---
### Button
**Snippet file:** `ds-button.liquid`
```liquid
{% comment %}
Design System Button
Parameters:
label - Button text (required)
variant - filled | outlined | text (default: filled)
size - sm | md | lg (default: md)
disabled - true | false (default: false)
href - URL, renders <a> instead of <button>
type - button | submit (default: button)
class - Additional CSS classes
{% endcomment %}
{% assign tag = 'button' %}
{% if href %}{% assign tag = 'a' %}{% endif %}
{% assign v = variant | default: 'filled' %}
{% assign s = size | default: 'md' %}
<{{ tag }}
class="ds-button ds-button--{{ v }} ds-button--{{ s }}{% if disabled %} ds-button--disabled{% endif %}{% if class %} {{ class }}{% endif %}"
{% if tag == 'button' %}type="{{ type | default: 'button' }}"{% endif %}
{% if href %}href="{{ href }}"{% endif %}
{% if disabled %}disabled aria-disabled="true"{% endif %}
>
{{ label }}
</{{ tag }}>```
**Usage examples:**
```liquid
{% render 'ds-button', label: 'Add to Cart', variant: 'filled', size: 'lg' %}
{% render 'ds-button', label: 'Learn More', variant: 'outlined', href: '/pages/about' %}
{% render 'ds-button', label: 'Cancel', variant: 'text' %}```
---
### Card
**Snippet file:** `ds-card.liquid`
```liquid
{% comment %}
Design System Card
Parameters:
image_url - Image source URL
image_alt - Image alt text
title - Card title
description - Card description text
price - Price text (e.g., "$12.99")
href - Link URL (wraps entire card)
variant - standard | horizontal (default: standard)
{% endcomment %}
{% assign v = variant | default: 'standard' %}
{% if href %}<a href="{{ href }}" class="ds-card-link">{% endif %}
<div class="ds-card ds-card--{{ v }}">
{% if image_url %}
<div class="ds-card__image">
<img src="{{ image_url }}" alt="{{ image_alt | default: title }}" loading="lazy" />
</div>
{% endif %}
<div class="ds-card__content">
{% if title %}<h3 class="ds-card__title">{{ title }}</h3>{% endif %}
{% if description %}<p class="ds-card__description">{{ description }}</p>{% endif %}
{% if price %}
<div class="ds-card__footer">
<span class="ds-card__price">{{ price }}</span>
</div>
{% endif %}
</div>
</div>
{% if href %}</a>{% endif %}```
**Usage with product data:**
```liquid
{% for product in collection.products %}
{% render 'ds-card',
image_url: product.featured_image | image_url: width: 600,
image_alt: product.featured_image.alt,
title: product.title,
price: product.price | money,
href: product.url
%}
{% endfor %}```
---
### Badge
**Snippet file:** `ds-badge.liquid`
```liquid
{% comment %}
Design System Badge
Parameters:
type - count | dot (default: count)
count - Number to display (for count type)
color - error | success | warning (default: error)
position - top-right | top-left (default: top-right)
{% endcomment %}
{% assign t = type | default: 'count' %}
{% assign c = color | default: 'error' %}
{% assign p = position | default: 'top-right' %}
<span class="ds-badge ds-badge--{{ t }} ds-badge--{{ c }} ds-badge--{{ p }}">
{% if t == 'count' %}{{ count | default: 0 }}{% endif %}
</span>```
---
### Accordion (requires JS)
**Snippet file:** `ds-accordion.liquid`
```liquid
{% comment %}
Design System Accordion
Parameters:
type - single | multiple (default: single)
Usage: Wrap accordion items in a section block loop
{% endcomment %}
{% assign t = type | default: 'single' %}
<div class="ds-accordion" data-ds="accordion" data-ds-type="{{ t }}">
{% for block in section.blocks %}
{% if block.type == 'accordion_item' %}
<div class="ds-accordion__item" data-ds-accordion-item {{ block.shopify_attributes }}>
<button
class="ds-accordion__trigger"
data-ds-accordion-trigger
aria-expanded="false"
type="button"
>
<span>{{ block.settings.title }}</span>
<svg class="ds-accordion__icon" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<polyline points="6 9 12 15 18 9"></polyline>
</svg>
</button>
<div class="ds-accordion__content" data-ds-accordion-content hidden>
<div class="ds-accordion__body">
{{ block.settings.content }}
</div>
</div>
</div>
{% endif %}
{% endfor %}
</div>```
**Section schema for accordion:**
```json
{
"name": "FAQ",
"tag": "section",
"blocks": [
{
"type": "accordion_item",
"name": "Question",
"settings": [
{
"type": "text",
"id": "title",
"label": "Question"
},
{
"type": "richtext",
"id": "content",
"label": "Answer"
}
]
}
]
}This allows merchants to add/remove FAQ items directly from the theme editor.
Skeleton
Snippet file: ds-skeleton.liquid
{% comment %}
Design System Skeleton
Parameters:
type - text | circle | rect (default: text)
width - CSS width value (e.g., "100%", "200px")
height - CSS height value (e.g., "1rem", "200px")
{% endcomment %}
{% assign t = type | default: 'text' %}
<div
class="ds-skeleton ds-skeleton--{{ t }}"
{% if width or height %}
style="{% if width %}width: {{ width }};{% endif %}{% if height %}height: {{ height }};{% endif %}"
{% endif %}
aria-hidden="true"
></div>```
---
### Breadcrumb
**Snippet file:** `ds-breadcrumb.liquid`
```liquid
{% comment %}
Design System Breadcrumb
Automatically generates breadcrumbs from the current page context.
{% endcomment %}
<nav class="ds-breadcrumb" aria-label="Breadcrumb">
<ol class="ds-breadcrumb__list">
<li class="ds-breadcrumb__item">
<a class="ds-breadcrumb__link" href="/">{{ 'general.breadcrumb.home' | t | default: 'Home' }}</a>
</li>
{% if collection %}
<li class="ds-breadcrumb__item">
<span class="ds-breadcrumb__separator" aria-hidden="true">/</span>
<a class="ds-breadcrumb__link" href="{{ collection.url }}">{{ collection.title }}</a>
</li>
{% endif %}
{% if product %}
<li class="ds-breadcrumb__item">
<span class="ds-breadcrumb__separator" aria-hidden="true">/</span>
<span class="ds-breadcrumb__current" aria-current="page">{{ product.title }}</span>
</li>
{% endif %}
{% if page %}
<li class="ds-breadcrumb__item">
<span class="ds-breadcrumb__separator" aria-hidden="true">/</span>
<span class="ds-breadcrumb__current" aria-current="page">{{ page.title }}</span>
</li>
{% endif %}
</ol>
</nav>```
---
## Step 5: Use Components in Sections & Templates
Once your snippets are created, you can use them anywhere in your theme sections and templates.
### Example: Product Card Grid Section
Create a new section file `sections/ds-product-grid.liquid`:
```liquid
<div class="ds-product-grid">
<div class="ds-product-grid__header">
{% if section.settings.title != blank %}
<h2>{{ section.settings.title }}</h2>
{% endif %}
</div>
<div class="ds-product-grid__items">
{% for product in collections[section.settings.collection].products limit: section.settings.limit %}
{% render 'ds-card',
image_url: product.featured_image | image_url: width: 600,
image_alt: product.featured_image.alt,
title: product.title,
price: product.price | money,
href: product.url
%}
{% endfor %}
</div>
</div>
{% schema %}
{
"name": "Product Grid",
"settings": [
{
"type": "text",
"id": "title",
"label": "Section Title",
"default": "Featured Products"
},
{
"type": "collection",
"id": "collection",
"label": "Collection"
},
{
"type": "range",
"id": "limit",
"label": "Number of products",
"min": 2,
"max": 12,
"step": 1,
"default": 4
}
],
"presets": [
{
"name": "Product Grid"
}
]
}
{% endschema %}```
### Example: FAQ Section with Accordion
Create `sections/ds-faq.liquid`:
```liquid
<div class="ds-faq-section">
{% if section.settings.title != blank %}
<h2>{{ section.settings.title }}</h2>
{% endif %}
{% render 'ds-accordion', type: 'single' %}
</div>
{% schema %}
{
"name": "FAQ",
"settings": [
{
"type": "text",
"id": "title",
"label": "Section Title",
"default": "Frequently Asked Questions"
}
],
"blocks": [
{
"type": "accordion_item",
"name": "Question",
"settings": [
{
"type": "text",
"id": "title",
"label": "Question",
"default": "What is your return policy?"
},
{
"type": "richtext",
"id": "content",
"label": "Answer",
"default": "<p>We offer a 30-day return policy for all unused products.</p>"
}
]
}
],
"presets": [
{
"name": "FAQ",
"blocks": [
{ "type": "accordion_item" },
{ "type": "accordion_item" },
{ "type": "accordion_item" }
]
}
]
}
{% endschema %}```
---
## Step 6: Brand & Theme Configuration
If your store needs to support multiple brands (ELFBAR / Lost Mary) or dark mode, add settings to your theme.
### 6.1 Add brand settings
Open `config/settings_schema.json` and add this block:
```json
{
"name": "Design System",
"settings": [
{
"type": "select",
"id": "ds_brand",
"label": "Brand",
"options": [
{ "value": "elfbar", "label": "ELFBAR" },
{ "value": "lostmary", "label": "Lost Mary" }
],
"default": "elfbar"
},
{
"type": "checkbox",
"id": "ds_dark_mode",
"label": "Enable dark mode",
"default": false
}
]
}6.2 Apply brand attributes
In layout/theme.liquid, update the <html> tag:
<html
lang="{{ request.locale.iso_code }}"
{% if settings.ds_brand != 'elfbar' %}data-brand="{{ settings.ds_brand }}"{% endif %}
{% if settings.ds_dark_mode %}data-theme="dark"{% endif %}
>```
All design system components will automatically switch to the selected brand's colors and styles.
---
## Component Reference
The table below is automatically generated from the design system source code and shows all available components, their CSS classes, snippet names, and variants.
<ComponentCoverageTable />