climaybe 1.7.2 → 1.8.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.
Files changed (39) hide show
  1. package/README.md +9 -7
  2. package/bin/version.txt +1 -1
  3. package/package.json +6 -7
  4. package/src/commands/add-cursor-skill.js +12 -7
  5. package/src/commands/init.js +10 -5
  6. package/src/cursor/rules/00-rule-index.mdc +24 -0
  7. package/src/cursor/rules/accessibility-rules.mdc +527 -0
  8. package/src/cursor/rules/commit-rules.mdc +286 -0
  9. package/src/cursor/rules/cursor-rule-template.mdc +66 -0
  10. package/src/cursor/rules/examples/section-example.liquid +52 -0
  11. package/src/cursor/rules/examples/snippet-example.liquid +83 -0
  12. package/src/cursor/rules/figma-design-system.mdc +182 -0
  13. package/src/cursor/rules/global-rules-reference.mdc +62 -0
  14. package/src/cursor/rules/javascript-standards.mdc +1125 -0
  15. package/src/cursor/rules/js-refactor-tasks.mdc +123 -0
  16. package/src/cursor/rules/linear-task-creation.mdc +105 -0
  17. package/src/cursor/rules/liquid-doc-rules.mdc +595 -0
  18. package/src/cursor/rules/liquid.mdc +228 -0
  19. package/src/cursor/rules/project-overview.mdc +81 -0
  20. package/src/cursor/rules/schemas.mdc +150 -0
  21. package/src/cursor/rules/sections.mdc +25 -0
  22. package/src/cursor/rules/snippets.mdc +134 -0
  23. package/src/cursor/rules/tailwindcss-rules.mdc +410 -0
  24. package/src/cursor/skills/accessibility-pass/SKILL.md +54 -0
  25. package/src/cursor/skills/changelog-release/SKILL.md +50 -0
  26. package/src/cursor/skills/commit/SKILL.md +27 -0
  27. package/src/cursor/skills/commit-in-groups/SKILL.md +55 -0
  28. package/src/cursor/skills/linear-create-task/SKILL.md +81 -0
  29. package/src/cursor/skills/liquid-doc-comments/SKILL.md +37 -0
  30. package/src/cursor/skills/locale-translation-prep/SKILL.md +49 -0
  31. package/src/cursor/skills/schema-section-change/SKILL.md +39 -0
  32. package/src/cursor/skills/section-from-spec/SKILL.md +39 -0
  33. package/src/cursor/skills/theme-check-fix/SKILL.md +47 -0
  34. package/src/index.js +3 -2
  35. package/src/lib/commit-tooling.js +0 -44
  36. package/src/lib/config.js +1 -1
  37. package/src/lib/cursor-bundle.js +47 -0
  38. package/src/lib/prompts.js +3 -2
  39. package/src/workflows/shared/version-bump.yml +5 -2
@@ -0,0 +1,228 @@
1
+ ---
2
+ description: Liquid syntax standards — render tag, valid tags/filters, formatting
3
+ globs:
4
+ - "**/*.liquid"
5
+ alwaysApply: false
6
+ ---
7
+
8
+ # Liquid Syntax Standards
9
+
10
+ ## Render tag: assign before passing computed values
11
+
12
+ **Do not use filters or `append` inside a `render` tag's parameter values.** Assign the computed string to a variable first, then pass that variable.
13
+
14
+ ```liquid
15
+ {%- assign props = 'data-section-id="' | append: section.id | append: '"' -%}
16
+ {% render 'a--button', properties: props %}
17
+ ```
18
+
19
+ **Wrong:** `render 'snippet', properties: 'data-id="' | append: section.id | append: '"'` — inline append in a render parameter is invalid/unreliable. Always assign, then pass.
20
+
21
+ ## Valid Tags with Parameters
22
+
23
+ **Control Flow:**
24
+
25
+ - `if condition` / `endif` - Conditional logic
26
+ - `unless condition` / `endunless` - Negative conditional
27
+ - `case variable` / `when value` / `endcase` - Switch statement
28
+ - `for item in array` / `endfor` - Loop with optional `limit:`, `offset:`
29
+
30
+ **Variable Assignment:**
31
+
32
+ - `assign variable = value` - Create variable
33
+ - `capture variable` / `endcapture` - Capture output
34
+ - `increment variable` - Add 1 to counter
35
+ - `decrement variable` - Subtract 1 from counter
36
+
37
+ **Template Inclusion:**
38
+
39
+ - `render 'snippet-name'` - Include snippet
40
+ - `render 'snippet-name', param: value` - With parameters
41
+ - `section 'section-name'` - Include section
42
+
43
+ **Forms:**
44
+
45
+ - `form 'cart'` / `endform` - Cart form
46
+ - `form 'product'` / `endform` - Product form
47
+ - `form 'customer_login'` / `endform` - Login form
48
+
49
+ **Other:**
50
+
51
+ - `paginate collection.products by 12` / `endpaginate` - Paginate results
52
+ - `liquid` / `endliquid` - Multiline Liquid block
53
+ - `comment` / `endcomment` - Block comments
54
+ - `raw` / `endraw` - Output without processing
55
+
56
+ ## Valid Filters
57
+
58
+ **Array Filters:**
59
+
60
+ - `compact` - Remove nil values: `array | compact`
61
+ - `concat` - Join arrays: `array | concat: array`
62
+ - `find` - Find object: `array | find: property, value`
63
+ - `where` - Filter objects: `array | where: property, value`
64
+ - `map` - Extract property: `array | map: property`
65
+ - `sort` - Sort array: `array | sort`
66
+ - `reverse` - Reverse order: `array | reverse`
67
+ - `first` - First item: `array | first`
68
+ - `last` - Last item: `array | last`
69
+ - `size` - Count items: `array | size`
70
+
71
+ **String Filters:**
72
+
73
+ - `escape` - HTML escape: `string | escape`
74
+ - `truncate` - Limit length: `string | truncate: 150`
75
+ - `handleize` - URL handle: `string | handleize`
76
+ - `replace` - Replace text: `string | replace: 'old', 'new'`
77
+ - `split` - Split string: `string | split: 'delimiter'`
78
+ - `upcase` - Uppercase: `string | upcase`
79
+ - `downcase` - Lowercase: `string | downcase`
80
+ - `capitalize` - Capitalize: `string | capitalize`
81
+
82
+ **Money Filters:**
83
+
84
+ - `money` - Format price: `price | money`
85
+ - `money_with_currency` - With symbol: `price | money_with_currency`
86
+ - `money_without_currency` - No symbol: `price | money_without_currency`
87
+
88
+ **Media Filters:**
89
+
90
+ - `image_url` - Responsive image: `image | image_url: width: 800`
91
+ - `image_tag` - Complete img tag: `image | image_tag`
92
+ - `asset_url` - Theme asset: `'style.css' | asset_url`
93
+
94
+ ## Syntax Rules
95
+
96
+ - Use `{% liquid %}` for multiline code blocks
97
+ - Use `{% # comment %}` for inline comments
98
+ - Never invent new filters, tags, or objects
99
+ - Follow proper tag closing order (last opened, first closed)
100
+ - Use object dot notation: `product.title` not `product['title']`
101
+ - Respect object scope and availability
102
+
103
+ ## Render Tag Formatting Rules
104
+
105
+ ### Within Liquid Blocks
106
+ When using `render` within a `{% liquid %}` block, all parameters must be on the same line:
107
+
108
+ **✅ Do this (single line within liquid block):**
109
+ ```liquid
110
+ {% liquid
111
+ render 'm--electric-slider', id: 'slider-1', feed: content, per_row_mobile: 1, per_row_tablet: 2, per_row_desktop: 2, gap: 'gap-x-4', nav: false
112
+ %}
113
+ ```
114
+
115
+ **❌ Don't do this (multiline within liquid block):**
116
+ ```liquid
117
+ {% liquid
118
+ render 'm--electric-slider',
119
+ id: 'slider-1',
120
+ feed: content,
121
+ per_row_mobile: 1,
122
+ per_row_tablet: 2,
123
+ per_row_desktop: 2
124
+ %}
125
+ ```
126
+
127
+ ### Standalone Render Tags
128
+ When using `render` as a standalone tag (outside of `{% liquid %}` blocks), you can and should use multiline formatting for readability:
129
+
130
+ **✅ Do this (multiline standalone render):**
131
+ ```liquid
132
+ {% render 'm--electric-slider',
133
+ id: 'slider-1',
134
+ feed: content,
135
+ per_row_mobile: 1,
136
+ per_row_tablet: 2,
137
+ per_row_desktop: 2,
138
+ gap: 'gap-x-4',
139
+ nav: false
140
+ %}
141
+ ```
142
+
143
+ **✅ Also acceptable (single line standalone render):**
144
+ ```liquid
145
+ {% render 'm--electric-slider', id: 'slider-1', feed: content, per_row_mobile: 1 %}
146
+ ```
147
+
148
+ ## Inline Variables Pattern
149
+
150
+ For props that are relatively straightforward, prefer to inline the liquid instead of declaring extra variables. In smaller components it doesn't make a big difference, but in bigger ones it helps not having to scroll up and down to know what is being applied where.
151
+
152
+ **✅ Do this (inline approach):**
153
+
154
+ ```liquid
155
+ <div
156
+ class='component component--{{ settings.style_modifier }}'
157
+ style='
158
+ color: {{ settings.text_color }};
159
+ {% if settings.show_border %}
160
+ border: 1px solid {{ settings.border_color }};
161
+ {% endif %}
162
+ '
163
+ >
164
+ <h2>{{ 'sections.component.title' | t }}</h2>
165
+
166
+ {{ content | truncate: settings.max_length | default: 200 }}
167
+
168
+ <a
169
+ href='{{ link_url }}'
170
+ class='link--{{ settings.link_style | default: 'primary' }}'
171
+ >
172
+ {{ 'general.read_more' | t }}
173
+ </a>
174
+ </div>
175
+ ```
176
+
177
+ **❌ Don't do this (variable declaration approach):**
178
+
179
+ ```liquid
180
+ {% liquid
181
+ assign component_class = 'component component--' | append: settings.style_modifier
182
+ assign text_color = settings.text_color
183
+ assign truncate_length = settings.max_length | default: 200
184
+ assign link_class = 'link--' | append: settings.link_style | default: 'primary'
185
+ %}
186
+
187
+ {% capture component_style %}
188
+ color: {{ text_color }};
189
+ {% if settings.show_border %}
190
+ border: 1px solid {{ settings.border_color }};
191
+ {% endif %}
192
+ {% endcapture %}
193
+
194
+ <div
195
+ class='{{ component_class }}'
196
+ style='{{ component_style }}'
197
+ >
198
+ <h2>{{ 'sections.component.title' | t }}</h2>
199
+
200
+ {{ content | truncate: truncate_length }}
201
+
202
+ <a
203
+ href='{{ link_url }}'
204
+ class='{{ link_class }}'
205
+ >
206
+ {{ 'general.read_more' | t }}
207
+ </a>
208
+ </div>
209
+ ```
210
+
211
+ **Exceptions:**
212
+
213
+ - When Liquid filter parameters require string values and complex logic cannot be inlined
214
+ - When the same complex calculation is used multiple times
215
+ - When the logic is extremely complex and would harm readability
216
+ - When you need to build a string incrementally with conditional parts
217
+
218
+ **Benefits:**
219
+
220
+ - Easier to understand what's being applied where
221
+ - No need to scroll up and down to find variable definitions
222
+ - Reduces cognitive load in larger components
223
+ - Makes the code more maintainable
224
+
225
+ - Easier to understand what's being applied where
226
+ - No need to scroll up and down to find variable definitions
227
+ - Reduces cognitive load in larger components
228
+ - Makes the code more maintainable
@@ -0,0 +1,81 @@
1
+ ---
2
+ description: Electric Maybe Shopify Theme project overview and development standards
3
+ globs:
4
+ - "**/*"
5
+ alwaysApply: true
6
+ ---
7
+ # Electric Maybe Shopify Theme Development Rules
8
+
9
+ ## Project Overview
10
+ This is a professional Shopify theme project for Electric Maybe agency. All code must follow the highest standards for performance, accessibility, and maintainability.
11
+
12
+ ## JavaScript Development Standards
13
+
14
+ All JavaScript code must follow the comprehensive standards defined in `javascript-standards.mdc`.
15
+
16
+ ### Core Requirements
17
+ - **Zero external dependencies** - Native browser APIs only
18
+ - **Performance first** - Operations < 16ms
19
+ - **Accessibility always** - WCAG 2.1 AA minimum
20
+ - **Memory conscious** - Proper cleanup, no leaks
21
+ - **Documentation complete** - JSDoc for all public APIs
22
+
23
+ ### Key Patterns
24
+ - Private fields/methods with `#` syntax (never `_` or `private`)
25
+ - AbortController for all event listeners
26
+ - Try-catch boundaries around critical operations
27
+ - RequestAnimationFrame for animations
28
+ - Debounce/throttle for expensive operations
29
+ - Custom events with typed detail objects
30
+
31
+ ### Reference Implementation
32
+ Use `_scripts/electric-modal.js` as the gold standard for all web components.
33
+
34
+ ## Liquid Template Standards
35
+
36
+ ### Sections (sections/*.liquid)
37
+ - Semantic HTML structure
38
+ - ARIA attributes for accessibility
39
+ - Performance-optimized asset loading
40
+ - Responsive design patterns
41
+ - Schema settings properly typed
42
+
43
+ ### Snippets (snippets/*.liquid)
44
+ - Reusable and modular
45
+ - Clear parameter documentation
46
+ - DRY principles
47
+ - Consistent naming conventions
48
+
49
+ ## CSS/Tailwind Standards
50
+ - Mobile-first responsive design
51
+ - Utility-first with Tailwind classes
52
+ - Custom properties for theming
53
+ - Performance-optimized animations
54
+ - Print styles where appropriate
55
+
56
+ ## File Organization
57
+ ```
58
+ _scripts/ # Web components and utilities
59
+ assets/ # Compiled CSS/JS and static assets
60
+ sections/ # Liquid section files
61
+ snippets/ # Reusable Liquid snippets
62
+ templates/ # Page templates
63
+ locales/ # Translation files
64
+ config/ # Theme settings
65
+ ```
66
+
67
+ ## Code Review Requirements
68
+ All code must pass the checklist in `javascript-standards.mdc` before merge.
69
+
70
+ ## Browser Support
71
+ - Chrome 74+ (for private class fields)
72
+ - Firefox 90+
73
+ - Safari 15+
74
+ - Edge 79+
75
+
76
+ ## Performance Targets
77
+ - Component initialization: < 16ms
78
+ - Event handlers: < 8ms
79
+ - Animation frames: 60fps
80
+ - First Contentful Paint: < 1.5s
81
+ - Time to Interactive: < 3.5s
@@ -0,0 +1,150 @@
1
+ ---
2
+ description: Schema design rules — minimal settings, translation keys, no redundancy
3
+ globs:
4
+ - "sections/**/*.liquid"
5
+ - "**/sections/*.liquid"
6
+ - "blocks/**/*.liquid"
7
+ - "**/blocks/*.liquid"
8
+ alwaysApply: false
9
+ ---
10
+ # Schema Design Rules for Electric Maybe Shopify Theme
11
+
12
+ ## Core Principles
13
+
14
+ ### 1. **Start Simple, Expand Gradually**
15
+ - Begin with minimal, essential settings only
16
+ - Add complexity only when there's a clear, demonstrated need
17
+ - Ask for permission before adding multiple settings at once
18
+
19
+ ### 2. **Avoid Redundancy**
20
+ - If text content exists in translation files (`en.default.json`), don't duplicate it in schema
21
+ - Use translation keys for all text content, not schema text inputs
22
+ - Schema should focus on functionality, not content
23
+
24
+ ### 3. **Question Every Setting**
25
+ Before adding any schema setting, ask:
26
+ - Is this truly necessary for the user?
27
+ - Can this be handled by translation files instead?
28
+ - Will this setting be used by most merchants?
29
+ - Does this add value or just complexity?
30
+
31
+ ### 4. **Limit Settings Per Section**
32
+ - **Maximum 5 settings per section** (excluding headers)
33
+ - If more are needed, consider splitting into multiple sections
34
+ - Group related settings under headers
35
+
36
+ ## Schema Setting Guidelines
37
+
38
+ ### **Essential Settings (Always Include)**
39
+ - Link list selectors for menus
40
+ - Image upload fields for key visuals
41
+ - Color scheme selectors (if theme supports multiple schemes)
42
+
43
+ ### **Optional Settings (Add Only When Needed)**
44
+ - Layout toggles (show/hide elements)
45
+ - Spacing adjustments
46
+ - Text alignment options
47
+ - Background color/image options
48
+
49
+ ### **Avoid These Settings**
50
+ - Text content inputs (use translation files)
51
+ - Toggle switches for every element
52
+ - Complex layout selectors
53
+ - Settings that duplicate existing functionality
54
+
55
+ ## Implementation Rules
56
+
57
+ ### **Before Adding Settings**
58
+ 1. Check if the functionality can be achieved through:
59
+ - Translation files
60
+ - CSS classes
61
+ - Existing theme settings
62
+ - Liquid conditionals
63
+
64
+ 2. Consider the user experience:
65
+ - Will merchants actually use this setting?
66
+ - Is it intuitive and discoverable?
67
+ - Does it solve a real problem?
68
+
69
+ 3. Evaluate maintenance cost:
70
+ - Will this setting need updates?
71
+ - Does it create technical debt?
72
+ - Is it worth the complexity?
73
+
74
+ ### **When Adding Multiple Settings**
75
+ - **Ask for permission first**
76
+ - Explain the reasoning for each setting
77
+ - Consider if they can be grouped or simplified
78
+ - Test with a small subset first
79
+
80
+ ## Examples
81
+
82
+ ### ✅ Good Schema (Simple)
83
+ ```json
84
+ {
85
+ "settings": [
86
+ {
87
+ "type": "link_list",
88
+ "id": "main_menu",
89
+ "label": "Main menu"
90
+ },
91
+ {
92
+ "type": "image_picker",
93
+ "id": "logo",
94
+ "label": "Logo"
95
+ }
96
+ ]
97
+ }
98
+ ```
99
+
100
+ ### ❌ Bad Schema (Over-engineered)
101
+ ```json
102
+ {
103
+ "settings": [
104
+ {
105
+ "type": "link_list",
106
+ "id": "main_menu",
107
+ "label": "Main menu"
108
+ },
109
+ {
110
+ "type": "checkbox",
111
+ "id": "show_menu",
112
+ "label": "Show menu",
113
+ "default": true
114
+ },
115
+ {
116
+ "type": "select",
117
+ "id": "menu_style",
118
+ "label": "Menu style",
119
+ "options": [
120
+ {"value": "horizontal", "label": "Horizontal"},
121
+ {"value": "vertical", "label": "Vertical"},
122
+ {"value": "dropdown", "label": "Dropdown"}
123
+ ]
124
+ },
125
+ {
126
+ "type": "range",
127
+ "id": "menu_spacing",
128
+ "min": 0,
129
+ "max": 50,
130
+ "step": 5,
131
+ "label": "Menu spacing"
132
+ }
133
+ ]
134
+ }
135
+ ```
136
+
137
+ ## Review Process
138
+
139
+ Before committing any schema changes:
140
+ 1. **Count the settings** - Keep under 5 per section
141
+ 2. **Check for redundancy** - Ensure no duplicate functionality
142
+ 3. **Verify necessity** - Each setting should solve a real problem
143
+ 4. **Consider alternatives** - Could this be handled differently?
144
+ 5. **Get approval** - For multiple settings or complex changes
145
+
146
+ ## Remember
147
+ - **Simplicity is a feature**
148
+ - **Less is more**
149
+ - **When in doubt, leave it out**
150
+ - **Ask before expanding**
@@ -0,0 +1,25 @@
1
+ ---
2
+ description: Section development standards — schema, structure, blocks, performance patterns
3
+ globs:
4
+ - "sections/**/*.liquid"
5
+ - "**/sections/*.liquid"
6
+ alwaysApply: false
7
+ ---
8
+ # Section Development Standards
9
+
10
+ ## Section Requirements
11
+
12
+ Every section must include:
13
+
14
+ - `{% schema %}` tag with valid JSON
15
+ - Proper HTML semantic structure
16
+ - CSS scoping with section classes
17
+ - Translation keys for all text
18
+
19
+ ## Section Patterns
20
+
21
+ _(To be filled in on review.)_
22
+
23
+ ## Performance Patterns
24
+
25
+ _(To be filled in on review.)_
@@ -0,0 +1,134 @@
1
+ ---
2
+ description: Snippet development standards — LiquidDoc, parameters, patterns
3
+ globs:
4
+ - "snippets/**/*.liquid"
5
+ - "**/snippets/*.liquid"
6
+ alwaysApply: false
7
+ ---
8
+ # Snippet Development Standards
9
+
10
+ ## Snippet Documentation
11
+
12
+ Every snippet must include JSDoc-style comments using LiquidDoc:
13
+
14
+ ```liquid
15
+ {% doc %}
16
+ Product Card Component
17
+
18
+ Renders a product card with customizable options.
19
+
20
+ @param product {Object} Product object (required)
21
+ @param show_vendor {Boolean} Display vendor name (default: false)
22
+ @param show_quick_add {Boolean} Show quick add button (default: false)
23
+ @param image_ratio {String} Image aspect ratio (default: 'adapt')
24
+ @param lazy_load {Boolean} Enable lazy loading (default: true)
25
+ @param card_class {String} Additional CSS classes
26
+
27
+ @example
28
+ {% render 'product-card',
29
+ product: product,
30
+ show_vendor: true,
31
+ image_ratio: 'square'
32
+ %}
33
+ {% enddoc %}
34
+ ```
35
+
36
+ ## Parameter Handling
37
+
38
+ Always provide defaults and validate parameters:
39
+
40
+ ```liquid
41
+ {% liquid
42
+ # Parameter validation and defaults
43
+ assign product = product | default: empty
44
+ assign show_vendor = show_vendor | default: false
45
+ assign show_quick_add = show_quick_add | default: false
46
+ assign image_ratio = image_ratio | default: 'adapt'
47
+ assign lazy_load = lazy_load | default: true
48
+ assign card_class = card_class | default: ''
49
+
50
+ # Early return if required parameters missing
51
+ unless product != empty
52
+ echo '<!-- Error: product parameter required for product-card snippet -->'
53
+ break
54
+ endunless
55
+ %}
56
+ ```
57
+
58
+ ## Common Snippet Patterns
59
+
60
+ **Icon Snippet:**
61
+ ```liquid
62
+ {% comment %}
63
+ @param icon {String} Icon name (required)
64
+ @param size {String} Icon size class (default: 'icon--medium')
65
+ @param class {String} Additional classes
66
+ {% endcomment %}
67
+
68
+ {% liquid
69
+ assign icon = icon | default: ''
70
+ assign size = size | default: 'icon--medium'
71
+ assign class = class | default: ''
72
+
73
+ unless icon != blank
74
+ break
75
+ endunless
76
+ %}
77
+
78
+ <svg class="icon {{ size }} {{ class }}" aria-hidden="true" focusable="false">
79
+ <use href="#icon-{{ icon }}"></use>
80
+ </svg>
81
+ ```
82
+
83
+ **Price Snippet:**
84
+ ```liquid
85
+ {% comment %}
86
+ @param product {Object} Product object (required)
87
+ @param show_compare_at {Boolean} Show compare at price (default: true)
88
+ @param show_unit_price {Boolean} Show unit price (default: false)
89
+ {% endcomment %}
90
+
91
+ {% liquid
92
+ assign show_compare_at = show_compare_at | default: true
93
+ assign show_unit_price = show_unit_price | default: false
94
+ %}
95
+
96
+ <div class="price">
97
+ <div class="price__regular">
98
+ {{ product.price | money }}
99
+ </div>
100
+
101
+ {% if show_compare_at and product.compare_at_price > product.price %}
102
+ <div class="price__compare-at">
103
+ <s>{{ product.compare_at_price | money }}</s>
104
+ </div>
105
+ {% endif %}
106
+
107
+ {% if show_unit_price and product.selected_or_first_available_variant.unit_price_measurement %}
108
+ <div class="price__unit">
109
+ {{ product.selected_or_first_available_variant.unit_price | money }}/
110
+ {%- if product.selected_or_first_available_variant.unit_price_measurement.reference_value != 1 -%}
111
+ {{ product.selected_or_first_available_variant.unit_price_measurement.reference_value }}
112
+ {%- endif -%}
113
+ {{ product.selected_or_first_available_variant.unit_price_measurement.reference_unit }}
114
+ </div>
115
+ {% endif %}
116
+ </div>
117
+ ```
118
+
119
+ ## Testing Patterns
120
+
121
+ Include testing scenarios in comments:
122
+
123
+ ```liquid
124
+ {% comment %}
125
+ Test cases:
126
+ - Product with variants
127
+ - Product without image
128
+ - Product with compare_at_price
129
+ - Product with unit pricing
130
+ - Out of stock product
131
+ {% endcomment %}
132
+ ```
133
+
134
+ [snippet-example.liquid](mdc:.cursor/rules/examples/snippet-example.liquid)