@runwell/shopify-toolkit 0.1.0 → 0.3.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 (44) hide show
  1. package/modules/_shared/css-tokens/assets/runwell-tokens.css +14 -0
  2. package/modules/_shared/css-tokens/module.json +13 -0
  3. package/modules/bundle-builder/README.md +40 -0
  4. package/modules/bundle-builder/assets/runwell-bundle-builder.css +383 -0
  5. package/modules/bundle-builder/module.json +26 -0
  6. package/modules/bundle-builder/sections/runwell-bundle-builder.liquid +370 -0
  7. package/modules/cart-cross-sell/README.md +32 -0
  8. package/modules/cart-cross-sell/module.json +15 -0
  9. package/modules/cart-cross-sell/snippets/runwell-cart-xsell.liquid +40 -0
  10. package/modules/cart-freeship-progress/README.md +29 -0
  11. package/modules/cart-freeship-progress/module.json +16 -0
  12. package/modules/cart-freeship-progress/snippets/runwell-cart-freeship.liquid +27 -0
  13. package/modules/cart-usps/README.md +22 -0
  14. package/modules/cart-usps/module.json +17 -0
  15. package/modules/cart-usps/snippets/runwell-cart-usps.liquid +11 -0
  16. package/modules/editorial-hero/sections/runwell-video-hero.liquid +9 -3
  17. package/modules/gift-with-purchase/README.md +36 -0
  18. package/modules/gift-with-purchase/assets/runwell-gwp.js +42 -0
  19. package/modules/gift-with-purchase/module.json +32 -0
  20. package/modules/gift-with-purchase/snippets/runwell-gwp.liquid +30 -0
  21. package/modules/loyalty-tiers/README.md +45 -0
  22. package/modules/loyalty-tiers/module.json +40 -0
  23. package/modules/loyalty-tiers/sections/runwell-tier-card.liquid +86 -0
  24. package/modules/product-badges/README.md +35 -0
  25. package/modules/product-badges/module.json +16 -0
  26. package/modules/product-badges/snippets/runwell-product-badges.liquid +19 -0
  27. package/modules/quantity-breaks/README.md +33 -0
  28. package/modules/quantity-breaks/module.json +35 -0
  29. package/modules/quantity-breaks/snippets/runwell-quantity-breaks.liquid +28 -0
  30. package/modules/quick-view/README.md +36 -0
  31. package/modules/quick-view/assets/runwell-quickview.js +153 -0
  32. package/modules/quick-view/module.json +14 -0
  33. package/modules/quick-view/snippets/runwell-quickview-modal.liquid +14 -0
  34. package/modules/quick-view/snippets/runwell-quickview-trigger.liquid +19 -0
  35. package/modules/subscriptions/README.md +37 -0
  36. package/modules/subscriptions/module.json +36 -0
  37. package/modules/subscriptions/snippets/runwell-subscription-picker.liquid +35 -0
  38. package/modules/wishlist/README.md +48 -0
  39. package/modules/wishlist/assets/runwell-wishlist.js +112 -0
  40. package/modules/wishlist/module.json +25 -0
  41. package/modules/wishlist/sections/runwell-wishlist-page.liquid +35 -0
  42. package/modules/wishlist/snippets/runwell-wishlist-icon.liquid +17 -0
  43. package/modules/wishlist/templates/page.wishlist.json +13 -0
  44. package/package.json +1 -1
@@ -0,0 +1,14 @@
1
+ /* Runwell Shopify Toolkit: brand tokens.
2
+ Generated from runwell.config.json brand vars. Every other module
3
+ references these via var(--runwell-X). Do not hand-edit in client
4
+ themes; re-run runwell-shopify sync to update.
5
+ */
6
+ :root {
7
+ --runwell-primary: {{brand.primary}};
8
+ --runwell-accent: {{brand.accent}};
9
+ --runwell-cream: {{brand.cream}};
10
+ --runwell-oat: {{brand.oat}};
11
+ --runwell-celadon: {{brand.celadon}};
12
+ --runwell-blue: {{brand.blue}};
13
+ --runwell-rain-forrest: {{brand.rain-forrest}};
14
+ }
@@ -0,0 +1,13 @@
1
+ {
2
+ "name": "_shared/css-tokens",
3
+ "version": "0.1.0",
4
+ "category": "foundation",
5
+ "description": "CSS custom properties published as :root vars so every Runwell module pulls brand colors from one source. Always synced.",
6
+ "always_enabled": true,
7
+ "files": {
8
+ "assets": ["assets/runwell-tokens.css"]
9
+ },
10
+ "config": {
11
+ "schema": {}
12
+ }
13
+ }
@@ -0,0 +1,40 @@
1
+ # bundle-builder
2
+
3
+ PDP section for build-your-own-bundle merchandising. Slideshow gallery + thumbnail nav + radio bundle picker (1x / 2x / 3x with savings, free-ship and free-gift badges) + sticky ATC + FOMO countdown + scarcity. Migrated from Lusha's bundle-selector.
4
+
5
+ ## Files
6
+
7
+ - `sections/runwell-bundle-builder.liquid`. Section template (392 lines).
8
+ - `assets/runwell-bundle-builder.css`. ~370 lines of styling, brand-aware via `var(--runwell-*)`.
9
+
10
+ ## Behaviour
11
+
12
+ - **Gallery**: configurable via section blocks of type `gallery_image`. If no images set, falls back to the product's featured image, then to a brand-coloured placeholder.
13
+ - **Thumbnails**: clickable navigation between gallery images.
14
+ - **Bundle options**: configurable via section blocks of type `bundle_option`. Each one shows: title, price, compare-at price, savings badge, free-ship badge, "MOST POPULAR" highlight, free-gift text.
15
+ - **FOMO mode**: `discount` (countdown to sale end), `scarcity` (low-stock count), `both`, or `none`. The deadline rotates on a configurable cycle so it never expires for a returning visitor.
16
+ - **Trust badges**: 3 configurable promise lines below the ATC.
17
+ - **ATC**: posts to `/cart/add.js` with quantity parsed from the title (`"3x Product"` adds qty 3).
18
+
19
+ ## How to use
20
+
21
+ 1. Sync: `runwell-shopify sync`
22
+ 2. In any product template (or a custom landing page), add the section "Runwell Bundle Builder"
23
+ 3. Inside the section, add `gallery_image` blocks for product photography
24
+ 4. Add `bundle_option` blocks for each bundle tier (typically 3 with the middle marked "popular")
25
+ 5. Configure FOMO mode if desired
26
+ 6. Style further via the brand's `--runwell-*` CSS custom properties
27
+
28
+ ## Lineage
29
+
30
+ Migrated from `guabrasha-store/sections/bundle-selector.liquid` (Lusha gua sha brand). Class prefix renamed from `bundle-selector` to `runwell-bundle-builder`. Lusha-specific hardcoded gallery filenames replaced with a placeholder pattern. Lusha-specific copy ("Lusha Sculpting Brush", "Spring Sculpting Sale") replaced with generic defaults that the merchant overrides via section settings.
31
+
32
+ ## Replaces
33
+
34
+ Bundle Builder, BYOB Bundles by Pickystory, Bundler. The toolkit version is display + ATC only; if you need true bundle-as-SKU pricing the merchant should pair this with a Shopify Functions discount.
35
+
36
+ ## Future variants
37
+
38
+ - `step-by-step` (single-product, multi-step BYOB walkthrough)
39
+ - `mix-and-match` (any 3 from a curated set)
40
+ - `subscription-bundle` (bundle with subscription price option)
@@ -0,0 +1,383 @@
1
+ .runwell-bundle-builder__grid {
2
+ display: grid;
3
+ grid-template-columns: 1fr 1fr;
4
+ gap: 2.4rem;
5
+ align-items: start;
6
+ }
7
+
8
+ /* Slideshow Gallery */
9
+ .runwell-bundle-builder__slideshow {
10
+ position: relative;
11
+ border-radius: 12px;
12
+ overflow: hidden;
13
+ background: #E8D5C4;
14
+ }
15
+
16
+ .runwell-bundle-builder__slide {
17
+ display: none;
18
+ }
19
+
20
+ .runwell-bundle-builder__slide--active {
21
+ display: block;
22
+ }
23
+
24
+ .runwell-bundle-builder__img {
25
+ width: 100%;
26
+ height: auto;
27
+ display: block;
28
+ aspect-ratio: 1 / 1;
29
+ object-fit: cover;
30
+ max-height: calc(100vh - 260px);
31
+ }
32
+
33
+ /* Thumbnail Strip - ALWAYS visible including mobile */
34
+ .runwell-bundle-builder__thumbnails {
35
+ display: flex;
36
+ gap: 8px;
37
+ margin-top: 12px;
38
+ overflow-x: auto;
39
+ scrollbar-width: thin;
40
+ scrollbar-color: #EADFD4 transparent;
41
+ padding-bottom: 4px;
42
+ -webkit-overflow-scrolling: touch;
43
+ }
44
+
45
+ .runwell-bundle-builder__thumbnails::-webkit-scrollbar {
46
+ height: 4px;
47
+ }
48
+
49
+ .runwell-bundle-builder__thumbnails::-webkit-scrollbar-thumb {
50
+ background: #EADFD4;
51
+ border-radius: 2px;
52
+ }
53
+
54
+ .runwell-bundle-builder__thumb {
55
+ flex: 0 0 72px;
56
+ height: 72px;
57
+ border-radius: 8px;
58
+ overflow: hidden;
59
+ border: 2px solid transparent;
60
+ cursor: pointer;
61
+ padding: 0;
62
+ background: #E8D5C4;
63
+ transition: border-color 0.2s, opacity 0.2s;
64
+ opacity: 0.7;
65
+ }
66
+
67
+ .runwell-bundle-builder__thumb--active {
68
+ border-color: #3F5B4C;
69
+ opacity: 1;
70
+ }
71
+
72
+ .runwell-bundle-builder__thumb:hover {
73
+ opacity: 1;
74
+ }
75
+
76
+ .runwell-bundle-builder__thumb img {
77
+ width: 100%;
78
+ height: 100%;
79
+ object-fit: cover;
80
+ }
81
+
82
+ /* Rating */
83
+ .runwell-bundle-builder__rating {
84
+ display: flex;
85
+ align-items: center;
86
+ gap: 8px;
87
+ margin-bottom: 0;
88
+ }
89
+
90
+ .runwell-bundle-builder__stars {
91
+ color: #E8B931;
92
+ font-size: 1.6rem;
93
+ letter-spacing: 1px;
94
+ }
95
+
96
+ .runwell-bundle-builder__rating-text {
97
+ font-size: 1.4rem;
98
+ font-weight: 600;
99
+ font-style: italic;
100
+ }
101
+
102
+ /* Title */
103
+ .runwell-bundle-builder__title {
104
+ margin-top: 0.4rem;
105
+ margin-bottom: 1rem;
106
+ }
107
+
108
+ /* Sale heading */
109
+ .runwell-bundle-builder__sale-heading {
110
+ display: flex;
111
+ align-items: center;
112
+ gap: 1.2rem;
113
+ margin-bottom: 1.2rem;
114
+ }
115
+
116
+ .runwell-bundle-builder__sale-line {
117
+ flex: 1;
118
+ height: 1px;
119
+ background: #2A2622;
120
+ }
121
+
122
+ .runwell-bundle-builder__sale-text {
123
+ font-weight: 700;
124
+ font-size: 1.5rem;
125
+ white-space: nowrap;
126
+ }
127
+
128
+ /* Scarcity indicator */
129
+ .runwell-bundle-builder__scarcity {
130
+ display: flex;
131
+ align-items: center;
132
+ justify-content: center;
133
+ gap: 6px;
134
+ font-size: 1.3rem;
135
+ font-weight: 500;
136
+ color: #b45309;
137
+ margin-bottom: 1rem;
138
+ }
139
+
140
+ .runwell-bundle-builder__scarcity-dot {
141
+ width: 8px;
142
+ height: 8px;
143
+ border-radius: 50%;
144
+ background: #b45309;
145
+ animation: scarcity-pulse 2s ease-in-out infinite;
146
+ }
147
+
148
+ @keyframes scarcity-pulse {
149
+ 0%, 100% { opacity: 1; }
150
+ 50% { opacity: 0.4; }
151
+ }
152
+
153
+ /* Options */
154
+ .runwell-bundle-builder__options {
155
+ display: flex;
156
+ flex-direction: column;
157
+ gap: 10px;
158
+ margin-bottom: 1.2rem;
159
+ }
160
+
161
+ .runwell-bundle-builder__option {
162
+ display: flex;
163
+ align-items: flex-start;
164
+ gap: 12px;
165
+ padding: 14px 18px;
166
+ border: 2px solid #EADFD4;
167
+ border-radius: 10px;
168
+ cursor: pointer;
169
+ transition: border-color 0.2s, box-shadow 0.2s;
170
+ position: relative;
171
+ }
172
+
173
+ .runwell-bundle-builder__option:hover {
174
+ border-color: #3F5B4C;
175
+ }
176
+
177
+ .runwell-bundle-builder__option--selected {
178
+ border-color: #2A2622;
179
+ box-shadow: 0 0 0 1px #2A2622;
180
+ }
181
+
182
+ .runwell-bundle-builder__option--popular {
183
+ border-color: #3F5B4C;
184
+ position: relative;
185
+ }
186
+
187
+ .runwell-bundle-builder__popular-badge {
188
+ position: absolute;
189
+ top: -10px;
190
+ right: 16px;
191
+ background: #3F5B4C;
192
+ color: #fff;
193
+ font-size: 1.0rem;
194
+ font-weight: 700;
195
+ padding: 2px 10px;
196
+ border-radius: 4px;
197
+ letter-spacing: 0.06em;
198
+ text-transform: uppercase;
199
+ }
200
+
201
+ .runwell-bundle-builder__option input {
202
+ position: absolute;
203
+ opacity: 0;
204
+ pointer-events: none;
205
+ }
206
+
207
+ .runwell-bundle-builder__option-radio {
208
+ width: 22px;
209
+ height: 22px;
210
+ border-radius: 50%;
211
+ border: 2px solid #EADFD4;
212
+ flex-shrink: 0;
213
+ margin-top: 2px;
214
+ display: flex;
215
+ align-items: center;
216
+ justify-content: center;
217
+ transition: border-color 0.2s;
218
+ }
219
+
220
+ .runwell-bundle-builder__option--selected .runwell-bundle-builder__option-radio {
221
+ border-color: #2A2622;
222
+ }
223
+
224
+ .runwell-bundle-builder__option--selected .runwell-bundle-builder__option-radio::after {
225
+ content: '';
226
+ width: 12px;
227
+ height: 12px;
228
+ border-radius: 50%;
229
+ background: #2A2622;
230
+ }
231
+
232
+ .runwell-bundle-builder__option-content {
233
+ flex: 1;
234
+ }
235
+
236
+ .runwell-bundle-builder__option-header {
237
+ display: flex;
238
+ justify-content: space-between;
239
+ align-items: baseline;
240
+ gap: 12px;
241
+ }
242
+
243
+ .runwell-bundle-builder__option-title {
244
+ font-weight: 700;
245
+ font-size: 1.5rem;
246
+ }
247
+
248
+ .runwell-bundle-builder__option-pricing {
249
+ display: flex;
250
+ align-items: baseline;
251
+ gap: 8px;
252
+ flex-shrink: 0;
253
+ }
254
+
255
+ .runwell-bundle-builder__option-price {
256
+ font-weight: 700;
257
+ font-size: 1.8rem;
258
+ }
259
+
260
+ .runwell-bundle-builder__option-compare {
261
+ font-size: 1.3rem;
262
+ text-decoration: line-through;
263
+ opacity: 0.5;
264
+ }
265
+
266
+ .runwell-bundle-builder__option-badges {
267
+ display: flex;
268
+ gap: 6px;
269
+ margin-top: 6px;
270
+ flex-wrap: wrap;
271
+ }
272
+
273
+ .runwell-bundle-builder__badge {
274
+ font-size: 1.1rem;
275
+ font-weight: 700;
276
+ padding: 2px 8px;
277
+ border-radius: 4px;
278
+ text-transform: uppercase;
279
+ letter-spacing: 0.03em;
280
+ }
281
+
282
+ .runwell-bundle-builder__badge--save {
283
+ background: #3F5B4C;
284
+ color: #fff;
285
+ }
286
+
287
+ .runwell-bundle-builder__badge--shipping {
288
+ color: #3F5B4C;
289
+ font-weight: 600;
290
+ }
291
+
292
+ .runwell-bundle-builder__free-gift {
293
+ display: flex;
294
+ align-items: center;
295
+ gap: 6px;
296
+ margin-top: 8px;
297
+ padding: 8px 12px;
298
+ background: rgba(63, 91, 76, 0.06);
299
+ border-radius: 6px;
300
+ font-size: 1.3rem;
301
+ font-weight: 600;
302
+ }
303
+
304
+ .runwell-bundle-builder__gift-icon {
305
+ font-size: 1.6rem;
306
+ }
307
+
308
+ /* ATC Button */
309
+ .runwell-bundle-builder__atc {
310
+ width: 100%;
311
+ padding: 1.6rem;
312
+ font-size: 1.6rem;
313
+ font-weight: 700;
314
+ letter-spacing: 0.06em;
315
+ text-transform: uppercase;
316
+ background: #2A2622;
317
+ color: #fff;
318
+ border: none;
319
+ border-radius: 8px;
320
+ cursor: pointer;
321
+ transition: background 0.2s;
322
+ margin-bottom: 1.2rem;
323
+ }
324
+
325
+ .runwell-bundle-builder__atc:hover {
326
+ background: #3F5B4C;
327
+ }
328
+
329
+ /* Trust badges */
330
+ .runwell-bundle-builder__trust {
331
+ display: flex;
332
+ justify-content: center;
333
+ gap: 2rem;
334
+ font-size: 1.3rem;
335
+ opacity: 0.7;
336
+ flex-wrap: wrap;
337
+ }
338
+
339
+ /* Sticky ATC on mobile */
340
+ @media screen and (max-width: 989px) {
341
+ .runwell-bundle-builder__grid {
342
+ grid-template-columns: 1fr;
343
+ gap: 2rem;
344
+ }
345
+
346
+ .runwell-bundle-builder__atc-wrap {
347
+ position: sticky;
348
+ bottom: 0;
349
+ z-index: 10;
350
+ background: #fff;
351
+ padding: 12px 0 max(12px, env(safe-area-inset-bottom));
352
+ box-shadow: 0 -2px 12px rgba(0, 0, 0, 0.08);
353
+ margin: 0 -1.5rem;
354
+ padding-left: 1.5rem;
355
+ padding-right: 1.5rem;
356
+ }
357
+ }
358
+
359
+ @media screen and (max-width: 749px) {
360
+ .runwell-bundle-builder__option-header {
361
+ flex-direction: column;
362
+ gap: 4px;
363
+ }
364
+
365
+ .runwell-bundle-builder__trust {
366
+ flex-direction: column;
367
+ align-items: center;
368
+ gap: 0.6rem;
369
+ }
370
+ }
371
+
372
+ /* Runwell additions: placeholder states when gallery is empty */
373
+ .runwell-bundle-builder__img--placeholder,
374
+ .runwell-bundle-builder__thumb-img--placeholder {
375
+ width: 100%;
376
+ height: 100%;
377
+ min-height: 320px;
378
+ background: linear-gradient(135deg, var(--runwell-oat, #F5F0EE), var(--runwell-cream, #EDE6D8));
379
+ display: block;
380
+ }
381
+ .runwell-bundle-builder__thumb-img--placeholder {
382
+ min-height: 0;
383
+ }
@@ -0,0 +1,26 @@
1
+ {
2
+ "name": "bundle-builder",
3
+ "version": "0.1.0",
4
+ "category": "catalog",
5
+ "description": "Build-your-own-bundle PDP section. Slideshow gallery + thumbnail nav + radio bundle picker (1x / 2x / 3x with savings, free-ship and free-gift badges) + sticky ATC + FOMO countdown + scarcity. Migrated from Lusha (guabrasha-store/sections/bundle-selector.liquid). Replaces BYOB-style bundle apps.",
6
+ "files": {
7
+ "sections": ["sections/runwell-bundle-builder.liquid"],
8
+ "assets": ["assets/runwell-bundle-builder.css"]
9
+ },
10
+ "config": {
11
+ "schema": {
12
+ "heading": { "type": "string", "default": "Build your bundle" },
13
+ "sale_prefix": { "type": "string", "default": "Limited time offer" },
14
+ "show_rating": { "type": "boolean", "default": true },
15
+ "rating_score": { "type": "string", "default": "4.8/5" },
16
+ "rating_count": { "type": "string", "default": "2,400+" },
17
+ "show_trust_badges": { "type": "boolean", "default": true },
18
+ "trust_1": { "type": "string", "default": "90-Day Guarantee" },
19
+ "trust_2": { "type": "string", "default": "Easy Returns" },
20
+ "trust_3": { "type": "string", "default": "Free Shipping" },
21
+ "fomo_mode": { "type": "string", "default": "both", "enum": ["discount", "scarcity", "both", "none"] },
22
+ "fomo_cycle_days": { "type": "number", "default": 30 },
23
+ "fomo_stock_count": { "type": "number", "default": 47 }
24
+ }
25
+ }
26
+ }