@lime-bundles/react 6.1.0 → 7.0.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/README.md +7 -1
- package/dist/index.cjs +673 -543
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +35 -42
- package/dist/index.d.ts +35 -42
- package/dist/index.js +589 -460
- package/dist/index.js.map +1 -1
- package/dist/styles.css +1929 -0
- package/docs/hydrogen.md +28 -3
- package/docs/react-nextjs.md +23 -3
- package/package.json +2 -2
package/dist/styles.css
ADDED
|
@@ -0,0 +1,1929 @@
|
|
|
1
|
+
/* Lime Bundles — Default styles with CSS custom properties for theming.
|
|
2
|
+
* Import: import '@lime-bundles/react/styles.css'
|
|
3
|
+
* Override: set --lb-* variables on any ancestor element.
|
|
4
|
+
*
|
|
5
|
+
* Mirrors the storefront theme widget's "manifest + receipt" redesign
|
|
6
|
+
* (extensions/bundle-theme/assets/bundle-base.css + bundle-fixed.css):
|
|
7
|
+
* a quiet title block, hairline-separated product rows with a right-aligned
|
|
8
|
+
* price column, and a receipt-style summary whose sale price is the heaviest
|
|
9
|
+
* element. No colored header band, no save-badge pill, no savings bar — the
|
|
10
|
+
* single savings signal is a quiet "You save" line under the total.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
:root {
|
|
14
|
+
--lb-primary-color: #1a1a1a;
|
|
15
|
+
--lb-secondary-color: #666;
|
|
16
|
+
--lb-accent-color: #2563eb;
|
|
17
|
+
--lb-background: #fff;
|
|
18
|
+
--lb-border-color: #e5e7eb;
|
|
19
|
+
--lb-border-radius: 8px;
|
|
20
|
+
--lb-font-family: inherit;
|
|
21
|
+
--lb-font-size: 16px;
|
|
22
|
+
--lb-spacing-sm: 8px;
|
|
23
|
+
--lb-spacing-md: 16px;
|
|
24
|
+
--lb-spacing-lg: 24px;
|
|
25
|
+
--lb-button-bg: var(--lb-primary-color);
|
|
26
|
+
--lb-button-text: #fff;
|
|
27
|
+
--lb-button-radius: var(--lb-border-radius);
|
|
28
|
+
--lb-error-color: #92400e;
|
|
29
|
+
/* Cap on the per-bundle product/slot/tier list height — keeps long
|
|
30
|
+
bundles from pushing the CTA off-screen. The list scrolls
|
|
31
|
+
internally (with the .lb-edge-fade treatment) when content exceeds
|
|
32
|
+
this. */
|
|
33
|
+
--lb-list-max-height: 360px;
|
|
34
|
+
/* Depth of the soft fade at a scroll list's clipped edge. */
|
|
35
|
+
--lb-edge-fade-size: 20px;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/* Derived "small" corner radius for inner controls (thumbnails, variant
|
|
39
|
+
selects, the qty chip). One step tighter than the global --lb-radius so
|
|
40
|
+
small elements stay proportionate. Both come from the global radius preset
|
|
41
|
+
(emitted as --lb-radius by useWidgetConfigVars); nothing else sets a radius.
|
|
42
|
+
Falls back to --lb-border-radius until the bundle config has loaded, matching
|
|
43
|
+
the rest of this stylesheet. */
|
|
44
|
+
.lb-bundle {
|
|
45
|
+
--lb-radius-sm: max(0px, calc(var(--lb-radius, var(--lb-border-radius)) - 4px));
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/* Edge fade — the shared treatment for inset scroll lists (fixed products,
|
|
49
|
+
mix & match slots, volume tiers). The native scrollbar channel is hidden;
|
|
50
|
+
instead the clipped edge of the list softly fades so content melts away
|
|
51
|
+
rather than ending in a hard cut against an app-chrome scrollbar. The
|
|
52
|
+
useEdgeFade hook toggles data-edge-fade so an edge fades ONLY when content
|
|
53
|
+
is actually scrolled past it — never at rest — which keeps the first/last
|
|
54
|
+
card and the volume "Most popular" badge from ever being dimmed. Without JS
|
|
55
|
+
the list simply scrolls with no bar and no fade (a safe, quiet fallback). */
|
|
56
|
+
.lb-edge-fade {
|
|
57
|
+
scrollbar-width: none;
|
|
58
|
+
}
|
|
59
|
+
.lb-edge-fade::-webkit-scrollbar {
|
|
60
|
+
width: 0;
|
|
61
|
+
height: 0;
|
|
62
|
+
}
|
|
63
|
+
.lb-edge-fade[data-edge-fade="top"] {
|
|
64
|
+
-webkit-mask-image: linear-gradient(to bottom, transparent 0, #000 var(--lb-edge-fade-size));
|
|
65
|
+
mask-image: linear-gradient(to bottom, transparent 0, #000 var(--lb-edge-fade-size));
|
|
66
|
+
}
|
|
67
|
+
.lb-edge-fade[data-edge-fade="bottom"] {
|
|
68
|
+
-webkit-mask-image: linear-gradient(to top, transparent 0, #000 var(--lb-edge-fade-size));
|
|
69
|
+
mask-image: linear-gradient(to top, transparent 0, #000 var(--lb-edge-fade-size));
|
|
70
|
+
}
|
|
71
|
+
.lb-edge-fade[data-edge-fade="both"] {
|
|
72
|
+
-webkit-mask-image: linear-gradient(to bottom, transparent 0, #000 var(--lb-edge-fade-size), #000 calc(100% - var(--lb-edge-fade-size)), transparent 100%);
|
|
73
|
+
mask-image: linear-gradient(to bottom, transparent 0, #000 var(--lb-edge-fade-size), #000 calc(100% - var(--lb-edge-fade-size)), transparent 100%);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
.lb-bundle {
|
|
77
|
+
font-family: var(--lb-font-family);
|
|
78
|
+
font-size: var(--lb-font-size);
|
|
79
|
+
/* `--lb-text` is the merchant-driven body colour emitted by
|
|
80
|
+
useWidgetConfigVars; fall back to --lb-primary-color when the bundle
|
|
81
|
+
hasn't loaded yet. */
|
|
82
|
+
color: var(--lb-text, var(--lb-primary-color));
|
|
83
|
+
background: var(--lb-bg, var(--lb-background));
|
|
84
|
+
border: var(--lb-border-width, 1px) solid var(--lb-border, var(--lb-border-color));
|
|
85
|
+
border-radius: var(--lb-radius, var(--lb-border-radius));
|
|
86
|
+
padding: 20px;
|
|
87
|
+
box-sizing: border-box;
|
|
88
|
+
max-width: 440px;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/* General sibling combinator (`~`) rather than adjacent (`+`) so the
|
|
92
|
+
spacing still applies when other elements sit between rendered
|
|
93
|
+
<Bundle>s (e.g. wrapper divs or breadcrumb markup in the consumer
|
|
94
|
+
layout). Single-bundle pages stay unaffected. */
|
|
95
|
+
.lb-bundle ~ .lb-bundle {
|
|
96
|
+
margin-top: var(--lb-spacing-lg);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/* ───────────────────────────────────────────────────────────────────
|
|
100
|
+
* Header — a plain section-heading title block in the host theme's own
|
|
101
|
+
* type. No colored band, no full-bleed, no save-badge pill.
|
|
102
|
+
* ─────────────────────────────────────────────────────────────────── */
|
|
103
|
+
|
|
104
|
+
.lb-bundle-header {
|
|
105
|
+
margin: 0 0 16px;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
.lb-bundle-header__content {
|
|
109
|
+
min-width: 0;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
.lb-bundle-title {
|
|
113
|
+
/* Weight 600 (not 700): the receipt's sale price is the widget's heaviest,
|
|
114
|
+
largest element, so the title steps down to clear the hierarchy. */
|
|
115
|
+
font-size: 18px;
|
|
116
|
+
font-weight: 600;
|
|
117
|
+
line-height: 24px;
|
|
118
|
+
letter-spacing: -0.01em;
|
|
119
|
+
color: var(--lb-text, var(--lb-primary-color));
|
|
120
|
+
margin: 0;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
.lb-bundle-subtitle {
|
|
124
|
+
font-size: 14px;
|
|
125
|
+
font-weight: 400;
|
|
126
|
+
line-height: 20px;
|
|
127
|
+
color: color-mix(in srgb, var(--lb-text, var(--lb-primary-color)) 60%, transparent);
|
|
128
|
+
margin: 4px 0 0;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
.lb-bundle__instructions {
|
|
132
|
+
color: color-mix(in srgb, var(--lb-text, var(--lb-primary-color)) 60%, transparent);
|
|
133
|
+
margin: 0 0 var(--lb-spacing-md);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/* Divider */
|
|
137
|
+
.lb-bundle-divider {
|
|
138
|
+
height: var(--lb-border-width, 1px);
|
|
139
|
+
background: var(--lb-border, var(--lb-border-color));
|
|
140
|
+
margin: 16px 0;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/* ───────────────────────────────────────────────────────────────────
|
|
144
|
+
* Product list — manifest rows.
|
|
145
|
+
* ─────────────────────────────────────────────────────────────────── */
|
|
146
|
+
|
|
147
|
+
.lb-bundle__products {
|
|
148
|
+
display: flex;
|
|
149
|
+
flex-direction: column;
|
|
150
|
+
gap: 12px;
|
|
151
|
+
margin: 0;
|
|
152
|
+
max-height: var(--lb-list-max-height);
|
|
153
|
+
overflow-y: auto;
|
|
154
|
+
/* Scrollbar hidden + edge fade — see .lb-edge-fade above. */
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/* Both bundle types use the same card layout: a bordered row with a
|
|
158
|
+
thumbnail, an info column (name → variant → price → unit → pickers on the
|
|
159
|
+
inherited type), and a right-slot element. Fixed bundles can't remove items,
|
|
160
|
+
so their right slot is the quiet .lb-bundle-qty-chip (×N); mix & match puts a
|
|
161
|
+
remove × there instead. Mirrors the storefront theme widget
|
|
162
|
+
(extensions/bundle-theme/assets/bundle-fixed.css + bundle-mix-match.css). */
|
|
163
|
+
.lb-bundle-product-row {
|
|
164
|
+
display: flex;
|
|
165
|
+
gap: 12px;
|
|
166
|
+
align-items: flex-start;
|
|
167
|
+
padding: 8px;
|
|
168
|
+
border: var(--lb-border-width, 1px) solid var(--lb-border, var(--lb-border-color));
|
|
169
|
+
border-radius: var(--lb-radius, var(--lb-border-radius));
|
|
170
|
+
box-sizing: border-box;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/* Out-of-stock product row */
|
|
174
|
+
.lb-bundle-product-row--oos {
|
|
175
|
+
opacity: 0.5;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
.lb-bundle__product-image {
|
|
179
|
+
width: 60px;
|
|
180
|
+
min-width: 60px;
|
|
181
|
+
/* Aspect-ratio + object-fit derived from the merchant's
|
|
182
|
+
`productList.thumbnailRatio` enum, applied via useWidgetConfigVars().
|
|
183
|
+
Defaults preserve a square cover thumbnail. */
|
|
184
|
+
aspect-ratio: var(--lb-thumbnail-aspect-ratio, 1 / 1);
|
|
185
|
+
object-fit: var(--lb-thumbnail-img-fit, cover);
|
|
186
|
+
/* Thumbnails carry only the derived corner radius — no border. */
|
|
187
|
+
border-radius: var(--lb-radius-sm);
|
|
188
|
+
box-sizing: border-box;
|
|
189
|
+
flex-shrink: 0;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
/* Info column flows name → variant badge → prices → unit price → pickers on
|
|
193
|
+
the inherited type. */
|
|
194
|
+
.lb-bundle__product-info {
|
|
195
|
+
flex: 1;
|
|
196
|
+
min-width: 0;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
.lb-bundle__product-title {
|
|
200
|
+
margin: 0;
|
|
201
|
+
font-size: 16px;
|
|
202
|
+
font-weight: 600;
|
|
203
|
+
line-height: 20px;
|
|
204
|
+
color: var(--lb-text, var(--lb-primary-color));
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
/* Read-only variant text under the product name. */
|
|
208
|
+
.lb-bundle-variant-badge {
|
|
209
|
+
display: block;
|
|
210
|
+
font-size: 14px;
|
|
211
|
+
line-height: 20px;
|
|
212
|
+
margin-top: 2px;
|
|
213
|
+
color: color-mix(in srgb, var(--lb-text, var(--lb-primary-color)) 60%, transparent);
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
/* Price row — compare, price and inline "×N" share one line, unit price below. */
|
|
217
|
+
.lb-bundle-product-prices {
|
|
218
|
+
display: flex;
|
|
219
|
+
align-items: baseline;
|
|
220
|
+
gap: 6px;
|
|
221
|
+
flex-wrap: wrap;
|
|
222
|
+
margin-top: 4px;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
/* Quantity chip — the fixed card's right slot. A quiet, non-interactive count
|
|
226
|
+
(×N), deliberately border-less so it never reads as the mix & match remove
|
|
227
|
+
button. */
|
|
228
|
+
.lb-bundle-qty-chip {
|
|
229
|
+
flex-shrink: 0;
|
|
230
|
+
min-width: 34px;
|
|
231
|
+
height: 28px;
|
|
232
|
+
padding: 0 9px;
|
|
233
|
+
display: inline-flex;
|
|
234
|
+
align-items: center;
|
|
235
|
+
justify-content: center;
|
|
236
|
+
border-radius: var(--lb-radius-sm);
|
|
237
|
+
background: color-mix(in srgb, var(--lb-text, var(--lb-primary-color)) 7%, transparent);
|
|
238
|
+
color: color-mix(in srgb, var(--lb-text, var(--lb-primary-color)) 75%, transparent);
|
|
239
|
+
font-size: 14px;
|
|
240
|
+
font-weight: 500;
|
|
241
|
+
line-height: 1;
|
|
242
|
+
font-variant-numeric: tabular-nums;
|
|
243
|
+
white-space: nowrap;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
.lb-bundle__product-price {
|
|
247
|
+
display: var(--lb-product-price-display, block);
|
|
248
|
+
font-size: 14px;
|
|
249
|
+
font-weight: 400;
|
|
250
|
+
line-height: 20px;
|
|
251
|
+
color: var(--lb-text, var(--lb-primary-color));
|
|
252
|
+
font-variant-numeric: tabular-nums;
|
|
253
|
+
margin: 0;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
.lb-bundle-product-compare-price {
|
|
257
|
+
display: var(--lb-product-compare-display, inline);
|
|
258
|
+
font-size: 14px;
|
|
259
|
+
font-weight: 400;
|
|
260
|
+
line-height: 20px;
|
|
261
|
+
color: color-mix(in srgb, var(--lb-text, var(--lb-primary-color)) 60%, transparent);
|
|
262
|
+
text-decoration: line-through;
|
|
263
|
+
font-variant-numeric: tabular-nums;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
.lb-bundle__product-unit-price {
|
|
267
|
+
display: block;
|
|
268
|
+
font-size: 12px;
|
|
269
|
+
line-height: 16px;
|
|
270
|
+
color: color-mix(in srgb, var(--lb-text, var(--lb-primary-color)) 60%, transparent);
|
|
271
|
+
margin: 2px 0 0;
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
/* Inline quantity — "×2" beside the product price (mix & match chosen-product
|
|
275
|
+
cards). Quiet, theme-inherited; the fixed card uses .lb-bundle-qty-chip in the
|
|
276
|
+
card's right slot instead. */
|
|
277
|
+
.lb-bundle-qty-inline {
|
|
278
|
+
font-size: 13px;
|
|
279
|
+
font-weight: 400;
|
|
280
|
+
margin-left: 5px;
|
|
281
|
+
color: color-mix(in srgb, var(--lb-text, var(--lb-primary-color)) 55%, transparent);
|
|
282
|
+
font-variant-numeric: tabular-nums;
|
|
283
|
+
white-space: nowrap;
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
.lb-bundle-oos-label {
|
|
287
|
+
font-size: 12px;
|
|
288
|
+
font-weight: 500;
|
|
289
|
+
color: var(--lb-low-stock-text, var(--lb-error-color));
|
|
290
|
+
white-space: nowrap;
|
|
291
|
+
margin-left: auto;
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
.lb-bundle__product-variant-pickers {
|
|
295
|
+
display: flex;
|
|
296
|
+
flex-direction: column;
|
|
297
|
+
gap: 8px;
|
|
298
|
+
margin-top: 8px;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
/* "Only X left" low-stock badge */
|
|
302
|
+
.lb-bundle-low-stock-badge {
|
|
303
|
+
display: inline-flex;
|
|
304
|
+
align-items: center;
|
|
305
|
+
gap: 4px;
|
|
306
|
+
margin-top: 4px;
|
|
307
|
+
padding: 2px 8px;
|
|
308
|
+
font-size: 11px;
|
|
309
|
+
font-weight: 600;
|
|
310
|
+
line-height: 1.4;
|
|
311
|
+
color: var(--lb-low-stock-text, var(--lb-error-color));
|
|
312
|
+
background-color: var(--lb-low-stock-bg, #fef3c7);
|
|
313
|
+
border-radius: 4px;
|
|
314
|
+
white-space: nowrap;
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
/* ───────────────────────────────────────────────────────────────────
|
|
318
|
+
* Mix-and-match — modal-based picker UX.
|
|
319
|
+
*
|
|
320
|
+
* Ported one-for-one from the storefront theme widget
|
|
321
|
+
* (extensions/bundle-theme/assets/bundle-mix-match.css). The shopper picks
|
|
322
|
+
* distinct products from a portaled modal; chosen products render as cards
|
|
323
|
+
* with a segmented progress bar above and a receipt summary below.
|
|
324
|
+
*
|
|
325
|
+
* Var convention follows this stylesheet: merchant-configurable colours use
|
|
326
|
+
* `var(--lb-text, var(--lb-primary-color))`; `--lb-border` / `--lb-radius`
|
|
327
|
+
* fall back to `--lb-border-color` / `--lb-border-radius`. The picker
|
|
328
|
+
* (`--lb-picker-*`) vars are emitted by useWidgetConfigVars onto both the
|
|
329
|
+
* widget root and the portaled modal overlay.
|
|
330
|
+
* ─────────────────────────────────────────────────────────────────── */
|
|
331
|
+
|
|
332
|
+
/* Screen-reader-only live regions inside the modal. */
|
|
333
|
+
.lb-visually-hidden {
|
|
334
|
+
position: absolute;
|
|
335
|
+
width: 1px;
|
|
336
|
+
height: 1px;
|
|
337
|
+
padding: 0;
|
|
338
|
+
margin: -1px;
|
|
339
|
+
overflow: hidden;
|
|
340
|
+
clip: rect(0, 0, 0, 0);
|
|
341
|
+
white-space: nowrap;
|
|
342
|
+
border: 0;
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
/* === Chosen-product card list ============================================ */
|
|
346
|
+
.lb-mix-match__slots {
|
|
347
|
+
display: flex;
|
|
348
|
+
flex-direction: column;
|
|
349
|
+
gap: 12px;
|
|
350
|
+
max-height: var(--lb-list-max-height);
|
|
351
|
+
overflow-y: auto;
|
|
352
|
+
/* Scrollbar hidden + edge fade — see .lb-edge-fade above. */
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
.lb-mix-match__slots:empty {
|
|
356
|
+
display: none;
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
/* === Segmented progress bar ============================================== */
|
|
360
|
+
.lb-mix-match__progress {
|
|
361
|
+
margin-bottom: 16px;
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
.lb-mix-match__progress-segments {
|
|
365
|
+
display: flex;
|
|
366
|
+
gap: 6px;
|
|
367
|
+
width: 100%;
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
.lb-mix-match__progress-segment {
|
|
371
|
+
flex: 1;
|
|
372
|
+
height: 6px;
|
|
373
|
+
/* Follows the global radius (like the widget's other small elements); the
|
|
374
|
+
modal override below switches it to the picker radius. Capped by the 6px
|
|
375
|
+
height, so it reads as a pill until the merchant picks a tighter radius. */
|
|
376
|
+
border-radius: var(--lb-radius-sm);
|
|
377
|
+
background: color-mix(in srgb, var(--lb-text, var(--lb-primary-color)) 12%, transparent);
|
|
378
|
+
transition: background 0.25s ease;
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
.lb-mix-match__progress-segment--filled {
|
|
382
|
+
background: var(--lb-text, var(--lb-primary-color));
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
.lb-mix-match__progress-labels {
|
|
386
|
+
display: flex;
|
|
387
|
+
justify-content: space-between;
|
|
388
|
+
margin-top: 8px;
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
.lb-mix-match__progress-count {
|
|
392
|
+
font-size: 12px;
|
|
393
|
+
font-weight: 500;
|
|
394
|
+
line-height: 16px;
|
|
395
|
+
color: color-mix(in srgb, var(--lb-text, var(--lb-primary-color)) 60%, transparent);
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
.lb-mix-match__progress-remaining {
|
|
399
|
+
font-size: 12px;
|
|
400
|
+
font-weight: 500;
|
|
401
|
+
line-height: 16px;
|
|
402
|
+
color: var(--lb-text, var(--lb-primary-color));
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
.lb-mix-match__modal-progress {
|
|
406
|
+
margin: 0;
|
|
407
|
+
padding: 0;
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
/* The modal's progress segments follow the picker radius, not the global one. */
|
|
411
|
+
.lb-mix-match__modal-progress .lb-mix-match__progress-segment {
|
|
412
|
+
border-radius: var(--lb-picker-radius-sm);
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
/* === Chosen-product cards =============================================== */
|
|
416
|
+
.lb-mix-match__slot--filled {
|
|
417
|
+
display: flex;
|
|
418
|
+
align-items: center;
|
|
419
|
+
gap: 12px;
|
|
420
|
+
padding: 8px;
|
|
421
|
+
border: var(--lb-border-width, 1px) solid var(--lb-border, var(--lb-border-color));
|
|
422
|
+
border-radius: var(--lb-radius, var(--lb-border-radius));
|
|
423
|
+
box-sizing: border-box;
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
.lb-mix-match .lb-bundle-thumbnail {
|
|
427
|
+
position: relative;
|
|
428
|
+
width: 60px;
|
|
429
|
+
min-width: 60px;
|
|
430
|
+
/* Thumbnails carry only the derived corner radius — no border. */
|
|
431
|
+
border-radius: var(--lb-radius-sm);
|
|
432
|
+
box-sizing: border-box;
|
|
433
|
+
flex-shrink: 0;
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
.lb-mix-match .lb-bundle-thumbnail img {
|
|
437
|
+
width: 100%;
|
|
438
|
+
aspect-ratio: var(--lb-thumbnail-aspect-ratio, 1 / 1);
|
|
439
|
+
object-fit: var(--lb-thumbnail-img-fit, cover);
|
|
440
|
+
border-radius: var(--lb-radius-sm);
|
|
441
|
+
border: none;
|
|
442
|
+
display: block;
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
.lb-mix-match__slot--filled .lb-mix-match__filled-info {
|
|
446
|
+
flex: 1;
|
|
447
|
+
min-width: 0;
|
|
448
|
+
display: flex;
|
|
449
|
+
flex-direction: column;
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
.lb-mix-match__slot--filled .lb-mix-match__filled-title {
|
|
453
|
+
font-size: 16px;
|
|
454
|
+
font-weight: 600;
|
|
455
|
+
line-height: 20px;
|
|
456
|
+
color: var(--lb-text, var(--lb-primary-color));
|
|
457
|
+
text-decoration: none;
|
|
458
|
+
overflow-wrap: break-word;
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
.lb-mix-match__slot--filled a.lb-mix-match__filled-title:hover {
|
|
462
|
+
text-decoration: underline;
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
.lb-mix-match__slot--filled a.lb-mix-match__filled-title:focus-visible {
|
|
466
|
+
outline: 2px solid var(--lb-primary-color);
|
|
467
|
+
outline-offset: 2px;
|
|
468
|
+
box-shadow: none;
|
|
469
|
+
border-radius: 2px;
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
.lb-mix-match__filled-variant {
|
|
473
|
+
display: block;
|
|
474
|
+
font-size: 14px;
|
|
475
|
+
line-height: 20px;
|
|
476
|
+
margin-top: 2px;
|
|
477
|
+
color: color-mix(in srgb, var(--lb-text, var(--lb-primary-color)) 60%, transparent);
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
.lb-mix-match__slot--filled .lb-mix-match__filled-price {
|
|
481
|
+
display: var(--lb-product-price-display, block);
|
|
482
|
+
font-size: 14px;
|
|
483
|
+
line-height: 20px;
|
|
484
|
+
margin-top: 2px;
|
|
485
|
+
color: var(--lb-text, var(--lb-primary-color));
|
|
486
|
+
font-weight: 500;
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
.lb-mix-match__filled-compare {
|
|
490
|
+
display: var(--lb-product-compare-display, inline);
|
|
491
|
+
font-size: 14px;
|
|
492
|
+
font-weight: 400;
|
|
493
|
+
color: color-mix(in srgb, var(--lb-text, var(--lb-primary-color)) 60%, transparent);
|
|
494
|
+
text-decoration: line-through;
|
|
495
|
+
margin-right: 4px;
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
.lb-mix-match__slot--filled .lb-bundle-product-unit-price {
|
|
499
|
+
display: block;
|
|
500
|
+
font-size: 12px;
|
|
501
|
+
line-height: 16px;
|
|
502
|
+
color: color-mix(in srgb, var(--lb-text, var(--lb-primary-color)) 60%, transparent);
|
|
503
|
+
margin-top: 2px;
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
.lb-mix-match__slot-remove {
|
|
507
|
+
flex-shrink: 0;
|
|
508
|
+
width: 36px;
|
|
509
|
+
height: 36px;
|
|
510
|
+
min-width: 36px;
|
|
511
|
+
display: flex;
|
|
512
|
+
align-items: center;
|
|
513
|
+
justify-content: center;
|
|
514
|
+
background: none;
|
|
515
|
+
border: var(--lb-border-width, 1px) solid var(--lb-border, var(--lb-border-color));
|
|
516
|
+
border-radius: var(--lb-radius, var(--lb-border-radius));
|
|
517
|
+
cursor: pointer;
|
|
518
|
+
color: var(--lb-text, var(--lb-primary-color));
|
|
519
|
+
padding: 0;
|
|
520
|
+
margin-left: auto;
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
.lb-mix-match__slot-remove:hover {
|
|
524
|
+
background: color-mix(in srgb, var(--lb-text, var(--lb-primary-color)) 6%, transparent);
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
.lb-mix-match__slot-remove:focus-visible {
|
|
528
|
+
outline: 2px solid var(--lb-primary-color);
|
|
529
|
+
outline-offset: -2px;
|
|
530
|
+
box-shadow: none;
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
/* === Dashed "Add a product" slot ======================================= */
|
|
534
|
+
.lb-mix-match__add-product {
|
|
535
|
+
display: flex;
|
|
536
|
+
align-items: center;
|
|
537
|
+
gap: 12px;
|
|
538
|
+
width: 100%;
|
|
539
|
+
margin-top: 12px;
|
|
540
|
+
padding: 8px;
|
|
541
|
+
background: none;
|
|
542
|
+
border: 1px dashed color-mix(in srgb, var(--lb-text, var(--lb-primary-color)) 28%, transparent);
|
|
543
|
+
border-radius: var(--lb-radius, var(--lb-border-radius));
|
|
544
|
+
color: color-mix(in srgb, var(--lb-text, var(--lb-primary-color)) 75%, transparent);
|
|
545
|
+
font-family: inherit;
|
|
546
|
+
font-size: 15px;
|
|
547
|
+
font-weight: 500;
|
|
548
|
+
line-height: 1.2;
|
|
549
|
+
text-align: left;
|
|
550
|
+
cursor: pointer;
|
|
551
|
+
box-sizing: border-box;
|
|
552
|
+
transition: border-color 0.15s ease, color 0.15s ease;
|
|
553
|
+
}
|
|
554
|
+
|
|
555
|
+
.lb-mix-match__add-product:hover {
|
|
556
|
+
border-color: color-mix(in srgb, var(--lb-text, var(--lb-primary-color)) 45%, transparent);
|
|
557
|
+
color: var(--lb-text, var(--lb-primary-color));
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
.lb-mix-match__add-product:focus-visible {
|
|
561
|
+
outline: 2px solid var(--lb-primary-color);
|
|
562
|
+
outline-offset: 2px;
|
|
563
|
+
box-shadow: none;
|
|
564
|
+
}
|
|
565
|
+
|
|
566
|
+
.lb-mix-match__add-product-icon {
|
|
567
|
+
display: flex;
|
|
568
|
+
align-items: center;
|
|
569
|
+
justify-content: center;
|
|
570
|
+
width: 60px;
|
|
571
|
+
min-width: 60px;
|
|
572
|
+
height: 40px;
|
|
573
|
+
flex-shrink: 0;
|
|
574
|
+
color: inherit;
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
/* === Variant option groups (shared with picker rows) =================== */
|
|
578
|
+
.lb-bundle-variant-option-groups {
|
|
579
|
+
display: flex;
|
|
580
|
+
flex-direction: column;
|
|
581
|
+
gap: 8px;
|
|
582
|
+
margin-top: 8px;
|
|
583
|
+
}
|
|
584
|
+
|
|
585
|
+
.lb-bundle-variant-option-group {
|
|
586
|
+
display: flex;
|
|
587
|
+
flex-direction: column;
|
|
588
|
+
gap: 2px;
|
|
589
|
+
}
|
|
590
|
+
|
|
591
|
+
.lb-bundle-variant-option-label {
|
|
592
|
+
font-size: 12px;
|
|
593
|
+
font-weight: 500;
|
|
594
|
+
color: color-mix(in srgb, var(--lb-text, var(--lb-primary-color)) 70%, transparent);
|
|
595
|
+
}
|
|
596
|
+
|
|
597
|
+
/* Derived "small" radius for the picker's inner controls (search, thumbnails,
|
|
598
|
+
variant select, qty stepper, Add/Done buttons), one step tighter than the
|
|
599
|
+
modal's --lb-picker-radius — the picker-scoped mirror of --lb-radius-sm in
|
|
600
|
+
the main widget. Defined on the overlay (which carries data-modal-overlay)
|
|
601
|
+
so the modal AND any portaled child inherit it; --lb-picker-radius is
|
|
602
|
+
emitted onto this element by useWidgetConfigVars. The modal shell and
|
|
603
|
+
product tiles keep the full --lb-picker-radius. Falls back to 16px to match
|
|
604
|
+
the rest of the picker rules until the bundle config has loaded. */
|
|
605
|
+
[data-modal-overlay] {
|
|
606
|
+
--lb-picker-radius-sm: max(0px, calc(var(--lb-picker-radius, 16px) - 4px));
|
|
607
|
+
}
|
|
608
|
+
|
|
609
|
+
/* === Modal overlay ===================================================== */
|
|
610
|
+
.lb-mix-match__modal-overlay {
|
|
611
|
+
position: fixed;
|
|
612
|
+
top: 0;
|
|
613
|
+
left: 0;
|
|
614
|
+
right: 0;
|
|
615
|
+
bottom: 0;
|
|
616
|
+
background: rgba(0, 0, 0, 0.5);
|
|
617
|
+
z-index: 9999;
|
|
618
|
+
display: flex;
|
|
619
|
+
align-items: center;
|
|
620
|
+
justify-content: center;
|
|
621
|
+
opacity: 0;
|
|
622
|
+
transition: opacity 0.2s ease-out;
|
|
623
|
+
font-family: var(--lb-font-family);
|
|
624
|
+
}
|
|
625
|
+
|
|
626
|
+
.lb-mix-match__modal-overlay--open {
|
|
627
|
+
opacity: 1;
|
|
628
|
+
}
|
|
629
|
+
|
|
630
|
+
/* === Modal panel ====================================================== */
|
|
631
|
+
.lb-mix-match__modal {
|
|
632
|
+
background: var(--lb-picker-bg, var(--lb-bg, var(--lb-background)));
|
|
633
|
+
color: var(--lb-picker-text, var(--lb-text, var(--lb-primary-color)));
|
|
634
|
+
border-radius: var(--lb-picker-radius, 16px);
|
|
635
|
+
border: var(--lb-picker-border-width, 0px) solid var(--lb-picker-border-color, var(--lb-border-color));
|
|
636
|
+
box-sizing: border-box;
|
|
637
|
+
width: 100%;
|
|
638
|
+
max-width: 520px;
|
|
639
|
+
max-height: 70vh;
|
|
640
|
+
display: flex;
|
|
641
|
+
flex-direction: column;
|
|
642
|
+
overflow: hidden;
|
|
643
|
+
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.16);
|
|
644
|
+
transform: translateY(24px);
|
|
645
|
+
transition: transform 0.25s ease-out;
|
|
646
|
+
will-change: transform;
|
|
647
|
+
}
|
|
648
|
+
|
|
649
|
+
.lb-mix-match__modal-overlay--open .lb-mix-match__modal {
|
|
650
|
+
transform: translateY(0);
|
|
651
|
+
}
|
|
652
|
+
|
|
653
|
+
/* === Modal header ===================================================== */
|
|
654
|
+
.lb-mix-match__modal-header {
|
|
655
|
+
display: flex;
|
|
656
|
+
flex-direction: column;
|
|
657
|
+
gap: 16px;
|
|
658
|
+
padding: 20px;
|
|
659
|
+
border-bottom: 1px solid color-mix(in srgb, var(--lb-picker-text, var(--lb-text, var(--lb-primary-color))) 15%, transparent);
|
|
660
|
+
flex-shrink: 0;
|
|
661
|
+
}
|
|
662
|
+
|
|
663
|
+
.lb-mix-match__modal-header-top {
|
|
664
|
+
display: flex;
|
|
665
|
+
align-items: flex-start;
|
|
666
|
+
justify-content: space-between;
|
|
667
|
+
gap: 12px;
|
|
668
|
+
}
|
|
669
|
+
|
|
670
|
+
.lb-mix-match__modal-heading {
|
|
671
|
+
min-width: 0;
|
|
672
|
+
}
|
|
673
|
+
|
|
674
|
+
.lb-mix-match__modal-title {
|
|
675
|
+
font-size: 20px;
|
|
676
|
+
font-weight: 600;
|
|
677
|
+
line-height: 24px;
|
|
678
|
+
margin: 0;
|
|
679
|
+
color: inherit;
|
|
680
|
+
}
|
|
681
|
+
|
|
682
|
+
.lb-mix-match__modal-subtitle {
|
|
683
|
+
margin: 4px 0 0;
|
|
684
|
+
font-size: 13px;
|
|
685
|
+
line-height: 18px;
|
|
686
|
+
color: color-mix(in srgb, var(--lb-picker-text, var(--lb-text, var(--lb-primary-color))) 60%, transparent);
|
|
687
|
+
}
|
|
688
|
+
|
|
689
|
+
.lb-mix-match__modal-subtitle:empty {
|
|
690
|
+
display: none;
|
|
691
|
+
}
|
|
692
|
+
|
|
693
|
+
.lb-mix-match__modal-close {
|
|
694
|
+
min-width: 44px;
|
|
695
|
+
min-height: 44px;
|
|
696
|
+
display: flex;
|
|
697
|
+
align-items: center;
|
|
698
|
+
justify-content: center;
|
|
699
|
+
background: none;
|
|
700
|
+
border: none;
|
|
701
|
+
cursor: pointer;
|
|
702
|
+
color: var(--lb-picker-text, var(--lb-text, var(--lb-primary-color)));
|
|
703
|
+
border-radius: 8px;
|
|
704
|
+
padding: 0;
|
|
705
|
+
margin: -12px -12px 0 0;
|
|
706
|
+
}
|
|
707
|
+
|
|
708
|
+
.lb-mix-match__modal-close:focus-visible {
|
|
709
|
+
outline: 2px solid var(--lb-primary-color);
|
|
710
|
+
outline-offset: 0;
|
|
711
|
+
box-shadow: none;
|
|
712
|
+
}
|
|
713
|
+
|
|
714
|
+
/* === Filter pills ===================================================== */
|
|
715
|
+
.lb-mix-match__filters {
|
|
716
|
+
display: flex;
|
|
717
|
+
flex-wrap: wrap;
|
|
718
|
+
gap: 8px;
|
|
719
|
+
padding: 16px 20px 16px;
|
|
720
|
+
flex-shrink: 0;
|
|
721
|
+
}
|
|
722
|
+
|
|
723
|
+
.lb-mix-match__filter {
|
|
724
|
+
padding: 6px 14px;
|
|
725
|
+
border: var(--lb-picker-border-width, 0px) solid var(--lb-picker-border-color, var(--lb-border-color));
|
|
726
|
+
border-radius: 999px;
|
|
727
|
+
background: transparent;
|
|
728
|
+
color: var(--lb-picker-text, var(--lb-text, var(--lb-primary-color)));
|
|
729
|
+
font-family: inherit;
|
|
730
|
+
font-size: 13px;
|
|
731
|
+
font-weight: 500;
|
|
732
|
+
line-height: 1;
|
|
733
|
+
cursor: pointer;
|
|
734
|
+
white-space: nowrap;
|
|
735
|
+
}
|
|
736
|
+
|
|
737
|
+
.lb-mix-match__filter:focus-visible {
|
|
738
|
+
outline: 2px solid var(--lb-primary-color);
|
|
739
|
+
outline-offset: 2px;
|
|
740
|
+
box-shadow: none;
|
|
741
|
+
}
|
|
742
|
+
|
|
743
|
+
.lb-mix-match__filter--active {
|
|
744
|
+
background: #1a1a1a;
|
|
745
|
+
border-color: #1a1a1a;
|
|
746
|
+
color: #ffffff;
|
|
747
|
+
}
|
|
748
|
+
|
|
749
|
+
/* === Modal search ===================================================== */
|
|
750
|
+
.lb-mix-match__modal-search {
|
|
751
|
+
padding: 16px 20px 0;
|
|
752
|
+
position: relative;
|
|
753
|
+
flex-shrink: 0;
|
|
754
|
+
}
|
|
755
|
+
|
|
756
|
+
.lb-mix-match__modal-search::before {
|
|
757
|
+
content: "";
|
|
758
|
+
position: absolute;
|
|
759
|
+
left: 36px;
|
|
760
|
+
top: 16px;
|
|
761
|
+
bottom: 0;
|
|
762
|
+
width: 18px;
|
|
763
|
+
background-color: color-mix(in srgb, var(--lb-picker-text, var(--lb-text, var(--lb-primary-color))) 60%, transparent);
|
|
764
|
+
-webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M10 10m-7 0a7 7 0 1 0 14 0a7 7 0 1 0 -14 0'/%3E%3Cpath d='M21 21l-6 -6'/%3E%3C/svg%3E") center / 18px no-repeat;
|
|
765
|
+
mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M10 10m-7 0a7 7 0 1 0 14 0a7 7 0 1 0 -14 0'/%3E%3Cpath d='M21 21l-6 -6'/%3E%3C/svg%3E") center / 18px no-repeat;
|
|
766
|
+
pointer-events: none;
|
|
767
|
+
}
|
|
768
|
+
|
|
769
|
+
.lb-mix-match__modal-search-input {
|
|
770
|
+
width: 100%;
|
|
771
|
+
padding: 12px 40px 12px 44px;
|
|
772
|
+
border: var(--lb-picker-border-width, 0px) solid var(--lb-picker-border-color, var(--lb-border-color));
|
|
773
|
+
border-radius: var(--lb-picker-radius-sm);
|
|
774
|
+
font-size: 16px;
|
|
775
|
+
line-height: 20px;
|
|
776
|
+
color: var(--lb-picker-text, var(--lb-text, var(--lb-primary-color)));
|
|
777
|
+
background-color: var(--lb-picker-bg, var(--lb-bg, var(--lb-background)));
|
|
778
|
+
box-sizing: border-box;
|
|
779
|
+
-webkit-appearance: none;
|
|
780
|
+
appearance: none;
|
|
781
|
+
font-family: inherit;
|
|
782
|
+
}
|
|
783
|
+
|
|
784
|
+
.lb-mix-match__modal-search-input::placeholder {
|
|
785
|
+
color: color-mix(in srgb, var(--lb-picker-text, var(--lb-text, var(--lb-primary-color))) 50%, transparent);
|
|
786
|
+
}
|
|
787
|
+
|
|
788
|
+
.lb-mix-match__modal-search-input:focus-visible {
|
|
789
|
+
outline: 2px solid var(--lb-primary-color);
|
|
790
|
+
outline-offset: 2px;
|
|
791
|
+
box-shadow: none;
|
|
792
|
+
}
|
|
793
|
+
|
|
794
|
+
.lb-mix-match__modal-search-clear {
|
|
795
|
+
position: absolute;
|
|
796
|
+
right: 32px;
|
|
797
|
+
top: 16px;
|
|
798
|
+
bottom: 0;
|
|
799
|
+
min-width: 32px;
|
|
800
|
+
min-height: 32px;
|
|
801
|
+
display: flex;
|
|
802
|
+
align-items: center;
|
|
803
|
+
justify-content: center;
|
|
804
|
+
background: none;
|
|
805
|
+
border: none;
|
|
806
|
+
cursor: pointer;
|
|
807
|
+
color: color-mix(in srgb, var(--lb-picker-text, var(--lb-text, var(--lb-primary-color))) 60%, transparent);
|
|
808
|
+
padding: 0;
|
|
809
|
+
}
|
|
810
|
+
|
|
811
|
+
.lb-mix-match__modal--filters-hidden .lb-mix-match__modal-search {
|
|
812
|
+
padding-bottom: 16px;
|
|
813
|
+
}
|
|
814
|
+
|
|
815
|
+
.lb-mix-match__modal--filters-hidden .lb-mix-match__modal-search::before,
|
|
816
|
+
.lb-mix-match__modal--filters-hidden .lb-mix-match__modal-search-clear {
|
|
817
|
+
bottom: 16px;
|
|
818
|
+
}
|
|
819
|
+
|
|
820
|
+
/* === Modal product grid =============================================== */
|
|
821
|
+
.lb-mix-match__modal-list {
|
|
822
|
+
overflow-y: auto;
|
|
823
|
+
flex: 1;
|
|
824
|
+
padding: 8px 20px 20px;
|
|
825
|
+
-webkit-overflow-scrolling: touch;
|
|
826
|
+
display: grid;
|
|
827
|
+
grid-template-columns: repeat(2, minmax(0, 1fr));
|
|
828
|
+
column-gap: 24px;
|
|
829
|
+
row-gap: 28px;
|
|
830
|
+
align-content: start;
|
|
831
|
+
}
|
|
832
|
+
|
|
833
|
+
.lb-mix-match__modal-header + .lb-mix-match__modal-list {
|
|
834
|
+
padding-top: 16px;
|
|
835
|
+
}
|
|
836
|
+
|
|
837
|
+
.lb-mix-match__modal-product {
|
|
838
|
+
display: flex;
|
|
839
|
+
flex-direction: column;
|
|
840
|
+
padding: 8px;
|
|
841
|
+
border: var(--lb-picker-border-width, 0px) solid var(--lb-picker-border-color, var(--lb-border-color));
|
|
842
|
+
border-radius: var(--lb-picker-radius, 16px);
|
|
843
|
+
box-sizing: border-box;
|
|
844
|
+
transition: border-color 0.15s ease, background 0.15s ease;
|
|
845
|
+
}
|
|
846
|
+
|
|
847
|
+
.lb-mix-match__modal-product-thumb {
|
|
848
|
+
width: 100%;
|
|
849
|
+
aspect-ratio: var(--lb-picker-thumbnail-aspect-ratio, 1 / 1);
|
|
850
|
+
/* Thumbnails carry only the picker corner radius — no border. */
|
|
851
|
+
border-radius: var(--lb-picker-radius-sm);
|
|
852
|
+
box-sizing: border-box;
|
|
853
|
+
overflow: hidden;
|
|
854
|
+
background: var(--lb-thumbnail-bg, transparent);
|
|
855
|
+
margin-bottom: 10px;
|
|
856
|
+
}
|
|
857
|
+
|
|
858
|
+
.lb-mix-match__modal-product-thumb img {
|
|
859
|
+
width: 100%;
|
|
860
|
+
height: var(--lb-picker-thumbnail-img-height, 100%);
|
|
861
|
+
object-fit: var(--lb-picker-thumbnail-img-fit, cover);
|
|
862
|
+
border-radius: var(--lb-picker-radius-sm);
|
|
863
|
+
display: block;
|
|
864
|
+
}
|
|
865
|
+
|
|
866
|
+
.lb-mix-match__modal-product-info {
|
|
867
|
+
flex: 1;
|
|
868
|
+
min-width: 0;
|
|
869
|
+
}
|
|
870
|
+
|
|
871
|
+
.lb-mix-match__modal-product-title {
|
|
872
|
+
font-size: 16px;
|
|
873
|
+
font-weight: 600;
|
|
874
|
+
line-height: 20px;
|
|
875
|
+
color: inherit;
|
|
876
|
+
margin: 0;
|
|
877
|
+
}
|
|
878
|
+
|
|
879
|
+
.lb-mix-match__modal-product-price {
|
|
880
|
+
display: flex;
|
|
881
|
+
align-items: baseline;
|
|
882
|
+
gap: 6px;
|
|
883
|
+
font-size: 14px;
|
|
884
|
+
line-height: 20px;
|
|
885
|
+
color: inherit;
|
|
886
|
+
margin: 2px 0 0;
|
|
887
|
+
}
|
|
888
|
+
|
|
889
|
+
.lb-mix-match__modal-product-compare {
|
|
890
|
+
display: var(--lb-product-compare-display, inline);
|
|
891
|
+
font-size: 13px;
|
|
892
|
+
font-weight: 400;
|
|
893
|
+
color: color-mix(in srgb, var(--lb-picker-text, var(--lb-text, var(--lb-primary-color))) 55%, transparent);
|
|
894
|
+
text-decoration: line-through;
|
|
895
|
+
}
|
|
896
|
+
|
|
897
|
+
.lb-mix-match__modal-product-unit-price {
|
|
898
|
+
font-size: 12px;
|
|
899
|
+
line-height: 16px;
|
|
900
|
+
color: color-mix(in srgb, var(--lb-picker-text, var(--lb-text, var(--lb-primary-color))) 60%, transparent);
|
|
901
|
+
margin: 2px 0 0;
|
|
902
|
+
}
|
|
903
|
+
|
|
904
|
+
.lb-mix-match__variant-select-dropdown {
|
|
905
|
+
font-size: 12px;
|
|
906
|
+
}
|
|
907
|
+
|
|
908
|
+
/* Per-pick quantity stepper. */
|
|
909
|
+
.lb-mix-match__qty-stepper-group {
|
|
910
|
+
flex-direction: row;
|
|
911
|
+
width: fit-content;
|
|
912
|
+
}
|
|
913
|
+
|
|
914
|
+
.lb-mix-match__qty-stepper {
|
|
915
|
+
display: inline-flex;
|
|
916
|
+
align-items: center;
|
|
917
|
+
justify-content: space-between;
|
|
918
|
+
width: 100%;
|
|
919
|
+
flex-shrink: 0;
|
|
920
|
+
border: var(--lb-picker-border-width, 0px) solid var(--lb-picker-border-color, var(--lb-border-color));
|
|
921
|
+
border-radius: var(--lb-picker-radius-sm);
|
|
922
|
+
background-color: var(--lb-picker-bg, var(--lb-bg, var(--lb-background)));
|
|
923
|
+
overflow: hidden;
|
|
924
|
+
box-sizing: border-box;
|
|
925
|
+
min-height: 32px;
|
|
926
|
+
max-height: 32px;
|
|
927
|
+
}
|
|
928
|
+
|
|
929
|
+
.lb-mix-match__qty-stepper-button {
|
|
930
|
+
appearance: none;
|
|
931
|
+
-webkit-appearance: none;
|
|
932
|
+
background: transparent;
|
|
933
|
+
border: none;
|
|
934
|
+
margin: 0;
|
|
935
|
+
padding: 0 4px;
|
|
936
|
+
width: 24px;
|
|
937
|
+
height: 24px;
|
|
938
|
+
box-sizing: border-box;
|
|
939
|
+
font-family: inherit;
|
|
940
|
+
font-size: 16px;
|
|
941
|
+
font-weight: 500;
|
|
942
|
+
line-height: 1;
|
|
943
|
+
color: var(--lb-picker-text, var(--lb-text, var(--lb-primary-color)));
|
|
944
|
+
cursor: pointer;
|
|
945
|
+
display: inline-flex;
|
|
946
|
+
align-items: center;
|
|
947
|
+
justify-content: center;
|
|
948
|
+
}
|
|
949
|
+
|
|
950
|
+
.lb-mix-match__qty-stepper-button:focus-visible {
|
|
951
|
+
outline: 2px solid var(--lb-primary-color);
|
|
952
|
+
outline-offset: -2px;
|
|
953
|
+
box-shadow: none;
|
|
954
|
+
}
|
|
955
|
+
|
|
956
|
+
.lb-mix-match__qty-stepper-button:disabled {
|
|
957
|
+
opacity: 0.4;
|
|
958
|
+
cursor: not-allowed;
|
|
959
|
+
}
|
|
960
|
+
|
|
961
|
+
.lb-mix-match__qty-stepper-value {
|
|
962
|
+
display: inline-flex;
|
|
963
|
+
align-items: center;
|
|
964
|
+
justify-content: center;
|
|
965
|
+
width: 24px;
|
|
966
|
+
height: 24px;
|
|
967
|
+
font-family: inherit;
|
|
968
|
+
font-size: 13px;
|
|
969
|
+
font-weight: 500;
|
|
970
|
+
color: var(--lb-picker-text, var(--lb-text, var(--lb-primary-color)));
|
|
971
|
+
box-sizing: border-box;
|
|
972
|
+
font-variant-numeric: tabular-nums;
|
|
973
|
+
}
|
|
974
|
+
|
|
975
|
+
.lb-mix-match__modal-product-actions {
|
|
976
|
+
display: flex;
|
|
977
|
+
flex-wrap: wrap;
|
|
978
|
+
align-items: stretch;
|
|
979
|
+
row-gap: 8px;
|
|
980
|
+
column-gap: 8px;
|
|
981
|
+
margin-top: 12px;
|
|
982
|
+
}
|
|
983
|
+
|
|
984
|
+
.lb-mix-match__modal-add {
|
|
985
|
+
flex: 1;
|
|
986
|
+
padding: 8px 16px;
|
|
987
|
+
background: var(--lb-picker-add-bg, var(--lb-primary-color));
|
|
988
|
+
color: var(--lb-picker-add-label, #fff);
|
|
989
|
+
border: var(--lb-picker-add-border-width, 0px) solid var(--lb-picker-add-border-color, var(--lb-primary-color));
|
|
990
|
+
border-radius: var(--lb-picker-radius-sm);
|
|
991
|
+
box-sizing: border-box;
|
|
992
|
+
font-family: inherit;
|
|
993
|
+
font-size: 12px;
|
|
994
|
+
font-weight: 600;
|
|
995
|
+
cursor: pointer;
|
|
996
|
+
min-height: 32px;
|
|
997
|
+
max-height: 32px;
|
|
998
|
+
}
|
|
999
|
+
|
|
1000
|
+
.lb-mix-match__modal-add:hover:not(:disabled) {
|
|
1001
|
+
opacity: 0.9;
|
|
1002
|
+
}
|
|
1003
|
+
|
|
1004
|
+
.lb-mix-match__modal-add:focus-visible {
|
|
1005
|
+
outline: 2px solid var(--lb-primary-color);
|
|
1006
|
+
outline-offset: 2px;
|
|
1007
|
+
box-shadow: none;
|
|
1008
|
+
}
|
|
1009
|
+
|
|
1010
|
+
.lb-mix-match__modal-add:disabled {
|
|
1011
|
+
background: color-mix(in srgb, var(--lb-picker-add-bg, var(--lb-primary-color)) 35%, var(--lb-picker-bg, var(--lb-bg, var(--lb-background))));
|
|
1012
|
+
color: color-mix(in srgb, var(--lb-picker-add-label, #fff) 85%, transparent);
|
|
1013
|
+
cursor: not-allowed;
|
|
1014
|
+
}
|
|
1015
|
+
|
|
1016
|
+
/* "Added" toggle — quiet neutral outlined treatment with a leading check, so an
|
|
1017
|
+
in-bundle product reads as selected (click removes it). Lime stays on the
|
|
1018
|
+
un-added "Add" button. */
|
|
1019
|
+
.lb-mix-match__modal-add--added {
|
|
1020
|
+
background: transparent;
|
|
1021
|
+
color: var(--lb-picker-text, var(--lb-text, var(--lb-primary-color)));
|
|
1022
|
+
border-color: color-mix(in srgb, var(--lb-text, var(--lb-primary-color)) 25%, transparent);
|
|
1023
|
+
display: inline-flex;
|
|
1024
|
+
align-items: center;
|
|
1025
|
+
justify-content: center;
|
|
1026
|
+
gap: 5px;
|
|
1027
|
+
}
|
|
1028
|
+
|
|
1029
|
+
.lb-mix-match__modal-add--added:hover {
|
|
1030
|
+
opacity: 1;
|
|
1031
|
+
background: color-mix(in srgb, var(--lb-text, var(--lb-primary-color)) 6%, transparent);
|
|
1032
|
+
}
|
|
1033
|
+
|
|
1034
|
+
.lb-mix-match__modal-add--added svg {
|
|
1035
|
+
width: 14px;
|
|
1036
|
+
height: 14px;
|
|
1037
|
+
flex-shrink: 0;
|
|
1038
|
+
}
|
|
1039
|
+
|
|
1040
|
+
/* In-bundle card — a quiet neutral tint + stronger border marks the selected
|
|
1041
|
+
products without spending lime on a non-button element. */
|
|
1042
|
+
.lb-mix-match__modal-product--in-bundle {
|
|
1043
|
+
background: color-mix(in srgb, var(--lb-text, var(--lb-primary-color)) 4%, transparent);
|
|
1044
|
+
border-color: color-mix(in srgb, var(--lb-text, var(--lb-primary-color)) 22%, transparent);
|
|
1045
|
+
}
|
|
1046
|
+
|
|
1047
|
+
.lb-mix-match__modal-product--sold-out {
|
|
1048
|
+
opacity: 0.5;
|
|
1049
|
+
}
|
|
1050
|
+
|
|
1051
|
+
.lb-mix-match__modal-sold-out-label {
|
|
1052
|
+
font-size: 12px;
|
|
1053
|
+
color: inherit;
|
|
1054
|
+
font-weight: 500;
|
|
1055
|
+
white-space: nowrap;
|
|
1056
|
+
display: block;
|
|
1057
|
+
margin-top: 8px;
|
|
1058
|
+
}
|
|
1059
|
+
|
|
1060
|
+
/* "Needs N spots" hint — exact-size enforcement: the product's minimum
|
|
1061
|
+
pick exceeds the bundle's remaining open spots, so its Add and stepper
|
|
1062
|
+
are disabled. Same quiet label treatment as the sold-out state. */
|
|
1063
|
+
.lb-mix-match__modal-needs-spots {
|
|
1064
|
+
display: block;
|
|
1065
|
+
margin-top: 8px;
|
|
1066
|
+
font-size: 12px;
|
|
1067
|
+
color: inherit;
|
|
1068
|
+
font-weight: 500;
|
|
1069
|
+
white-space: nowrap;
|
|
1070
|
+
opacity: 0.7;
|
|
1071
|
+
}
|
|
1072
|
+
|
|
1073
|
+
/* === Modal empty state ================================================ */
|
|
1074
|
+
.lb-mix-match__modal-empty {
|
|
1075
|
+
padding: 32px 20px;
|
|
1076
|
+
text-align: center;
|
|
1077
|
+
}
|
|
1078
|
+
|
|
1079
|
+
.lb-mix-match__modal-empty p {
|
|
1080
|
+
margin: 0;
|
|
1081
|
+
font-size: 16px;
|
|
1082
|
+
color: var(--lb-picker-text, var(--lb-text, var(--lb-primary-color)));
|
|
1083
|
+
}
|
|
1084
|
+
|
|
1085
|
+
/* === Modal footer ===================================================== */
|
|
1086
|
+
.lb-mix-match__modal-footer {
|
|
1087
|
+
display: flex;
|
|
1088
|
+
align-items: center;
|
|
1089
|
+
justify-content: space-between;
|
|
1090
|
+
gap: 12px;
|
|
1091
|
+
padding: 16px 20px;
|
|
1092
|
+
border-top: 1px solid color-mix(in srgb, var(--lb-picker-text, var(--lb-text, var(--lb-primary-color))) 15%, transparent);
|
|
1093
|
+
flex-shrink: 0;
|
|
1094
|
+
}
|
|
1095
|
+
|
|
1096
|
+
.lb-mix-match__modal-footer-count {
|
|
1097
|
+
font-size: 13px;
|
|
1098
|
+
font-weight: 500;
|
|
1099
|
+
color: color-mix(in srgb, var(--lb-picker-text, var(--lb-text, var(--lb-primary-color))) 70%, transparent);
|
|
1100
|
+
}
|
|
1101
|
+
|
|
1102
|
+
/* The flex centring + min-height pin the footer-button silhouette: the wizard
|
|
1103
|
+
Back copies these metrics so the pair stays equal-height whatever border
|
|
1104
|
+
widths the merchant's picker tokens set. */
|
|
1105
|
+
.lb-mix-match__modal-done {
|
|
1106
|
+
display: inline-flex;
|
|
1107
|
+
align-items: center;
|
|
1108
|
+
justify-content: center;
|
|
1109
|
+
min-height: 40px;
|
|
1110
|
+
padding: 10px 24px;
|
|
1111
|
+
background: var(--lb-picker-add-bg, var(--lb-primary-color));
|
|
1112
|
+
color: var(--lb-picker-add-label, #fff);
|
|
1113
|
+
border: var(--lb-picker-add-border-width, 0px) solid var(--lb-picker-add-border-color, var(--lb-primary-color));
|
|
1114
|
+
border-radius: var(--lb-picker-radius-sm);
|
|
1115
|
+
box-sizing: border-box;
|
|
1116
|
+
font-family: inherit;
|
|
1117
|
+
font-size: 14px;
|
|
1118
|
+
font-weight: 600;
|
|
1119
|
+
cursor: pointer;
|
|
1120
|
+
}
|
|
1121
|
+
|
|
1122
|
+
.lb-mix-match__modal-done:hover:not(:disabled) {
|
|
1123
|
+
opacity: 0.9;
|
|
1124
|
+
}
|
|
1125
|
+
|
|
1126
|
+
/* Disabled Next/Done (wizard step minimum not met) — same washed-out
|
|
1127
|
+
treatment as a disabled row Add, no hover reaction; the solid button
|
|
1128
|
+
returns the moment the requirement is met. */
|
|
1129
|
+
.lb-mix-match__modal-done:disabled {
|
|
1130
|
+
background: color-mix(in srgb, var(--lb-picker-add-bg, var(--lb-primary-color)) 35%, var(--lb-picker-bg, var(--lb-bg, var(--lb-background))));
|
|
1131
|
+
color: color-mix(in srgb, var(--lb-picker-add-label, #fff) 85%, transparent);
|
|
1132
|
+
cursor: not-allowed;
|
|
1133
|
+
}
|
|
1134
|
+
|
|
1135
|
+
.lb-mix-match__modal-done:focus-visible {
|
|
1136
|
+
outline: 2px solid var(--lb-primary-color);
|
|
1137
|
+
outline-offset: 2px;
|
|
1138
|
+
box-shadow: none;
|
|
1139
|
+
}
|
|
1140
|
+
|
|
1141
|
+
.lb-hidden {
|
|
1142
|
+
display: none !important;
|
|
1143
|
+
}
|
|
1144
|
+
|
|
1145
|
+
/* Desktop: stepper group + Add share the action row equally. */
|
|
1146
|
+
@media (min-width: 768px) {
|
|
1147
|
+
.lb-mix-match__qty-stepper-group {
|
|
1148
|
+
flex: 1;
|
|
1149
|
+
}
|
|
1150
|
+
}
|
|
1151
|
+
|
|
1152
|
+
/* Mobile full-screen bottom-sheet modal. */
|
|
1153
|
+
@media (max-width: 767px) {
|
|
1154
|
+
.lb-mix-match__modal-overlay {
|
|
1155
|
+
align-items: flex-end;
|
|
1156
|
+
}
|
|
1157
|
+
|
|
1158
|
+
.lb-mix-match__modal {
|
|
1159
|
+
max-width: 100%;
|
|
1160
|
+
max-height: 90vh;
|
|
1161
|
+
border-radius: 16px 16px 0 0;
|
|
1162
|
+
transform: translateY(100%);
|
|
1163
|
+
}
|
|
1164
|
+
|
|
1165
|
+
.lb-mix-match__modal-overlay--open .lb-mix-match__modal {
|
|
1166
|
+
transform: translateY(0);
|
|
1167
|
+
}
|
|
1168
|
+
|
|
1169
|
+
.lb-mix-match__qty-stepper {
|
|
1170
|
+
min-height: 44px;
|
|
1171
|
+
max-height: 44px;
|
|
1172
|
+
}
|
|
1173
|
+
|
|
1174
|
+
.lb-mix-match__qty-stepper-button {
|
|
1175
|
+
width: 44px;
|
|
1176
|
+
height: 44px;
|
|
1177
|
+
}
|
|
1178
|
+
|
|
1179
|
+
.lb-mix-match__modal-add {
|
|
1180
|
+
min-height: 44px;
|
|
1181
|
+
max-height: 44px;
|
|
1182
|
+
}
|
|
1183
|
+
|
|
1184
|
+
.lb-mix-match__qty-stepper-group {
|
|
1185
|
+
width: 100%;
|
|
1186
|
+
}
|
|
1187
|
+
}
|
|
1188
|
+
|
|
1189
|
+
@media (max-width: 430px) {
|
|
1190
|
+
.lb-mix-match__modal-list {
|
|
1191
|
+
grid-template-columns: 1fr;
|
|
1192
|
+
}
|
|
1193
|
+
}
|
|
1194
|
+
|
|
1195
|
+
@media (prefers-reduced-motion: reduce) {
|
|
1196
|
+
.lb-mix-match__modal-overlay,
|
|
1197
|
+
.lb-mix-match__modal,
|
|
1198
|
+
.lb-mix-match__progress-segment {
|
|
1199
|
+
transition: none;
|
|
1200
|
+
}
|
|
1201
|
+
}
|
|
1202
|
+
|
|
1203
|
+
/* ───────────────────────────────────────────────────────────────────
|
|
1204
|
+
* Volume bundle — quantity selector.
|
|
1205
|
+
* ─────────────────────────────────────────────────────────────────── */
|
|
1206
|
+
|
|
1207
|
+
.lb-bundle__quantity-selector {
|
|
1208
|
+
margin: var(--lb-spacing-lg) 0;
|
|
1209
|
+
}
|
|
1210
|
+
|
|
1211
|
+
.lb-bundle__quantity-selector label {
|
|
1212
|
+
display: block;
|
|
1213
|
+
margin-bottom: var(--lb-spacing-sm);
|
|
1214
|
+
font-weight: 500;
|
|
1215
|
+
}
|
|
1216
|
+
|
|
1217
|
+
.lb-bundle__quantity-control {
|
|
1218
|
+
display: inline-flex;
|
|
1219
|
+
align-items: center;
|
|
1220
|
+
gap: 0;
|
|
1221
|
+
border: 1px solid var(--lb-border, var(--lb-border-color));
|
|
1222
|
+
border-radius: var(--lb-border-radius);
|
|
1223
|
+
}
|
|
1224
|
+
|
|
1225
|
+
.lb-bundle__quantity-control button {
|
|
1226
|
+
width: 32px;
|
|
1227
|
+
height: 32px;
|
|
1228
|
+
border: none;
|
|
1229
|
+
background: transparent;
|
|
1230
|
+
cursor: pointer;
|
|
1231
|
+
font-size: 1.1em;
|
|
1232
|
+
display: flex;
|
|
1233
|
+
align-items: center;
|
|
1234
|
+
justify-content: center;
|
|
1235
|
+
color: inherit;
|
|
1236
|
+
}
|
|
1237
|
+
|
|
1238
|
+
.lb-bundle__quantity-control span,
|
|
1239
|
+
.lb-bundle__quantity-input {
|
|
1240
|
+
width: 40px;
|
|
1241
|
+
text-align: center;
|
|
1242
|
+
border: none;
|
|
1243
|
+
border-left: 1px solid var(--lb-border, var(--lb-border-color));
|
|
1244
|
+
border-right: 1px solid var(--lb-border, var(--lb-border-color));
|
|
1245
|
+
height: 32px;
|
|
1246
|
+
line-height: 32px;
|
|
1247
|
+
font-size: var(--lb-font-size);
|
|
1248
|
+
background: transparent;
|
|
1249
|
+
color: inherit;
|
|
1250
|
+
}
|
|
1251
|
+
|
|
1252
|
+
.lb-bundle__quantity-input {
|
|
1253
|
+
-moz-appearance: textfield;
|
|
1254
|
+
}
|
|
1255
|
+
.lb-bundle__quantity-input::-webkit-outer-spin-button,
|
|
1256
|
+
.lb-bundle__quantity-input::-webkit-inner-spin-button {
|
|
1257
|
+
-webkit-appearance: none;
|
|
1258
|
+
}
|
|
1259
|
+
|
|
1260
|
+
/* ───────────────────────────────────────────────────────────────────
|
|
1261
|
+
* Volume tier cards — mirror the fixed / mix & match bundle card so volume
|
|
1262
|
+
* reads as the same app: a bordered card with matching geometry, a price row,
|
|
1263
|
+
* and a right-slot savings chip. The radio sits where those cards put the
|
|
1264
|
+
* thumbnail, since a volume tier is the same product at a different quantity
|
|
1265
|
+
* (no thumbnail). Ported from extensions/bundle-theme/assets/bundle-volume.css.
|
|
1266
|
+
* ─────────────────────────────────────────────────────────────────── */
|
|
1267
|
+
|
|
1268
|
+
.lb-bundle__tiers {
|
|
1269
|
+
display: flex;
|
|
1270
|
+
flex-direction: column;
|
|
1271
|
+
gap: 16px;
|
|
1272
|
+
margin: var(--lb-spacing-lg) 0 0;
|
|
1273
|
+
max-height: var(--lb-list-max-height);
|
|
1274
|
+
overflow-y: auto;
|
|
1275
|
+
/* Scrollbar hidden + edge fade — see .lb-edge-fade above. */
|
|
1276
|
+
}
|
|
1277
|
+
|
|
1278
|
+
/* Match the theme: when the first tier is the popular one, reserve room above
|
|
1279
|
+
for the floating "Most popular" badge so it has the same breathing space. */
|
|
1280
|
+
.lb-bundle__tiers:has(> .lb-bundle__tier:first-child .lb-bundle__tier-badge) {
|
|
1281
|
+
padding-top: 12px;
|
|
1282
|
+
}
|
|
1283
|
+
|
|
1284
|
+
.lb-bundle__tier {
|
|
1285
|
+
position: relative;
|
|
1286
|
+
display: flex;
|
|
1287
|
+
align-items: center;
|
|
1288
|
+
gap: 12px;
|
|
1289
|
+
border: var(--lb-border-width, 1px) solid var(--lb-border, var(--lb-border-color));
|
|
1290
|
+
border-radius: var(--lb-radius, var(--lb-border-radius));
|
|
1291
|
+
padding: 12px;
|
|
1292
|
+
box-sizing: border-box;
|
|
1293
|
+
}
|
|
1294
|
+
|
|
1295
|
+
/* Selected (active) tier — the same quiet neutral highlight as the mix & match
|
|
1296
|
+
in-bundle / Added card (soft tint + stronger border), plus the filled radio,
|
|
1297
|
+
so "selected" looks the same everywhere in the app. The old
|
|
1298
|
+
--lb-tier-selected-* tokens are gone. */
|
|
1299
|
+
.lb-bundle__tier--active {
|
|
1300
|
+
border-color: var(--lb-text, var(--lb-primary-color));
|
|
1301
|
+
border-width: 2px;
|
|
1302
|
+
}
|
|
1303
|
+
|
|
1304
|
+
/* Tier the selected variant can't cover — same greyed treatment as an
|
|
1305
|
+
out-of-stock product row, and not selectable. */
|
|
1306
|
+
.lb-bundle__tier--oos {
|
|
1307
|
+
opacity: 0.5;
|
|
1308
|
+
cursor: not-allowed;
|
|
1309
|
+
}
|
|
1310
|
+
|
|
1311
|
+
.lb-bundle__tier-radio {
|
|
1312
|
+
width: 20px;
|
|
1313
|
+
height: 20px;
|
|
1314
|
+
min-width: 20px;
|
|
1315
|
+
flex: none;
|
|
1316
|
+
box-sizing: border-box;
|
|
1317
|
+
border: 2px solid color-mix(in srgb, var(--lb-text, var(--lb-primary-color)) 45%, transparent);
|
|
1318
|
+
border-radius: 50%;
|
|
1319
|
+
display: flex;
|
|
1320
|
+
align-items: center;
|
|
1321
|
+
justify-content: center;
|
|
1322
|
+
}
|
|
1323
|
+
|
|
1324
|
+
/* Ring and dot follow the SELECTED tier (aria-checked), matching the
|
|
1325
|
+
single-selection radio the theme renders — `--active` marks every tier
|
|
1326
|
+
the current quantity reaches and keeps the row highlight only. */
|
|
1327
|
+
.lb-bundle__tier[aria-checked="true"] .lb-bundle__tier-radio {
|
|
1328
|
+
border-color: var(--lb-text, var(--lb-primary-color));
|
|
1329
|
+
}
|
|
1330
|
+
|
|
1331
|
+
.lb-bundle__tier-radio-dot {
|
|
1332
|
+
width: 10px;
|
|
1333
|
+
height: 10px;
|
|
1334
|
+
border-radius: 50%;
|
|
1335
|
+
background: transparent;
|
|
1336
|
+
}
|
|
1337
|
+
|
|
1338
|
+
.lb-bundle__tier[aria-checked="true"] .lb-bundle__tier-radio-dot {
|
|
1339
|
+
background: var(--lb-text, var(--lb-primary-color));
|
|
1340
|
+
}
|
|
1341
|
+
|
|
1342
|
+
/* Info column: the quantity over the price row. */
|
|
1343
|
+
.lb-bundle__tier-info {
|
|
1344
|
+
flex: 1;
|
|
1345
|
+
min-width: 0;
|
|
1346
|
+
display: flex;
|
|
1347
|
+
flex-direction: column;
|
|
1348
|
+
}
|
|
1349
|
+
|
|
1350
|
+
.lb-bundle__tier-label {
|
|
1351
|
+
font-size: 16px;
|
|
1352
|
+
font-weight: 600;
|
|
1353
|
+
line-height: 20px;
|
|
1354
|
+
color: var(--lb-text, var(--lb-primary-color));
|
|
1355
|
+
}
|
|
1356
|
+
|
|
1357
|
+
/* Right column — stacks the "Most popular" badge (when present) over the
|
|
1358
|
+
savings chip, so the markers group on the right and the quantity row stays
|
|
1359
|
+
clean. */
|
|
1360
|
+
.lb-bundle__tier-right {
|
|
1361
|
+
flex: none;
|
|
1362
|
+
display: flex;
|
|
1363
|
+
flex-direction: column;
|
|
1364
|
+
align-items: flex-end;
|
|
1365
|
+
gap: 6px;
|
|
1366
|
+
}
|
|
1367
|
+
|
|
1368
|
+
/* "Most popular" pill — a floating crown straddling the card's top-right edge.
|
|
1369
|
+
The 16px gap on .lb-bundle__tiers leaves room for it above each card. */
|
|
1370
|
+
.lb-bundle__tier-badge {
|
|
1371
|
+
position: absolute;
|
|
1372
|
+
top: -12px;
|
|
1373
|
+
right: 12px;
|
|
1374
|
+
z-index: 1;
|
|
1375
|
+
font-size: 12px;
|
|
1376
|
+
font-weight: 500;
|
|
1377
|
+
line-height: 1;
|
|
1378
|
+
color: var(--lb-popular-badge-text);
|
|
1379
|
+
background: var(--lb-popular-badge-bg);
|
|
1380
|
+
border: var(--lb-popular-badge-border-width) solid var(--lb-popular-badge-border-color);
|
|
1381
|
+
/* The small floating badge reads better one step softer than --lb-radius-sm —
|
|
1382
|
+
~3px at the "subtle" preset — while still scaling with the radius setting. */
|
|
1383
|
+
border-radius: max(0px, calc(var(--lb-radius, var(--lb-border-radius)) - 3px));
|
|
1384
|
+
padding: 4px 9px;
|
|
1385
|
+
}
|
|
1386
|
+
|
|
1387
|
+
/* Price row — the same struck → per-unit → "each" treatment the product cards
|
|
1388
|
+
use (compare-at muted and struck, per-unit price, tabular figures). */
|
|
1389
|
+
.lb-bundle__tier-price {
|
|
1390
|
+
display: flex;
|
|
1391
|
+
align-items: baseline;
|
|
1392
|
+
gap: 6px;
|
|
1393
|
+
flex-wrap: wrap;
|
|
1394
|
+
margin-top: 3px;
|
|
1395
|
+
font-size: 14px;
|
|
1396
|
+
color: var(--lb-text, var(--lb-primary-color));
|
|
1397
|
+
font-variant-numeric: tabular-nums;
|
|
1398
|
+
}
|
|
1399
|
+
|
|
1400
|
+
.lb-bundle__tier-compare {
|
|
1401
|
+
color: color-mix(in srgb, var(--lb-text, var(--lb-primary-color)) 55%, transparent);
|
|
1402
|
+
text-decoration: line-through;
|
|
1403
|
+
}
|
|
1404
|
+
|
|
1405
|
+
.lb-bundle__tier-unit {
|
|
1406
|
+
font-size: 12px;
|
|
1407
|
+
color: color-mix(in srgb, var(--lb-text, var(--lb-primary-color)) 60%, transparent);
|
|
1408
|
+
}
|
|
1409
|
+
|
|
1410
|
+
/* Savings chip — the same soft neutral chip as the fixed card's quantity chip,
|
|
1411
|
+
here carrying the per-tier discount so "buy more, save more" is scannable. */
|
|
1412
|
+
.lb-bundle__tier-savings {
|
|
1413
|
+
flex-shrink: 0;
|
|
1414
|
+
display: inline-flex;
|
|
1415
|
+
align-items: center;
|
|
1416
|
+
height: 28px;
|
|
1417
|
+
padding: 0 10px;
|
|
1418
|
+
border-radius: max(0px, calc(var(--lb-radius, var(--lb-border-radius)) - 2px));
|
|
1419
|
+
background: color-mix(in srgb, var(--lb-text, var(--lb-primary-color)) 7%, transparent);
|
|
1420
|
+
color: color-mix(in srgb, var(--lb-text, var(--lb-primary-color)) 80%, transparent);
|
|
1421
|
+
font-size: 13px;
|
|
1422
|
+
font-weight: 500;
|
|
1423
|
+
line-height: 1;
|
|
1424
|
+
white-space: nowrap;
|
|
1425
|
+
font-variant-numeric: tabular-nums;
|
|
1426
|
+
}
|
|
1427
|
+
|
|
1428
|
+
/* ───────────────────────────────────────────────────────────────────
|
|
1429
|
+
* Receipt summary — a two-column row: the label (+ savings line) on the
|
|
1430
|
+
* left, the price stack on the right, vertically centred. The sale price is
|
|
1431
|
+
* the widget's #1 element (largest, heaviest), so the eye lands on what the
|
|
1432
|
+
* bundle costs. Inherits the widget's global text color.
|
|
1433
|
+
* ─────────────────────────────────────────────────────────────────── */
|
|
1434
|
+
|
|
1435
|
+
.lb-bundle-summary {
|
|
1436
|
+
display: flex;
|
|
1437
|
+
align-items: center;
|
|
1438
|
+
justify-content: space-between;
|
|
1439
|
+
gap: 12px;
|
|
1440
|
+
margin-bottom: 16px;
|
|
1441
|
+
}
|
|
1442
|
+
|
|
1443
|
+
/* Left column — the label over the savings line. Paired with the price stack
|
|
1444
|
+
on the right and vertically centred against it, so the summary stays
|
|
1445
|
+
balanced whether or not a savings line / compare price is present (e.g. an
|
|
1446
|
+
undiscounted bundle reads as a clean "label … total" on one centred line). */
|
|
1447
|
+
.lb-bundle-summary__text {
|
|
1448
|
+
display: flex;
|
|
1449
|
+
flex-direction: column;
|
|
1450
|
+
gap: 2px;
|
|
1451
|
+
min-width: 0;
|
|
1452
|
+
}
|
|
1453
|
+
|
|
1454
|
+
.lb-bundle-summary__label {
|
|
1455
|
+
font-size: 15px;
|
|
1456
|
+
font-weight: 400;
|
|
1457
|
+
line-height: 1.4;
|
|
1458
|
+
text-transform: uppercase;
|
|
1459
|
+
color: color-mix(in srgb, var(--lb-text, var(--lb-primary-color)) 70%, transparent);
|
|
1460
|
+
}
|
|
1461
|
+
|
|
1462
|
+
/* Savings line — the one savings signal, quiet text under the label. No pill,
|
|
1463
|
+
no lime: lime is reserved for the CTA. */
|
|
1464
|
+
.lb-bundle-savings-line {
|
|
1465
|
+
font-size: 13px;
|
|
1466
|
+
font-weight: 400;
|
|
1467
|
+
line-height: 1.4;
|
|
1468
|
+
color: color-mix(in srgb, var(--lb-text, var(--lb-primary-color)) 60%, transparent);
|
|
1469
|
+
margin: 0;
|
|
1470
|
+
}
|
|
1471
|
+
|
|
1472
|
+
.lb-bundle-savings-line [data-savings-amount] {
|
|
1473
|
+
color: var(--lb-text, var(--lb-primary-color));
|
|
1474
|
+
font-variant-numeric: tabular-nums;
|
|
1475
|
+
}
|
|
1476
|
+
|
|
1477
|
+
/* Right column — the struck original over the bundle total ("was / now"),
|
|
1478
|
+
vertically centred against the label/savings column on the left. */
|
|
1479
|
+
.lb-bundle-summary__prices {
|
|
1480
|
+
display: flex;
|
|
1481
|
+
flex-direction: column;
|
|
1482
|
+
align-items: flex-end;
|
|
1483
|
+
gap: 1px;
|
|
1484
|
+
flex-shrink: 0;
|
|
1485
|
+
text-align: right;
|
|
1486
|
+
}
|
|
1487
|
+
|
|
1488
|
+
.lb-bundle-sale-price {
|
|
1489
|
+
font-size: 24px;
|
|
1490
|
+
font-weight: 600;
|
|
1491
|
+
line-height: 1.1;
|
|
1492
|
+
letter-spacing: -0.02em;
|
|
1493
|
+
color: var(--lb-text, var(--lb-primary-color));
|
|
1494
|
+
font-variant-numeric: tabular-nums;
|
|
1495
|
+
}
|
|
1496
|
+
|
|
1497
|
+
.lb-bundle-compare-price {
|
|
1498
|
+
font-size: 14px;
|
|
1499
|
+
font-weight: 400;
|
|
1500
|
+
line-height: 1.3;
|
|
1501
|
+
color: color-mix(in srgb, var(--lb-text, var(--lb-primary-color)) 55%, transparent);
|
|
1502
|
+
text-decoration: line-through;
|
|
1503
|
+
font-variant-numeric: tabular-nums;
|
|
1504
|
+
}
|
|
1505
|
+
|
|
1506
|
+
/* ───────────────────────────────────────────────────────────────────
|
|
1507
|
+
* CTA button.
|
|
1508
|
+
* ─────────────────────────────────────────────────────────────────── */
|
|
1509
|
+
|
|
1510
|
+
.lb-bundle__cta {
|
|
1511
|
+
width: 100%;
|
|
1512
|
+
padding: 12px 16px;
|
|
1513
|
+
border: var(--lb-cta-border-width, 0px) solid var(--lb-cta-border-color, var(--lb-primary-color));
|
|
1514
|
+
border-radius: var(--lb-radius, var(--lb-border-radius));
|
|
1515
|
+
background: var(--lb-primary-color, var(--lb-button-bg));
|
|
1516
|
+
color: var(--lb-btn-text, var(--lb-button-text));
|
|
1517
|
+
font-size: 16px;
|
|
1518
|
+
font-weight: 600;
|
|
1519
|
+
line-height: 20px;
|
|
1520
|
+
cursor: pointer;
|
|
1521
|
+
text-align: center;
|
|
1522
|
+
font-family: inherit;
|
|
1523
|
+
transition: opacity 0.15s;
|
|
1524
|
+
}
|
|
1525
|
+
|
|
1526
|
+
.lb-bundle__cta:hover:not(:disabled) {
|
|
1527
|
+
opacity: 0.9;
|
|
1528
|
+
}
|
|
1529
|
+
|
|
1530
|
+
.lb-bundle__cta:disabled {
|
|
1531
|
+
background: color-mix(in srgb, var(--lb-primary-color) 35%, var(--lb-bg, var(--lb-background)));
|
|
1532
|
+
color: color-mix(in srgb, var(--lb-btn-text, var(--lb-button-text)) 85%, transparent);
|
|
1533
|
+
cursor: not-allowed;
|
|
1534
|
+
}
|
|
1535
|
+
|
|
1536
|
+
.lb-bundle__error {
|
|
1537
|
+
color: var(--lb-low-stock-text, var(--lb-error-color));
|
|
1538
|
+
margin: var(--lb-spacing-sm) 0;
|
|
1539
|
+
font-size: 0.9em;
|
|
1540
|
+
}
|
|
1541
|
+
|
|
1542
|
+
/* Skeleton loading */
|
|
1543
|
+
.lb-skeleton {
|
|
1544
|
+
background: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%);
|
|
1545
|
+
background-size: 200% 100%;
|
|
1546
|
+
animation: lb-shimmer 1.5s infinite;
|
|
1547
|
+
border-radius: var(--lb-border-radius);
|
|
1548
|
+
}
|
|
1549
|
+
|
|
1550
|
+
.lb-skeleton--title {
|
|
1551
|
+
height: 24px;
|
|
1552
|
+
width: 60%;
|
|
1553
|
+
margin-bottom: var(--lb-spacing-md);
|
|
1554
|
+
}
|
|
1555
|
+
|
|
1556
|
+
.lb-skeleton--products {
|
|
1557
|
+
height: 200px;
|
|
1558
|
+
}
|
|
1559
|
+
|
|
1560
|
+
.lb-skeleton--tiers {
|
|
1561
|
+
height: 120px;
|
|
1562
|
+
}
|
|
1563
|
+
|
|
1564
|
+
@keyframes lb-shimmer {
|
|
1565
|
+
0% { background-position: 200% 0; }
|
|
1566
|
+
100% { background-position: -200% 0; }
|
|
1567
|
+
}
|
|
1568
|
+
|
|
1569
|
+
/* ───────────────────────────────────────────────────────────────────
|
|
1570
|
+
* Variant-picker dropdown — accessible custom combobox.
|
|
1571
|
+
* Reuses the widget vars (--lb-bg, --lb-text, the global --lb-border /
|
|
1572
|
+
* --lb-border-width, and the derived --lb-radius-sm) emitted by
|
|
1573
|
+
* useWidgetConfigVars on the bundle component root, so values match the
|
|
1574
|
+
* merchant's WidgetConfig without separate plumbing.
|
|
1575
|
+
* ─────────────────────────────────────────────────────────────────── */
|
|
1576
|
+
|
|
1577
|
+
.lb-dropdown {
|
|
1578
|
+
position: relative;
|
|
1579
|
+
display: inline-block;
|
|
1580
|
+
width: 100%;
|
|
1581
|
+
max-width: 100%;
|
|
1582
|
+
font-family: inherit;
|
|
1583
|
+
}
|
|
1584
|
+
|
|
1585
|
+
.lb-dropdown-trigger {
|
|
1586
|
+
display: inline-flex;
|
|
1587
|
+
align-items: center;
|
|
1588
|
+
justify-content: space-between;
|
|
1589
|
+
gap: 8px;
|
|
1590
|
+
width: 100%;
|
|
1591
|
+
border: var(--lb-border-width, 1px) solid var(--lb-border, var(--lb-border-color));
|
|
1592
|
+
border-radius: var(--lb-radius-sm);
|
|
1593
|
+
padding: 8px 12px;
|
|
1594
|
+
font-size: 12px;
|
|
1595
|
+
line-height: 16px;
|
|
1596
|
+
color: var(--lb-text, var(--lb-primary-color));
|
|
1597
|
+
background: var(--lb-bg, var(--lb-background));
|
|
1598
|
+
font-family: inherit;
|
|
1599
|
+
cursor: pointer;
|
|
1600
|
+
appearance: none;
|
|
1601
|
+
-webkit-appearance: none;
|
|
1602
|
+
text-align: start;
|
|
1603
|
+
transition: border-color 120ms ease;
|
|
1604
|
+
}
|
|
1605
|
+
|
|
1606
|
+
.lb-dropdown-trigger:focus-visible {
|
|
1607
|
+
outline: 2px solid var(--lb-primary-color);
|
|
1608
|
+
outline-offset: 2px;
|
|
1609
|
+
}
|
|
1610
|
+
|
|
1611
|
+
.lb-dropdown-trigger[aria-expanded="true"] {
|
|
1612
|
+
border-color: var(--lb-text, var(--lb-primary-color));
|
|
1613
|
+
}
|
|
1614
|
+
|
|
1615
|
+
.lb-dropdown-trigger-value {
|
|
1616
|
+
flex: 1 1 auto;
|
|
1617
|
+
white-space: nowrap;
|
|
1618
|
+
overflow: hidden;
|
|
1619
|
+
text-overflow: ellipsis;
|
|
1620
|
+
text-align: start;
|
|
1621
|
+
}
|
|
1622
|
+
|
|
1623
|
+
.lb-dropdown-chevron {
|
|
1624
|
+
flex: 0 0 auto;
|
|
1625
|
+
width: 12px;
|
|
1626
|
+
height: 12px;
|
|
1627
|
+
background: var(--lb-variant-chevron) center / contain no-repeat;
|
|
1628
|
+
transition: transform 120ms ease;
|
|
1629
|
+
}
|
|
1630
|
+
|
|
1631
|
+
.lb-dropdown-trigger[aria-expanded="true"] .lb-dropdown-chevron {
|
|
1632
|
+
transform: rotate(180deg);
|
|
1633
|
+
}
|
|
1634
|
+
|
|
1635
|
+
.lb-dropdown-listbox {
|
|
1636
|
+
position: absolute;
|
|
1637
|
+
left: 0;
|
|
1638
|
+
/* Default to below-trigger placement so the panel doesn't overlap the
|
|
1639
|
+
trigger if data-placement is missing for any reason. The explicit
|
|
1640
|
+
[data-placement="down"|"up"] rules below override this. */
|
|
1641
|
+
top: calc(100% + 4px);
|
|
1642
|
+
width: 100%;
|
|
1643
|
+
z-index: 9999;
|
|
1644
|
+
margin: 0;
|
|
1645
|
+
padding: 4px 0;
|
|
1646
|
+
list-style: none;
|
|
1647
|
+
background: var(--lb-bg, var(--lb-background));
|
|
1648
|
+
color: var(--lb-text, var(--lb-primary-color));
|
|
1649
|
+
border: var(--lb-border-width, 1px) solid var(--lb-border, var(--lb-border-color));
|
|
1650
|
+
border-radius: var(--lb-radius-sm);
|
|
1651
|
+
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.08);
|
|
1652
|
+
overflow-y: auto;
|
|
1653
|
+
overflow-x: hidden;
|
|
1654
|
+
/* Quiet overlay scrollbar — transparent track, soft rounded thumb. The
|
|
1655
|
+
popover has a shadow + border, so it keeps a thumb rather than the inset
|
|
1656
|
+
lists' edge fade (a mask would clip the shadow). */
|
|
1657
|
+
scrollbar-width: thin;
|
|
1658
|
+
scrollbar-color: color-mix(in srgb, var(--lb-text, var(--lb-primary-color)) 18%, transparent) transparent;
|
|
1659
|
+
animation: lb-dropdown-in-down 120ms ease-out;
|
|
1660
|
+
transform-origin: top center;
|
|
1661
|
+
}
|
|
1662
|
+
|
|
1663
|
+
.lb-dropdown-listbox[data-placement="down"] {
|
|
1664
|
+
top: calc(100% + 4px);
|
|
1665
|
+
}
|
|
1666
|
+
|
|
1667
|
+
.lb-dropdown-listbox[data-placement="up"] {
|
|
1668
|
+
top: auto;
|
|
1669
|
+
bottom: calc(100% + 4px);
|
|
1670
|
+
animation-name: lb-dropdown-in-up;
|
|
1671
|
+
transform-origin: bottom center;
|
|
1672
|
+
}
|
|
1673
|
+
|
|
1674
|
+
/* Quiet overlay scrollbar — Webkit/Blink: transparent track, soft rounded
|
|
1675
|
+
thumb that darkens on hover. */
|
|
1676
|
+
.lb-dropdown-listbox::-webkit-scrollbar {
|
|
1677
|
+
width: 6px;
|
|
1678
|
+
}
|
|
1679
|
+
.lb-dropdown-listbox::-webkit-scrollbar-track {
|
|
1680
|
+
background: transparent;
|
|
1681
|
+
}
|
|
1682
|
+
.lb-dropdown-listbox::-webkit-scrollbar-thumb {
|
|
1683
|
+
background: color-mix(in srgb, var(--lb-text, var(--lb-primary-color)) 16%, transparent);
|
|
1684
|
+
border-radius: 999px;
|
|
1685
|
+
}
|
|
1686
|
+
.lb-dropdown-listbox::-webkit-scrollbar-thumb:hover {
|
|
1687
|
+
background: color-mix(in srgb, var(--lb-text, var(--lb-primary-color)) 30%, transparent);
|
|
1688
|
+
}
|
|
1689
|
+
|
|
1690
|
+
.lb-dropdown-option {
|
|
1691
|
+
padding: 8px 12px;
|
|
1692
|
+
font-size: 12px;
|
|
1693
|
+
line-height: 16px;
|
|
1694
|
+
cursor: pointer;
|
|
1695
|
+
white-space: nowrap;
|
|
1696
|
+
overflow: hidden;
|
|
1697
|
+
text-overflow: ellipsis;
|
|
1698
|
+
color: var(--lb-text, var(--lb-primary-color));
|
|
1699
|
+
}
|
|
1700
|
+
|
|
1701
|
+
.lb-dropdown-option[aria-selected="true"] {
|
|
1702
|
+
font-weight: 600;
|
|
1703
|
+
}
|
|
1704
|
+
|
|
1705
|
+
.lb-dropdown-option.is-active,
|
|
1706
|
+
.lb-dropdown-option:hover:not([aria-disabled="true"]) {
|
|
1707
|
+
background: color-mix(in srgb, var(--lb-text, var(--lb-primary-color)) 2%, transparent);
|
|
1708
|
+
}
|
|
1709
|
+
|
|
1710
|
+
.lb-dropdown-option[aria-disabled="true"] {
|
|
1711
|
+
opacity: 0.4;
|
|
1712
|
+
cursor: not-allowed;
|
|
1713
|
+
}
|
|
1714
|
+
|
|
1715
|
+
@keyframes lb-dropdown-in-down {
|
|
1716
|
+
from { opacity: 0; transform: translateY(-4px) scale(0.98); }
|
|
1717
|
+
to { opacity: 1; transform: translateY(0) scale(1); }
|
|
1718
|
+
}
|
|
1719
|
+
|
|
1720
|
+
@keyframes lb-dropdown-in-up {
|
|
1721
|
+
from { opacity: 0; transform: translateY(4px) scale(0.98); }
|
|
1722
|
+
to { opacity: 1; transform: translateY(0) scale(1); }
|
|
1723
|
+
}
|
|
1724
|
+
|
|
1725
|
+
@media (prefers-reduced-motion: reduce) {
|
|
1726
|
+
.lb-dropdown-listbox { animation: none; }
|
|
1727
|
+
.lb-dropdown-chevron { transition: none; }
|
|
1728
|
+
.lb-dropdown-trigger { transition: none; }
|
|
1729
|
+
}
|
|
1730
|
+
|
|
1731
|
+
@media (forced-colors: active) {
|
|
1732
|
+
.lb-dropdown-trigger {
|
|
1733
|
+
border-color: ButtonBorder;
|
|
1734
|
+
color: ButtonText;
|
|
1735
|
+
background: ButtonFace;
|
|
1736
|
+
}
|
|
1737
|
+
.lb-dropdown-listbox {
|
|
1738
|
+
border-color: ButtonBorder;
|
|
1739
|
+
background: Canvas;
|
|
1740
|
+
color: CanvasText;
|
|
1741
|
+
}
|
|
1742
|
+
.lb-dropdown-option.is-active {
|
|
1743
|
+
background: Highlight;
|
|
1744
|
+
color: HighlightText;
|
|
1745
|
+
}
|
|
1746
|
+
}
|
|
1747
|
+
|
|
1748
|
+
/* === BOGO (Buy X Get Y) ===
|
|
1749
|
+
* Mirrors extensions/bundle-theme/assets/bundle-bogo.css translated to this
|
|
1750
|
+
* stylesheet's var-fallback convention. */
|
|
1751
|
+
|
|
1752
|
+
/* The "+" divider between the buy and get cards — a small accent medallion
|
|
1753
|
+
so the offer's hinge stands out. */
|
|
1754
|
+
.lb-bogo__plus {
|
|
1755
|
+
align-self: center;
|
|
1756
|
+
display: inline-flex;
|
|
1757
|
+
align-items: center;
|
|
1758
|
+
justify-content: center;
|
|
1759
|
+
width: 24px;
|
|
1760
|
+
height: 24px;
|
|
1761
|
+
border-radius: 50%;
|
|
1762
|
+
background: var(--lb-primary-color, var(--lb-button-bg));
|
|
1763
|
+
color: var(--lb-btn-text, var(--lb-button-text));
|
|
1764
|
+
}
|
|
1765
|
+
|
|
1766
|
+
/* Reward badge on the get card — a right-slot chip family member
|
|
1767
|
+
(WIDGET-DESIGN.md): 28px neutral silhouette, small radius, 13/600. */
|
|
1768
|
+
.lb-bogo__badge {
|
|
1769
|
+
display: inline-flex;
|
|
1770
|
+
align-items: center;
|
|
1771
|
+
align-self: flex-start;
|
|
1772
|
+
flex-shrink: 0;
|
|
1773
|
+
height: 28px;
|
|
1774
|
+
padding: 0 8px;
|
|
1775
|
+
border-radius: var(--lb-radius-sm, 4px);
|
|
1776
|
+
background: color-mix(in srgb, var(--lb-text, var(--lb-primary-color)) 7%, transparent);
|
|
1777
|
+
color: color-mix(in srgb, var(--lb-text, var(--lb-primary-color)) 75%, transparent);
|
|
1778
|
+
font-size: 13px;
|
|
1779
|
+
font-weight: 600;
|
|
1780
|
+
line-height: 1;
|
|
1781
|
+
white-space: nowrap;
|
|
1782
|
+
}
|
|
1783
|
+
|
|
1784
|
+
/* ───────────────────────────────────────────────────────────────────
|
|
1785
|
+
Countdown timer bar — ported from the theme's bundle-base.css. The
|
|
1786
|
+
theme insets with --lb-widget-pad; this stylesheet's root uses a fixed
|
|
1787
|
+
20px pad, so the full-bleed margins use the same constant.
|
|
1788
|
+
─────────────────────────────────────────────────────────────────── */
|
|
1789
|
+
|
|
1790
|
+
.lb-bundle-countdown {
|
|
1791
|
+
margin: 0 -20px 20px;
|
|
1792
|
+
padding: 12px 20px;
|
|
1793
|
+
background: var(--lb-countdown-bg);
|
|
1794
|
+
display: flex;
|
|
1795
|
+
align-items: center;
|
|
1796
|
+
justify-content: space-between;
|
|
1797
|
+
}
|
|
1798
|
+
|
|
1799
|
+
.lb-bundle-countdown__label {
|
|
1800
|
+
display: flex;
|
|
1801
|
+
align-items: center;
|
|
1802
|
+
gap: 8px;
|
|
1803
|
+
}
|
|
1804
|
+
|
|
1805
|
+
.lb-bundle-countdown__label span {
|
|
1806
|
+
font-size: 12px;
|
|
1807
|
+
font-weight: 500;
|
|
1808
|
+
line-height: 1;
|
|
1809
|
+
color: var(--lb-countdown-text);
|
|
1810
|
+
}
|
|
1811
|
+
|
|
1812
|
+
.lb-bundle-countdown__timer {
|
|
1813
|
+
font-family: 'SF Mono', 'Roboto Mono', ui-monospace, monospace;
|
|
1814
|
+
font-size: 12px;
|
|
1815
|
+
font-weight: 600;
|
|
1816
|
+
line-height: 1;
|
|
1817
|
+
color: var(--lb-countdown-text);
|
|
1818
|
+
letter-spacing: 0.02em;
|
|
1819
|
+
}
|
|
1820
|
+
|
|
1821
|
+
/* ───────────────────────────────────────────────────────────────────
|
|
1822
|
+
Multi-step groups — ported from the theme's bundle-multi-step.css.
|
|
1823
|
+
The step-group markup shares the theme's class names; without these
|
|
1824
|
+
rules the step name and count chip render as unstyled run-on text.
|
|
1825
|
+
─────────────────────────────────────────────────────────────────── */
|
|
1826
|
+
|
|
1827
|
+
.lb-multi-step__groups {
|
|
1828
|
+
display: flex;
|
|
1829
|
+
flex-direction: column;
|
|
1830
|
+
gap: 16px;
|
|
1831
|
+
}
|
|
1832
|
+
|
|
1833
|
+
.lb-multi-step__group {
|
|
1834
|
+
display: flex;
|
|
1835
|
+
flex-direction: column;
|
|
1836
|
+
gap: 8px;
|
|
1837
|
+
}
|
|
1838
|
+
|
|
1839
|
+
/* Heading is a quiet, non-interactive row: step name left, live count
|
|
1840
|
+
chip right. */
|
|
1841
|
+
.lb-multi-step__group-heading {
|
|
1842
|
+
display: flex;
|
|
1843
|
+
align-items: center;
|
|
1844
|
+
justify-content: space-between;
|
|
1845
|
+
gap: 12px;
|
|
1846
|
+
color: var(--lb-text);
|
|
1847
|
+
}
|
|
1848
|
+
|
|
1849
|
+
.lb-multi-step__group-name {
|
|
1850
|
+
font-size: 14px;
|
|
1851
|
+
font-weight: 600;
|
|
1852
|
+
line-height: 1.4;
|
|
1853
|
+
}
|
|
1854
|
+
|
|
1855
|
+
/* Count chip — right-slot chip family (28px, 0 8px, radius-sm, 13/500,
|
|
1856
|
+
neutral 7%/75% fill). Weight-only emphasis when the step is met. */
|
|
1857
|
+
.lb-multi-step__group-count {
|
|
1858
|
+
display: inline-flex;
|
|
1859
|
+
align-items: center;
|
|
1860
|
+
height: 28px;
|
|
1861
|
+
padding: 0 8px;
|
|
1862
|
+
border-radius: var(--lb-radius-sm);
|
|
1863
|
+
background: color-mix(in srgb, var(--lb-text) 7%, transparent);
|
|
1864
|
+
color: color-mix(in srgb, var(--lb-text) 75%, transparent);
|
|
1865
|
+
font-size: 13px;
|
|
1866
|
+
font-weight: 500;
|
|
1867
|
+
white-space: nowrap;
|
|
1868
|
+
}
|
|
1869
|
+
|
|
1870
|
+
.lb-multi-step__group-count--met {
|
|
1871
|
+
font-weight: 600;
|
|
1872
|
+
}
|
|
1873
|
+
|
|
1874
|
+
/* Empty step group: the slots container collapses so the heading rows
|
|
1875
|
+
read as a compact checklist until picks land. */
|
|
1876
|
+
.lb-multi-step__group-slots:empty {
|
|
1877
|
+
display: none;
|
|
1878
|
+
}
|
|
1879
|
+
|
|
1880
|
+
/* ── Wizard modal footer: [Back] [count] [Next|Done] ─────────── */
|
|
1881
|
+
|
|
1882
|
+
.lb-multi-step__modal-footer {
|
|
1883
|
+
display: grid;
|
|
1884
|
+
grid-template-columns: 1fr auto 1fr;
|
|
1885
|
+
align-items: center;
|
|
1886
|
+
gap: 12px;
|
|
1887
|
+
}
|
|
1888
|
+
|
|
1889
|
+
.lb-multi-step__modal-footer > .lb-multi-step__modal-back {
|
|
1890
|
+
grid-area: 1 / 1;
|
|
1891
|
+
justify-self: start;
|
|
1892
|
+
}
|
|
1893
|
+
|
|
1894
|
+
.lb-multi-step__modal-footer > .lb-mix-match__modal-footer-count {
|
|
1895
|
+
grid-area: 1 / 2;
|
|
1896
|
+
text-align: center;
|
|
1897
|
+
}
|
|
1898
|
+
|
|
1899
|
+
.lb-multi-step__modal-footer > .lb-mix-match__modal-done {
|
|
1900
|
+
grid-area: 1 / 3;
|
|
1901
|
+
justify-self: end;
|
|
1902
|
+
}
|
|
1903
|
+
|
|
1904
|
+
.lb-multi-step__modal-back {
|
|
1905
|
+
display: inline-flex;
|
|
1906
|
+
align-items: center;
|
|
1907
|
+
justify-content: center;
|
|
1908
|
+
min-height: 40px;
|
|
1909
|
+
padding: 10px 24px;
|
|
1910
|
+
background: none;
|
|
1911
|
+
border: var(--lb-picker-border-width) solid var(--lb-picker-border-color);
|
|
1912
|
+
border-radius: var(--lb-picker-radius-sm);
|
|
1913
|
+
box-sizing: border-box;
|
|
1914
|
+
color: var(--lb-picker-text);
|
|
1915
|
+
font-family: inherit;
|
|
1916
|
+
font-size: 14px;
|
|
1917
|
+
font-weight: 600;
|
|
1918
|
+
cursor: pointer;
|
|
1919
|
+
transition: background-color 0.25s ease;
|
|
1920
|
+
}
|
|
1921
|
+
|
|
1922
|
+
.lb-multi-step__modal-back:hover {
|
|
1923
|
+
background: color-mix(in srgb, var(--lb-picker-text) 5%, transparent);
|
|
1924
|
+
}
|
|
1925
|
+
|
|
1926
|
+
.lb-multi-step__modal-back:focus-visible {
|
|
1927
|
+
outline: 2px solid var(--lb-primary-color);
|
|
1928
|
+
outline-offset: 2px;
|
|
1929
|
+
}
|