rebly-sections 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +67 -0
- package/assets/SKILL.md +65 -0
- package/assets/commands/section.md +27 -0
- package/assets/commands/theme-init.md +20 -0
- package/assets/data/component-library/_index.csv +19 -0
- package/assets/data/component-library/announcement-bar.liquid +69 -0
- package/assets/data/component-library/blog-posts-grid.liquid +77 -0
- package/assets/data/component-library/collection-list.liquid +71 -0
- package/assets/data/component-library/cta-banner.liquid +58 -0
- package/assets/data/component-library/faq-accordion.liquid +76 -0
- package/assets/data/component-library/features-grid.liquid +94 -0
- package/assets/data/component-library/hero-banner.liquid +104 -0
- package/assets/data/component-library/image-gallery.liquid +77 -0
- package/assets/data/component-library/image-with-text.liquid +84 -0
- package/assets/data/component-library/logo-cloud.liquid +70 -0
- package/assets/data/component-library/newsletter-signup.liquid +72 -0
- package/assets/data/component-library/pricing-table.liquid +101 -0
- package/assets/data/component-library/product-grid.liquid +74 -0
- package/assets/data/component-library/rich-text-content.liquid +52 -0
- package/assets/data/component-library/stats-counter.liquid +73 -0
- package/assets/data/component-library/team-members.liquid +81 -0
- package/assets/data/component-library/testimonials-slider.liquid +93 -0
- package/assets/data/component-library/video-hero.liquid +82 -0
- package/assets/data/data-version.json +19 -0
- package/assets/data/design-tokens.csv +57 -0
- package/assets/data/liquid-stdlib.csv +134 -0
- package/assets/data/schema-library.csv +46 -0
- package/assets/data/shopify-best-practices.csv +36 -0
- package/assets/data/theme-dna.csv +20 -0
- package/assets/scripts/core.py +194 -0
- package/assets/scripts/quality-gate.py +179 -0
- package/assets/scripts/search.py +72 -0
- package/assets/scripts/section-generator.py +202 -0
- package/assets/scripts/theme-init.py +181 -0
- package/assets/templates/generation-prompt.md +31 -0
- package/assets/templates/section-base.liquid +49 -0
- package/assets/templates/theme-profile-template.md +21 -0
- package/dist/commands/init.d.ts +1 -0
- package/dist/commands/init.js +70 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +14 -0
- package/dist/utils/copy-assets.d.ts +1 -0
- package/dist/utils/copy-assets.js +44 -0
- package/dist/utils/detect-platform.d.ts +6 -0
- package/dist/utils/detect-platform.js +18 -0
- package/package.json +35 -0
package/README.md
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# rebly-sections
|
|
2
|
+
|
|
3
|
+
AI-powered Shopify Liquid section builder for Claude Code and Antigravity Kit.
|
|
4
|
+
|
|
5
|
+
## Quick Start
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npx rebly-sections init
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Detects your platform and installs the skill + slash commands automatically.
|
|
12
|
+
|
|
13
|
+
## Prerequisites
|
|
14
|
+
|
|
15
|
+
- **Node.js** 16.7+
|
|
16
|
+
- **Python** 3.6+ (stdlib only, no pip install needed)
|
|
17
|
+
- **Claude Code** (`.claude/` directory) or **Antigravity Kit** (`.agent/` directory)
|
|
18
|
+
|
|
19
|
+
## What It Installs
|
|
20
|
+
|
|
21
|
+
| Location | Contents |
|
|
22
|
+
|----------|----------|
|
|
23
|
+
| `.claude/skills/rebly-sections/` | Scripts, data (6 knowledge bases), templates, SKILL.md |
|
|
24
|
+
| `.claude/commands/section.md` | `/section` slash command |
|
|
25
|
+
| `.claude/commands/theme-init.md` | `/theme-init` slash command |
|
|
26
|
+
|
|
27
|
+
## Usage
|
|
28
|
+
|
|
29
|
+
### Generate a Section
|
|
30
|
+
|
|
31
|
+
```
|
|
32
|
+
/section hero "modern animated hero with background video"
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
Assembles context from knowledge bases (schema types, Liquid tags, component patterns, best practices) and generates a production-ready OS2.0 section.
|
|
36
|
+
|
|
37
|
+
### Detect Theme Profile
|
|
38
|
+
|
|
39
|
+
```
|
|
40
|
+
/theme-init /path/to/your/shopify-theme
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Scans theme for CSS variables, naming conventions, and block patterns. Outputs `theme-profile.md` for use with `/section --theme-profile`.
|
|
44
|
+
|
|
45
|
+
### Search Knowledge Bases
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
python3 .claude/skills/rebly-sections/scripts/search.py "product grid" --domain components
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Search across schema, liquid, tokens, components, themes, and practices domains.
|
|
52
|
+
|
|
53
|
+
### Quality Gate
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
python3 .claude/skills/rebly-sections/scripts/quality-gate.py sections/hero.liquid
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
10-point OS2.0 compliance validation.
|
|
60
|
+
|
|
61
|
+
## Full Documentation
|
|
62
|
+
|
|
63
|
+
See the [main repository](https://github.com/rebly-sections/sections-ai) for architecture, contributing guidelines, and roadmap.
|
|
64
|
+
|
|
65
|
+
## License
|
|
66
|
+
|
|
67
|
+
MIT
|
package/assets/SKILL.md
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: rebly-sections
|
|
3
|
+
description: "Shopify Liquid section builder. Generates OS2.0 compliant sections, blocks, snippets with schema settings. Covers: hero, testimonials, product grid, FAQ, CTA, newsletter, gallery, pricing, team, collection list, blog posts, announcement bar. Searches: Shopify schema types, Liquid tags/filters/objects, design tokens, component patterns, theme DNA, best practices. Commands: /section, /theme-init. Quality gate validates OS2.0 compliance."
|
|
4
|
+
version: 1.0.0
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Rebly Sections - Shopify Section AI Skill
|
|
8
|
+
|
|
9
|
+
## When to Apply
|
|
10
|
+
- User mentions: Shopify, Liquid, section, block, snippet, schema, theme, OS2.0
|
|
11
|
+
- User wants to: create/modify Shopify sections, build theme components, generate section schemas
|
|
12
|
+
- User asks about: Shopify settings types, Liquid syntax, section best practices
|
|
13
|
+
|
|
14
|
+
## Prerequisites
|
|
15
|
+
- Python 3.x (stdlib only, no pip install needed)
|
|
16
|
+
|
|
17
|
+
## Workflows
|
|
18
|
+
|
|
19
|
+
### /theme-init — Theme Profile Detection
|
|
20
|
+
Scans a local Shopify theme directory, detects the theme, generates a theme-profile.md.
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
python3 scripts/theme-init.py /path/to/theme [--output theme-profile.md]
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
### /section — Section Generation
|
|
27
|
+
Assembles context from knowledge bases for Claude to generate a production section.
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
python3 scripts/section-generator.py "section-name" "description" [--theme-profile path] [--refine path/to/section.liquid]
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
### Search CLI
|
|
34
|
+
```bash
|
|
35
|
+
python3 scripts/search.py "<query>" [--domain <domain>] [-n 3] [--component] [--json]
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
**Domains:**
|
|
39
|
+
| Domain | Data | Rows |
|
|
40
|
+
|--------|------|------|
|
|
41
|
+
| schema | Shopify setting types | 45 |
|
|
42
|
+
| liquid | Tags, filters, objects | 133 |
|
|
43
|
+
| tokens | Design tokens (Tailwind) | 56 |
|
|
44
|
+
| components | Section patterns | 18 |
|
|
45
|
+
| themes | Theme DNA profiles | ~40 |
|
|
46
|
+
| practices | Best practices | ~35 |
|
|
47
|
+
|
|
48
|
+
### Quality Gate
|
|
49
|
+
```bash
|
|
50
|
+
python3 scripts/quality-gate.py path/to/section.liquid
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
Validates: valid schema JSON, presets, @app blocks, block.shopify_attributes, no {% include %}, scoped CSS, semantic HTML, lazy-load images.
|
|
54
|
+
|
|
55
|
+
## Pre-Delivery Checklist
|
|
56
|
+
Before delivering any Shopify section to the user:
|
|
57
|
+
- [ ] Valid {% schema %} JSON
|
|
58
|
+
- [ ] Non-empty presets array
|
|
59
|
+
- [ ] @app block type included
|
|
60
|
+
- [ ] {{ block.shopify_attributes }} on all block wrappers
|
|
61
|
+
- [ ] {% render %} not {% include %}
|
|
62
|
+
- [ ] CSS scoped via #section-{{ section.id }}
|
|
63
|
+
- [ ] Responsive (mobile-first)
|
|
64
|
+
- [ ] Accessible (semantic HTML, aria-labels, alt text)
|
|
65
|
+
- [ ] Images use loading="lazy" (except hero/above-fold)
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# Section Generator - Generate Shopify OS2.0 section
|
|
2
|
+
|
|
3
|
+
Generate a production-ready Shopify OS2.0 compliant Liquid section.
|
|
4
|
+
|
|
5
|
+
IMPORTANT: All rebly-sections scripts are in the PROJECT-LOCAL `.claude/skills/rebly-sections/` directory (relative to project root), NOT in `~/.claude/skills/`. Always use project-relative paths.
|
|
6
|
+
|
|
7
|
+
## Instructions
|
|
8
|
+
|
|
9
|
+
1. Parse arguments: $ARGUMENTS (expected format: "description" or section-name "description")
|
|
10
|
+
2. Locate scripts directory: `.claude/skills/rebly-sections/scripts/`
|
|
11
|
+
3. If theme-profile.md exists in project root, use it with `--theme-profile`
|
|
12
|
+
4. Run the section generator to assemble context:
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
python3 .claude/skills/rebly-sections/scripts/section-generator.py "<section-name>" "<description>" --theme-profile theme-profile.md
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
5. Use the output context to generate the complete .liquid section file
|
|
19
|
+
6. Save to `sections/<section-name>.liquid`
|
|
20
|
+
7. Run quality gate validation:
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
python3 .claude/skills/rebly-sections/scripts/quality-gate.py sections/<section-name>.liquid
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
8. If quality gate fails, fix issues and re-validate until PASS
|
|
27
|
+
9. Display the quality gate results to the user
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# Theme Init - Scan Shopify theme and generate profile
|
|
2
|
+
|
|
3
|
+
Scan the Shopify theme directory and generate a theme-profile.md file.
|
|
4
|
+
|
|
5
|
+
## Instructions
|
|
6
|
+
|
|
7
|
+
1. Determine the theme directory path from arguments: $ARGUMENTS
|
|
8
|
+
- If no path given, use current working directory
|
|
9
|
+
2. Find the rebly-sections scripts in the PROJECT directory (not global ~/.claude):
|
|
10
|
+
- Look for scripts at: `.claude/skills/rebly-sections/scripts/`
|
|
11
|
+
3. Run the theme-init script using `python3`:
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
python3 .claude/skills/rebly-sections/scripts/theme-init.py "<theme-path>" --output theme-profile.md
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
4. Read and display the generated theme-profile.md
|
|
18
|
+
5. Summarize findings: theme name, version, CSS variable prefix, section count, naming patterns
|
|
19
|
+
|
|
20
|
+
IMPORTANT: Use the project-local `.claude/skills/rebly-sections/` directory, NOT `~/.claude/skills/`. The scripts are installed per-project.
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
No,Name,Slug,Category,Keywords,Difficulty,Blocks Used,Settings Count,ui_style_keywords,File,Description
|
|
2
|
+
1,Hero Banner,hero-banner,hero,"hero banner headline image background overlay call-to-action above-fold full-width",beginner,heading|button|image,8,glassmorphism gradient overlay dark-mode hero,hero-banner.liquid,Full-width hero section with background image/video and CTA overlay
|
|
3
|
+
2,Image with Text,image-with-text,content,"image text side-by-side split layout media content columns",beginner,heading|text|button|image,7,clean minimal balanced layout,image-with-text.liquid,Side-by-side image and text content block
|
|
4
|
+
3,Features Grid,features-grid,content,"features grid columns icons benefits multicolumn highlights",beginner,heading|text|icon,6,card grid minimal modern,features-grid.liquid,Multi-column feature highlights with icons
|
|
5
|
+
4,Product Grid,product-grid,product,"products collection grid cards featured shop browse",intermediate,product-card,5,ecommerce grid card modern,product-grid.liquid,Product collection grid with cards
|
|
6
|
+
5,CTA Banner,cta-banner,conversion,"call-to-action banner button signup conversion promo",beginner,heading|button,5,bold contrast gradient cta,cta-banner.liquid,Call-to-action banner with heading and button
|
|
7
|
+
6,Rich Text Content,rich-text-content,content,"rich text content wysiwyg paragraph body copy",beginner,heading|text,4,clean typography readable,rich-text-content.liquid,Rich text content section with customizable typography
|
|
8
|
+
7,Testimonials Slider,testimonials-slider,social-proof,"testimonials reviews quotes customers social-proof slider carousel",intermediate,testimonial,7,card slider social-proof trust,testimonials-slider.liquid,Customer testimonials with quote blocks
|
|
9
|
+
8,FAQ Accordion,faq-accordion,content,"faq questions answers accordion expandable collapsible help",intermediate,faq-item,5,clean accordion expandable minimal,faq-accordion.liquid,Expandable FAQ with question-answer pairs
|
|
10
|
+
9,Newsletter Signup,newsletter-signup,conversion,"newsletter email signup subscribe form capture leads",beginner,heading|text,6,form input minimal conversion,newsletter-signup.liquid,Email capture form with Shopify customer form
|
|
11
|
+
10,Blog Posts Grid,blog-posts-grid,content,"blog articles posts grid cards latest news",intermediate,none,6,card grid editorial blog,blog-posts-grid.liquid,Latest blog articles in responsive grid
|
|
12
|
+
11,Collection List,collection-list,product,"collections categories grid cards browse shop departments",intermediate,none,5,card grid ecommerce browse,collection-list.liquid,Display collection cards for store navigation
|
|
13
|
+
12,Pricing Table,pricing-table,conversion,"pricing plans tiers comparison table subscription",advanced,pricing-tier,8,card comparison table pricing,pricing-table.liquid,2-3 tier pricing comparison with feature lists
|
|
14
|
+
13,Stats Counter,stats-counter,social-proof,"statistics numbers counter metrics achievements data",beginner,stat-item,4,bold numbers counter minimal,stats-counter.liquid,Number statistics with animated counters
|
|
15
|
+
14,Logo Cloud,logo-cloud,social-proof,"logos partners brands clients trust badges sponsors",beginner,logo-item,4,grid logos trust minimal,logo-cloud.liquid,Partner/brand logos grid display
|
|
16
|
+
15,Team Members,team-members,content,"team people staff members bios photos about",intermediate,team-member,6,card grid people team,team-members.liquid,Team member grid with photos and bios
|
|
17
|
+
16,Video Hero,video-hero,media,"video background hero embed youtube vimeo fullscreen",intermediate,heading|button,7,video fullscreen cinematic overlay,video-hero.liquid,Video background hero with text overlay
|
|
18
|
+
17,Image Gallery,image-gallery,media,"gallery images photos grid masonry lightbox portfolio",intermediate,gallery-item,5,grid masonry gallery portfolio,image-gallery.liquid,Image gallery grid with optional lightbox
|
|
19
|
+
18,Announcement Bar,announcement-bar,utility,"announcement banner top bar notification alert dismiss",beginner,announcement,5,minimal bar notification utility,announcement-bar.liquid,Top banner with announcement text and link
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
{%- comment -%} rebly-sections: Announcement Bar | Category: utility | OS2.0 {%- endcomment -%}
|
|
2
|
+
|
|
3
|
+
<section id="section-{{ section.id }}" class="announcement-bar" style="--bg: {{ section.settings.background_color }}; --color: {{ section.settings.text_color }};" data-dismissible="{{ section.settings.dismissible }}">
|
|
4
|
+
<div class="announcement-bar__track">
|
|
5
|
+
{%- for block in section.blocks -%}
|
|
6
|
+
{%- if block.type == 'announcement' -%}
|
|
7
|
+
<div class="announcement-bar__item" {{ block.shopify_attributes }}>
|
|
8
|
+
{%- if block.settings.link != blank and block.settings.link_text != blank -%}
|
|
9
|
+
{{ block.settings.text | escape }}
|
|
10
|
+
<a href="{{ block.settings.link }}" class="announcement-bar__link">{{ block.settings.link_text | escape }}</a>
|
|
11
|
+
{%- else -%}
|
|
12
|
+
{{ block.settings.text | escape }}
|
|
13
|
+
{%- endif -%}
|
|
14
|
+
</div>
|
|
15
|
+
{%- endif -%}
|
|
16
|
+
{%- endfor -%}
|
|
17
|
+
</div>
|
|
18
|
+
{%- if section.settings.dismissible -%}
|
|
19
|
+
<button class="announcement-bar__close" aria-label="Dismiss announcement" onclick="this.closest('.announcement-bar').style.display='none'">✕</button>
|
|
20
|
+
{%- endif -%}
|
|
21
|
+
</section>
|
|
22
|
+
|
|
23
|
+
<style>
|
|
24
|
+
#section-{{ section.id }} {
|
|
25
|
+
background: var(--bg, #000);
|
|
26
|
+
color: var(--color, #fff);
|
|
27
|
+
position: relative;
|
|
28
|
+
display: flex;
|
|
29
|
+
align-items: center;
|
|
30
|
+
justify-content: center;
|
|
31
|
+
min-height: 44px;
|
|
32
|
+
padding: 0.5rem 3rem;
|
|
33
|
+
}
|
|
34
|
+
#section-{{ section.id }} .announcement-bar__track { display: flex; gap: 2rem; flex-wrap: wrap; justify-content: center; align-items: center; text-align: center; font-size: 0.9rem; }
|
|
35
|
+
#section-{{ section.id }} .announcement-bar__item { white-space: nowrap; }
|
|
36
|
+
#section-{{ section.id }} .announcement-bar__link { color: inherit; font-weight: 600; margin-left: 0.35rem; }
|
|
37
|
+
#section-{{ section.id }} .announcement-bar__close { position: absolute; right: 1rem; top: 50%; transform: translateY(-50%); background: none; border: none; color: inherit; cursor: pointer; font-size: 1rem; padding: 0.25rem; opacity: 0.75; }
|
|
38
|
+
#section-{{ section.id }} .announcement-bar__close:hover { opacity: 1; }
|
|
39
|
+
@media (max-width: 749px) { #section-{{ section.id }} { padding: 0.5rem 2.5rem; } #section-{{ section.id }} .announcement-bar__track { gap: 1rem; } }
|
|
40
|
+
</style>
|
|
41
|
+
|
|
42
|
+
{% schema %}
|
|
43
|
+
{
|
|
44
|
+
"name": "Announcement Bar",
|
|
45
|
+
"tag": "section",
|
|
46
|
+
"class": "section-announcement-bar",
|
|
47
|
+
"settings": [
|
|
48
|
+
{ "type": "color_background", "id": "background_color", "label": "Background Color", "default": "#000000" },
|
|
49
|
+
{ "type": "color", "id": "text_color", "label": "Text Color", "default": "#ffffff" },
|
|
50
|
+
{ "type": "checkbox", "id": "dismissible", "label": "Allow Dismiss", "default": true }
|
|
51
|
+
],
|
|
52
|
+
"blocks": [
|
|
53
|
+
{
|
|
54
|
+
"type": "announcement",
|
|
55
|
+
"name": "Announcement",
|
|
56
|
+
"settings": [
|
|
57
|
+
{ "type": "text", "id": "text", "label": "Text", "default": "Free shipping on orders over $50" },
|
|
58
|
+
{ "type": "url", "id": "link", "label": "Link" },
|
|
59
|
+
{ "type": "text", "id": "link_text", "label": "Link Text", "default": "Shop now" }
|
|
60
|
+
]
|
|
61
|
+
},
|
|
62
|
+
{ "type": "@app" }
|
|
63
|
+
],
|
|
64
|
+
"presets": [{
|
|
65
|
+
"name": "Announcement Bar",
|
|
66
|
+
"blocks": [{ "type": "announcement" }]
|
|
67
|
+
}]
|
|
68
|
+
}
|
|
69
|
+
{% endschema %}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
{%- comment -%} rebly-sections: Blog Posts Grid | Category: content | OS2.0 {%- endcomment -%}
|
|
2
|
+
|
|
3
|
+
<section id="section-{{ section.id }}" class="blog-posts-grid">
|
|
4
|
+
<div class="blog-posts-grid__container">
|
|
5
|
+
|
|
6
|
+
{%- if section.settings.heading != blank -%}
|
|
7
|
+
<h2 class="blog-posts-grid__heading">{{ section.settings.heading | escape }}</h2>
|
|
8
|
+
{%- endif -%}
|
|
9
|
+
|
|
10
|
+
{%- for block in section.blocks -%}<div {{ block.shopify_attributes }}></div>{%- endfor -%}
|
|
11
|
+
{%- assign blog = blogs[section.settings.blog] -%}
|
|
12
|
+
<div class="blog-posts-grid__items" style="--cols: {{ section.settings.columns }};">
|
|
13
|
+
{%- if blog != blank -%}
|
|
14
|
+
{%- for article in blog.articles limit: section.settings.posts_to_show -%}
|
|
15
|
+
<article class="blog-posts-grid__card">
|
|
16
|
+
{%- if article.image != blank -%}
|
|
17
|
+
<a href="{{ article.url }}" class="blog-posts-grid__card-img-link">
|
|
18
|
+
{{- article.image | image_url: width: 600 | image_tag: loading: 'lazy', alt: article.title -}}
|
|
19
|
+
</a>
|
|
20
|
+
{%- endif -%}
|
|
21
|
+
<div class="blog-posts-grid__card-body">
|
|
22
|
+
{%- if section.settings.show_date -%}
|
|
23
|
+
<time class="blog-posts-grid__date" datetime="{{ article.published_at | date: '%Y-%m-%d' }}">
|
|
24
|
+
{{ article.published_at | date: '%B %d, %Y' }}
|
|
25
|
+
</time>
|
|
26
|
+
{%- endif -%}
|
|
27
|
+
<h3 class="blog-posts-grid__card-title"><a href="{{ article.url }}">{{ article.title }}</a></h3>
|
|
28
|
+
{%- if section.settings.show_author -%}
|
|
29
|
+
<p class="blog-posts-grid__author">{{ article.author }}</p>
|
|
30
|
+
{%- endif -%}
|
|
31
|
+
{%- if section.settings.show_excerpt and article.excerpt != blank -%}
|
|
32
|
+
<p class="blog-posts-grid__excerpt">{{ article.excerpt | strip_html | truncate: 120 }}</p>
|
|
33
|
+
{%- endif -%}
|
|
34
|
+
</div>
|
|
35
|
+
</article>
|
|
36
|
+
{%- endfor -%}
|
|
37
|
+
{%- else -%}
|
|
38
|
+
<p>Select a blog to display articles.</p>
|
|
39
|
+
{%- endif -%}
|
|
40
|
+
</div>
|
|
41
|
+
|
|
42
|
+
</div>
|
|
43
|
+
</section>
|
|
44
|
+
|
|
45
|
+
<style>
|
|
46
|
+
#section-{{ section.id }} .blog-posts-grid__container { max-width: 1200px; margin: 0 auto; padding: 4rem 2rem; }
|
|
47
|
+
#section-{{ section.id }} .blog-posts-grid__heading { font-size: 2rem; text-align: center; margin: 0 0 2rem; }
|
|
48
|
+
#section-{{ section.id }} .blog-posts-grid__items { display: grid; grid-template-columns: repeat(var(--cols, 3), 1fr); gap: 2rem; }
|
|
49
|
+
#section-{{ section.id }} .blog-posts-grid__card-img-link img { width: 100%; aspect-ratio: 16/9; object-fit: cover; border-radius: 4px; display: block; }
|
|
50
|
+
#section-{{ section.id }} .blog-posts-grid__card-body { padding: 1rem 0; }
|
|
51
|
+
#section-{{ section.id }} .blog-posts-grid__date { font-size: 0.8rem; opacity: 0.6; display: block; margin-bottom: 0.4rem; }
|
|
52
|
+
#section-{{ section.id }} .blog-posts-grid__card-title { font-size: 1.1rem; margin: 0 0 0.4rem; }
|
|
53
|
+
#section-{{ section.id }} .blog-posts-grid__card-title a { text-decoration: none; color: inherit; }
|
|
54
|
+
#section-{{ section.id }} .blog-posts-grid__author { font-size: 0.85rem; opacity: 0.65; margin: 0 0 0.5rem; }
|
|
55
|
+
#section-{{ section.id }} .blog-posts-grid__excerpt { font-size: 0.9rem; line-height: 1.5; opacity: 0.8; margin: 0; }
|
|
56
|
+
@media (max-width: 989px) { #section-{{ section.id }} .blog-posts-grid__items { grid-template-columns: repeat(2, 1fr); } }
|
|
57
|
+
@media (max-width: 749px) { #section-{{ section.id }} .blog-posts-grid__items { grid-template-columns: 1fr; } }
|
|
58
|
+
</style>
|
|
59
|
+
|
|
60
|
+
{% schema %}
|
|
61
|
+
{
|
|
62
|
+
"name": "Blog Posts Grid",
|
|
63
|
+
"tag": "section",
|
|
64
|
+
"class": "section-blog-posts-grid",
|
|
65
|
+
"settings": [
|
|
66
|
+
{ "type": "text", "id": "heading", "label": "Heading", "default": "Latest Articles" },
|
|
67
|
+
{ "type": "blog", "id": "blog", "label": "Blog" },
|
|
68
|
+
{ "type": "range", "id": "posts_to_show", "label": "Posts to Show", "min": 2, "max": 9, "step": 1, "default": 3 },
|
|
69
|
+
{ "type": "range", "id": "columns", "label": "Columns", "min": 2, "max": 4, "step": 1, "default": 3 },
|
|
70
|
+
{ "type": "checkbox", "id": "show_date", "label": "Show Date", "default": true },
|
|
71
|
+
{ "type": "checkbox", "id": "show_author", "label": "Show Author", "default": false },
|
|
72
|
+
{ "type": "checkbox", "id": "show_excerpt", "label": "Show Excerpt", "default": true }
|
|
73
|
+
],
|
|
74
|
+
"blocks": [{ "type": "@app" }],
|
|
75
|
+
"presets": [{ "name": "Blog Posts Grid" }]
|
|
76
|
+
}
|
|
77
|
+
{% endschema %}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
{%- comment -%} rebly-sections: Collection List | Category: product | OS2.0 {%- endcomment -%}
|
|
2
|
+
|
|
3
|
+
<section id="section-{{ section.id }}" class="collection-list">
|
|
4
|
+
<div class="collection-list__container">
|
|
5
|
+
|
|
6
|
+
{%- if section.settings.heading != blank -%}
|
|
7
|
+
<h2 class="collection-list__heading">{{ section.settings.heading | escape }}</h2>
|
|
8
|
+
{%- endif -%}
|
|
9
|
+
|
|
10
|
+
<div class="collection-list__grid">
|
|
11
|
+
{%- for block in section.blocks -%}
|
|
12
|
+
{%- if block.type == 'collection' -%}
|
|
13
|
+
{%- assign col = collections[block.settings.collection] -%}
|
|
14
|
+
<a href="{{ col.url }}" class="collection-list__card" {{ block.shopify_attributes }}>
|
|
15
|
+
<div class="collection-list__card-image">
|
|
16
|
+
{%- if col.image != blank -%}
|
|
17
|
+
{{- col.image | image_url: width: 600 | image_tag: loading: 'lazy', alt: col.title -}}
|
|
18
|
+
{%- else -%}
|
|
19
|
+
{{ 'collection-1' | placeholder_svg_tag }}
|
|
20
|
+
{%- endif -%}
|
|
21
|
+
</div>
|
|
22
|
+
<div class="collection-list__card-info">
|
|
23
|
+
<h3 class="collection-list__card-title">{{ col.title }}</h3>
|
|
24
|
+
<span class="collection-list__card-count">{{ col.products_count }} products</span>
|
|
25
|
+
</div>
|
|
26
|
+
</a>
|
|
27
|
+
{%- endif -%}
|
|
28
|
+
{%- endfor -%}
|
|
29
|
+
</div>
|
|
30
|
+
|
|
31
|
+
</div>
|
|
32
|
+
</section>
|
|
33
|
+
|
|
34
|
+
<style>
|
|
35
|
+
#section-{{ section.id }} .collection-list__container { max-width: 1200px; margin: 0 auto; padding: 4rem 2rem; }
|
|
36
|
+
#section-{{ section.id }} .collection-list__heading { font-size: 2rem; text-align: center; margin: 0 0 2rem; }
|
|
37
|
+
#section-{{ section.id }} .collection-list__grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 1.5rem; }
|
|
38
|
+
#section-{{ section.id }} .collection-list__card { text-decoration: none; color: inherit; display: block; border-radius: 6px; overflow: hidden; }
|
|
39
|
+
#section-{{ section.id }} .collection-list__card-image img,
|
|
40
|
+
#section-{{ section.id }} .collection-list__card-image svg { width: 100%; aspect-ratio: 4/3; object-fit: cover; display: block; }
|
|
41
|
+
#section-{{ section.id }} .collection-list__card-info { padding: 0.75rem; }
|
|
42
|
+
#section-{{ section.id }} .collection-list__card-title { font-size: 1.1rem; margin: 0 0 0.25rem; }
|
|
43
|
+
#section-{{ section.id }} .collection-list__card-count { font-size: 0.85rem; opacity: 0.6; }
|
|
44
|
+
@media (max-width: 989px) { #section-{{ section.id }} .collection-list__grid { grid-template-columns: repeat(2, 1fr); } }
|
|
45
|
+
@media (max-width: 749px) { #section-{{ section.id }} .collection-list__grid { grid-template-columns: repeat(2, 1fr); } }
|
|
46
|
+
</style>
|
|
47
|
+
|
|
48
|
+
{% schema %}
|
|
49
|
+
{
|
|
50
|
+
"name": "Collection List",
|
|
51
|
+
"tag": "section",
|
|
52
|
+
"class": "section-collection-list",
|
|
53
|
+
"settings": [
|
|
54
|
+
{ "type": "text", "id": "heading", "label": "Heading", "default": "Shop by Collection" }
|
|
55
|
+
],
|
|
56
|
+
"blocks": [
|
|
57
|
+
{
|
|
58
|
+
"type": "collection",
|
|
59
|
+
"name": "Collection",
|
|
60
|
+
"settings": [
|
|
61
|
+
{ "type": "collection", "id": "collection", "label": "Collection" }
|
|
62
|
+
]
|
|
63
|
+
},
|
|
64
|
+
{ "type": "@app" }
|
|
65
|
+
],
|
|
66
|
+
"presets": [{
|
|
67
|
+
"name": "Collection List",
|
|
68
|
+
"blocks": [{ "type": "collection" }, { "type": "collection" }, { "type": "collection" }]
|
|
69
|
+
}]
|
|
70
|
+
}
|
|
71
|
+
{% endschema %}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
{%- comment -%} rebly-sections: CTA Banner | Category: conversion | OS2.0 {%- endcomment -%}
|
|
2
|
+
|
|
3
|
+
<section id="section-{{ section.id }}" class="cta-banner">
|
|
4
|
+
{%- for block in section.blocks -%}<div {{ block.shopify_attributes }}></div>{%- endfor -%}
|
|
5
|
+
<div class="cta-banner__inner" style="--bg: {{ section.settings.background_color }}; --color: {{ section.settings.text_color }};">
|
|
6
|
+
<div class="cta-banner__content">
|
|
7
|
+
{%- if section.settings.heading != blank -%}
|
|
8
|
+
<h2 class="cta-banner__heading">{{ section.settings.heading | escape }}</h2>
|
|
9
|
+
{%- endif -%}
|
|
10
|
+
{%- if section.settings.text != blank -%}
|
|
11
|
+
<p class="cta-banner__text">{{ section.settings.text | escape }}</p>
|
|
12
|
+
{%- endif -%}
|
|
13
|
+
{%- if section.settings.button_label != blank -%}
|
|
14
|
+
<a href="{{ section.settings.button_link }}" class="cta-banner__btn">
|
|
15
|
+
{{ section.settings.button_label | escape }}
|
|
16
|
+
</a>
|
|
17
|
+
{%- endif -%}
|
|
18
|
+
</div>
|
|
19
|
+
</div>
|
|
20
|
+
</section>
|
|
21
|
+
|
|
22
|
+
<style>
|
|
23
|
+
#section-{{ section.id }} .cta-banner__inner {
|
|
24
|
+
background: var(--bg, #000);
|
|
25
|
+
color: var(--color, #fff);
|
|
26
|
+
padding: 4rem 2rem;
|
|
27
|
+
text-align: center;
|
|
28
|
+
}
|
|
29
|
+
#section-{{ section.id }} .cta-banner__content { max-width: 700px; margin: 0 auto; }
|
|
30
|
+
#section-{{ section.id }} .cta-banner__heading { font-size: 2.25rem; margin: 0 0 1rem; }
|
|
31
|
+
#section-{{ section.id }} .cta-banner__text { font-size: 1.125rem; margin: 0 0 1.5rem; opacity: 0.85; }
|
|
32
|
+
#section-{{ section.id }} .cta-banner__btn {
|
|
33
|
+
display: inline-block; padding: 0.85rem 2rem;
|
|
34
|
+
border: 2px solid currentColor; border-radius: 4px;
|
|
35
|
+
text-decoration: none; color: inherit; font-weight: 600;
|
|
36
|
+
transition: background 0.2s, color 0.2s;
|
|
37
|
+
}
|
|
38
|
+
#section-{{ section.id }} .cta-banner__btn:hover { background: var(--color, #fff); color: var(--bg, #000); }
|
|
39
|
+
@media (max-width: 749px) { #section-{{ section.id }} .cta-banner__heading { font-size: 1.75rem; } }
|
|
40
|
+
</style>
|
|
41
|
+
|
|
42
|
+
{% schema %}
|
|
43
|
+
{
|
|
44
|
+
"name": "CTA Banner",
|
|
45
|
+
"tag": "section",
|
|
46
|
+
"class": "section-cta-banner",
|
|
47
|
+
"settings": [
|
|
48
|
+
{ "type": "text", "id": "heading", "label": "Heading", "default": "Ready to get started?" },
|
|
49
|
+
{ "type": "text", "id": "text", "label": "Text", "default": "Join thousands of happy customers." },
|
|
50
|
+
{ "type": "text", "id": "button_label", "label": "Button Label", "default": "Shop Now" },
|
|
51
|
+
{ "type": "url", "id": "button_link", "label": "Button Link" },
|
|
52
|
+
{ "type": "color_background", "id": "background_color", "label": "Background", "default": "#000000" },
|
|
53
|
+
{ "type": "color", "id": "text_color", "label": "Text Color", "default": "#ffffff" }
|
|
54
|
+
],
|
|
55
|
+
"blocks": [{ "type": "@app" }],
|
|
56
|
+
"presets": [{ "name": "CTA Banner" }]
|
|
57
|
+
}
|
|
58
|
+
{% endschema %}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
{%- comment -%} rebly-sections: FAQ Accordion | Category: content | OS2.0 {%- endcomment -%}
|
|
2
|
+
|
|
3
|
+
<section id="section-{{ section.id }}" class="faq-accordion">
|
|
4
|
+
<div class="faq-accordion__container">
|
|
5
|
+
|
|
6
|
+
{%- if section.settings.heading != blank or section.settings.subheading != blank -%}
|
|
7
|
+
<div class="faq-accordion__header">
|
|
8
|
+
{%- if section.settings.heading != blank -%}
|
|
9
|
+
<h2 class="faq-accordion__heading">{{ section.settings.heading | escape }}</h2>
|
|
10
|
+
{%- endif -%}
|
|
11
|
+
{%- if section.settings.subheading != blank -%}
|
|
12
|
+
<p class="faq-accordion__subheading">{{ section.settings.subheading | escape }}</p>
|
|
13
|
+
{%- endif -%}
|
|
14
|
+
</div>
|
|
15
|
+
{%- endif -%}
|
|
16
|
+
|
|
17
|
+
<div class="faq-accordion__items">
|
|
18
|
+
{%- for block in section.blocks -%}
|
|
19
|
+
{%- if block.type == 'faq-item' -%}
|
|
20
|
+
<details class="faq-accordion__item" {{ block.shopify_attributes }}>
|
|
21
|
+
<summary class="faq-accordion__question">
|
|
22
|
+
<span>{{ block.settings.question | escape }}</span>
|
|
23
|
+
<span class="faq-accordion__icon" aria-hidden="true">+</span>
|
|
24
|
+
</summary>
|
|
25
|
+
<div class="faq-accordion__answer rte">{{ block.settings.answer }}</div>
|
|
26
|
+
</details>
|
|
27
|
+
{%- endif -%}
|
|
28
|
+
{%- endfor -%}
|
|
29
|
+
</div>
|
|
30
|
+
|
|
31
|
+
</div>
|
|
32
|
+
</section>
|
|
33
|
+
|
|
34
|
+
<style>
|
|
35
|
+
#section-{{ section.id }} .faq-accordion__container { max-width: 800px; margin: 0 auto; padding: 4rem 2rem; }
|
|
36
|
+
#section-{{ section.id }} .faq-accordion__header { text-align: center; margin-bottom: 2.5rem; }
|
|
37
|
+
#section-{{ section.id }} .faq-accordion__heading { font-size: 2rem; margin: 0 0 0.75rem; }
|
|
38
|
+
#section-{{ section.id }} .faq-accordion__subheading { opacity: 0.7; margin: 0; }
|
|
39
|
+
#section-{{ section.id }} .faq-accordion__item { border-bottom: 1px solid rgba(0,0,0,0.12); }
|
|
40
|
+
#section-{{ section.id }} .faq-accordion__question {
|
|
41
|
+
display: flex; justify-content: space-between; align-items: center;
|
|
42
|
+
padding: 1.25rem 0; cursor: pointer; list-style: none; font-weight: 600; font-size: 1.05rem;
|
|
43
|
+
}
|
|
44
|
+
#section-{{ section.id }} .faq-accordion__question::-webkit-details-marker { display: none; }
|
|
45
|
+
#section-{{ section.id }} details[open] .faq-accordion__icon { transform: rotate(45deg); }
|
|
46
|
+
#section-{{ section.id }} .faq-accordion__icon { transition: transform 0.2s; flex-shrink: 0; font-size: 1.5rem; line-height: 1; }
|
|
47
|
+
#section-{{ section.id }} .faq-accordion__answer { padding: 0 0 1.25rem; line-height: 1.7; }
|
|
48
|
+
@media (max-width: 749px) { #section-{{ section.id }} .faq-accordion__container { padding: 2.5rem 1.5rem; } }
|
|
49
|
+
</style>
|
|
50
|
+
|
|
51
|
+
{% schema %}
|
|
52
|
+
{
|
|
53
|
+
"name": "FAQ Accordion",
|
|
54
|
+
"tag": "section",
|
|
55
|
+
"class": "section-faq-accordion",
|
|
56
|
+
"settings": [
|
|
57
|
+
{ "type": "text", "id": "heading", "label": "Heading", "default": "Frequently Asked Questions" },
|
|
58
|
+
{ "type": "text", "id": "subheading", "label": "Subheading" }
|
|
59
|
+
],
|
|
60
|
+
"blocks": [
|
|
61
|
+
{
|
|
62
|
+
"type": "faq-item",
|
|
63
|
+
"name": "FAQ Item",
|
|
64
|
+
"settings": [
|
|
65
|
+
{ "type": "text", "id": "question", "label": "Question", "default": "What is your return policy?" },
|
|
66
|
+
{ "type": "richtext", "id": "answer", "label": "Answer", "default": "<p>We offer a 30-day return policy on all items.</p>" }
|
|
67
|
+
]
|
|
68
|
+
},
|
|
69
|
+
{ "type": "@app" }
|
|
70
|
+
],
|
|
71
|
+
"presets": [{
|
|
72
|
+
"name": "FAQ Accordion",
|
|
73
|
+
"blocks": [{ "type": "faq-item" }, { "type": "faq-item" }, { "type": "faq-item" }]
|
|
74
|
+
}]
|
|
75
|
+
}
|
|
76
|
+
{% endschema %}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
{%- comment -%} rebly-sections: Features Grid | Category: content | OS2.0 {%- endcomment -%}
|
|
2
|
+
|
|
3
|
+
<section id="section-{{ section.id }}" class="features-grid">
|
|
4
|
+
<div class="features-grid__container">
|
|
5
|
+
|
|
6
|
+
{%- if section.settings.heading != blank or section.settings.subheading != blank -%}
|
|
7
|
+
<div class="features-grid__header">
|
|
8
|
+
{%- if section.settings.heading != blank -%}
|
|
9
|
+
<h2 class="features-grid__heading">{{ section.settings.heading | escape }}</h2>
|
|
10
|
+
{%- endif -%}
|
|
11
|
+
{%- if section.settings.subheading != blank -%}
|
|
12
|
+
<p class="features-grid__subheading">{{ section.settings.subheading | escape }}</p>
|
|
13
|
+
{%- endif -%}
|
|
14
|
+
</div>
|
|
15
|
+
{%- endif -%}
|
|
16
|
+
|
|
17
|
+
<div class="features-grid__items" style="--cols: {{ section.settings.columns_per_row }};">
|
|
18
|
+
{%- for block in section.blocks -%}
|
|
19
|
+
{%- if block.type == 'feature' -%}
|
|
20
|
+
<div class="features-grid__item" {{ block.shopify_attributes }}>
|
|
21
|
+
{%- if block.settings.icon_image != blank -%}
|
|
22
|
+
<div class="features-grid__icon">
|
|
23
|
+
{{- block.settings.icon_image | image_url: width: 80 | image_tag: loading: 'lazy' -}}
|
|
24
|
+
</div>
|
|
25
|
+
{%- endif -%}
|
|
26
|
+
{%- if block.settings.heading != blank -%}
|
|
27
|
+
<h3 class="features-grid__item-heading">{{ block.settings.heading | escape }}</h3>
|
|
28
|
+
{%- endif -%}
|
|
29
|
+
{%- if block.settings.text != blank -%}
|
|
30
|
+
<p class="features-grid__item-text">{{ block.settings.text | escape }}</p>
|
|
31
|
+
{%- endif -%}
|
|
32
|
+
</div>
|
|
33
|
+
{%- endif -%}
|
|
34
|
+
{%- endfor -%}
|
|
35
|
+
</div>
|
|
36
|
+
|
|
37
|
+
</div>
|
|
38
|
+
</section>
|
|
39
|
+
|
|
40
|
+
<style>
|
|
41
|
+
#section-{{ section.id }} .features-grid__container { max-width: 1200px; margin: 0 auto; padding: 4rem 2rem; }
|
|
42
|
+
#section-{{ section.id }} .features-grid__header { text-align: center; margin-bottom: 3rem; }
|
|
43
|
+
#section-{{ section.id }} .features-grid__heading { font-size: 2rem; margin: 0 0 0.75rem; }
|
|
44
|
+
#section-{{ section.id }} .features-grid__subheading { font-size: 1.125rem; opacity: 0.75; margin: 0; }
|
|
45
|
+
#section-{{ section.id }} .features-grid__items {
|
|
46
|
+
display: grid;
|
|
47
|
+
grid-template-columns: repeat(var(--cols, 3), 1fr);
|
|
48
|
+
gap: 2rem;
|
|
49
|
+
}
|
|
50
|
+
#section-{{ section.id }} .features-grid__item { text-align: center; padding: 1.5rem; }
|
|
51
|
+
#section-{{ section.id }} .features-grid__icon { margin: 0 auto 1rem; width: 60px; height: 60px; }
|
|
52
|
+
#section-{{ section.id }} .features-grid__icon img { width: 100%; height: 100%; object-fit: contain; }
|
|
53
|
+
#section-{{ section.id }} .features-grid__item-heading { font-size: 1.25rem; margin: 0 0 0.5rem; }
|
|
54
|
+
#section-{{ section.id }} .features-grid__item-text { line-height: 1.6; opacity: 0.8; margin: 0; }
|
|
55
|
+
@media (max-width: 989px) {
|
|
56
|
+
#section-{{ section.id }} .features-grid__items { grid-template-columns: repeat(2, 1fr); }
|
|
57
|
+
}
|
|
58
|
+
@media (max-width: 749px) {
|
|
59
|
+
#section-{{ section.id }} .features-grid__items { grid-template-columns: 1fr; }
|
|
60
|
+
}
|
|
61
|
+
</style>
|
|
62
|
+
|
|
63
|
+
{% schema %}
|
|
64
|
+
{
|
|
65
|
+
"name": "Features Grid",
|
|
66
|
+
"tag": "section",
|
|
67
|
+
"class": "section-features-grid",
|
|
68
|
+
"settings": [
|
|
69
|
+
{ "type": "text", "id": "heading", "label": "Heading", "default": "Why choose us" },
|
|
70
|
+
{ "type": "text", "id": "subheading", "label": "Subheading" },
|
|
71
|
+
{ "type": "range", "id": "columns_per_row", "label": "Columns", "min": 2, "max": 4, "step": 1, "default": 3 }
|
|
72
|
+
],
|
|
73
|
+
"blocks": [
|
|
74
|
+
{
|
|
75
|
+
"type": "feature",
|
|
76
|
+
"name": "Feature",
|
|
77
|
+
"settings": [
|
|
78
|
+
{ "type": "image_picker", "id": "icon_image", "label": "Icon Image" },
|
|
79
|
+
{ "type": "text", "id": "heading", "label": "Heading", "default": "Feature title" },
|
|
80
|
+
{ "type": "text", "id": "text", "label": "Description", "default": "Describe your feature here." }
|
|
81
|
+
]
|
|
82
|
+
},
|
|
83
|
+
{ "type": "@app" }
|
|
84
|
+
],
|
|
85
|
+
"presets": [{
|
|
86
|
+
"name": "Features Grid",
|
|
87
|
+
"blocks": [
|
|
88
|
+
{ "type": "feature" },
|
|
89
|
+
{ "type": "feature" },
|
|
90
|
+
{ "type": "feature" }
|
|
91
|
+
]
|
|
92
|
+
}]
|
|
93
|
+
}
|
|
94
|
+
{% endschema %}
|