@lime-bundles/widget 4.5.0 → 4.5.1

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/dist/index.cjs CHANGED
@@ -3574,6 +3574,8 @@ function mergeCartLines(selections) {
3574
3574
  var ALL_TYPES2 = "__all__";
3575
3575
  var CLOSE_TRANSITION_MS2 = 300;
3576
3576
  var SEARCH_DEBOUNCE_MS2 = 200;
3577
+ var STEP_CASCADE_MS = 500;
3578
+ var AUTO_ADVANCE_HOLD_MS = 160;
3577
3579
  function createWizard(deps) {
3578
3580
  const { container, steps, selections, t } = deps;
3579
3581
  const overlay = container.querySelector("[data-modal-overlay]");
@@ -3598,6 +3600,8 @@ function createWizard(deps) {
3598
3600
  let modalOpen = false;
3599
3601
  let stepIndex = 0;
3600
3602
  let rows = [];
3603
+ let cascadeTimer = null;
3604
+ let autoAdvanceTimer = null;
3601
3605
  const productsFor = (i) => steps[i].eligibleProducts || [];
3602
3606
  const rowCapacity = {
3603
3607
  remainingSpots: () => stepHeadroom(selections, steps, stepIndex),
@@ -3698,7 +3702,13 @@ function createWizard(deps) {
3698
3702
  if (!deps.autoAdvance) return;
3699
3703
  if (stepIndex >= steps.length - 1) return;
3700
3704
  if (stepHeadroom(selections, steps, stepIndex) !== 0) return;
3701
- goToStep(stepIndex + 1);
3705
+ const from = stepIndex;
3706
+ if (autoAdvanceTimer !== null) clearTimeout(autoAdvanceTimer);
3707
+ autoAdvanceTimer = setTimeout(() => {
3708
+ autoAdvanceTimer = null;
3709
+ if (!modalOpen) return;
3710
+ goToStep(from + 1);
3711
+ }, AUTO_ADVANCE_HOLD_MS);
3702
3712
  }
3703
3713
  function buildProductList(forStep) {
3704
3714
  if (!modalList) return;
@@ -3886,7 +3896,29 @@ function createWizard(deps) {
3886
3896
  });
3887
3897
  }
3888
3898
  function goToStep(i, opts = {}) {
3889
- stepIndex = Math.max(0, Math.min(steps.length - 1, i));
3899
+ const target = Math.max(0, Math.min(steps.length - 1, i));
3900
+ if (autoAdvanceTimer !== null) {
3901
+ clearTimeout(autoAdvanceTimer);
3902
+ autoAdvanceTimer = null;
3903
+ }
3904
+ if (modalDialog) {
3905
+ if (cascadeTimer !== null) clearTimeout(cascadeTimer);
3906
+ cascadeTimer = null;
3907
+ modalDialog.removeAttribute("data-step-transition");
3908
+ if (opts.animate !== false && target !== stepIndex) {
3909
+ void modalDialog.offsetHeight;
3910
+ modalDialog.setAttribute(
3911
+ "data-step-transition",
3912
+ target > stepIndex ? "forward" : "back"
3913
+ );
3914
+ const dialog = modalDialog;
3915
+ cascadeTimer = setTimeout(() => {
3916
+ cascadeTimer = null;
3917
+ dialog.removeAttribute("data-step-transition");
3918
+ }, STEP_CASCADE_MS);
3919
+ }
3920
+ }
3921
+ stepIndex = target;
3890
3922
  buildProductList(stepIndex);
3891
3923
  buildFilters(stepIndex);
3892
3924
  activeType = ALL_TYPES2;
@@ -3911,7 +3943,10 @@ function createWizard(deps) {
3911
3943
  function open(atStep) {
3912
3944
  if (!overlay || modalOpen) return;
3913
3945
  modalOpen = true;
3914
- goToStep(typeof atStep === "number" ? atStep : 0, { skipFocus: true });
3946
+ goToStep(typeof atStep === "number" ? atStep : 0, {
3947
+ skipFocus: true,
3948
+ animate: false
3949
+ });
3915
3950
  overlay.style.display = "";
3916
3951
  void overlay.offsetHeight;
3917
3952
  overlay.classList.add("lb-mix-match__modal-overlay--open");
@@ -3924,6 +3959,14 @@ function createWizard(deps) {
3924
3959
  function close() {
3925
3960
  if (!overlay || !modalOpen) return;
3926
3961
  modalOpen = false;
3962
+ if (autoAdvanceTimer !== null) {
3963
+ clearTimeout(autoAdvanceTimer);
3964
+ autoAdvanceTimer = null;
3965
+ }
3966
+ if (cascadeTimer !== null) {
3967
+ clearTimeout(cascadeTimer);
3968
+ cascadeTimer = null;
3969
+ }
3927
3970
  overlay.classList.remove("lb-mix-match__modal-overlay--open");
3928
3971
  unlock();
3929
3972
  setTimeout(() => {
@@ -4311,11 +4354,18 @@ var BUNDLE_BASE_CSS = `/* Lime Bundles \u2014 shared base styles for all bundle
4311
4354
  --lb-list-max-height: 360px;
4312
4355
  /* Depth of the soft fade at a scroll list's clipped edge. */
4313
4356
  --lb-edge-fade-size: 20px;
4314
- /* Derived "small" corner radius for inner controls (thumbnails, variant
4315
- selects, the qty chip). One step tighter than the global --lb-radius so
4316
- small elements stay proportionate. Both come from the global radius
4317
- preset; nothing else sets a radius. */
4318
- --lb-radius-sm: max(0px, calc(var(--lb-radius) - 4px));
4357
+ /* Derived "small" corner radius for chips and badges \u2014 the low-stock badge,
4358
+ the volume tier badge, the multi-step count chip. Controls and media
4359
+ (thumbnails, selects, steppers, buttons) take the full --lb-radius: they
4360
+ are the elements the merchant is looking at when they pick a preset, and
4361
+ the picker's own help text already promises they follow it.
4362
+
4363
+ Proportional rather than a fixed subtraction. At "subtle" (6px) minus-4px
4364
+ left 2px, which reads as square \u2014 the merchant saw a picker set to Subtle
4365
+ render with sharp corners (issue #363). Two thirds holds the proportion at
4366
+ every preset: none 0, subtle 4px, rounded 8px, round 12px. No max() needed,
4367
+ since 0 \xD7 \u2154 is 0. */
4368
+ --lb-radius-sm: calc(var(--lb-radius) * 2 / 3);
4319
4369
 
4320
4370
  font-family: inherit;
4321
4371
  font-size: 16px;
@@ -4479,7 +4529,7 @@ var BUNDLE_BASE_CSS = `/* Lime Bundles \u2014 shared base styles for all bundle
4479
4529
  ratio. Default keeps the historical 1:1 behaviour. */
4480
4530
  aspect-ratio: var(--lb-thumbnail-aspect-ratio, 1 / 1);
4481
4531
  background: var(--lb-thumbnail-bg);
4482
- border-radius: var(--lb-radius-sm);
4532
+ border-radius: var(--lb-radius);
4483
4533
  overflow: hidden;
4484
4534
  display: flex;
4485
4535
  align-items: center;
@@ -5029,12 +5079,12 @@ var BUNDLE_FIXED_CSS = `/* Lime Bundles \u2014 Fixed bundle styles */
5029
5079
  .lb-fixed .lb-bundle-thumbnail {
5030
5080
  width: 60px;
5031
5081
  min-width: 60px;
5032
- border-radius: var(--lb-radius-sm);
5082
+ border-radius: var(--lb-radius);
5033
5083
  box-sizing: border-box;
5034
5084
  }
5035
5085
 
5036
5086
  .lb-fixed .lb-bundle-thumbnail img {
5037
- border-radius: var(--lb-radius-sm);
5087
+ border-radius: var(--lb-radius);
5038
5088
  border: none;
5039
5089
  }
5040
5090
 
@@ -5051,7 +5101,7 @@ var BUNDLE_FIXED_CSS = `/* Lime Bundles \u2014 Fixed bundle styles */
5051
5101
  display: var(--lb-product-qty-chip-display, inline-flex);
5052
5102
  align-items: center;
5053
5103
  justify-content: center;
5054
- border-radius: var(--lb-radius-sm);
5104
+ border-radius: var(--lb-radius);
5055
5105
  background: color-mix(in srgb, var(--lb-text) 7%, transparent);
5056
5106
  color: color-mix(in srgb, var(--lb-text) 75%, transparent);
5057
5107
  font-size: 13px;
@@ -5067,7 +5117,7 @@ var BUNDLE_FIXED_CSS = `/* Lime Bundles \u2014 Fixed bundle styles */
5067
5117
  .lb-bundle-variant-select {
5068
5118
  display: inline-block;
5069
5119
  border: var(--lb-border-width) solid var(--lb-border);
5070
- border-radius: var(--lb-radius-sm);
5120
+ border-radius: var(--lb-radius);
5071
5121
  padding: 8px 32px 8px 12px;
5072
5122
  font-size: 12px;
5073
5123
  line-height: 16px;
@@ -5215,12 +5265,12 @@ var BUNDLE_MIX_MATCH_CSS = `/* Lime Bundles \u2014 Mix & Match styles */
5215
5265
  position: relative;
5216
5266
  width: 60px;
5217
5267
  min-width: 60px;
5218
- border-radius: var(--lb-radius-sm);
5268
+ border-radius: var(--lb-radius);
5219
5269
  box-sizing: border-box;
5220
5270
  }
5221
5271
 
5222
5272
  .lb-mix-match .lb-bundle-thumbnail img {
5223
- border-radius: var(--lb-radius-sm);
5273
+ border-radius: var(--lb-radius);
5224
5274
  border: none;
5225
5275
  }
5226
5276
 
@@ -5386,14 +5436,26 @@ var BUNDLE_MIX_MATCH_CSS = `/* Lime Bundles \u2014 Mix & Match styles */
5386
5436
  color: inherit;
5387
5437
  }
5388
5438
 
5389
- /* Derived "small" radius for the picker's inner controls (search, thumbnails,
5390
- variant select, qty stepper, Add/Done buttons), one step tighter than the
5391
- modal's --lb-picker-radius \u2014 the picker-scoped mirror of --lb-radius-sm in the
5392
- main widget. Defined on the overlay so the modal AND the variant listbox
5393
- (which portals up to [data-modal-overlay]) both inherit it. The modal shell
5394
- and product tiles keep the full --lb-picker-radius. */
5439
+ /* Derived "small" radius for the picker's chips and badges \u2014 the progress
5440
+ segments, the "Added" badge, the close button, the filter pills. The
5441
+ picker-scoped mirror of --lb-radius-sm, and proportional for the same reason
5442
+ (see bundle-base.css).
5443
+
5444
+ Everything the merchant would call a control or an image \u2014 the modal, search,
5445
+ product tiles, thumbnails, variant dropdown, quantity stepper and the
5446
+ buttons \u2014 takes the full --lb-picker-radius instead. That is what the
5447
+ editor's own Borders copy promises them, and the reduced tier had it
5448
+ rendering square at the Subtle preset (issue #363).
5449
+
5450
+ Declared on BOTH hosts the modal can live under. On the storefront it portals
5451
+ to [data-modal-overlay], which the variant listbox portals up to as well. In
5452
+ the admin widget editor there is no overlay at all \u2014 the preview renders the
5453
+ modal directly under .lb-bundle-widget \u2014 so scoping this to the overlay alone
5454
+ left the variable undefined there and every control using it fell back to
5455
+ square corners while the modal and tiles rounded correctly (issue #363). */
5456
+ .lb-bundle-widget,
5395
5457
  [data-modal-overlay] {
5396
- --lb-picker-radius-sm: max(0px, calc(var(--lb-picker-radius) - 4px));
5458
+ --lb-picker-radius-sm: calc(var(--lb-picker-radius) * 2 / 3);
5397
5459
  }
5398
5460
 
5399
5461
  /* === Modal Overlay === */
@@ -5490,7 +5552,7 @@ var BUNDLE_MIX_MATCH_CSS = `/* Lime Bundles \u2014 Mix & Match styles */
5490
5552
  border: none;
5491
5553
  cursor: pointer;
5492
5554
  color: var(--lb-picker-text);
5493
- border-radius: 8px;
5555
+ border-radius: var(--lb-picker-radius-sm);
5494
5556
  padding: 0;
5495
5557
  margin: -12px -12px 0 0;
5496
5558
  transition: background 0.25s ease;
@@ -5520,7 +5582,9 @@ var BUNDLE_MIX_MATCH_CSS = `/* Lime Bundles \u2014 Mix & Match styles */
5520
5582
  .lb-mix-match__filter {
5521
5583
  padding: 6px 14px;
5522
5584
  border: var(--lb-picker-border-width) solid var(--lb-picker-border-color);
5523
- border-radius: 999px;
5585
+ /* Pills followed the merchant's picker radius as of #363 \u2014 a fixed 999px
5586
+ read as a stray rounded shape in a picker set to None or Subtle. */
5587
+ border-radius: var(--lb-picker-radius-sm);
5524
5588
  background: transparent;
5525
5589
  color: var(--lb-picker-text);
5526
5590
  font-family: inherit;
@@ -5574,7 +5638,7 @@ var BUNDLE_MIX_MATCH_CSS = `/* Lime Bundles \u2014 Mix & Match styles */
5574
5638
  width: 100%;
5575
5639
  padding: 12px 40px 12px 44px;
5576
5640
  border: var(--lb-picker-border-width) solid var(--lb-picker-border-color);
5577
- border-radius: var(--lb-picker-radius-sm);
5641
+ border-radius: var(--lb-picker-radius);
5578
5642
  font-size: 16px;
5579
5643
  line-height: 20px;
5580
5644
  color: var(--lb-picker-text);
@@ -5674,7 +5738,7 @@ var BUNDLE_MIX_MATCH_CSS = `/* Lime Bundles \u2014 Mix & Match styles */
5674
5738
  independent from the main widget's thumbnailRatio so a merchant can
5675
5739
  e.g. show tall picker thumbs with square main thumbs. */
5676
5740
  aspect-ratio: var(--lb-picker-thumbnail-aspect-ratio, 1 / 1);
5677
- border-radius: var(--lb-picker-radius-sm);
5741
+ border-radius: var(--lb-picker-radius);
5678
5742
  box-sizing: border-box;
5679
5743
  overflow: hidden;
5680
5744
  background: var(--lb-thumbnail-bg);
@@ -5687,7 +5751,7 @@ var BUNDLE_MIX_MATCH_CSS = `/* Lime Bundles \u2014 Mix & Match styles */
5687
5751
  to auto/contain so the image renders uncropped at intrinsic ratio. */
5688
5752
  height: var(--lb-picker-thumbnail-img-height, 100%);
5689
5753
  object-fit: var(--lb-picker-thumbnail-img-fit, cover);
5690
- border-radius: var(--lb-picker-radius-sm);
5754
+ border-radius: var(--lb-picker-radius);
5691
5755
  }
5692
5756
 
5693
5757
  .lb-mix-match__modal-product-info {
@@ -5762,7 +5826,7 @@ var BUNDLE_MIX_MATCH_CSS = `/* Lime Bundles \u2014 Mix & Match styles */
5762
5826
  font-size: 12px;
5763
5827
  padding: 4px 24px 4px 8px;
5764
5828
  border: var(--lb-picker-border-width) solid var(--lb-picker-border-color);
5765
- border-radius: var(--lb-picker-radius-sm);
5829
+ border-radius: var(--lb-picker-radius);
5766
5830
  background-color: var(--lb-picker-bg);
5767
5831
  background-image: var(--lb-picker-variant-chevron);
5768
5832
  background-repeat: no-repeat;
@@ -5813,7 +5877,7 @@ var BUNDLE_MIX_MATCH_CSS = `/* Lime Bundles \u2014 Mix & Match styles */
5813
5877
  width: 100%;
5814
5878
  flex-shrink: 0;
5815
5879
  border: var(--lb-picker-border-width) solid var(--lb-picker-border-color);
5816
- border-radius: var(--lb-picker-radius-sm);
5880
+ border-radius: var(--lb-picker-radius);
5817
5881
  background-color: var(--lb-picker-bg);
5818
5882
  overflow: hidden;
5819
5883
  box-sizing: border-box;
@@ -5890,7 +5954,7 @@ var BUNDLE_MIX_MATCH_CSS = `/* Lime Bundles \u2014 Mix & Match styles */
5890
5954
  background: var(--lb-picker-add-bg);
5891
5955
  color: var(--lb-picker-add-label);
5892
5956
  border: var(--lb-picker-add-border-width) solid var(--lb-picker-add-border-color);
5893
- border-radius: var(--lb-picker-radius-sm);
5957
+ border-radius: var(--lb-picker-radius);
5894
5958
  box-sizing: border-box;
5895
5959
  font-size: 12px;
5896
5960
  font-weight: 600;
@@ -6031,7 +6095,7 @@ var BUNDLE_MIX_MATCH_CSS = `/* Lime Bundles \u2014 Mix & Match styles */
6031
6095
  background: var(--lb-picker-add-bg);
6032
6096
  color: var(--lb-picker-add-label);
6033
6097
  border: var(--lb-picker-add-border-width) solid var(--lb-picker-add-border-color);
6034
- border-radius: var(--lb-picker-radius-sm);
6098
+ border-radius: var(--lb-picker-radius);
6035
6099
  box-sizing: border-box;
6036
6100
  font-family: inherit;
6037
6101
  font-size: 14px;
@@ -6080,7 +6144,9 @@ var BUNDLE_MIX_MATCH_CSS = `/* Lime Bundles \u2014 Mix & Match styles */
6080
6144
  .lb-mix-match__modal {
6081
6145
  max-width: 100%;
6082
6146
  max-height: 90vh;
6083
- border-radius: 16px 16px 0 0;
6147
+ /* Bottom sheet: only the top corners round, but they round to whatever the
6148
+ merchant picked rather than a fixed 16px (issue #363). */
6149
+ border-radius: var(--lb-picker-radius) var(--lb-picker-radius) 0 0;
6084
6150
  transform: translateY(100%);
6085
6151
  }
6086
6152
 
@@ -6347,12 +6413,12 @@ var BUNDLE_BOGO_CSS = `/* Lime Bundles \u2014 BOGO (Buy X Get Y) bundle styles *
6347
6413
  .lb-bogo .lb-bundle-thumbnail {
6348
6414
  width: 60px;
6349
6415
  min-width: 60px;
6350
- border-radius: var(--lb-radius-sm);
6416
+ border-radius: var(--lb-radius);
6351
6417
  box-sizing: border-box;
6352
6418
  }
6353
6419
 
6354
6420
  .lb-bogo .lb-bundle-thumbnail img {
6355
- border-radius: var(--lb-radius-sm);
6421
+ border-radius: var(--lb-radius);
6356
6422
  border: none;
6357
6423
  }
6358
6424
 
@@ -6473,6 +6539,13 @@ var BUNDLE_MULTI_STEP_CSS = `/**
6473
6539
  cursor: pointer;
6474
6540
  box-sizing: border-box;
6475
6541
  transition: background-color 0.25s ease;
6542
+ /* Deliberately no border-radius. This row paints the checklist hairline as
6543
+ its own border-top (see the run rule above), and a radius tapers that
6544
+ border into the corner arcs \u2014 the dividers came out visibly curved at the
6545
+ "round" preset (issue #363). A full-bleed list row is meant to be square
6546
+ anyway; the hover tint below spans the card width, so it has no corner to
6547
+ round against. The :focus-visible radius is fine: an outline is a
6548
+ separate paint and never touches the border. */
6476
6549
  }
6477
6550
 
6478
6551
  .lb-multi-step__step-row:hover {
@@ -6620,7 +6693,7 @@ var BUNDLE_MULTI_STEP_CSS = `/**
6620
6693
  padding: 10px 24px;
6621
6694
  background: none;
6622
6695
  border: var(--lb-picker-border-width) solid var(--lb-picker-border-color);
6623
- border-radius: var(--lb-picker-radius-sm);
6696
+ border-radius: var(--lb-picker-radius);
6624
6697
  box-sizing: border-box;
6625
6698
  color: var(--lb-picker-text);
6626
6699
  font-family: inherit;
@@ -6638,6 +6711,108 @@ var BUNDLE_MULTI_STEP_CSS = `/**
6638
6711
  outline: 2px solid var(--lb-primary-color);
6639
6712
  outline-offset: 2px;
6640
6713
  }
6714
+
6715
+ /* \u2500\u2500 Step-change transition \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
6716
+ Moving between steps swaps the whole step-scoped region in a single
6717
+ paint, which reads as nothing happening (or as a glitch) rather than
6718
+ as arriving somewhere new \u2014 and worst of all under auto-advance,
6719
+ where the shopper never clicked anything. So the step assembles
6720
+ instead of arriving whole: the step label leads, the filter pills
6721
+ follow, then the product cards one after another. Staging is what
6722
+ makes the change legible; a uniform slide of everything at once only
6723
+ wobbles the card.
6724
+
6725
+ The wizard stamps data-step-transition="forward" | "back" on the
6726
+ dialog on every step change (manual Next/Back and auto-advance
6727
+ alike, never on open, where the modal entrance already carries the
6728
+ motion), and clears it again once the cascade has played \u2014 see
6729
+ STEP_CASCADE_MS in multi-step/wizard.ts. That clear is load-bearing,
6730
+ not tidiness: search and filter hide cards with .lb-hidden
6731
+ (display: none), and restoring display restarts a card's animation,
6732
+ so a live attribute would replay the whole cascade on every
6733
+ keystroke that reveals a card.
6734
+
6735
+ Two elements deliberately hold still. The footer, because Back/Next
6736
+ are the shopper's anchor while everything above them moves. And the
6737
+ progress rail, because it is the one thing that answers "where am I
6738
+ now" \u2014 animating the shopper's only orientation cue is what made the
6739
+ previous version hard to read. Its segment fill carries its own
6740
+ state change already. */
6741
+ @keyframes lb-multi-step-cascade-fwd {
6742
+ from {
6743
+ opacity: 0;
6744
+ transform: translateY(10px);
6745
+ }
6746
+ }
6747
+
6748
+ @keyframes lb-multi-step-cascade-back {
6749
+ from {
6750
+ opacity: 0;
6751
+ transform: translateY(-10px);
6752
+ }
6753
+ }
6754
+
6755
+ .lb-mix-match__modal[data-step-transition] .lb-mix-match__modal-subtitle {
6756
+ animation: lb-multi-step-cascade-fwd 0.2s ease-out both;
6757
+ }
6758
+
6759
+ .lb-mix-match__modal[data-step-transition] .lb-mix-match__filters {
6760
+ animation: lb-multi-step-cascade-fwd 0.2s ease-out 0.05s both;
6761
+ }
6762
+
6763
+ /* Cards stagger 30ms apart, but only the first four: a step can hold
6764
+ dozens of products and the two-column grid shows about four at a
6765
+ time, so past that the stagger is below the fold and would only add
6766
+ lag. Everything from the fifth on shares the fourth's landing. */
6767
+ .lb-mix-match__modal[data-step-transition] .lb-mix-match__modal-list > * {
6768
+ animation: lb-multi-step-cascade-fwd 0.22s ease-out 0.2s both;
6769
+ }
6770
+
6771
+ .lb-mix-match__modal[data-step-transition] .lb-mix-match__modal-list > :nth-child(1) {
6772
+ animation-delay: 0.09s;
6773
+ }
6774
+
6775
+ .lb-mix-match__modal[data-step-transition] .lb-mix-match__modal-list > :nth-child(2) {
6776
+ animation-delay: 0.12s;
6777
+ }
6778
+
6779
+ .lb-mix-match__modal[data-step-transition] .lb-mix-match__modal-list > :nth-child(3) {
6780
+ animation-delay: 0.15s;
6781
+ }
6782
+
6783
+ .lb-mix-match__modal[data-step-transition] .lb-mix-match__modal-list > :nth-child(4) {
6784
+ animation-delay: 0.18s;
6785
+ }
6786
+
6787
+ /* Going back runs the same cascade in the same order \u2014 only the offset
6788
+ flips, so the shopper still reads which way they moved. Overrides
6789
+ the name alone; the staggered delays above must survive. */
6790
+ .lb-mix-match__modal[data-step-transition="back"] .lb-mix-match__modal-subtitle,
6791
+ .lb-mix-match__modal[data-step-transition="back"] .lb-mix-match__filters,
6792
+ .lb-mix-match__modal[data-step-transition="back"] .lb-mix-match__modal-list > * {
6793
+ animation-name: lb-multi-step-cascade-back;
6794
+ }
6795
+
6796
+ @keyframes lb-multi-step-cascade-fade {
6797
+ from {
6798
+ opacity: 0;
6799
+ }
6800
+ }
6801
+
6802
+ /* Reduced motion keeps the fade and drops the travel and the stagger:
6803
+ the step change still has to be perceptible, which is the whole
6804
+ point of this block. The card selector is :nth-child(n) rather than
6805
+ * on purpose \u2014 a plain * loses to the :nth-child(1..4) delays above
6806
+ on specificity, which would leave the stagger running with nothing
6807
+ moving. :nth-child(n) matches every child at equal specificity and
6808
+ wins on order. */
6809
+ @media (prefers-reduced-motion: reduce) {
6810
+ .lb-mix-match__modal[data-step-transition] .lb-mix-match__modal-subtitle,
6811
+ .lb-mix-match__modal[data-step-transition] .lb-mix-match__filters,
6812
+ .lb-mix-match__modal[data-step-transition] .lb-mix-match__modal-list > :nth-child(n) {
6813
+ animation: lb-multi-step-cascade-fade 0.15s ease-out both;
6814
+ }
6815
+ }
6641
6816
  `;
6642
6817
  var BUNDLE_DROPDOWN_CSS = `/**
6643
6818
  * Lime Bundles \u2014 Custom variant-picker dropdown styling.
@@ -6685,7 +6860,7 @@ var BUNDLE_DROPDOWN_CSS = `/**
6685
6860
  gap: 8px;
6686
6861
  width: 100%;
6687
6862
  border: var(--lb-border-width) solid var(--lb-border);
6688
- border-radius: var(--lb-radius-sm);
6863
+ border-radius: var(--lb-radius);
6689
6864
  padding: 8px 12px;
6690
6865
  font-size: 12px;
6691
6866
  line-height: 16px;
@@ -6748,7 +6923,7 @@ var BUNDLE_DROPDOWN_CSS = `/**
6748
6923
  background: var(--lb-bg);
6749
6924
  color: var(--lb-text);
6750
6925
  border: var(--lb-border-width) solid var(--lb-border);
6751
- border-radius: var(--lb-radius-sm);
6926
+ border-radius: var(--lb-radius);
6752
6927
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.08);
6753
6928
  overflow-y: auto;
6754
6929
  overflow-x: hidden;
@@ -6809,6 +6984,10 @@ var BUNDLE_DROPDOWN_CSS = `/**
6809
6984
  overflow: hidden;
6810
6985
  text-overflow: ellipsis;
6811
6986
  color: var(--lb-text);
6987
+ /* The active/hover tint below fills the option, so it rounds with the rest
6988
+ of the widget rather than squaring off against the listbox corner it sits
6989
+ in (issue #363). */
6990
+ border-radius: var(--lb-radius-sm);
6812
6991
  }
6813
6992
 
6814
6993
  .lb-dropdown-option[aria-selected="true"] {
@@ -6867,7 +7046,7 @@ var BUNDLE_DROPDOWN_CSS = `/**
6867
7046
  .lb-mix-match__modal .lb-dropdown-trigger {
6868
7047
  border-color: var(--lb-picker-border-color);
6869
7048
  border-width: var(--lb-picker-border-width);
6870
- border-radius: var(--lb-picker-radius-sm);
7049
+ border-radius: var(--lb-picker-radius);
6871
7050
  background: var(--lb-picker-bg);
6872
7051
  color: var(--lb-picker-text);
6873
7052
  /* Match the picker qty stepper + Add button height (border-box so 32px is
@@ -6888,13 +7067,17 @@ var BUNDLE_DROPDOWN_CSS = `/**
6888
7067
  [data-modal-overlay] > .lb-dropdown-listbox {
6889
7068
  border-color: var(--lb-picker-border-color);
6890
7069
  border-width: var(--lb-picker-border-width);
6891
- border-radius: var(--lb-picker-radius-sm);
7070
+ border-radius: var(--lb-picker-radius);
6892
7071
  background: var(--lb-picker-bg);
6893
7072
  color: var(--lb-picker-text);
6894
7073
  scrollbar-color: color-mix(in srgb, var(--lb-picker-text) 15%, transparent)
6895
7074
  color-mix(in srgb, var(--lb-picker-text) 2%, transparent);
6896
7075
  }
6897
7076
 
7077
+ [data-modal-overlay] > .lb-dropdown-listbox .lb-dropdown-option {
7078
+ border-radius: var(--lb-picker-radius-sm);
7079
+ }
7080
+
6898
7081
  [data-modal-overlay] > .lb-dropdown-listbox::-webkit-scrollbar-track {
6899
7082
  background: color-mix(in srgb, var(--lb-picker-text) 2%, transparent);
6900
7083
  border-radius: 2px;