@zohofinance/commerce 1.0.0 → 1.1.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 (127) hide show
  1. package/README.md +59 -0
  2. package/package.json +2 -2
  3. package/ts-dist/mocks/init-theme/.claude/CLAUDE.md +6 -0
  4. package/ts-dist/mocks/init-theme/.claude/skills/.archive/zcommerce-section-from-design.20260528/SKILL.md +242 -0
  5. package/ts-dist/mocks/init-theme/.claude/skills/.archive/zcommerce-section-from-design.20260528/inputs/figma.md +81 -0
  6. package/ts-dist/mocks/init-theme/.claude/skills/.archive/zcommerce-section-from-design.20260528/inputs/screenshot.md +54 -0
  7. package/ts-dist/mocks/init-theme/.claude/skills/.archive/zcommerce-section-from-design.20260528/inputs/url.md +88 -0
  8. package/ts-dist/mocks/init-theme/.claude/skills/.archive/zcommerce-section-from-design.20260528/spec-table.md +102 -0
  9. package/ts-dist/mocks/init-theme/.claude/skills/.archive/zcommerce-section-from-design.20260528/verification/accessibility.md +110 -0
  10. package/ts-dist/mocks/init-theme/.claude/skills/.archive/zcommerce-section-from-design.20260528/verification/performance.md +127 -0
  11. package/ts-dist/mocks/init-theme/.claude/skills/.archive/zcommerce-section-from-design.20260528/verification/tokens.md +87 -0
  12. package/ts-dist/mocks/init-theme/.claude/skills/.archive/zcommerce-section-from-design.20260528/verification/visual-diff.md +123 -0
  13. package/ts-dist/mocks/init-theme/.claude/skills/.archive/zcommerce-theme-builder.20260528/SKILL.md +605 -0
  14. package/ts-dist/mocks/init-theme/.claude/skills/.archive/zcommerce-theme-builder.20260528/design-tokens.md +105 -0
  15. package/ts-dist/mocks/init-theme/.claude/skills/.archive/zcommerce-theme-builder.20260528/page-json-contract.md +58 -0
  16. package/ts-dist/mocks/init-theme/.claude/skills/.archive/zcommerce-theme-builder.20260528/qa-accessibility.md +35 -0
  17. package/ts-dist/mocks/init-theme/.claude/skills/.archive/zcommerce-theme-builder.20260528/reference-lookup.md +94 -0
  18. package/ts-dist/mocks/init-theme/.claude/skills/.archive/zcommerce-theme-builder.20260528/section-anatomy.md +109 -0
  19. package/ts-dist/mocks/init-theme/.claude/skills/theme-from-figma/SKILL.md +313 -0
  20. package/ts-dist/mocks/init-theme/.claude/skills/theme-from-figma/agent-hierarchy.md +142 -0
  21. package/ts-dist/mocks/init-theme/.claude/skills/theme-from-figma/ask-developer.md +113 -0
  22. package/ts-dist/mocks/init-theme/.claude/skills/theme-from-figma/bootstrap.md +260 -0
  23. package/ts-dist/mocks/init-theme/.claude/skills/theme-from-figma/build-metrics.md +89 -0
  24. package/ts-dist/mocks/init-theme/.claude/skills/theme-from-figma/code-quality.md +186 -0
  25. package/ts-dist/mocks/init-theme/.claude/skills/theme-from-figma/common-pages-agent.md +97 -0
  26. package/ts-dist/mocks/init-theme/.claude/skills/theme-from-figma/dev-server-and-urls.md +136 -0
  27. package/ts-dist/mocks/init-theme/.claude/skills/theme-from-figma/exemplars.md +79 -0
  28. package/ts-dist/mocks/init-theme/.claude/skills/theme-from-figma/figma-discovery.md +138 -0
  29. package/ts-dist/mocks/init-theme/.claude/skills/theme-from-figma/figma-extraction.md +132 -0
  30. package/ts-dist/mocks/init-theme/.claude/skills/theme-from-figma/image-sources.md +84 -0
  31. package/ts-dist/mocks/init-theme/.claude/skills/theme-from-figma/inputs/guidelines-frame.md +178 -0
  32. package/ts-dist/mocks/init-theme/.claude/skills/theme-from-figma/page-builder.md +322 -0
  33. package/ts-dist/mocks/init-theme/.claude/skills/theme-from-figma/page-orchestrator.md +199 -0
  34. package/ts-dist/mocks/init-theme/.claude/skills/theme-from-figma/parallel-fanout.md +152 -0
  35. package/ts-dist/mocks/init-theme/.claude/skills/theme-from-figma/scripts/a11y.mjs +129 -0
  36. package/ts-dist/mocks/init-theme/.claude/skills/theme-from-figma/scripts/lint-section.mjs +502 -0
  37. package/ts-dist/mocks/init-theme/.claude/skills/theme-from-figma/scripts/perf.mjs +134 -0
  38. package/ts-dist/mocks/init-theme/.claude/skills/theme-from-figma/scripts/pixel-diff.mjs +206 -0
  39. package/ts-dist/mocks/init-theme/.claude/skills/theme-from-figma/scripts/record-build-metrics.mjs +118 -0
  40. package/ts-dist/mocks/init-theme/.claude/skills/theme-from-figma/section-builder.md +131 -0
  41. package/ts-dist/mocks/init-theme/.claude/skills/theme-from-figma/subagent-escalation.md +75 -0
  42. package/ts-dist/mocks/init-theme/.claude/skills/theme-from-figma/transcription-rules.md +98 -0
  43. package/ts-dist/mocks/init-theme/.claude/skills/theme-from-figma/verification.md +227 -0
  44. package/ts-dist/mocks/init-theme/.claude/skills/theme-from-figma/visual-verify-loop.md +117 -0
  45. package/ts-dist/mocks/init-theme/.claude/skills/theme-from-figma/zcommerce-docs/_index.md +4 -0
  46. package/ts-dist/mocks/init-theme/.claude/skills/theme-from-figma/zcommerce-docs/assets.md +105 -0
  47. package/ts-dist/mocks/init-theme/.claude/skills/theme-from-figma/zcommerce-docs/best-practices.md +212 -0
  48. package/ts-dist/mocks/init-theme/.claude/skills/theme-from-figma/zcommerce-docs/custom-scripts.md +294 -0
  49. package/ts-dist/mocks/init-theme/.claude/skills/theme-from-figma/zcommerce-docs/i18n.md +155 -0
  50. package/ts-dist/mocks/init-theme/.claude/skills/theme-from-figma/zcommerce-docs/introduction.md +91 -0
  51. package/ts-dist/mocks/init-theme/.claude/skills/theme-from-figma/zcommerce-docs/layouts.md +158 -0
  52. package/ts-dist/mocks/init-theme/.claude/skills/theme-from-figma/zcommerce-docs/pages.md +156 -0
  53. package/ts-dist/mocks/init-theme/.claude/skills/theme-from-figma/zcommerce-docs/reference/_index.md +4 -0
  54. package/ts-dist/mocks/init-theme/.claude/skills/theme-from-figma/zcommerce-docs/reference/filters.md +419 -0
  55. package/ts-dist/mocks/init-theme/.claude/skills/theme-from-figma/zcommerce-docs/reference/global-objects.md +415 -0
  56. package/ts-dist/mocks/init-theme/.claude/skills/theme-from-figma/zcommerce-docs/reference/schema-types.md +926 -0
  57. package/ts-dist/mocks/init-theme/.claude/skills/theme-from-figma/zcommerce-docs/reference/tags.md +259 -0
  58. package/ts-dist/mocks/init-theme/.claude/skills/theme-from-figma/zcommerce-docs/sections.md +203 -0
  59. package/ts-dist/mocks/init-theme/.claude/skills/theme-from-figma/zcommerce-docs/setup-guide.md +424 -0
  60. package/ts-dist/mocks/init-theme/.claude/skills/theme-from-figma/zcommerce-docs/snippets.md +70 -0
  61. package/ts-dist/mocks/init-theme/.claude/skills/theme-from-figma/zcommerce-docs/theme-structure.md +252 -0
  62. package/ts-dist/mocks/init-theme/.cursor/PLAYBOOK.md +144 -0
  63. package/ts-dist/mocks/init-theme/.cursor/README.md +6 -0
  64. package/ts-dist/mocks/init-theme/.cursor/agents/figma-desktop-mobile-parallel.md +48 -0
  65. package/ts-dist/mocks/init-theme/.cursor/agents/visual-compare.md +221 -0
  66. package/ts-dist/mocks/init-theme/.cursor/commands/add-field.md +83 -0
  67. package/ts-dist/mocks/init-theme/.cursor/commands/add-theme-setting.md +200 -0
  68. package/ts-dist/mocks/init-theme/.cursor/commands/assemble-page.md +72 -0
  69. package/ts-dist/mocks/init-theme/.cursor/commands/audit-page.md +57 -0
  70. package/ts-dist/mocks/init-theme/.cursor/commands/build-page-sections.md +110 -0
  71. package/ts-dist/mocks/init-theme/.cursor/commands/build-section.md +418 -0
  72. package/ts-dist/mocks/init-theme/.cursor/commands/build-theme.md +307 -0
  73. package/ts-dist/mocks/init-theme/.cursor/commands/compare-section.md +358 -0
  74. package/ts-dist/mocks/init-theme/.cursor/commands/create-theme.md +77 -0
  75. package/ts-dist/mocks/init-theme/.cursor/commands/extract-tokens.md +43 -0
  76. package/ts-dist/mocks/init-theme/.cursor/commands/fix-section.md +92 -0
  77. package/ts-dist/mocks/init-theme/.cursor/commands/impact.md +50 -0
  78. package/ts-dist/mocks/init-theme/.cursor/commands/qa-a11y.md +66 -0
  79. package/ts-dist/mocks/init-theme/.cursor/commands/qa-i18n.md +110 -0
  80. package/ts-dist/mocks/init-theme/.cursor/commands/qa-layout.md +127 -0
  81. package/ts-dist/mocks/init-theme/.cursor/commands/qa-performance.md +72 -0
  82. package/ts-dist/mocks/init-theme/.cursor/commands/qa-section.md +84 -0
  83. package/ts-dist/mocks/init-theme/.cursor/commands/qa-sections.md +48 -0
  84. package/ts-dist/mocks/init-theme/.cursor/commands/qa-theme.md +85 -0
  85. package/ts-dist/mocks/init-theme/.cursor/commands/redesign-section.md +177 -0
  86. package/ts-dist/mocks/init-theme/.cursor/commands/refactor-section.md +185 -0
  87. package/ts-dist/mocks/init-theme/.cursor/commands/sync-theme-settings.md +132 -0
  88. package/ts-dist/mocks/init-theme/.cursor/commands/validate-page.md +60 -0
  89. package/ts-dist/mocks/init-theme/.cursor/commands/validate-section-group.md +88 -0
  90. package/ts-dist/mocks/init-theme/.cursor/commands/validate-theme-settings.md +119 -0
  91. package/ts-dist/mocks/init-theme/.cursor/examples/design-instructions-template.md +151 -0
  92. package/ts-dist/mocks/init-theme/.cursor/mcp.json +18 -0
  93. package/ts-dist/mocks/init-theme/.cursor/rules/README.md +160 -0
  94. package/ts-dist/mocks/init-theme/.cursor/rules/accessibility.mdc +24 -0
  95. package/ts-dist/mocks/init-theme/.cursor/rules/add-field.mdc +222 -0
  96. package/ts-dist/mocks/init-theme/.cursor/rules/add-theme-setting.mdc +39 -0
  97. package/ts-dist/mocks/init-theme/.cursor/rules/assemble-page.mdc +130 -0
  98. package/ts-dist/mocks/init-theme/.cursor/rules/audit-page.mdc +92 -0
  99. package/ts-dist/mocks/init-theme/.cursor/rules/build-section.mdc +178 -0
  100. package/ts-dist/mocks/init-theme/.cursor/rules/build-theme.mdc +47 -0
  101. package/ts-dist/mocks/init-theme/.cursor/rules/compare-section.mdc +94 -0
  102. package/ts-dist/mocks/init-theme/.cursor/rules/create-theme.mdc +78 -0
  103. package/ts-dist/mocks/init-theme/.cursor/rules/css.mdc +137 -0
  104. package/ts-dist/mocks/init-theme/.cursor/rules/design-spec-extraction.mdc +255 -0
  105. package/ts-dist/mocks/init-theme/.cursor/rules/extract-tokens.mdc +43 -0
  106. package/ts-dist/mocks/init-theme/.cursor/rules/figma-mcp-resolution.mdc +40 -0
  107. package/ts-dist/mocks/init-theme/.cursor/rules/fix-section.mdc +154 -0
  108. package/ts-dist/mocks/init-theme/.cursor/rules/general.mdc +30 -0
  109. package/ts-dist/mocks/init-theme/.cursor/rules/i18n.mdc +85 -0
  110. package/ts-dist/mocks/init-theme/.cursor/rules/javascript.mdc +85 -0
  111. package/ts-dist/mocks/init-theme/.cursor/rules/liquid-no-hardcoded-strings.mdc +42 -0
  112. package/ts-dist/mocks/init-theme/.cursor/rules/liquid.mdc +171 -0
  113. package/ts-dist/mocks/init-theme/.cursor/rules/mobile-desktop-setting-meta.mdc +34 -0
  114. package/ts-dist/mocks/init-theme/.cursor/rules/naming-convention.mdc +64 -0
  115. package/ts-dist/mocks/init-theme/.cursor/rules/pages.mdc +120 -0
  116. package/ts-dist/mocks/init-theme/.cursor/rules/performance.mdc +51 -0
  117. package/ts-dist/mocks/init-theme/.cursor/rules/qa-section.mdc +134 -0
  118. package/ts-dist/mocks/init-theme/.cursor/rules/redesign-section.mdc +147 -0
  119. package/ts-dist/mocks/init-theme/.cursor/rules/schema-sync.mdc +110 -0
  120. package/ts-dist/mocks/init-theme/.cursor/rules/schema.mdc +360 -0
  121. package/ts-dist/mocks/init-theme/.cursor/rules/share-urls.mdc +68 -0
  122. package/ts-dist/mocks/init-theme/.cursor/skills/browser-verify.md +128 -0
  123. package/ts-dist/mocks/init-theme/.cursor/skills/design-tokens.md +105 -0
  124. package/ts-dist/mocks/init-theme/.cursor/skills/page-json-contract.md +87 -0
  125. package/ts-dist/mocks/init-theme/.cursor/skills/qa-accessibility.md +35 -0
  126. package/ts-dist/mocks/init-theme/.cursor/skills/reference-lookup.md +88 -0
  127. package/ts-dist/mocks/init-theme/.cursor/skills/section-anatomy.md +173 -0
@@ -0,0 +1,87 @@
1
+ # SKILL: Page JSON contract
2
+ # Usage in chat: @page-json-contract
3
+
4
+ How page JSON relates to section and block schemas. Use when running `/assemble-page` or `/validate-page`.
5
+
6
+ ---
7
+
8
+ ## Page JSON shape
9
+
10
+ ```json
11
+ {
12
+ "layout": "theme",
13
+ "sections": {
14
+ "<section_key>": {
15
+ "type": "<section_filename_without_.liquid>",
16
+ "settings": { ... },
17
+ "blocks": { "<block_key>": { "type": "<block_type>", "settings": {} } },
18
+ "block_order": ["<block_key>", ...]
19
+ }
20
+ },
21
+ "order": ["<section_key_1>", "<section_key_2>", ...]
22
+ }
23
+ ```
24
+
25
+ - **section_key:** arbitrary key (e.g. `hero`, `product_details`). Must be unique in the page.
26
+ - **type:** must exactly match a section file name under `sections/` (e.g. `product-details` for `product-details.liquid`).
27
+ - **blocks:** only present if the section schema declares a `"blocks"` array. Each key in `blocks` is a block instance.
28
+ - **block_order:** array of block keys; every key must exist in `blocks`. Order determines render order.
29
+ - **order:** array of section keys; every key must exist in `sections`. Order determines section order on the page.
30
+
31
+ ---
32
+
33
+ ## Block types — local vs theme
34
+
35
+ | Model | Page JSON `type` | Schema source |
36
+ |-------|------------------|---------------|
37
+ | **Local block** | bare name, e.g. `"badge"` | Section `{% schema %}` `blocks` entry with inline `settings` |
38
+ | **Theme block** | `zc_theme__<name>`, e.g. `"zc_theme__text"` | `blocks/<name>.liquid` `{% schema %}` |
39
+
40
+ A section opts into theme blocks in its schema:
41
+
42
+ ```jsonc
43
+ "blocks": [
44
+ { "type": "@theme" }, // all theme blocks
45
+ { "type": "zc_theme__text", "name": "t:blocks.text.name" }, // specific only
46
+ { "type": "badge", "name": "t:sections....", "settings": [ ... ] } // local
47
+ ]
48
+ ```
49
+
50
+ Only block types declared in the section schema are allowed in page JSON (enforced at render).
51
+
52
+ Nested theme blocks: a parent block instance in page JSON may have its own `"blocks"` and `"block_order"` for children (up to nesting depth 5).
53
+
54
+ ---
55
+
56
+ ## Settings value formats (inline in page JSON)
57
+
58
+ | Schema type | Page JSON value format |
59
+ |---------------|------------------------|
60
+ | text | string |
61
+ | url | `{ "display_name": "t:...", "handle": "/path" }` |
62
+ | image_picker | `{ "url": "file.webp", "enable_customisation": true }` |
63
+ | media_picker | `{ "url": "video.mp4", "is_video": true }` |
64
+ | select | `{ "display_name": "t:...", "value": "option-value" }` |
65
+ | menu | `{ "display_name": "t:...", "handle": "menu-handle" }` |
66
+ | checkbox | true / false |
67
+ | range/number | number |
68
+ | color | hex string e.g. "#000000" |
69
+
70
+ All user-facing strings use `t:` keys. Setting IDs in page JSON must match the schema for that level:
71
+ - Section settings → section `{% schema %}`
72
+ - Local block settings → section `{% schema %}` block entry
73
+ - Theme block settings → `blocks/<name>.liquid` `{% schema %}`
74
+
75
+ ---
76
+
77
+ ## Validation (for /validate-page)
78
+
79
+ - For each entry in `order`, the key exists in `sections`.
80
+ - For each `sections.<key>.type`, the file `sections/<type>.liquid` exists.
81
+ - For each section that has `blocks` and `block_order`, every entry in `block_order` exists in `blocks`.
82
+ - For each `blocks.<key>.type`:
83
+ - **Local:** type is declared in the section schema `blocks` array (bare name with inline `settings`).
84
+ - **Theme (`zc_theme__<name>`):** `blocks/<name>.liquid` exists AND the section schema lists `@theme` or that specific `zc_theme__<name>` entry.
85
+ - Recursively validate nested `blocks` / `block_order` on theme block instances against each parent block file's schema.
86
+
87
+ Reference this skill when assembling or validating page JSON.
@@ -0,0 +1,35 @@
1
+ # SKILL: QA Accessibility
2
+ # Usage in chat: @qa-accessibility
3
+
4
+ Checklist for auditing section accessibility when running `/qa-section` or reviewing a section manually.
5
+
6
+ ---
7
+
8
+ ## Images
9
+ - Every `<img>` has a non-empty `alt`. Use meaningful description (e.g. product name, CTA context); decorative images may use `alt=""`.
10
+ - Avoid images of text for critical content; if used, `alt` must convey the same information.
11
+
12
+ ## Headings
13
+ - Logical order: do not skip levels (e.g. h1 → h3). Use h1 once per section/page for main title.
14
+ - Headings describe the content that follows.
15
+
16
+ ## Forms and controls
17
+ - Every form control has an associated label: use `<label for="id">` or `aria-label` / `aria-labelledby`.
18
+ - Groups of controls (e.g. variant options, sort options): use `<fieldset>` + `<legend>` or `role="group"` with `aria-labelledby` pointing to a visible label element (e.g. `<div id="...">`).
19
+ - Required fields indicated (e.g. `aria-required="true"` or visible "required" text).
20
+
21
+ ## Focus and keyboard
22
+ - No `outline: none` (or similar) without a visible focus style (e.g. `outline: 2px solid var(--color-primary)` or `ring-2`).
23
+ - Interactive elements (links, buttons, custom controls) are focusable and have a visible focus indicator.
24
+ - Focus order follows visual order where possible.
25
+
26
+ ## Buttons and links
27
+ - Icon-only buttons/links have a descriptive `aria-label` (e.g. "Add to cart", "Close menu", "Previous slide").
28
+ - Links that open in new tab: consider `target="_blank"` + `rel="noopener"` and optionally announce in `aria-label` for screen readers.
29
+
30
+ ## Landmarks
31
+ - Section has a sensible structure; if it’s a main content region, consider `role="region"` and `aria-labelledby` for the section heading where it improves navigation.
32
+
33
+ ---
34
+
35
+ Use this skill when running the ACCESSIBILITY row of `/qa-section` or when asked to review a section for a11y.
@@ -0,0 +1,88 @@
1
+ # SKILL: Reference Lookup
2
+ # Save this as a Cursor Notepad named: reference-lookup
3
+ # Usage in chat: @reference-lookup
4
+
5
+ How to find and use existing theme sections as references when building new sections.
6
+
7
+ ---
8
+
9
+ ## Step 1 — Find the Reference
10
+ Look for an equivalent section within the current theme:
11
+ ```
12
+ sections/ ← look for existing sections with similar purpose
13
+ snippets/ ← look for reusable snippets
14
+ ```
15
+
16
+ Match by purpose, not filename. Examples:
17
+ | Building | Look for reference named |
18
+ |----------|------------------------|
19
+ | hero-banner | banner, hero, slider, masthead |
20
+ | category-grid | category, collection-grid, product-listing |
21
+ | featured-products | featured, products, product-grid |
22
+ | testimonials | testimonials, reviews, quotes |
23
+ | footer | footer |
24
+ | header | header |
25
+
26
+ ---
27
+
28
+ ## Step 2 — What to Extract
29
+ Open the reference file and extract ONLY these parts:
30
+
31
+ ### Keep exactly as-is
32
+ - Schema field IDs (e.g. `heading`, `cta_url`, `bg_image`)
33
+ - Schema field types
34
+ - `{% liquid %}` assign variable names
35
+ - Loop variable names (e.g. `{% for product in products %}`)
36
+ - `{% render %}` snippet calls (these are shared infrastructure)
37
+ - JS web component tag names (e.g. `<product-card>`)
38
+ - Conditional logic patterns
39
+
40
+ ### Adapt (keep structure, update values)
41
+ - Schema labels → update `t:` key path to new section name
42
+ - Schema defaults → update `t:` key path to new section name
43
+ - CSS class names → replace with new Figma-based Tailwind classes
44
+ - HTML structure → replace with new Figma layout
45
+
46
+ ### Discard
47
+ - Inline hardcoded colors from old theme
48
+ - Old theme's specific layout classes
49
+ - Deprecated workarounds or comments marked as fixes
50
+
51
+ ---
52
+
53
+ ## Step 3 — When No Reference Exists
54
+ If no matching section exists in this theme:
55
+ 1. Look for the closest partial match (e.g. use a card section as base for a different card layout)
56
+ 2. Build schema from scratch using schema.mdc rules
57
+ 3. Mark in your build notes: "NEW — no reference, built from schema.mdc"
58
+
59
+ ---
60
+
61
+ ## Quick Reference: Common Section Patterns
62
+
63
+ ### Settings every section should have
64
+ ```jsonc
65
+ { "type": "text", "id": "heading" }
66
+ { "type": "checkbox", "id": "show_section", "default": true }
67
+ { "type": "range", "id": "padding_top" }
68
+ { "type": "range", "id": "padding_bottom" }
69
+ ```
70
+
71
+ ### Settings for sections with images
72
+ ```jsonc
73
+ { "type": "image_picker", "id": "section_image",
74
+ "default": { "url": "placeholder.webp", "enable_customisation": true } }
75
+ ```
76
+
77
+ ### Settings for sections with CTAs
78
+ ```jsonc
79
+ { "type": "text", "id": "cta_text" }
80
+ { "type": "url", "id": "cta_url",
81
+ "default": { "display_name": "t:...", "handle": "/" } }
82
+ ```
83
+
84
+ ### Settings for sections with menus
85
+ ```jsonc
86
+ { "type": "menu", "id": "section_menu",
87
+ "default": { "display_name": "t:...", "handle": "" } }
88
+ ```
@@ -0,0 +1,173 @@
1
+ # SKILL: Section Anatomy
2
+ # Save this as a Cursor Notepad named: section-anatomy
3
+ # Usage in chat: @section-anatomy
4
+
5
+ Every section file must follow this exact anatomy. Use this as the structural checklist.
6
+
7
+ ---
8
+
9
+ ## Complete Section File Structure (top to bottom)
10
+
11
+ ```liquid
12
+ {{-- 1. SCRIPT TAGS (if JS component needed) --}}
13
+ <script src="{{ 'component-name.js' | asset_url }}" defer></script>
14
+
15
+ {{-- 2. STYLE BLOCK (dynamic CSS scoped to this section) --}}
16
+ {% style %}
17
+ #section-{{ section.id }} {
18
+ padding-top: {{ section.settings.padding_top }}px;
19
+ padding-bottom: {{ section.settings.padding_bottom }}px;
20
+ }
21
+ {% endstyle %}
22
+
23
+ {{-- 3. LIQUID ASSIGNS (all settings extracted at top) --}}
24
+ {% liquid
25
+ assign heading = section.settings.heading
26
+ assign sub_heading = section.settings.sub_heading
27
+ assign cta_text = section.settings.cta_text
28
+ assign cta_url = section.settings.cta_url
29
+ assign bg_image = section.settings.bg_image
30
+ assign show_section = section.settings.show_section
31
+ %}
32
+
33
+ {{-- 4. CONDITIONAL VISIBILITY --}}
34
+ {% if show_section %}
35
+
36
+ {{-- 5. SECTION WRAPPER --}}
37
+ <section id="section-{{ section.id }}" class="section-name w-full">
38
+ <div class="max-w-container-theme mx-auto" style="padding-left: var(--section-padding-x, 16px); padding-right: var(--section-padding-x, 16px);">
39
+
40
+ {{-- 6. SECTION CONTENT --}}
41
+ {% if heading != blank %}
42
+ <h2 class="text-4xl font-bold" style="color: var(--color-heading);">{{ heading | escape }}</h2>
43
+ {% endif %}
44
+
45
+ {{-- 7. LOOPS WITH EMPTY STATE --}}
46
+ {% if items.size > 0 %}
47
+ {% for item in items %}
48
+ {{-- item markup --}}
49
+ {% endfor %}
50
+ {% else %}
51
+ <p class="text-center" style="color: var(--color-heading);">No items found.</p>
52
+ {% endif %}
53
+
54
+ </div>
55
+ </section>
56
+
57
+ {% endif %}
58
+
59
+ {{-- 8. SCHEMA (always at the very bottom) --}}
60
+ {% schema %}
61
+ {
62
+ "name": "t:sections.<name>.name",
63
+ "tag": "section",
64
+ "class": "section",
65
+ "settings": [
66
+ {
67
+ "type": "text",
68
+ "id": "heading",
69
+ "label": "t:sections.<name>.settings.heading.label",
70
+ "default": "t:sections.<name>.settings.heading.default"
71
+ },
72
+ {
73
+ "type": "checkbox",
74
+ "id": "show_section",
75
+ "label": "t:sections.<name>.settings.show_section.label",
76
+ "default": true
77
+ },
78
+ {
79
+ "type": "range",
80
+ "id": "padding_top",
81
+ "min": 0, "max": 100, "step": 4, "unit": "px", "default": 40,
82
+ "label": "t:sections.<name>.settings.padding_top.label"
83
+ },
84
+ {
85
+ "type": "range",
86
+ "id": "padding_bottom",
87
+ "min": 0, "max": 100, "step": 4, "unit": "px", "default": 40,
88
+ "label": "t:sections.<name>.settings.padding_bottom.label"
89
+ }
90
+ ],
91
+ "blocks": [],
92
+ "presets": [
93
+ { "name": "t:sections.<name>.presets.default.name" }
94
+ ]
95
+ }
96
+ {% endschema %}
97
+ ```
98
+
99
+ ---
100
+
101
+ ## Rules
102
+ - Script tags → TOP of file
103
+ - Style block → after scripts, before assigns
104
+ - All assigns → in one `{% liquid %}` block at top
105
+ - Conditional visibility → wrap entire section if needed
106
+ - Schema → ALWAYS last, never in the middle
107
+ - Padding settings → ALWAYS included in every section
108
+ - Every loop → MUST have empty state
109
+ - Every heading/text → check `!= blank` before rendering
110
+ - **Heading fields → `text` only** (render with `| escape`); **body/description → `richtext`** (render with `| raw`). Never use `richtext` for heading blocks.
111
+
112
+ ---
113
+
114
+ ## Theme block file anatomy (`blocks/<name>.liquid`)
115
+
116
+ Reusable blocks live in `blocks/`, not `sections/`. Each file has its own schema and optional snippet render.
117
+
118
+ ```liquid
119
+ {% render 'theme-text-block', block: block %}
120
+
121
+ {% schema %}
122
+ {
123
+ "name": "t:blocks.text.name",
124
+ "settings": [ ... ],
125
+ "blocks": [
126
+ { "type": "zc_theme__button" }
127
+ ],
128
+ "presets": [
129
+ { "name": "t:blocks.text.presets.default.name", "settings": { ... } }
130
+ ]
131
+ }
132
+ {% endschema %}
133
+ ```
134
+
135
+ - i18n: `t:blocks.<name>.*` (not `t:sections.*.blocks.*`)
136
+ - `"presets"` required — without it the block won't appear in the editor picker
137
+ - Render children: `{% render_blocks %}` inside the block file (nesting up to depth 5)
138
+ - Scope dynamic CSS to `#theme-block-<name>-{{ block.id }}` (or a snippet equivalent)
139
+ - Access settings: `block.settings.<id>`; output `{{ block.zcommerce_attributes }}` on the wrapper for editor chrome
140
+
141
+ ---
142
+
143
+ ## Section patterns for theme blocks
144
+
145
+ **Pure theme-block section** — schema lists `@theme` or specific `zc_theme__*` types; body uses `{% render_blocks %}`:
146
+
147
+ ```liquid
148
+ <div class="heading-area">
149
+ {% render_blocks %}
150
+ </div>
151
+ ```
152
+
153
+ **Mixed section** — local blocks inline, theme blocks delegated:
154
+
155
+ ```liquid
156
+ {% for block in section.blocks %}
157
+ {% case block.type %}
158
+ {% when 'badge' %}
159
+ {%- comment -%} local block markup {%- endcomment -%}
160
+ {% else %}
161
+ {% render block %}
162
+ {% endcase %}
163
+ {% endfor %}
164
+ ```
165
+
166
+ Section schema for mixed:
167
+
168
+ ```jsonc
169
+ "blocks": [
170
+ { "type": "zc_theme__text", "name": "t:blocks.text.name" },
171
+ { "type": "badge", "name": "t:sections.my_section.blocks.badge.name", "settings": [ ... ] }
172
+ ]
173
+ ```