@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.js CHANGED
@@ -3582,6 +3582,8 @@ function mergeCartLines(selections) {
3582
3582
  var ALL_TYPES2 = "__all__";
3583
3583
  var CLOSE_TRANSITION_MS2 = 300;
3584
3584
  var SEARCH_DEBOUNCE_MS2 = 200;
3585
+ var STEP_CASCADE_MS = 500;
3586
+ var AUTO_ADVANCE_HOLD_MS = 160;
3585
3587
  function createWizard(deps) {
3586
3588
  const { container, steps, selections, t } = deps;
3587
3589
  const overlay = container.querySelector("[data-modal-overlay]");
@@ -3606,6 +3608,8 @@ function createWizard(deps) {
3606
3608
  let modalOpen = false;
3607
3609
  let stepIndex = 0;
3608
3610
  let rows = [];
3611
+ let cascadeTimer = null;
3612
+ let autoAdvanceTimer = null;
3609
3613
  const productsFor = (i) => steps[i].eligibleProducts || [];
3610
3614
  const rowCapacity = {
3611
3615
  remainingSpots: () => stepHeadroom(selections, steps, stepIndex),
@@ -3706,7 +3710,13 @@ function createWizard(deps) {
3706
3710
  if (!deps.autoAdvance) return;
3707
3711
  if (stepIndex >= steps.length - 1) return;
3708
3712
  if (stepHeadroom(selections, steps, stepIndex) !== 0) return;
3709
- goToStep(stepIndex + 1);
3713
+ const from = stepIndex;
3714
+ if (autoAdvanceTimer !== null) clearTimeout(autoAdvanceTimer);
3715
+ autoAdvanceTimer = setTimeout(() => {
3716
+ autoAdvanceTimer = null;
3717
+ if (!modalOpen) return;
3718
+ goToStep(from + 1);
3719
+ }, AUTO_ADVANCE_HOLD_MS);
3710
3720
  }
3711
3721
  function buildProductList(forStep) {
3712
3722
  if (!modalList) return;
@@ -3894,7 +3904,29 @@ function createWizard(deps) {
3894
3904
  });
3895
3905
  }
3896
3906
  function goToStep(i, opts = {}) {
3897
- stepIndex = Math.max(0, Math.min(steps.length - 1, i));
3907
+ const target = Math.max(0, Math.min(steps.length - 1, i));
3908
+ if (autoAdvanceTimer !== null) {
3909
+ clearTimeout(autoAdvanceTimer);
3910
+ autoAdvanceTimer = null;
3911
+ }
3912
+ if (modalDialog) {
3913
+ if (cascadeTimer !== null) clearTimeout(cascadeTimer);
3914
+ cascadeTimer = null;
3915
+ modalDialog.removeAttribute("data-step-transition");
3916
+ if (opts.animate !== false && target !== stepIndex) {
3917
+ void modalDialog.offsetHeight;
3918
+ modalDialog.setAttribute(
3919
+ "data-step-transition",
3920
+ target > stepIndex ? "forward" : "back"
3921
+ );
3922
+ const dialog = modalDialog;
3923
+ cascadeTimer = setTimeout(() => {
3924
+ cascadeTimer = null;
3925
+ dialog.removeAttribute("data-step-transition");
3926
+ }, STEP_CASCADE_MS);
3927
+ }
3928
+ }
3929
+ stepIndex = target;
3898
3930
  buildProductList(stepIndex);
3899
3931
  buildFilters(stepIndex);
3900
3932
  activeType = ALL_TYPES2;
@@ -3919,7 +3951,10 @@ function createWizard(deps) {
3919
3951
  function open(atStep) {
3920
3952
  if (!overlay || modalOpen) return;
3921
3953
  modalOpen = true;
3922
- goToStep(typeof atStep === "number" ? atStep : 0, { skipFocus: true });
3954
+ goToStep(typeof atStep === "number" ? atStep : 0, {
3955
+ skipFocus: true,
3956
+ animate: false
3957
+ });
3923
3958
  overlay.style.display = "";
3924
3959
  void overlay.offsetHeight;
3925
3960
  overlay.classList.add("lb-mix-match__modal-overlay--open");
@@ -3932,6 +3967,14 @@ function createWizard(deps) {
3932
3967
  function close() {
3933
3968
  if (!overlay || !modalOpen) return;
3934
3969
  modalOpen = false;
3970
+ if (autoAdvanceTimer !== null) {
3971
+ clearTimeout(autoAdvanceTimer);
3972
+ autoAdvanceTimer = null;
3973
+ }
3974
+ if (cascadeTimer !== null) {
3975
+ clearTimeout(cascadeTimer);
3976
+ cascadeTimer = null;
3977
+ }
3935
3978
  overlay.classList.remove("lb-mix-match__modal-overlay--open");
3936
3979
  unlock();
3937
3980
  setTimeout(() => {
@@ -4319,11 +4362,18 @@ var BUNDLE_BASE_CSS = `/* Lime Bundles \u2014 shared base styles for all bundle
4319
4362
  --lb-list-max-height: 360px;
4320
4363
  /* Depth of the soft fade at a scroll list's clipped edge. */
4321
4364
  --lb-edge-fade-size: 20px;
4322
- /* Derived "small" corner radius for inner controls (thumbnails, variant
4323
- selects, the qty chip). One step tighter than the global --lb-radius so
4324
- small elements stay proportionate. Both come from the global radius
4325
- preset; nothing else sets a radius. */
4326
- --lb-radius-sm: max(0px, calc(var(--lb-radius) - 4px));
4365
+ /* Derived "small" corner radius for chips and badges \u2014 the low-stock badge,
4366
+ the volume tier badge, the multi-step count chip. Controls and media
4367
+ (thumbnails, selects, steppers, buttons) take the full --lb-radius: they
4368
+ are the elements the merchant is looking at when they pick a preset, and
4369
+ the picker's own help text already promises they follow it.
4370
+
4371
+ Proportional rather than a fixed subtraction. At "subtle" (6px) minus-4px
4372
+ left 2px, which reads as square \u2014 the merchant saw a picker set to Subtle
4373
+ render with sharp corners (issue #363). Two thirds holds the proportion at
4374
+ every preset: none 0, subtle 4px, rounded 8px, round 12px. No max() needed,
4375
+ since 0 \xD7 \u2154 is 0. */
4376
+ --lb-radius-sm: calc(var(--lb-radius) * 2 / 3);
4327
4377
 
4328
4378
  font-family: inherit;
4329
4379
  font-size: 16px;
@@ -4487,7 +4537,7 @@ var BUNDLE_BASE_CSS = `/* Lime Bundles \u2014 shared base styles for all bundle
4487
4537
  ratio. Default keeps the historical 1:1 behaviour. */
4488
4538
  aspect-ratio: var(--lb-thumbnail-aspect-ratio, 1 / 1);
4489
4539
  background: var(--lb-thumbnail-bg);
4490
- border-radius: var(--lb-radius-sm);
4540
+ border-radius: var(--lb-radius);
4491
4541
  overflow: hidden;
4492
4542
  display: flex;
4493
4543
  align-items: center;
@@ -5037,12 +5087,12 @@ var BUNDLE_FIXED_CSS = `/* Lime Bundles \u2014 Fixed bundle styles */
5037
5087
  .lb-fixed .lb-bundle-thumbnail {
5038
5088
  width: 60px;
5039
5089
  min-width: 60px;
5040
- border-radius: var(--lb-radius-sm);
5090
+ border-radius: var(--lb-radius);
5041
5091
  box-sizing: border-box;
5042
5092
  }
5043
5093
 
5044
5094
  .lb-fixed .lb-bundle-thumbnail img {
5045
- border-radius: var(--lb-radius-sm);
5095
+ border-radius: var(--lb-radius);
5046
5096
  border: none;
5047
5097
  }
5048
5098
 
@@ -5059,7 +5109,7 @@ var BUNDLE_FIXED_CSS = `/* Lime Bundles \u2014 Fixed bundle styles */
5059
5109
  display: var(--lb-product-qty-chip-display, inline-flex);
5060
5110
  align-items: center;
5061
5111
  justify-content: center;
5062
- border-radius: var(--lb-radius-sm);
5112
+ border-radius: var(--lb-radius);
5063
5113
  background: color-mix(in srgb, var(--lb-text) 7%, transparent);
5064
5114
  color: color-mix(in srgb, var(--lb-text) 75%, transparent);
5065
5115
  font-size: 13px;
@@ -5075,7 +5125,7 @@ var BUNDLE_FIXED_CSS = `/* Lime Bundles \u2014 Fixed bundle styles */
5075
5125
  .lb-bundle-variant-select {
5076
5126
  display: inline-block;
5077
5127
  border: var(--lb-border-width) solid var(--lb-border);
5078
- border-radius: var(--lb-radius-sm);
5128
+ border-radius: var(--lb-radius);
5079
5129
  padding: 8px 32px 8px 12px;
5080
5130
  font-size: 12px;
5081
5131
  line-height: 16px;
@@ -5223,12 +5273,12 @@ var BUNDLE_MIX_MATCH_CSS = `/* Lime Bundles \u2014 Mix & Match styles */
5223
5273
  position: relative;
5224
5274
  width: 60px;
5225
5275
  min-width: 60px;
5226
- border-radius: var(--lb-radius-sm);
5276
+ border-radius: var(--lb-radius);
5227
5277
  box-sizing: border-box;
5228
5278
  }
5229
5279
 
5230
5280
  .lb-mix-match .lb-bundle-thumbnail img {
5231
- border-radius: var(--lb-radius-sm);
5281
+ border-radius: var(--lb-radius);
5232
5282
  border: none;
5233
5283
  }
5234
5284
 
@@ -5394,14 +5444,26 @@ var BUNDLE_MIX_MATCH_CSS = `/* Lime Bundles \u2014 Mix & Match styles */
5394
5444
  color: inherit;
5395
5445
  }
5396
5446
 
5397
- /* Derived "small" radius for the picker's inner controls (search, thumbnails,
5398
- variant select, qty stepper, Add/Done buttons), one step tighter than the
5399
- modal's --lb-picker-radius \u2014 the picker-scoped mirror of --lb-radius-sm in the
5400
- main widget. Defined on the overlay so the modal AND the variant listbox
5401
- (which portals up to [data-modal-overlay]) both inherit it. The modal shell
5402
- and product tiles keep the full --lb-picker-radius. */
5447
+ /* Derived "small" radius for the picker's chips and badges \u2014 the progress
5448
+ segments, the "Added" badge, the close button, the filter pills. The
5449
+ picker-scoped mirror of --lb-radius-sm, and proportional for the same reason
5450
+ (see bundle-base.css).
5451
+
5452
+ Everything the merchant would call a control or an image \u2014 the modal, search,
5453
+ product tiles, thumbnails, variant dropdown, quantity stepper and the
5454
+ buttons \u2014 takes the full --lb-picker-radius instead. That is what the
5455
+ editor's own Borders copy promises them, and the reduced tier had it
5456
+ rendering square at the Subtle preset (issue #363).
5457
+
5458
+ Declared on BOTH hosts the modal can live under. On the storefront it portals
5459
+ to [data-modal-overlay], which the variant listbox portals up to as well. In
5460
+ the admin widget editor there is no overlay at all \u2014 the preview renders the
5461
+ modal directly under .lb-bundle-widget \u2014 so scoping this to the overlay alone
5462
+ left the variable undefined there and every control using it fell back to
5463
+ square corners while the modal and tiles rounded correctly (issue #363). */
5464
+ .lb-bundle-widget,
5403
5465
  [data-modal-overlay] {
5404
- --lb-picker-radius-sm: max(0px, calc(var(--lb-picker-radius) - 4px));
5466
+ --lb-picker-radius-sm: calc(var(--lb-picker-radius) * 2 / 3);
5405
5467
  }
5406
5468
 
5407
5469
  /* === Modal Overlay === */
@@ -5498,7 +5560,7 @@ var BUNDLE_MIX_MATCH_CSS = `/* Lime Bundles \u2014 Mix & Match styles */
5498
5560
  border: none;
5499
5561
  cursor: pointer;
5500
5562
  color: var(--lb-picker-text);
5501
- border-radius: 8px;
5563
+ border-radius: var(--lb-picker-radius-sm);
5502
5564
  padding: 0;
5503
5565
  margin: -12px -12px 0 0;
5504
5566
  transition: background 0.25s ease;
@@ -5528,7 +5590,9 @@ var BUNDLE_MIX_MATCH_CSS = `/* Lime Bundles \u2014 Mix & Match styles */
5528
5590
  .lb-mix-match__filter {
5529
5591
  padding: 6px 14px;
5530
5592
  border: var(--lb-picker-border-width) solid var(--lb-picker-border-color);
5531
- border-radius: 999px;
5593
+ /* Pills followed the merchant's picker radius as of #363 \u2014 a fixed 999px
5594
+ read as a stray rounded shape in a picker set to None or Subtle. */
5595
+ border-radius: var(--lb-picker-radius-sm);
5532
5596
  background: transparent;
5533
5597
  color: var(--lb-picker-text);
5534
5598
  font-family: inherit;
@@ -5582,7 +5646,7 @@ var BUNDLE_MIX_MATCH_CSS = `/* Lime Bundles \u2014 Mix & Match styles */
5582
5646
  width: 100%;
5583
5647
  padding: 12px 40px 12px 44px;
5584
5648
  border: var(--lb-picker-border-width) solid var(--lb-picker-border-color);
5585
- border-radius: var(--lb-picker-radius-sm);
5649
+ border-radius: var(--lb-picker-radius);
5586
5650
  font-size: 16px;
5587
5651
  line-height: 20px;
5588
5652
  color: var(--lb-picker-text);
@@ -5682,7 +5746,7 @@ var BUNDLE_MIX_MATCH_CSS = `/* Lime Bundles \u2014 Mix & Match styles */
5682
5746
  independent from the main widget's thumbnailRatio so a merchant can
5683
5747
  e.g. show tall picker thumbs with square main thumbs. */
5684
5748
  aspect-ratio: var(--lb-picker-thumbnail-aspect-ratio, 1 / 1);
5685
- border-radius: var(--lb-picker-radius-sm);
5749
+ border-radius: var(--lb-picker-radius);
5686
5750
  box-sizing: border-box;
5687
5751
  overflow: hidden;
5688
5752
  background: var(--lb-thumbnail-bg);
@@ -5695,7 +5759,7 @@ var BUNDLE_MIX_MATCH_CSS = `/* Lime Bundles \u2014 Mix & Match styles */
5695
5759
  to auto/contain so the image renders uncropped at intrinsic ratio. */
5696
5760
  height: var(--lb-picker-thumbnail-img-height, 100%);
5697
5761
  object-fit: var(--lb-picker-thumbnail-img-fit, cover);
5698
- border-radius: var(--lb-picker-radius-sm);
5762
+ border-radius: var(--lb-picker-radius);
5699
5763
  }
5700
5764
 
5701
5765
  .lb-mix-match__modal-product-info {
@@ -5770,7 +5834,7 @@ var BUNDLE_MIX_MATCH_CSS = `/* Lime Bundles \u2014 Mix & Match styles */
5770
5834
  font-size: 12px;
5771
5835
  padding: 4px 24px 4px 8px;
5772
5836
  border: var(--lb-picker-border-width) solid var(--lb-picker-border-color);
5773
- border-radius: var(--lb-picker-radius-sm);
5837
+ border-radius: var(--lb-picker-radius);
5774
5838
  background-color: var(--lb-picker-bg);
5775
5839
  background-image: var(--lb-picker-variant-chevron);
5776
5840
  background-repeat: no-repeat;
@@ -5821,7 +5885,7 @@ var BUNDLE_MIX_MATCH_CSS = `/* Lime Bundles \u2014 Mix & Match styles */
5821
5885
  width: 100%;
5822
5886
  flex-shrink: 0;
5823
5887
  border: var(--lb-picker-border-width) solid var(--lb-picker-border-color);
5824
- border-radius: var(--lb-picker-radius-sm);
5888
+ border-radius: var(--lb-picker-radius);
5825
5889
  background-color: var(--lb-picker-bg);
5826
5890
  overflow: hidden;
5827
5891
  box-sizing: border-box;
@@ -5898,7 +5962,7 @@ var BUNDLE_MIX_MATCH_CSS = `/* Lime Bundles \u2014 Mix & Match styles */
5898
5962
  background: var(--lb-picker-add-bg);
5899
5963
  color: var(--lb-picker-add-label);
5900
5964
  border: var(--lb-picker-add-border-width) solid var(--lb-picker-add-border-color);
5901
- border-radius: var(--lb-picker-radius-sm);
5965
+ border-radius: var(--lb-picker-radius);
5902
5966
  box-sizing: border-box;
5903
5967
  font-size: 12px;
5904
5968
  font-weight: 600;
@@ -6039,7 +6103,7 @@ var BUNDLE_MIX_MATCH_CSS = `/* Lime Bundles \u2014 Mix & Match styles */
6039
6103
  background: var(--lb-picker-add-bg);
6040
6104
  color: var(--lb-picker-add-label);
6041
6105
  border: var(--lb-picker-add-border-width) solid var(--lb-picker-add-border-color);
6042
- border-radius: var(--lb-picker-radius-sm);
6106
+ border-radius: var(--lb-picker-radius);
6043
6107
  box-sizing: border-box;
6044
6108
  font-family: inherit;
6045
6109
  font-size: 14px;
@@ -6088,7 +6152,9 @@ var BUNDLE_MIX_MATCH_CSS = `/* Lime Bundles \u2014 Mix & Match styles */
6088
6152
  .lb-mix-match__modal {
6089
6153
  max-width: 100%;
6090
6154
  max-height: 90vh;
6091
- border-radius: 16px 16px 0 0;
6155
+ /* Bottom sheet: only the top corners round, but they round to whatever the
6156
+ merchant picked rather than a fixed 16px (issue #363). */
6157
+ border-radius: var(--lb-picker-radius) var(--lb-picker-radius) 0 0;
6092
6158
  transform: translateY(100%);
6093
6159
  }
6094
6160
 
@@ -6355,12 +6421,12 @@ var BUNDLE_BOGO_CSS = `/* Lime Bundles \u2014 BOGO (Buy X Get Y) bundle styles *
6355
6421
  .lb-bogo .lb-bundle-thumbnail {
6356
6422
  width: 60px;
6357
6423
  min-width: 60px;
6358
- border-radius: var(--lb-radius-sm);
6424
+ border-radius: var(--lb-radius);
6359
6425
  box-sizing: border-box;
6360
6426
  }
6361
6427
 
6362
6428
  .lb-bogo .lb-bundle-thumbnail img {
6363
- border-radius: var(--lb-radius-sm);
6429
+ border-radius: var(--lb-radius);
6364
6430
  border: none;
6365
6431
  }
6366
6432
 
@@ -6481,6 +6547,13 @@ var BUNDLE_MULTI_STEP_CSS = `/**
6481
6547
  cursor: pointer;
6482
6548
  box-sizing: border-box;
6483
6549
  transition: background-color 0.25s ease;
6550
+ /* Deliberately no border-radius. This row paints the checklist hairline as
6551
+ its own border-top (see the run rule above), and a radius tapers that
6552
+ border into the corner arcs \u2014 the dividers came out visibly curved at the
6553
+ "round" preset (issue #363). A full-bleed list row is meant to be square
6554
+ anyway; the hover tint below spans the card width, so it has no corner to
6555
+ round against. The :focus-visible radius is fine: an outline is a
6556
+ separate paint and never touches the border. */
6484
6557
  }
6485
6558
 
6486
6559
  .lb-multi-step__step-row:hover {
@@ -6628,7 +6701,7 @@ var BUNDLE_MULTI_STEP_CSS = `/**
6628
6701
  padding: 10px 24px;
6629
6702
  background: none;
6630
6703
  border: var(--lb-picker-border-width) solid var(--lb-picker-border-color);
6631
- border-radius: var(--lb-picker-radius-sm);
6704
+ border-radius: var(--lb-picker-radius);
6632
6705
  box-sizing: border-box;
6633
6706
  color: var(--lb-picker-text);
6634
6707
  font-family: inherit;
@@ -6646,6 +6719,108 @@ var BUNDLE_MULTI_STEP_CSS = `/**
6646
6719
  outline: 2px solid var(--lb-primary-color);
6647
6720
  outline-offset: 2px;
6648
6721
  }
6722
+
6723
+ /* \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
6724
+ Moving between steps swaps the whole step-scoped region in a single
6725
+ paint, which reads as nothing happening (or as a glitch) rather than
6726
+ as arriving somewhere new \u2014 and worst of all under auto-advance,
6727
+ where the shopper never clicked anything. So the step assembles
6728
+ instead of arriving whole: the step label leads, the filter pills
6729
+ follow, then the product cards one after another. Staging is what
6730
+ makes the change legible; a uniform slide of everything at once only
6731
+ wobbles the card.
6732
+
6733
+ The wizard stamps data-step-transition="forward" | "back" on the
6734
+ dialog on every step change (manual Next/Back and auto-advance
6735
+ alike, never on open, where the modal entrance already carries the
6736
+ motion), and clears it again once the cascade has played \u2014 see
6737
+ STEP_CASCADE_MS in multi-step/wizard.ts. That clear is load-bearing,
6738
+ not tidiness: search and filter hide cards with .lb-hidden
6739
+ (display: none), and restoring display restarts a card's animation,
6740
+ so a live attribute would replay the whole cascade on every
6741
+ keystroke that reveals a card.
6742
+
6743
+ Two elements deliberately hold still. The footer, because Back/Next
6744
+ are the shopper's anchor while everything above them moves. And the
6745
+ progress rail, because it is the one thing that answers "where am I
6746
+ now" \u2014 animating the shopper's only orientation cue is what made the
6747
+ previous version hard to read. Its segment fill carries its own
6748
+ state change already. */
6749
+ @keyframes lb-multi-step-cascade-fwd {
6750
+ from {
6751
+ opacity: 0;
6752
+ transform: translateY(10px);
6753
+ }
6754
+ }
6755
+
6756
+ @keyframes lb-multi-step-cascade-back {
6757
+ from {
6758
+ opacity: 0;
6759
+ transform: translateY(-10px);
6760
+ }
6761
+ }
6762
+
6763
+ .lb-mix-match__modal[data-step-transition] .lb-mix-match__modal-subtitle {
6764
+ animation: lb-multi-step-cascade-fwd 0.2s ease-out both;
6765
+ }
6766
+
6767
+ .lb-mix-match__modal[data-step-transition] .lb-mix-match__filters {
6768
+ animation: lb-multi-step-cascade-fwd 0.2s ease-out 0.05s both;
6769
+ }
6770
+
6771
+ /* Cards stagger 30ms apart, but only the first four: a step can hold
6772
+ dozens of products and the two-column grid shows about four at a
6773
+ time, so past that the stagger is below the fold and would only add
6774
+ lag. Everything from the fifth on shares the fourth's landing. */
6775
+ .lb-mix-match__modal[data-step-transition] .lb-mix-match__modal-list > * {
6776
+ animation: lb-multi-step-cascade-fwd 0.22s ease-out 0.2s both;
6777
+ }
6778
+
6779
+ .lb-mix-match__modal[data-step-transition] .lb-mix-match__modal-list > :nth-child(1) {
6780
+ animation-delay: 0.09s;
6781
+ }
6782
+
6783
+ .lb-mix-match__modal[data-step-transition] .lb-mix-match__modal-list > :nth-child(2) {
6784
+ animation-delay: 0.12s;
6785
+ }
6786
+
6787
+ .lb-mix-match__modal[data-step-transition] .lb-mix-match__modal-list > :nth-child(3) {
6788
+ animation-delay: 0.15s;
6789
+ }
6790
+
6791
+ .lb-mix-match__modal[data-step-transition] .lb-mix-match__modal-list > :nth-child(4) {
6792
+ animation-delay: 0.18s;
6793
+ }
6794
+
6795
+ /* Going back runs the same cascade in the same order \u2014 only the offset
6796
+ flips, so the shopper still reads which way they moved. Overrides
6797
+ the name alone; the staggered delays above must survive. */
6798
+ .lb-mix-match__modal[data-step-transition="back"] .lb-mix-match__modal-subtitle,
6799
+ .lb-mix-match__modal[data-step-transition="back"] .lb-mix-match__filters,
6800
+ .lb-mix-match__modal[data-step-transition="back"] .lb-mix-match__modal-list > * {
6801
+ animation-name: lb-multi-step-cascade-back;
6802
+ }
6803
+
6804
+ @keyframes lb-multi-step-cascade-fade {
6805
+ from {
6806
+ opacity: 0;
6807
+ }
6808
+ }
6809
+
6810
+ /* Reduced motion keeps the fade and drops the travel and the stagger:
6811
+ the step change still has to be perceptible, which is the whole
6812
+ point of this block. The card selector is :nth-child(n) rather than
6813
+ * on purpose \u2014 a plain * loses to the :nth-child(1..4) delays above
6814
+ on specificity, which would leave the stagger running with nothing
6815
+ moving. :nth-child(n) matches every child at equal specificity and
6816
+ wins on order. */
6817
+ @media (prefers-reduced-motion: reduce) {
6818
+ .lb-mix-match__modal[data-step-transition] .lb-mix-match__modal-subtitle,
6819
+ .lb-mix-match__modal[data-step-transition] .lb-mix-match__filters,
6820
+ .lb-mix-match__modal[data-step-transition] .lb-mix-match__modal-list > :nth-child(n) {
6821
+ animation: lb-multi-step-cascade-fade 0.15s ease-out both;
6822
+ }
6823
+ }
6649
6824
  `;
6650
6825
  var BUNDLE_DROPDOWN_CSS = `/**
6651
6826
  * Lime Bundles \u2014 Custom variant-picker dropdown styling.
@@ -6693,7 +6868,7 @@ var BUNDLE_DROPDOWN_CSS = `/**
6693
6868
  gap: 8px;
6694
6869
  width: 100%;
6695
6870
  border: var(--lb-border-width) solid var(--lb-border);
6696
- border-radius: var(--lb-radius-sm);
6871
+ border-radius: var(--lb-radius);
6697
6872
  padding: 8px 12px;
6698
6873
  font-size: 12px;
6699
6874
  line-height: 16px;
@@ -6756,7 +6931,7 @@ var BUNDLE_DROPDOWN_CSS = `/**
6756
6931
  background: var(--lb-bg);
6757
6932
  color: var(--lb-text);
6758
6933
  border: var(--lb-border-width) solid var(--lb-border);
6759
- border-radius: var(--lb-radius-sm);
6934
+ border-radius: var(--lb-radius);
6760
6935
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.08);
6761
6936
  overflow-y: auto;
6762
6937
  overflow-x: hidden;
@@ -6817,6 +6992,10 @@ var BUNDLE_DROPDOWN_CSS = `/**
6817
6992
  overflow: hidden;
6818
6993
  text-overflow: ellipsis;
6819
6994
  color: var(--lb-text);
6995
+ /* The active/hover tint below fills the option, so it rounds with the rest
6996
+ of the widget rather than squaring off against the listbox corner it sits
6997
+ in (issue #363). */
6998
+ border-radius: var(--lb-radius-sm);
6820
6999
  }
6821
7000
 
6822
7001
  .lb-dropdown-option[aria-selected="true"] {
@@ -6875,7 +7054,7 @@ var BUNDLE_DROPDOWN_CSS = `/**
6875
7054
  .lb-mix-match__modal .lb-dropdown-trigger {
6876
7055
  border-color: var(--lb-picker-border-color);
6877
7056
  border-width: var(--lb-picker-border-width);
6878
- border-radius: var(--lb-picker-radius-sm);
7057
+ border-radius: var(--lb-picker-radius);
6879
7058
  background: var(--lb-picker-bg);
6880
7059
  color: var(--lb-picker-text);
6881
7060
  /* Match the picker qty stepper + Add button height (border-box so 32px is
@@ -6896,13 +7075,17 @@ var BUNDLE_DROPDOWN_CSS = `/**
6896
7075
  [data-modal-overlay] > .lb-dropdown-listbox {
6897
7076
  border-color: var(--lb-picker-border-color);
6898
7077
  border-width: var(--lb-picker-border-width);
6899
- border-radius: var(--lb-picker-radius-sm);
7078
+ border-radius: var(--lb-picker-radius);
6900
7079
  background: var(--lb-picker-bg);
6901
7080
  color: var(--lb-picker-text);
6902
7081
  scrollbar-color: color-mix(in srgb, var(--lb-picker-text) 15%, transparent)
6903
7082
  color-mix(in srgb, var(--lb-picker-text) 2%, transparent);
6904
7083
  }
6905
7084
 
7085
+ [data-modal-overlay] > .lb-dropdown-listbox .lb-dropdown-option {
7086
+ border-radius: var(--lb-picker-radius-sm);
7087
+ }
7088
+
6906
7089
  [data-modal-overlay] > .lb-dropdown-listbox::-webkit-scrollbar-track {
6907
7090
  background: color-mix(in srgb, var(--lb-picker-text) 2%, transparent);
6908
7091
  border-radius: 2px;