@magic-spells/gift-with-purchase 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +332 -0
- package/dist/gift-with-purchase.cjs.css +43 -0
- package/dist/gift-with-purchase.cjs.css.map +1 -0
- package/dist/gift-with-purchase.cjs.js +339 -0
- package/dist/gift-with-purchase.cjs.js.map +1 -0
- package/dist/gift-with-purchase.esm.css +43 -0
- package/dist/gift-with-purchase.esm.css.map +1 -0
- package/dist/gift-with-purchase.esm.js +337 -0
- package/dist/gift-with-purchase.esm.js.map +1 -0
- package/dist/gift-with-purchase.min.css +2 -0
- package/dist/gift-with-purchase.min.css.map +1 -0
- package/dist/gift-with-purchase.min.js +2 -0
- package/dist/gift-with-purchase.min.js.map +1 -0
- package/dist/gift-with-purchase.scss +70 -0
- package/package.json +75 -0
- package/src/gift-with-purchase.js +338 -0
- package/src/gift-with-purchase.scss +70 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 Magic Spells
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,332 @@
|
|
|
1
|
+
# Gift with Purchase
|
|
2
|
+
|
|
3
|
+
A powerful, e-commerce web component for automatic gift-with-purchase threshold promotions. Seamlessly integrates with Shopify and automatically manages gift items in the cart based on spending thresholds.
|
|
4
|
+
|
|
5
|
+
[**Live Demo**](https://magic-spells.github.io/gift-with-purchase/demo/)
|
|
6
|
+
|
|
7
|
+
## Features
|
|
8
|
+
|
|
9
|
+
- 🎁 **Automatic Gift Management** - Adds/removes gifts based on cart thresholds using smart pricing logic
|
|
10
|
+
- 🛒 **Shopify Integration** - Built-in Cart API support with proper line item properties
|
|
11
|
+
- 📱 **Cart Panel Sync** - Automatically syncs with cart-dialog components using `calculated_subtotal`
|
|
12
|
+
- 🎨 **Highly Customizable** - CSS custom properties and swappable content elements
|
|
13
|
+
- ⚡ **Event-Driven** - Custom events for gift addition, removal, and errors
|
|
14
|
+
- 🔧 **Flexible Content** - Data attributes for dynamic image, title, and variant updates
|
|
15
|
+
- 📱 **Responsive** - Mobile-optimized with responsive design
|
|
16
|
+
|
|
17
|
+
## Installation
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
npm install @magic-spells/gift-with-purchase
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Basic Usage
|
|
24
|
+
|
|
25
|
+
```html
|
|
26
|
+
<gift-with-purchase
|
|
27
|
+
threshold="75.00"
|
|
28
|
+
current="45.00"
|
|
29
|
+
variant-id="12345678"
|
|
30
|
+
message-above="🎉 Congratulations! You've qualified for your FREE gift!"
|
|
31
|
+
message-below="Add ${ amount } more to unlock your free gift! 🎁">
|
|
32
|
+
<div class="gwp-product">
|
|
33
|
+
<img src="gift-image.jpg" alt="Free Gift" />
|
|
34
|
+
<div class="gwp-content">
|
|
35
|
+
<h4 class="gwp-title">Free Sample Set</h4>
|
|
36
|
+
<p class="gwp-variant">Travel Size Collection</p>
|
|
37
|
+
</div>
|
|
38
|
+
</div>
|
|
39
|
+
<p data-content-gwp-message class="text-sm font-medium"></p>
|
|
40
|
+
</gift-with-purchase>
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
```css
|
|
44
|
+
@import '@magic-spells/gift-with-purchase/css';
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## Cart Integration
|
|
48
|
+
|
|
49
|
+
The component automatically listens for cart data changes when placed inside a `<cart-dialog>` component from the `@magic-spells/cart-panel` package:
|
|
50
|
+
|
|
51
|
+
```html
|
|
52
|
+
<cart-dialog>
|
|
53
|
+
<gift-with-purchase
|
|
54
|
+
threshold="75.00"
|
|
55
|
+
variant-id="12345678"
|
|
56
|
+
message-above="🎉 Congratulations! You've qualified for your FREE gift!"
|
|
57
|
+
message-below="Add ${ amount } more to unlock your free gift! 🎁">
|
|
58
|
+
<!-- Gift content -->
|
|
59
|
+
</gift-with-purchase>
|
|
60
|
+
</cart-dialog>
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
When the cart-dialog emits a `cart-dialog:data-changed` event (typically from Shopify cart updates), the gift component will automatically:
|
|
64
|
+
|
|
65
|
+
- Update the current cart amount using `calculated_subtotal` for accurate threshold calculation
|
|
66
|
+
- Check if the threshold is met (excludes other gifts and honors pricing exclusions)
|
|
67
|
+
- Add the gift to cart if threshold is reached
|
|
68
|
+
- Remove the gift if cart falls below threshold
|
|
69
|
+
|
|
70
|
+
### Smart Pricing Logic
|
|
71
|
+
|
|
72
|
+
The component uses intelligent threshold calculation:
|
|
73
|
+
- **Uses `calculated_subtotal`** from cart-panel which properly handles item exclusions
|
|
74
|
+
- **Excludes gifts**: Other gifts with purchase won't count toward this threshold
|
|
75
|
+
- **Includes bundle items**: Hidden bundle components that should count are included
|
|
76
|
+
- **Backwards compatible**: Falls back to `total_price` if `calculated_subtotal` unavailable
|
|
77
|
+
|
|
78
|
+
## JavaScript API
|
|
79
|
+
|
|
80
|
+
```javascript
|
|
81
|
+
const gwp = document.querySelector('gift-with-purchase');
|
|
82
|
+
|
|
83
|
+
// Update cart amount
|
|
84
|
+
gwp.setCurrentAmount(85.5);
|
|
85
|
+
|
|
86
|
+
// Change threshold
|
|
87
|
+
gwp.setThreshold(100.0);
|
|
88
|
+
|
|
89
|
+
// Update variant ID
|
|
90
|
+
gwp.setVariantId('87654321');
|
|
91
|
+
|
|
92
|
+
// Get current state
|
|
93
|
+
const state = gwp.getState();
|
|
94
|
+
console.log(state.isActive, state.isAdded, state.remainingAmount);
|
|
95
|
+
|
|
96
|
+
// Manual message updates (component handles this automatically)
|
|
97
|
+
const messageEl = gwp.querySelector('[data-content-gwp-message]');
|
|
98
|
+
if (messageEl) {
|
|
99
|
+
messageEl.textContent = 'Custom message';
|
|
100
|
+
}
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
## Attributes
|
|
104
|
+
|
|
105
|
+
| Attribute | Description | Example |
|
|
106
|
+
| --------------- | -------------------------------------------------------------------- | ------------------------------------------------------------ |
|
|
107
|
+
| `threshold` | Spending threshold to unlock the gift | `"75.00"` |
|
|
108
|
+
| `current` | Current cart amount | `"45.00"` |
|
|
109
|
+
| `variant-id` | Shopify variant ID for the gift product | `"12345678"` |
|
|
110
|
+
| `message-above` | Message shown when threshold is met | `"🎉 Congratulations! You've qualified for your FREE gift!"` |
|
|
111
|
+
| `message-below` | Message shown when below threshold (uses `{ amount }` placeholder) | `"Add ${ amount } more to unlock your free gift! 🎁"` |
|
|
112
|
+
|
|
113
|
+
## Message Element
|
|
114
|
+
|
|
115
|
+
The component requires a message element to display threshold messages:
|
|
116
|
+
|
|
117
|
+
```html
|
|
118
|
+
<gift-with-purchase threshold="75.00" variant-id="12345678">
|
|
119
|
+
<!-- Your gift content with any styling -->
|
|
120
|
+
<div class="gift-content">
|
|
121
|
+
<h4 class="font-bold">Free Gift</h4>
|
|
122
|
+
<p class="text-gray-600">Sample Description</p>
|
|
123
|
+
</div>
|
|
124
|
+
|
|
125
|
+
<!-- Required: Element where messages will be injected -->
|
|
126
|
+
<p data-content-gwp-message class="bg-green-100 p-2 rounded"></p>
|
|
127
|
+
</gift-with-purchase>
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
## Events
|
|
131
|
+
|
|
132
|
+
The component emits custom events for integration:
|
|
133
|
+
|
|
134
|
+
```javascript
|
|
135
|
+
// Gift successfully added to cart
|
|
136
|
+
gwp.addEventListener('gwp:added', (event) => {
|
|
137
|
+
console.log('Gift added:', event.detail.variantId);
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
// Gift successfully removed from cart
|
|
141
|
+
gwp.addEventListener('gwp:removed', (event) => {
|
|
142
|
+
console.log('Gift removed:', event.detail.variantId);
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
// Error occurred during add/remove
|
|
146
|
+
gwp.addEventListener('gwp:error', (event) => {
|
|
147
|
+
console.error('Error:', event.detail.error);
|
|
148
|
+
console.log('Action:', event.detail.action); // 'add' or 'remove'
|
|
149
|
+
});
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
## Customization
|
|
153
|
+
|
|
154
|
+
Use CSS custom properties to customize the appearance:
|
|
155
|
+
|
|
156
|
+
```css
|
|
157
|
+
gift-with-purchase {
|
|
158
|
+
--gwp-border-radius: 12px;
|
|
159
|
+
--gwp-padding: 1.5rem;
|
|
160
|
+
--gwp-bg-active: #e8f5e8;
|
|
161
|
+
--gwp-border-active: #28a745;
|
|
162
|
+
--gwp-text-active: #155724;
|
|
163
|
+
--gwp-image-size: 80px;
|
|
164
|
+
}
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
## Available CSS Custom Properties
|
|
168
|
+
|
|
169
|
+
| Property | Description | Default |
|
|
170
|
+
| --------------------- | ---------------------- | --------- |
|
|
171
|
+
| `--gwp-border-radius` | Border radius | `8px` |
|
|
172
|
+
| `--gwp-padding` | Internal padding | `1rem` |
|
|
173
|
+
| `--gwp-bg-active` | Background when active | `#e8f5e8` |
|
|
174
|
+
| `--gwp-bg-added` | Background when added | `#d4edda` |
|
|
175
|
+
| `--gwp-border-active` | Border when active | `#28a745` |
|
|
176
|
+
| `--gwp-border-added` | Border when added | `#155724` |
|
|
177
|
+
| `--gwp-text-active` | Text color when active | `#155724` |
|
|
178
|
+
| `--gwp-text-added` | Text color when added | `#155724` |
|
|
179
|
+
| `--gwp-gap` | Gap between elements | `1rem` |
|
|
180
|
+
|
|
181
|
+
## Component States
|
|
182
|
+
|
|
183
|
+
The component automatically applies a `state` attribute based on its current condition:
|
|
184
|
+
|
|
185
|
+
- `state="active"` - Threshold met, gift available to add
|
|
186
|
+
- `state="added"` - Gift successfully added to cart
|
|
187
|
+
- `state="ended"` - Promo ended (component hidden)
|
|
188
|
+
|
|
189
|
+
Note: There is no `inactive` state since the component would typically not be loaded at all when below threshold in most Shopify implementations.
|
|
190
|
+
|
|
191
|
+
## Shopify Integration Details
|
|
192
|
+
|
|
193
|
+
### Cart API Calls
|
|
194
|
+
|
|
195
|
+
The component uses Shopify's Cart API endpoints:
|
|
196
|
+
|
|
197
|
+
- `POST /cart/add.js` - Adds the gift to cart
|
|
198
|
+
- `GET /cart.js` - Gets current cart state
|
|
199
|
+
- `POST /cart/change.js` - Removes gift from cart
|
|
200
|
+
|
|
201
|
+
### Line Item Properties
|
|
202
|
+
|
|
203
|
+
When adding gifts to the cart, the component automatically sets these properties for proper cart integration:
|
|
204
|
+
|
|
205
|
+
```javascript
|
|
206
|
+
{
|
|
207
|
+
id: variantId,
|
|
208
|
+
quantity: 1,
|
|
209
|
+
properties: {
|
|
210
|
+
_gwp_item: "true",
|
|
211
|
+
_hide_in_cart: "true",
|
|
212
|
+
_ignore_price_in_subtotal: "true"
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
**Property Functions:**
|
|
218
|
+
- **`_gwp_item: "true"`** - Identifies gift items in cart templates and for removal logic
|
|
219
|
+
- **`_hide_in_cart: "true"`** - Hides gifts from cart display (handled by `@magic-spells/cart-panel`)
|
|
220
|
+
- **`_ignore_price_in_subtotal: "true"`** - Excludes gift price from subtotal calculations and threshold checks
|
|
221
|
+
- **Automatic management** - These properties ensure gifts don't interfere with other promotions or cart totals
|
|
222
|
+
|
|
223
|
+
### Cart Template Integration
|
|
224
|
+
|
|
225
|
+
In your Shopify cart template, you can identify and handle gift items:
|
|
226
|
+
|
|
227
|
+
```liquid
|
|
228
|
+
{% for item in cart.items %}
|
|
229
|
+
{% if item.properties._gwp_item == 'true' %}
|
|
230
|
+
<!-- This is a gift item -->
|
|
231
|
+
<div class="cart-gift-item">
|
|
232
|
+
<span class="gift-badge">FREE GIFT</span>
|
|
233
|
+
{{ item.product.title }}
|
|
234
|
+
</div>
|
|
235
|
+
{% else %}
|
|
236
|
+
<!-- Regular cart item -->
|
|
237
|
+
{% endif %}
|
|
238
|
+
{% endfor %}
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
## Advanced Usage
|
|
242
|
+
|
|
243
|
+
### Multiple Thresholds
|
|
244
|
+
|
|
245
|
+
```html
|
|
246
|
+
<!-- Low tier gift -->
|
|
247
|
+
<gift-with-purchase
|
|
248
|
+
threshold="50.00"
|
|
249
|
+
variant-id="111111"
|
|
250
|
+
message-above="🎉 You've unlocked a free tote bag!"
|
|
251
|
+
message-below="Add ${ amount } more for a free tote bag! 👜">
|
|
252
|
+
<div class="gwp-product">
|
|
253
|
+
<img src="tote-bag.jpg" alt="Free Tote Bag" />
|
|
254
|
+
<h4 class="gwp-title">Free Tote Bag</h4>
|
|
255
|
+
</div>
|
|
256
|
+
<p data-content-gwp-message class="message-low-tier"></p>
|
|
257
|
+
</gift-with-purchase>
|
|
258
|
+
|
|
259
|
+
<!-- High tier gift -->
|
|
260
|
+
<gift-with-purchase
|
|
261
|
+
threshold="100.00"
|
|
262
|
+
variant-id="222222"
|
|
263
|
+
message-above="✨ Amazing! You've earned our premium gift set!"
|
|
264
|
+
message-below="Spend ${ amount } more for our exclusive premium gift set! ✨">
|
|
265
|
+
<div class="gwp-product">
|
|
266
|
+
<img src="gift-set.jpg" alt="Premium Gift Set" />
|
|
267
|
+
<h4 class="gwp-title">Premium Gift Set</h4>
|
|
268
|
+
</div>
|
|
269
|
+
<p data-content-gwp-message class="message-premium"></p>
|
|
270
|
+
</gift-with-purchase>
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
### Custom Styling Examples
|
|
274
|
+
|
|
275
|
+
```css
|
|
276
|
+
/* Minimal style */
|
|
277
|
+
.gwp-minimal {
|
|
278
|
+
--gwp-padding: 0.75rem;
|
|
279
|
+
--gwp-border-radius: 4px;
|
|
280
|
+
--gwp-bg-active: #f0f8f0;
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
/* Bold style */
|
|
284
|
+
.gwp-bold {
|
|
285
|
+
--gwp-padding: 1.5rem;
|
|
286
|
+
--gwp-border-radius: 12px;
|
|
287
|
+
--gwp-bg-active: #28a745;
|
|
288
|
+
--gwp-text-active: white;
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
/* Compact mobile style */
|
|
292
|
+
@media (max-width: 768px) {
|
|
293
|
+
gift-with-purchase {
|
|
294
|
+
--gwp-image-size: 40px;
|
|
295
|
+
--gwp-padding: 0.5rem;
|
|
296
|
+
--gwp-gap: 0.5rem;
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
## Browser Support
|
|
302
|
+
|
|
303
|
+
- Chrome/Edge 88+
|
|
304
|
+
- Firefox 85+
|
|
305
|
+
- Safari 14+
|
|
306
|
+
- All modern browsers with Custom Elements support
|
|
307
|
+
|
|
308
|
+
## TypeScript Support
|
|
309
|
+
|
|
310
|
+
Type definitions are included in the package:
|
|
311
|
+
|
|
312
|
+
```typescript
|
|
313
|
+
interface GiftWithPurchaseState {
|
|
314
|
+
currentAmount: number;
|
|
315
|
+
threshold: number;
|
|
316
|
+
variantId: string | null;
|
|
317
|
+
isActive: boolean;
|
|
318
|
+
isAdded: boolean;
|
|
319
|
+
remainingAmount: number;
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
// Component automatically handles message injection
|
|
323
|
+
// Style your content and message elements with any CSS classes
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
## Contributing
|
|
327
|
+
|
|
328
|
+
Contributions are welcome! Please read our contributing guidelines and submit pull requests to our repository.
|
|
329
|
+
|
|
330
|
+
## License
|
|
331
|
+
|
|
332
|
+
MIT License - see LICENSE file for details.
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
gift-with-purchase {
|
|
2
|
+
--gwp-border-radius: 8px;
|
|
3
|
+
--gwp-padding: 1rem;
|
|
4
|
+
--gwp-gap: 1rem;
|
|
5
|
+
--gwp-bg-active: #e8f5e8;
|
|
6
|
+
--gwp-bg-added: #d4edda;
|
|
7
|
+
--gwp-border-active: #28a745;
|
|
8
|
+
--gwp-border-added: #155724;
|
|
9
|
+
--gwp-text-active: #155724;
|
|
10
|
+
--gwp-text-added: #155724;
|
|
11
|
+
display: block;
|
|
12
|
+
border: 2px solid var(--gwp-border-active);
|
|
13
|
+
border-radius: var(--gwp-border-radius);
|
|
14
|
+
padding: var(--gwp-padding);
|
|
15
|
+
background-color: var(--gwp-bg-active);
|
|
16
|
+
color: var(--gwp-text-active);
|
|
17
|
+
}
|
|
18
|
+
gift-with-purchase .gwp-product {
|
|
19
|
+
display: flex;
|
|
20
|
+
align-items: flex-start;
|
|
21
|
+
gap: var(--gwp-gap);
|
|
22
|
+
}
|
|
23
|
+
gift-with-purchase [data-gwp-image] {
|
|
24
|
+
flex-shrink: 0;
|
|
25
|
+
}
|
|
26
|
+
gift-with-purchase .gwp-content {
|
|
27
|
+
flex: 1;
|
|
28
|
+
min-width: 0;
|
|
29
|
+
}
|
|
30
|
+
gift-with-purchase[state=active] {
|
|
31
|
+
background-color: var(--gwp-bg-active);
|
|
32
|
+
border-color: var(--gwp-border-active);
|
|
33
|
+
color: var(--gwp-text-active);
|
|
34
|
+
}
|
|
35
|
+
gift-with-purchase[state=added] {
|
|
36
|
+
background-color: var(--gwp-bg-added);
|
|
37
|
+
border-color: var(--gwp-border-added);
|
|
38
|
+
color: var(--gwp-text-added);
|
|
39
|
+
}
|
|
40
|
+
gift-with-purchase[state=ended] {
|
|
41
|
+
display: none;
|
|
42
|
+
}
|
|
43
|
+
/*# sourceMappingURL=gift-with-purchase.cjs.css.map */
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["gift-with-purchase.scss"],"names":[],"mappings":"AAAA;EACE,wBAAwB;EACxB,mBAAmB;EACnB,eAAe;EACf,wBAAwB;EACxB,uBAAuB;EACvB,4BAA4B;EAC5B,2BAA2B;EAC3B,0BAA0B;EAC1B,yBAAyB;EACzB,cAAc;EACd,0CAA0C;EAC1C,uCAAuC;EACvC,2BAA2B;EAC3B,sCAAsC;EACtC,6BAA6B;AAC/B;AACA;EACE,aAAa;EACb,uBAAuB;EACvB,mBAAmB;AACrB;AACA;EACE,cAAc;AAChB;AACA;EACE,OAAO;EACP,YAAY;AACd;AACA;EACE,sCAAsC;EACtC,sCAAsC;EACtC,6BAA6B;AAC/B;AACA;EACE,qCAAqC;EACrC,qCAAqC;EACrC,4BAA4B;AAC9B;AACA;EACE,aAAa;AACf","file":"gift-with-purchase.cjs.css","sourcesContent":["gift-with-purchase {\n --gwp-border-radius: 8px;\n --gwp-padding: 1rem;\n --gwp-gap: 1rem;\n --gwp-bg-active: #e8f5e8;\n --gwp-bg-added: #d4edda;\n --gwp-border-active: #28a745;\n --gwp-border-added: #155724;\n --gwp-text-active: #155724;\n --gwp-text-added: #155724;\n display: block;\n border: 2px solid var(--gwp-border-active);\n border-radius: var(--gwp-border-radius);\n padding: var(--gwp-padding);\n background-color: var(--gwp-bg-active);\n color: var(--gwp-text-active);\n}\ngift-with-purchase .gwp-product {\n display: flex;\n align-items: flex-start;\n gap: var(--gwp-gap);\n}\ngift-with-purchase [data-gwp-image] {\n flex-shrink: 0;\n}\ngift-with-purchase .gwp-content {\n flex: 1;\n min-width: 0;\n}\ngift-with-purchase[state=active] {\n background-color: var(--gwp-bg-active);\n border-color: var(--gwp-border-active);\n color: var(--gwp-text-active);\n}\ngift-with-purchase[state=added] {\n background-color: var(--gwp-bg-added);\n border-color: var(--gwp-border-added);\n color: var(--gwp-text-added);\n}\ngift-with-purchase[state=ended] {\n display: none;\n}"]}
|