@o2vend/theme-cli 1.0.37 → 1.0.38

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 (89) hide show
  1. package/lib/lib/dev-server.js +309 -40
  2. package/lib/lib/liquid-engine.js +3 -1
  3. package/lib/lib/mock-data.js +36 -124
  4. package/lib/lib/widget-service.js +12 -4
  5. package/package.json +1 -1
  6. package/test-theme/assets/async-sections.js +32 -24
  7. package/test-theme/assets/cart-drawer.js +20 -22
  8. package/test-theme/assets/cart-manager.js +1 -15
  9. package/test-theme/assets/checkout-price-handler.js +12 -11
  10. package/test-theme/assets/checkout.css +1415 -0
  11. package/test-theme/assets/checkout.js +3174 -0
  12. package/test-theme/assets/components.css +178 -29
  13. package/test-theme/assets/delivery-zone.js +1 -1
  14. package/test-theme/assets/product-detail.css +1050 -0
  15. package/test-theme/assets/product-detail.js +2940 -0
  16. package/test-theme/assets/theme.css +95 -120
  17. package/test-theme/assets/theme.js +781 -186
  18. package/test-theme/layout/theme.liquid +91 -17
  19. package/test-theme/sections/content.liquid +64 -57
  20. package/test-theme/sections/footer-fallback.liquid +57 -7
  21. package/test-theme/sections/footer.liquid +63 -12
  22. package/test-theme/sections/header-fallback.liquid +41 -41
  23. package/test-theme/sections/header.liquid +41 -51
  24. package/test-theme/sections/hero-fallback.liquid +1 -1
  25. package/test-theme/sections/hero.liquid +159 -136
  26. package/test-theme/snippets/account-sidebar.liquid +121 -29
  27. package/test-theme/snippets/add-to-cart-modal.liquid +258 -206
  28. package/test-theme/snippets/breadcrumbs.liquid +98 -11
  29. package/test-theme/snippets/cart-drawer.liquid +93 -0
  30. package/test-theme/snippets/delivery-zone-city-selector.liquid +101 -15
  31. package/test-theme/snippets/delivery-zone-modal.liquid +529 -84
  32. package/test-theme/snippets/delivery-zone-search.liquid +104 -18
  33. package/test-theme/snippets/login-modal.liquid +269 -82
  34. package/test-theme/snippets/mega-menu.liquid +130 -43
  35. package/test-theme/snippets/news-thumbnail.liquid +120 -28
  36. package/test-theme/snippets/pagination.liquid +1 -1
  37. package/test-theme/snippets/price.liquid +100 -9
  38. package/test-theme/snippets/product-card-related.liquid +22 -4
  39. package/test-theme/snippets/product-card-simple.liquid +521 -25
  40. package/test-theme/snippets/product-card.liquid +145 -232
  41. package/test-theme/snippets/rating.liquid +100 -9
  42. package/test-theme/snippets/skeleton-collection-grid.liquid +94 -8
  43. package/test-theme/snippets/skeleton-product-card.liquid +102 -16
  44. package/test-theme/snippets/skeleton-product-grid.liquid +87 -1
  45. package/test-theme/snippets/social-sharing.liquid +133 -32
  46. package/test-theme/templates/account/dashboard.liquid +30 -0
  47. package/test-theme/templates/account/loyalty-redemption.liquid +29 -28
  48. package/test-theme/templates/account/loyalty.liquid +45 -43
  49. package/test-theme/templates/account/order-detail.liquid +15 -8
  50. package/test-theme/templates/account/orders.liquid +189 -35
  51. package/test-theme/templates/account/profile.liquid +509 -114
  52. package/test-theme/templates/account/register.liquid +18 -8
  53. package/test-theme/templates/account/return-orders.liquid +31 -30
  54. package/test-theme/templates/account/store-credit.liquid +27 -26
  55. package/test-theme/templates/account/subscriptions.liquid +22 -5
  56. package/test-theme/templates/account/wishlist.liquid +88 -19
  57. package/test-theme/templates/address-book.liquid +166 -69
  58. package/test-theme/templates/categories.liquid +90 -30
  59. package/test-theme/templates/checkout.liquid +137 -3834
  60. package/test-theme/templates/error.liquid +23 -21
  61. package/test-theme/templates/index.liquid +29 -0
  62. package/test-theme/templates/login.liquid +33 -6
  63. package/test-theme/templates/order-confirmation.liquid +67 -9
  64. package/test-theme/templates/page.liquid +418 -206
  65. package/test-theme/templates/product-detail.liquid +124 -3878
  66. package/test-theme/templates/products.liquid +155 -30
  67. package/test-theme/templates/search.liquid +739 -225
  68. package/test-theme/widgets/brand-carousel.liquid +102 -82
  69. package/test-theme/widgets/brand.liquid +78 -50
  70. package/test-theme/widgets/carousel.liquid +253 -121
  71. package/test-theme/widgets/category-list-carousel.liquid +32 -8
  72. package/test-theme/widgets/category-list.liquid +21 -6
  73. package/test-theme/widgets/category.liquid +104 -37
  74. package/test-theme/widgets/discount-time.liquid +326 -119
  75. package/test-theme/widgets/footer-menu.liquid +115 -23
  76. package/test-theme/widgets/footer.liquid +118 -5
  77. package/test-theme/widgets/gallery.liquid +29 -5
  78. package/test-theme/widgets/header-menu.liquid +25 -13
  79. package/test-theme/widgets/header.liquid +64 -26
  80. package/test-theme/widgets/html.liquid +29 -6
  81. package/test-theme/widgets/news.liquid +6 -0
  82. package/test-theme/widgets/product-canvas.liquid +20 -12
  83. package/test-theme/widgets/product-carousel.liquid +118 -56
  84. package/test-theme/widgets/shared/product-grid.liquid +12 -0
  85. package/test-theme/widgets/single-product.liquid +688 -250
  86. package/test-theme/widgets/spacebar-carousel.liquid +39 -10
  87. package/test-theme/widgets/spacebar.liquid +77 -6
  88. package/test-theme/widgets/splash.liquid +40 -30
  89. package/test-theme/widgets/testimonial-carousel.liquid +111 -67
@@ -34,6 +34,98 @@
34
34
  </nav>
35
35
 
36
36
  <style>
37
+ :root {
38
+ --color-primary: {{ settings.color_primary | default: '#000000' }};
39
+ --color-primary-hover: {{ settings.color_primary_dark | default: '#333333' }};
40
+ --color-primary-light: {{ settings.color_primary_light | default: '#666666' }};
41
+ --color-success: {{ settings.color_success | default: '#22c55e' }};
42
+ --color-success-light: {{ settings.color_success | default: '#22c55e' }};
43
+ --color-success-dark: {{ settings.color_success | default: '#22c55e' }};
44
+ --color-danger: {{ settings.color_error | default: '#ef4444' }};
45
+ --color-danger-light: {{ settings.color_error | default: '#ef4444' }};
46
+ --color-danger-dark: {{ settings.color_error | default: '#ef4444' }};
47
+ --color-text: {{ settings.color_text | default: '#000000' }};
48
+ --color-text-light: {{ settings.color_text_light | default: '#999999' }};
49
+ --color-text-muted: {{ settings.color_text_muted | default: '#666666' }};
50
+ --color-background: {{ settings.color_background | default: '#ffffff' }};
51
+ --color-card-bg: {{ settings.color_surface | default: '#f5f5f5' }};
52
+ --color-border: {{ settings.color_border | default: '#cccccc' }};
53
+ --color-border-light: {{ settings.color_surface | default: '#f5f5f5' }};
54
+ --color-white: #ffffff;
55
+ --color-black: {{ settings.color_primary_dark | default: '#333333' }};
56
+ --color-gray-25: {{ settings.color_background | default: '#ffffff' }};
57
+ --color-gray-50: {{ settings.color_surface | default: '#f5f5f5' }};
58
+ --color-gray-100: {{ settings.color_surface | default: '#f5f5f5' }};
59
+ --color-gray-200: {{ settings.color_border | default: '#cccccc' }};
60
+ --color-gray-300: {{ settings.color_border | default: '#cccccc' }};
61
+ --color-gray-400: {{ settings.color_text_muted | default: '#666666' }};
62
+ --color-gray-500: {{ settings.color_text_muted | default: '#666666' }};
63
+ --color-gray-600: {{ settings.color_text_muted | default: '#666666' }};
64
+ --color-gray-700: {{ settings.color_text | default: '#000000' }};
65
+ --color-gray-800: {{ settings.color_text | default: '#000000' }};
66
+ --color-gray-900: {{ settings.color_text | default: '#000000' }};
67
+ --shadow-sm: var(--shadow-sm);
68
+ --shadow-md: var(--shadow-md);
69
+ --shadow-lg: var(--shadow-lg);
70
+ /* Shadow variables - mapped from settings */
71
+ --shadow-opacity: {{ settings.shadow_opacity | default: 0.1 }};
72
+ --shadow-blur: {{ settings.shadow_blur | default: 8 }}px;
73
+ --shadow-spread: {{ settings.shadow_spread | default: 0 }}px;
74
+
75
+ /* Border radius - mapped from settings */
76
+ --radius-sm: {{ settings.border_radius_small | default: 6 }}px;
77
+ --radius-md: {{ settings.border_radius_medium | default: 10 }}px;
78
+ --radius-lg: {{ settings.border_radius_large | default: 16 }}px;
79
+ --radius-xl: 24px;
80
+ --radius-2xl: 32px;
81
+ --radius-full: 9999px;
82
+
83
+ /* Spacing - mapped from settings */
84
+ --spacing-xs: {{ settings.spacing_xsmall | default: 4 }}px;
85
+ --spacing-sm: {{ settings.spacing_small | default: 8 }}px;
86
+ --spacing-md: {{ settings.spacing_element | default: 16 }}px;
87
+ --spacing-lg: {{ settings.spacing_component | default: 24 }}px;
88
+ --spacing-xl: {{ settings.spacing_large | default: 32 }}px;
89
+
90
+ /* Typography - mapped from settings */
91
+ --font-primary: {{ settings.font_primary | default: '' }}, -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Helvetica Neue', Arial, sans-serif;
92
+ --font-heading: {{ settings.font_heading | default: '' }}, -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Helvetica Neue', Arial, sans-serif;
93
+ --font-display: {{ settings.font_display | default: '' }}, 'Georgia', 'Times New Roman', serif;
94
+ --font-body: {{ settings.font_body | default: '' }}, -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Helvetica Neue', Arial, sans-serif;
95
+ --font-weight-bold: {{ settings.font_weight_bold | default: 700 }};
96
+ --font-weight-medium: {{ settings.font_weight_medium | default: 500 }};
97
+ --line-height-heading: {{ settings.line_height_heading | default: 1.2 }};
98
+
99
+ /* Text sizes - based on font_size_base from settings */
100
+ --text-xs: 12px;
101
+ --text-sm: {{ settings.font_size_base | default: 14 }}px;
102
+ --text-base: {{ settings.font_size_base | default: 14 }}px;
103
+ --text-lg: 16px;
104
+ --text-xl: 18px;
105
+ --text-2xl: 21px;
106
+
107
+ /* Transitions - mapped from settings */
108
+ --transition-fast: 133ms cubic-bezier(0, 0, 0.2, 1);
109
+ --transition: {{ settings.button_transition_speed | default: 200 }}ms cubic-bezier(0, 0, 0.2, 1);
110
+ --transition-slow: 300ms cubic-bezier(0, 0, 0.2, 1);
111
+ --duration-150: 150ms;
112
+ --duration-300: 300ms;
113
+ --ease-out: cubic-bezier(0, 0, 0.2, 1);
114
+ --ease-in: cubic-bezier(0.4, 0, 1, 1);
115
+ --ease-in-out: cubic-bezier(0.4, 0, 0.2, 1);
116
+
117
+ /* Z-index values */
118
+ --z-10: 10;
119
+ --z-modal: 1050;
120
+ --z-dropdown: 1000;
121
+
122
+ /* Line heights - mapped from settings */
123
+ --leading-none: 1;
124
+ --leading-normal: {{ settings.line_height_base | default: 1.6 }};
125
+ --leading-snug: 1.375;
126
+ --tracking-wider: var(--tracking-wider);
127
+ }
128
+
37
129
  .widget-footer-menu {
38
130
  padding: 0;
39
131
  margin: 0 auto;
@@ -42,24 +134,24 @@
42
134
 
43
135
  .widget-footer-menu__loading,
44
136
  .widget-footer-menu__error {
45
- padding: 1rem;
137
+ padding: var(--space-4);
46
138
  text-align: center;
47
- font-size: 0.875rem;
48
- color: #9ca3af;
139
+ font-size: var(--text-sm);
140
+ color: var(--color-gray-400);
49
141
  }
50
142
 
51
143
  .widget-footer-menu__error {
52
- color: #ef4444;
144
+ color: var(--color-error);
53
145
  }
54
146
 
55
147
  .widget-footer-menu__columns {
56
148
  display: grid;
57
149
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
58
- gap: 2.5rem;
150
+ gap: var(--space-10);
59
151
  list-style: none;
60
152
  margin: 0;
61
153
  padding: 0;
62
- min-height: 30px;
154
+ min-height: var(--space-8);
63
155
  }
64
156
 
65
157
  .widget-footer-menu__column {
@@ -73,10 +165,10 @@
73
165
 
74
166
  .widget-footer-menu__title {
75
167
  margin: 0;
76
- font-size: 0.875rem;
168
+ font-size: var(--text-sm);
77
169
  text-transform: uppercase;
78
- letter-spacing: 0.05em;
79
- font-weight: 600;
170
+ letter-spacing: var(--tracking-wider);
171
+ font-weight: var(--font-weight-bold);
80
172
  color: {{ widget_settings.title_color | default: '#ffffff' }};
81
173
  display: none;
82
174
  }
@@ -87,19 +179,19 @@
87
179
  padding: 0;
88
180
  display: flex;
89
181
  flex-direction: column;
90
- gap: 0.75rem;
91
- margin-top: 1rem;
182
+ gap: var(--space-3);
183
+ margin-top: var(--space-4);
92
184
  }
93
185
 
94
186
  .widget-footer-menu__child-list {
95
187
  list-style: none;
96
188
  margin: 0;
97
189
  padding: 0;
98
- padding-left: 1rem;
99
- margin-top: 0.5rem;
190
+ padding-left: var(--space-4);
191
+ margin-top: var(--space-2);
100
192
  display: flex;
101
193
  flex-direction: column;
102
- gap: 0.5rem;
194
+ gap: var(--space-2);
103
195
  }
104
196
 
105
197
  .widget-footer-menu__item--has-children {
@@ -115,9 +207,9 @@
115
207
  .widget-footer-menu__link {
116
208
  color: {{ widget_settings.link_color | default: '#9ca3af' }};
117
209
  text-decoration: none;
118
- font-size: 0.9375rem;
119
- font-weight: 400;
120
- transition: color 0.2s ease;
210
+ font-size: var(--text-base);
211
+ font-weight: var(--font-weight-normal);
212
+ transition: color var(--transition);
121
213
  display: inline-block;
122
214
  padding: 0;
123
215
  white-space: nowrap;
@@ -129,15 +221,15 @@
129
221
 
130
222
  @media (max-width: 768px) {
131
223
  .widget-footer-menu__columns {
132
- gap: 2rem;
224
+ gap: var(--space-8);
133
225
  }
134
226
 
135
227
  .widget-footer-menu__list {
136
- gap: 2rem;
228
+ gap: var(--space-8);
137
229
  }
138
230
 
139
231
  .widget-footer-menu__link {
140
- font-size: 0.875rem;
232
+ font-size: var(--text-sm);
141
233
  }
142
234
  }
143
235
 
@@ -145,20 +237,20 @@
145
237
  .widget-footer-menu__columns {
146
238
  flex-direction: column;
147
239
  align-items: center;
148
- gap: 1.5rem;
240
+ gap: var(--space-6);
149
241
  }
150
242
 
151
243
  .widget-footer-menu__list {
152
244
  flex-direction: column;
153
245
  align-items: center;
154
- gap: 1rem;
246
+ gap: var(--space-4);
155
247
  text-align: center;
156
248
  }
157
249
  }
158
250
  </style>
159
251
 
160
252
  <script>
161
- (function() {
253
+ (() => {
162
254
  'use strict';
163
255
 
164
256
  // Configuration
@@ -17,15 +17,61 @@
17
17
  endif
18
18
 
19
19
  assign social_links = widget_settings.social_links | default: widget_content.social_links | default: widget_data.social_links
20
+ assign heading = widget_settings.title | default: widget_content.title | default: widget.Title | default: widget.title
21
+ assign subtitle = widget_settings.subtitle | default: widget_content.subtitle | default: widget.Subtitle | default: widget.subtitle
22
+ assign show_widget_title_raw = widget_settings.showWidgetTitle | default: widget_settings.ShowWidgetTitle | default: widget_content.showWidgetTitle | default: widget_content.ShowWidgetTitle | default: true
23
+ if show_widget_title_raw == null or show_widget_title_raw == blank or show_widget_title_raw == 'null'
24
+ assign show_widget_title = true
25
+ else
26
+ if show_widget_title_raw == 'Yes' or show_widget_title_raw == true or show_widget_title_raw == 'true' or show_widget_title_raw == 1 or show_widget_title_raw == '1'
27
+ assign show_widget_title = true
28
+ else
29
+ assign show_widget_title = false
30
+ endif
31
+ endif
32
+ assign widget_title_alignment_raw = widget_settings.widgetTitleAlignment | default: widget_settings.WidgetTitleAlignment | default: widget_content.widgetTitleAlignment | default: widget_content.WidgetTitleAlignment | default: 'left'
33
+ assign widget_title_alignment = widget_title_alignment_raw | downcase
34
+ if widget_title_alignment != 'left' and widget_title_alignment != 'right' and widget_title_alignment != 'center'
35
+ assign widget_title_alignment = 'left'
36
+ endif
37
+
38
+ comment
39
+ HTML content for footer widget:
40
+ - Comes from widget.htmlData / HtmlData on the widget object (saved via editor)
41
+ - Fallbacks to HtmlContent/htmlContent if present
42
+ endcomment
43
+ assign footer_html_raw = widget.htmlData | default: widget.HtmlData | default: widget.htmlContent | default: widget.HtmlContent
44
+ assign footer_html = blank
45
+ if footer_html_raw and footer_html_raw != blank and footer_html_raw != 'null'
46
+ assign footer_html = footer_html_raw
47
+ endif
20
48
  %}
21
49
 
22
50
  <footer class="widget widget-footer" data-widget-id="{{ widget.id }}">
51
+ {% if show_widget_title %}
52
+ {% if heading or subtitle %}
53
+ <header class="widget-header" style="text-align: {{ widget_title_alignment }};">
54
+ {% if heading and heading != blank %}
55
+ <h2 class="widget-title">{{ heading }}</h2>
56
+ {% endif %}
57
+ {% if subtitle and subtitle != blank %}
58
+ <p class="widget-subtitle">{{ subtitle }}</p>
59
+ {% endif %}
60
+ </header>
61
+ {% endif %}
62
+ {% endif %}
63
+
23
64
  <div class="widget-footer__inner">
24
65
  <div class="widget-footer__brand">
25
- <h3>{{ widget_settings.title | default: widget_content.title | default: shop.name }}</h3>
26
66
  <p>{{ widget_settings.description | default: widget_content.description | default: shop.description }}</p>
27
67
  </div>
28
68
 
69
+ {% if footer_html and footer_html != blank %}
70
+ <div class="widget-footer__html">
71
+ {{ footer_html }}
72
+ </div>
73
+ {% endif %}
74
+
29
75
  {% if columns and columns.size > 0 %}
30
76
  <div class="widget-footer__columns">
31
77
  {% for column in columns %}
@@ -66,7 +112,7 @@
66
112
  </div>
67
113
 
68
114
  <div class="widget-footer__bottom">
69
- <p>&copy; {{ 'now' | date: '%Y' }} {{ shop.name }}. {{ widget_settings.legal_text | default: 'All rights reserved.' }}</p>
115
+
70
116
  {% if widget_settings.legal_links %}
71
117
  <ul>
72
118
  {% for link in widget_settings.legal_links %}
@@ -77,18 +123,52 @@
77
123
  </div>
78
124
 
79
125
  <style>
126
+ :root {
127
+ --footer-border: var(--color-border);
128
+ --footer-spacing-component: var(--spacing-component);
129
+ --footer-spacing-element: var(--spacing-element);
130
+ --footer-spacing-small: var(--spacing-small);
131
+ --footer-container-padding: var(--container-padding);
132
+ --footer-text-sm: var(--text-sm);
133
+ --footer-radius-full: var(--radius-full);
134
+ }
135
+
80
136
  .widget-footer {
81
137
  background: {{ widget_settings.background_color | default: settings.color_background }};
82
138
  color: {{ widget_settings.text_color | default: settings.color_text }};
83
139
  padding: 3rem 1rem;
84
140
  border-top: 1px solid rgba(0,0,0,0.08);
85
141
  }
142
+ .widget-footer .widget-header {
143
+ max-width: {{ settings.container_width | default: 1200 }}px;
144
+ margin: 0 auto 1.25rem;
145
+ padding: 0;
146
+ }
147
+ .widget-footer .widget-title {
148
+ margin: 0 0 0.35rem 0;
149
+ font-size: 1.4rem;
150
+ font-weight: 500;
151
+ line-height: 1.3;
152
+ color: inherit;
153
+ }
154
+ .widget-footer .widget-subtitle {
155
+ margin: 0;
156
+ font-size: 0.95rem;
157
+ line-height: 1.5;
158
+ opacity: 0.85;
159
+ color: inherit;
160
+ }
86
161
  .widget-footer__inner {
87
- max-width: {{ settings.container_width }}px;
162
+ max-width: {{ settings.container_width | default: 1200 }}px;
88
163
  margin: 0 auto 2rem;
89
164
  display: grid;
90
165
  gap: 2rem;
91
166
  }
167
+ .widget-footer__html {
168
+ margin-top: var(--footer-spacing-element);
169
+ font-size: var(--footer-text-sm);
170
+ line-height: var(--leading-normal);
171
+ }
92
172
  .widget-footer__brand h3 {
93
173
  margin: 0 0 0.5rem;
94
174
  font-size: 1.5rem;
@@ -143,7 +223,7 @@
143
223
  max-height: 18px;
144
224
  }
145
225
  .widget-footer__bottom {
146
- max-width: {{ settings.container_width }}px;
226
+ max-width: {{ settings.container_width | default: 1200 }}px;
147
227
  margin: 0 auto;
148
228
  padding-top: 1.5rem;
149
229
  border-top: 1px solid rgba(255,255,255,0.08);
@@ -152,6 +232,29 @@
152
232
  gap: 0.75rem;
153
233
  font-size: 0.875rem;
154
234
  }
235
+ .widget-footer__bottom-left {
236
+ display: flex;
237
+ flex-direction: column;
238
+ gap: 0.5rem;
239
+ flex: 1;
240
+ min-width: 0;
241
+ }
242
+ .widget-footer__bottom .footer-powered {
243
+ margin: 0;
244
+ color: inherit;
245
+ font-size: 0.875rem;
246
+ line-height: 1.5;
247
+ display: block;
248
+ visibility: visible;
249
+ }
250
+ .widget-footer__bottom .footer-powered-link {
251
+ color: inherit;
252
+ text-decoration: underline;
253
+ transition: opacity 0.2s ease;
254
+ }
255
+ .widget-footer__bottom .footer-powered-link:hover {
256
+ opacity: 0.8;
257
+ }
155
258
  .widget-footer__bottom ul {
156
259
  list-style: none;
157
260
  margin: 0;
@@ -164,13 +267,23 @@
164
267
  color: inherit;
165
268
  text-decoration: none;
166
269
  }
270
+ @media (max-width: 767px) {
271
+ .widget-footer__bottom-left {
272
+ width: 100%;
273
+ }
274
+ .widget-footer__bottom .footer-powered {
275
+ display: block !important;
276
+ visibility: visible !important;
277
+ margin-top: 0.5rem;
278
+ }
279
+ }
167
280
  @media (min-width: 768px) {
168
281
  .widget-footer__inner {
169
282
  grid-template-columns: minmax(0, 1.2fr) minmax(0, 2fr);
170
283
  }
171
284
  .widget-footer__bottom {
172
285
  flex-direction: row;
173
- align-items: center;
286
+ align-items: flex-start;
174
287
  justify-content: space-between;
175
288
  }
176
289
  }
@@ -36,6 +36,10 @@
36
36
  assign show_container = widget_settings.showContainer
37
37
  assign gap = widget_settings.gap | default: 16
38
38
  %}
39
+ {% assign is_hero_priority_widget = false %}
40
+ {% if is_hero_first == true or is_hero_first == 'true' or is_hero_first == 1 or is_hero_first == '1' %}
41
+ {% assign is_hero_priority_widget = true %}
42
+ {% endif %}
39
43
 
40
44
  <section class="widget widget-gallery" data-widget-id="{{ widget.id }}"{% if background_color and background_color != blank and background_color != 'null' %} style="background-color: {{ background_color }};"{% endif %}>
41
45
  <div class="widget-gallery__inner{% if show_container == 'No' %} widget-gallery__inner--full{% endif %}">
@@ -67,7 +71,10 @@
67
71
  {% if item_link and item_link != blank and item_link != 'null' %}
68
72
  <a href="{{ item_link }}" class="widget-gallery__item widget-gallery__item--link">
69
73
  {% if image_url and image_url != blank and image_url != 'null' %}
70
- <img src="{{ image_src }}" alt="{{ image_alt }}" width="400" height="400" loading="lazy">
74
+ {% if forloop.first and is_hero_priority_widget %}
75
+ <link rel="preload" as="image" href="{{ image_src }}" fetchpriority="high">
76
+ {% endif %}
77
+ <img src="{{ image_src }}" alt="{{ image_alt }}" width="400" height="400" loading="{% if forloop.first %}eager{% else %}lazy{% endif %}" {% if forloop.first and is_hero_priority_widget %}fetchpriority="high"{% endif %}>
71
78
  {% if item_caption and item_caption != blank %}
72
79
  <div class="widget-gallery__caption">{{ item_caption }}</div>
73
80
  {% endif %}
@@ -76,7 +83,10 @@
76
83
  {% else %}
77
84
  <figure class="widget-gallery__item">
78
85
  {% if image_url and image_url != blank and image_url != 'null' %}
79
- <img src="{{ image_src }}" alt="{{ image_alt }}" width="400" height="400" loading="lazy">
86
+ {% if forloop.first and is_hero_priority_widget %}
87
+ <link rel="preload" as="image" href="{{ image_src }}" fetchpriority="high">
88
+ {% endif %}
89
+ <img src="{{ image_src }}" alt="{{ image_alt }}" width="400" height="400" loading="{% if forloop.first %}eager{% else %}lazy{% endif %}" {% if forloop.first and is_hero_priority_widget %}fetchpriority="high"{% endif %}>
80
90
  {% if item_caption and item_caption != blank %}
81
91
  <figcaption class="widget-gallery__caption">{{ item_caption }}</figcaption>
82
92
  {% endif %}
@@ -93,6 +103,22 @@
93
103
  </div>
94
104
 
95
105
  <style>
106
+ :root {
107
+ --gallery-white: var(--color-white);
108
+ --gallery-text: var(--color-text);
109
+ --gallery-text-muted: var(--color-text-muted);
110
+ --gallery-spacing-section: var(--spacing-section);
111
+ --gallery-spacing-large: var(--spacing-large);
112
+ --gallery-spacing-component: var(--spacing-component);
113
+ --gallery-spacing-element: var(--spacing-element);
114
+ --gallery-spacing-small: var(--spacing-small);
115
+ --gallery-spacing-xsmall: var(--spacing-xsmall);
116
+ --gallery-container-padding: var(--container-padding);
117
+ --gallery-transition: var(--transition);
118
+ --gallery-transition-fast: var(--transition-fast);
119
+ --gallery-text-sm: var(--text-sm);
120
+ }
121
+
96
122
  .widget-gallery {
97
123
  padding: 48px 0;
98
124
  position: relative;
@@ -157,14 +183,12 @@
157
183
  overflow: hidden;
158
184
  background: #f5f5f5;
159
185
  aspect-ratio: 1 / 1;
160
- box-shadow: 0 4px 12px rgba(15, 23, 42, 0.08);
161
- transition: transform 0.3s ease, box-shadow 0.3s ease;
186
+ transition: transform 0.3s ease;
162
187
  border-radius: var(--border-radius-medium);
163
188
  }
164
189
 
165
190
  .widget-gallery__item:hover {
166
191
  transform: translateY(-4px);
167
- box-shadow: 0 8px 24px rgba(15, 23, 42, 0.12);
168
192
  }
169
193
 
170
194
  .widget-gallery__item--link {
@@ -52,6 +52,20 @@
52
52
  </div>
53
53
 
54
54
  <style>
55
+ :root {
56
+ --header-menu-text: var(--color-text);
57
+ --header-menu-text-muted: var(--color-text-muted);
58
+ --header-menu-border: var(--color-border);
59
+ --header-menu-white: var(--color-white);
60
+ --header-menu-spacing-element: var(--spacing-element);
61
+ --header-menu-spacing-small: var(--spacing-small);
62
+ --header-menu-spacing-xsmall: var(--spacing-xsmall);
63
+ --header-menu-transition-fast: var(--transition-fast);
64
+ --header-menu-text-sm: var(--text-sm);
65
+ --header-menu-text-base: var(--text-base);
66
+ --header-menu-text-lg: var(--text-lg);
67
+ }
68
+
55
69
  /* Menu Navigation Styles */
56
70
  .header-menu-nav {
57
71
  flex: 1 1 auto;
@@ -138,7 +152,7 @@
138
152
 
139
153
  .header-menu-nav__submenu {
140
154
  position: absolute;
141
- top: calc(100% + var(--space-2, 0.5rem));
155
+ top: 100%;
142
156
  left: 0;
143
157
  display: none;
144
158
  flex-direction: column;
@@ -146,7 +160,6 @@
146
160
  background: var(--dropdown-bg, #fff);
147
161
  padding: var(--space-2, 0.5rem) 0;
148
162
  border-radius: var(--border-radius-medium, 8px);
149
- box-shadow: 0 var(--space-4, 1rem) var(--space-6, 1.5rem) rgba(0, 0, 0, 0.1);
150
163
  min-width: var(--space-50, 12.5rem);
151
164
  list-style: none;
152
165
  margin: 0;
@@ -219,7 +232,6 @@
219
232
  -webkit-overflow-scrolling: touch;
220
233
  transform: translateX(-100%);
221
234
  transition: transform var(--transition-slow, var(--duration-300, 300ms) var(--ease-out, ease));
222
- box-shadow: var(--space-0-5, 0.125rem) 0 var(--space-2, 0.5rem) rgba(0, 0, 0, 0.15);
223
235
  display: flex !important;
224
236
  flex-direction: column !important;
225
237
  margin: 0 !important;
@@ -352,7 +364,7 @@
352
364
  </style>
353
365
 
354
366
  <script>
355
- document.addEventListener('DOMContentLoaded', function() {
367
+ document.addEventListener('DOMContentLoaded', () => {
356
368
  const menuNav = document.querySelector('[data-widget-id="{{ widget.id }}"][data-header-menu-nav]');
357
369
  if (!menuNav) return;
358
370
 
@@ -377,9 +389,9 @@
377
389
 
378
390
  // Re-setup on window resize
379
391
  let resizeTimeout;
380
- window.addEventListener('resize', function() {
392
+ window.addEventListener('resize', () => {
381
393
  clearTimeout(resizeTimeout);
382
- resizeTimeout = setTimeout(function() {
394
+ resizeTimeout = setTimeout(() => {
383
395
  if (window.innerWidth <= 768) {
384
396
  setupHamburgerMenu();
385
397
  }
@@ -498,7 +510,7 @@
498
510
 
499
511
  // Close on Escape key (only add once)
500
512
  if (!window.__headerMenuWidgetEscapeHandler) {
501
- window.__headerMenuWidgetEscapeHandler = function(e) {
513
+ window.__headerMenuWidgetEscapeHandler = (e) => {
502
514
  if (e.key === 'Escape' && window.innerWidth <= 768) {
503
515
  const currentDrawer = document.getElementById(drawerId);
504
516
  if (currentDrawer && currentDrawer.classList.contains('active')) {
@@ -512,7 +524,7 @@
512
524
 
513
525
  // Close on outside click (only add once)
514
526
  if (!window.__headerMenuWidgetOverlayHandler) {
515
- window.__headerMenuWidgetOverlayHandler = function(e) {
527
+ window.__headerMenuWidgetOverlayHandler = (e) => {
516
528
  if (window.innerWidth > 768) return;
517
529
  const currentDrawer = document.getElementById(drawerId);
518
530
  if (currentDrawer && currentDrawer.classList.contains('active')) {
@@ -651,11 +663,11 @@
651
663
  // Step 3: Fetch full menu details with items
652
664
  const menuResponse = await fetch(`/webstoreapi/menus/${mainMenu.id}`, {
653
665
  method: 'GET',
654
- headers: {
655
- 'Accept': 'application/json',
656
- 'X-Requested-With': 'XMLHttpRequest'
657
- }
658
- });
666
+ headers: {
667
+ 'Accept': 'application/json',
668
+ 'X-Requested-With': 'XMLHttpRequest'
669
+ }
670
+ });
659
671
 
660
672
  if (!menuResponse.ok) {
661
673
  throw new Error(`Failed to fetch menu details: ${menuResponse.status}`);