@cimplify/sdk 0.72.0 → 0.73.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/dist/react.d.mts CHANGED
@@ -1524,6 +1524,8 @@ interface VariantSelectorClassNames {
1524
1524
  axisOptions?: string;
1525
1525
  option?: string;
1526
1526
  optionSelected?: string;
1527
+ swatch?: string;
1528
+ swatchSelected?: string;
1527
1529
  listLabel?: string;
1528
1530
  list?: string;
1529
1531
  name?: string;
@@ -2420,6 +2422,7 @@ interface SlotPickerClassNames {
2420
2422
  slot?: string;
2421
2423
  slotTime?: string;
2422
2424
  slotPrice?: string;
2425
+ slotScarcity?: string;
2423
2426
  loading?: string;
2424
2427
  empty?: string;
2425
2428
  }
@@ -2440,6 +2443,12 @@ interface SlotPickerProps {
2440
2443
  groupByTimeOfDay?: boolean;
2441
2444
  /** Show price on each slot. Default: true. */
2442
2445
  showPrice?: boolean;
2446
+ /**
2447
+ * Show a "N left" urgency tag when a slot's remaining capacity is at or below
2448
+ * this number (and above zero). Slots at zero capacity render as sold out.
2449
+ * Default: 3. Set to 0 to disable scarcity tags.
2450
+ */
2451
+ lowCapacityThreshold?: number;
2443
2452
  /** Currency the slot prices are denominated in. */
2444
2453
  currency?: CurrencyCode;
2445
2454
  /**
@@ -2468,7 +2477,7 @@ interface SlotPickerProps {
2468
2477
  className?: string;
2469
2478
  classNames?: SlotPickerClassNames;
2470
2479
  }
2471
- declare function SlotPicker({ slots: slotsProp, serviceId, date, participantCount, selectedSlot, onSlotSelect, groupByTimeOfDay, showPrice, currency, schedulingMode, durationUnit, durationValue, hideElapsedSlots, minLeadMinutes, emptyMessage, className, classNames, }: SlotPickerProps): React$1.ReactElement;
2480
+ declare function SlotPicker({ slots: slotsProp, serviceId, date, participantCount, selectedSlot, onSlotSelect, groupByTimeOfDay, showPrice, lowCapacityThreshold, currency, schedulingMode, durationUnit, durationValue, hideElapsedSlots, minLeadMinutes, emptyMessage, className, classNames, }: SlotPickerProps): React$1.ReactElement;
2472
2481
 
2473
2482
  interface DateSlotPickerClassNames {
2474
2483
  root?: string;
package/dist/react.d.ts CHANGED
@@ -1524,6 +1524,8 @@ interface VariantSelectorClassNames {
1524
1524
  axisOptions?: string;
1525
1525
  option?: string;
1526
1526
  optionSelected?: string;
1527
+ swatch?: string;
1528
+ swatchSelected?: string;
1527
1529
  listLabel?: string;
1528
1530
  list?: string;
1529
1531
  name?: string;
@@ -2420,6 +2422,7 @@ interface SlotPickerClassNames {
2420
2422
  slot?: string;
2421
2423
  slotTime?: string;
2422
2424
  slotPrice?: string;
2425
+ slotScarcity?: string;
2423
2426
  loading?: string;
2424
2427
  empty?: string;
2425
2428
  }
@@ -2440,6 +2443,12 @@ interface SlotPickerProps {
2440
2443
  groupByTimeOfDay?: boolean;
2441
2444
  /** Show price on each slot. Default: true. */
2442
2445
  showPrice?: boolean;
2446
+ /**
2447
+ * Show a "N left" urgency tag when a slot's remaining capacity is at or below
2448
+ * this number (and above zero). Slots at zero capacity render as sold out.
2449
+ * Default: 3. Set to 0 to disable scarcity tags.
2450
+ */
2451
+ lowCapacityThreshold?: number;
2443
2452
  /** Currency the slot prices are denominated in. */
2444
2453
  currency?: CurrencyCode;
2445
2454
  /**
@@ -2468,7 +2477,7 @@ interface SlotPickerProps {
2468
2477
  className?: string;
2469
2478
  classNames?: SlotPickerClassNames;
2470
2479
  }
2471
- declare function SlotPicker({ slots: slotsProp, serviceId, date, participantCount, selectedSlot, onSlotSelect, groupByTimeOfDay, showPrice, currency, schedulingMode, durationUnit, durationValue, hideElapsedSlots, minLeadMinutes, emptyMessage, className, classNames, }: SlotPickerProps): React$1.ReactElement;
2480
+ declare function SlotPicker({ slots: slotsProp, serviceId, date, participantCount, selectedSlot, onSlotSelect, groupByTimeOfDay, showPrice, lowCapacityThreshold, currency, schedulingMode, durationUnit, durationValue, hideElapsedSlots, minLeadMinutes, emptyMessage, className, classNames, }: SlotPickerProps): React$1.ReactElement;
2472
2481
 
2473
2482
  interface DateSlotPickerClassNames {
2474
2483
  root?: string;
package/dist/react.js CHANGED
@@ -6255,6 +6255,36 @@ function VariantSelector({
6255
6255
  className: cn("flex flex-wrap gap-2", classNames?.axisOptions),
6256
6256
  children: axis.values.map((value) => {
6257
6257
  const isSelected = axisSelections[axis.id] === value.id;
6258
+ if (value.image_url || value.color_hex) {
6259
+ const isImage = Boolean(value.image_url);
6260
+ return /* @__PURE__ */ jsxRuntime.jsx(
6261
+ radio.Radio.Root,
6262
+ {
6263
+ value: value.id,
6264
+ "data-cimplify-variant-option": true,
6265
+ "data-cimplify-variant-swatch": true,
6266
+ "data-selected": isSelected || void 0,
6267
+ "aria-label": value.name,
6268
+ title: value.name,
6269
+ style: isImage ? void 0 : { backgroundColor: value.color_hex },
6270
+ className: cn(
6271
+ "relative overflow-hidden border border-border transition-shadow",
6272
+ isImage ? "h-12 w-12 rounded-md" : "h-9 w-9 rounded-full",
6273
+ isSelected && "ring-2 ring-foreground ring-offset-2 ring-offset-background border-transparent",
6274
+ isSelected ? classNames?.swatchSelected : classNames?.swatch
6275
+ ),
6276
+ children: isImage && /* @__PURE__ */ jsxRuntime.jsx(
6277
+ "img",
6278
+ {
6279
+ src: value.image_url,
6280
+ alt: "",
6281
+ className: "h-full w-full object-cover"
6282
+ }
6283
+ )
6284
+ },
6285
+ value.id
6286
+ );
6287
+ }
6258
6288
  return /* @__PURE__ */ jsxRuntime.jsx(
6259
6289
  radio.Radio.Root,
6260
6290
  {
@@ -8708,6 +8738,7 @@ function SlotPicker({
8708
8738
  onSlotSelect,
8709
8739
  groupByTimeOfDay = true,
8710
8740
  showPrice = true,
8741
+ lowCapacityThreshold = 3,
8711
8742
  currency,
8712
8743
  schedulingMode = "intraday",
8713
8744
  durationUnit,
@@ -8801,14 +8832,18 @@ function SlotPicker({
8801
8832
  children: group.slots.map((slot) => {
8802
8833
  const value = slotToValue(slot);
8803
8834
  const isSelected = selectedSlot?.start_time === slot.start_time && selectedSlot?.end_time === slot.end_time;
8835
+ const capacity = slot.capacity_available ?? slot.remaining_capacity;
8836
+ const soldOut = capacity === 0;
8837
+ const unavailable = slot.is_available === false || soldOut;
8838
+ const lowCapacity = lowCapacityThreshold > 0 && capacity != null && capacity > 0 && capacity <= lowCapacityThreshold;
8804
8839
  return /* @__PURE__ */ jsxRuntime.jsxs(
8805
8840
  radio.Radio.Root,
8806
8841
  {
8807
8842
  value,
8808
- disabled: slot.is_available === false,
8843
+ disabled: unavailable,
8809
8844
  "data-cimplify-slot": true,
8810
8845
  "data-selected": isSelected || void 0,
8811
- "data-unavailable": slot.is_available === false || void 0,
8846
+ "data-unavailable": unavailable || void 0,
8812
8847
  className: cn(
8813
8848
  "inline-flex items-center justify-center gap-2 rounded-md border border-border bg-background px-3 py-2 text-sm font-medium text-foreground transition-colors hover:border-foreground/40 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring data-[selected]:border-foreground data-[selected]:bg-foreground data-[selected]:text-background data-[unavailable]:cursor-not-allowed data-[unavailable]:opacity-40 data-[unavailable]:line-through",
8814
8849
  isMultiDay && "justify-between text-left",
@@ -8823,6 +8858,17 @@ function SlotPicker({
8823
8858
  className: cn("text-xs opacity-70", classNames?.slotPrice),
8824
8859
  children: /* @__PURE__ */ jsxRuntime.jsx(Price, { amount: slot.price, currency })
8825
8860
  }
8861
+ ),
8862
+ lowCapacity && /* @__PURE__ */ jsxRuntime.jsxs(
8863
+ "span",
8864
+ {
8865
+ "data-cimplify-slot-scarcity": true,
8866
+ className: cn("text-xs font-medium text-amber-600", classNames?.slotScarcity),
8867
+ children: [
8868
+ capacity,
8869
+ " left"
8870
+ ]
8871
+ }
8826
8872
  )
8827
8873
  ]
8828
8874
  },
@@ -9402,9 +9448,15 @@ function ProductImageGallery({
9402
9448
  [images]
9403
9449
  );
9404
9450
  const [selectedImage, setSelectedImage] = React14.useState(0);
9451
+ const [fadeIn, setFadeIn] = React14.useState(true);
9405
9452
  React14.useEffect(() => {
9406
9453
  setSelectedImage(0);
9407
9454
  }, [normalizedImages.length, productName]);
9455
+ React14.useEffect(() => {
9456
+ setFadeIn(false);
9457
+ const id = requestAnimationFrame(() => setFadeIn(true));
9458
+ return () => cancelAnimationFrame(id);
9459
+ }, [selectedImage]);
9408
9460
  if (normalizedImages.length === 0) {
9409
9461
  return null;
9410
9462
  }
@@ -9420,7 +9472,13 @@ function ProductImageGallery({
9420
9472
  {
9421
9473
  src: activeImage,
9422
9474
  alt: productName,
9423
- style: { width: "100%", height: "100%", objectFit: "cover" },
9475
+ style: {
9476
+ width: "100%",
9477
+ height: "100%",
9478
+ objectFit: "cover",
9479
+ opacity: fadeIn ? 1 : 0,
9480
+ transition: "opacity 300ms ease"
9481
+ },
9424
9482
  "data-cimplify-image-gallery-active": true
9425
9483
  }
9426
9484
  )
package/dist/react.mjs CHANGED
@@ -6250,6 +6250,36 @@ function VariantSelector({
6250
6250
  className: cn("flex flex-wrap gap-2", classNames?.axisOptions),
6251
6251
  children: axis.values.map((value) => {
6252
6252
  const isSelected = axisSelections[axis.id] === value.id;
6253
+ if (value.image_url || value.color_hex) {
6254
+ const isImage = Boolean(value.image_url);
6255
+ return /* @__PURE__ */ jsx(
6256
+ Radio.Root,
6257
+ {
6258
+ value: value.id,
6259
+ "data-cimplify-variant-option": true,
6260
+ "data-cimplify-variant-swatch": true,
6261
+ "data-selected": isSelected || void 0,
6262
+ "aria-label": value.name,
6263
+ title: value.name,
6264
+ style: isImage ? void 0 : { backgroundColor: value.color_hex },
6265
+ className: cn(
6266
+ "relative overflow-hidden border border-border transition-shadow",
6267
+ isImage ? "h-12 w-12 rounded-md" : "h-9 w-9 rounded-full",
6268
+ isSelected && "ring-2 ring-foreground ring-offset-2 ring-offset-background border-transparent",
6269
+ isSelected ? classNames?.swatchSelected : classNames?.swatch
6270
+ ),
6271
+ children: isImage && /* @__PURE__ */ jsx(
6272
+ "img",
6273
+ {
6274
+ src: value.image_url,
6275
+ alt: "",
6276
+ className: "h-full w-full object-cover"
6277
+ }
6278
+ )
6279
+ },
6280
+ value.id
6281
+ );
6282
+ }
6253
6283
  return /* @__PURE__ */ jsx(
6254
6284
  Radio.Root,
6255
6285
  {
@@ -8703,6 +8733,7 @@ function SlotPicker({
8703
8733
  onSlotSelect,
8704
8734
  groupByTimeOfDay = true,
8705
8735
  showPrice = true,
8736
+ lowCapacityThreshold = 3,
8706
8737
  currency,
8707
8738
  schedulingMode = "intraday",
8708
8739
  durationUnit,
@@ -8796,14 +8827,18 @@ function SlotPicker({
8796
8827
  children: group.slots.map((slot) => {
8797
8828
  const value = slotToValue(slot);
8798
8829
  const isSelected = selectedSlot?.start_time === slot.start_time && selectedSlot?.end_time === slot.end_time;
8830
+ const capacity = slot.capacity_available ?? slot.remaining_capacity;
8831
+ const soldOut = capacity === 0;
8832
+ const unavailable = slot.is_available === false || soldOut;
8833
+ const lowCapacity = lowCapacityThreshold > 0 && capacity != null && capacity > 0 && capacity <= lowCapacityThreshold;
8799
8834
  return /* @__PURE__ */ jsxs(
8800
8835
  Radio.Root,
8801
8836
  {
8802
8837
  value,
8803
- disabled: slot.is_available === false,
8838
+ disabled: unavailable,
8804
8839
  "data-cimplify-slot": true,
8805
8840
  "data-selected": isSelected || void 0,
8806
- "data-unavailable": slot.is_available === false || void 0,
8841
+ "data-unavailable": unavailable || void 0,
8807
8842
  className: cn(
8808
8843
  "inline-flex items-center justify-center gap-2 rounded-md border border-border bg-background px-3 py-2 text-sm font-medium text-foreground transition-colors hover:border-foreground/40 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring data-[selected]:border-foreground data-[selected]:bg-foreground data-[selected]:text-background data-[unavailable]:cursor-not-allowed data-[unavailable]:opacity-40 data-[unavailable]:line-through",
8809
8844
  isMultiDay && "justify-between text-left",
@@ -8818,6 +8853,17 @@ function SlotPicker({
8818
8853
  className: cn("text-xs opacity-70", classNames?.slotPrice),
8819
8854
  children: /* @__PURE__ */ jsx(Price, { amount: slot.price, currency })
8820
8855
  }
8856
+ ),
8857
+ lowCapacity && /* @__PURE__ */ jsxs(
8858
+ "span",
8859
+ {
8860
+ "data-cimplify-slot-scarcity": true,
8861
+ className: cn("text-xs font-medium text-amber-600", classNames?.slotScarcity),
8862
+ children: [
8863
+ capacity,
8864
+ " left"
8865
+ ]
8866
+ }
8821
8867
  )
8822
8868
  ]
8823
8869
  },
@@ -9397,9 +9443,15 @@ function ProductImageGallery({
9397
9443
  [images]
9398
9444
  );
9399
9445
  const [selectedImage, setSelectedImage] = useState(0);
9446
+ const [fadeIn, setFadeIn] = useState(true);
9400
9447
  useEffect(() => {
9401
9448
  setSelectedImage(0);
9402
9449
  }, [normalizedImages.length, productName]);
9450
+ useEffect(() => {
9451
+ setFadeIn(false);
9452
+ const id = requestAnimationFrame(() => setFadeIn(true));
9453
+ return () => cancelAnimationFrame(id);
9454
+ }, [selectedImage]);
9403
9455
  if (normalizedImages.length === 0) {
9404
9456
  return null;
9405
9457
  }
@@ -9415,7 +9467,13 @@ function ProductImageGallery({
9415
9467
  {
9416
9468
  src: activeImage,
9417
9469
  alt: productName,
9418
- style: { width: "100%", height: "100%", objectFit: "cover" },
9470
+ style: {
9471
+ width: "100%",
9472
+ height: "100%",
9473
+ objectFit: "cover",
9474
+ opacity: fadeIn ? 1 : 0,
9475
+ transition: "opacity 300ms ease"
9476
+ },
9419
9477
  "data-cimplify-image-gallery-active": true
9420
9478
  }
9421
9479
  )
package/dist/styles.css CHANGED
@@ -1,2 +1,2 @@
1
1
  /*! tailwindcss v4.2.2 | MIT License | https://tailwindcss.com */
2
- @layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0;--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-divide-y-reverse:0;--tw-border-style:solid;--tw-gradient-position:initial;--tw-gradient-from:#0000;--tw-gradient-via:#0000;--tw-gradient-to:#0000;--tw-gradient-stops:initial;--tw-gradient-via-stops:initial;--tw-gradient-from-position:0%;--tw-gradient-via-position:50%;--tw-gradient-to-position:100%;--tw-leading:initial;--tw-tracking:initial;--tw-ordinal:initial;--tw-slashed-zero:initial;--tw-numeric-figure:initial;--tw-numeric-spacing:initial;--tw-numeric-fraction:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-outline-style:solid;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial;--tw-backdrop-blur:initial;--tw-backdrop-brightness:initial;--tw-backdrop-contrast:initial;--tw-backdrop-grayscale:initial;--tw-backdrop-hue-rotate:initial;--tw-backdrop-invert:initial;--tw-backdrop-opacity:initial;--tw-backdrop-saturate:initial;--tw-backdrop-sepia:initial;--tw-duration:initial;--tw-ease:initial;--tw-scale-x:1;--tw-scale-y:1;--tw-scale-z:1}}}.pointer-events-auto{pointer-events:auto}.pointer-events-none{pointer-events:none}.collapse{visibility:collapse}.visible{visibility:visible}.sr-only{clip-path:inset(50%);white-space:nowrap;border-width:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.static{position:static}.sticky{position:sticky}.top-1\/2{top:50%}.top-\[18px\]{top:18px}.top-\[calc\(100\%\+8px\)\]{top:calc(100% + 8px)}.top-full{top:100%}.top-px{top:1px}.-right-px{right:-1px}.-bottom-px{bottom:-1px}.-left-\[9px\]{left:-9px}.left-\[14px\]{left:14px}.isolate{isolation:isolate}.z-10{z-index:10}.z-20{z-index:20}.z-30{z-index:30}.z-50{z-index:50}.z-\[1\]{z-index:1}.z-\[2\]{z-index:2}.z-\[200\]{z-index:200}.z-\[9999\]{z-index:9999}.container{width:100%}.m-auto{margin:auto}.mx-auto{margin-inline:auto}.-mt-px{margin-top:-1px}.mt-auto{margin-top:auto}.mt-px{margin-top:1px}.mr-auto{margin-right:auto}.-mb-px{margin-bottom:-1px}.ml-\[1px\]{margin-left:1px}.ml-\[9px\]{margin-left:9px}.ml-auto{margin-left:auto}.line-clamp-1{-webkit-line-clamp:1;-webkit-box-orient:vertical;display:-webkit-box;overflow:hidden}.line-clamp-2{-webkit-line-clamp:2;-webkit-box-orient:vertical;display:-webkit-box;overflow:hidden}.block{display:block}.contents{display:contents}.flex{display:flex}.grid{display:grid}.hidden{display:none}.inline{display:inline}.inline-block{display:inline-block}.inline-flex{display:inline-flex}.table{display:table}.aspect-\[3\/4\]{aspect-ratio:3/4}.aspect-\[4\/3\]{aspect-ratio:4/3}.aspect-\[5\/2\]{aspect-ratio:5/2}.aspect-\[16\/9\]{aspect-ratio:16/9}.aspect-square{aspect-ratio:1}.size-\[7px\]{width:7px;height:7px}.size-\[18px\]{width:18px;height:18px}.size-\[22px\]{width:22px;height:22px}.size-\[26px\]{width:26px;height:26px}.size-\[38px\]{width:38px;height:38px}.size-\[46px\]{width:46px;height:46px}.size-full{width:100%;height:100%}.h-\[6px\]{height:6px}.h-\[7px\]{height:7px}.h-\[11px\]{height:11px}.h-\[18px\]{height:18px}.h-\[72px\]{height:72px}.h-\[216px\]{height:216px}.h-\[min\(600px\,calc\(100vh-6rem\)\)\]{height:min(600px,100vh - 6rem)}.h-fit{height:fit-content}.h-full{height:100%}.h-px{height:1px}.max-h-\[85vh\]{max-height:85vh}.max-h-\[100px\]{max-height:100px}.min-h-\[20px\]{min-height:20px}.min-h-\[480px\]{min-height:480px}.min-h-\[720px\]{min-height:720px}.min-h-screen{min-height:100vh}.w-1\/2{width:50%}.w-2\/5{width:40%}.w-3\/4{width:75%}.w-3\/5{width:60%}.w-4\/5{width:80%}.w-\[6px\]{width:6px}.w-\[7px\]{width:7px}.w-\[11px\]{width:11px}.w-\[18px\]{width:18px}.w-\[72px\]{width:72px}.w-\[280px\]{width:280px}.w-\[400px\]{width:400px}.w-fit{width:fit-content}.w-full{width:100%}.max-w-\[85\%\]{max-width:85%}.max-w-\[120px\]{max-width:120px}.max-w-\[260px\]{max-width:260px}.max-w-\[280px\]{max-width:280px}.max-w-\[300px\]{max-width:300px}.max-w-\[380px\]{max-width:380px}.max-w-\[420px\]{max-width:420px}.max-w-\[460px\]{max-width:460px}.max-w-\[calc\(100vw-1\.5rem\)\]{max-width:calc(100vw - 1.5rem)}.max-w-\[calc\(100vw-3rem\)\]{max-width:calc(100vw - 3rem)}.max-w-full{max-width:100%}.flex-1{flex:1}.flex-shrink-0,.shrink-0{flex-shrink:0}.border-collapse{border-collapse:collapse}.origin-bottom-left{transform-origin:0 100%}.origin-bottom-right{transform-origin:100% 100%}.translate-x-full{--tw-translate-x:100%;translate:var(--tw-translate-x) var(--tw-translate-y)}.-translate-y-1\/2{--tw-translate-y:calc(calc(1 / 2 * 100%) * -1);translate:var(--tw-translate-x) var(--tw-translate-y)}.rotate-90{rotate:90deg}.rotate-180{rotate:180deg}.transform{transform:var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,)}.cursor-crosshair{cursor:crosshair}.cursor-default{cursor:default}.cursor-not-allowed{cursor:not-allowed}.cursor-pointer{cursor:pointer}.touch-none{touch-action:none}.resize-none{resize:none}.list-none{list-style-type:none}.\[appearance\:textfield\]{appearance:textfield}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.grid-cols-7{grid-template-columns:repeat(7,minmax(0,1fr))}.grid-cols-\[16px_1fr_auto\]{grid-template-columns:16px 1fr auto}.grid-cols-\[22px_1fr_auto_auto\]{grid-template-columns:22px 1fr auto auto}.grid-cols-\[40px_1fr\]{grid-template-columns:40px 1fr}.grid-cols-\[40px_1fr_auto\]{grid-template-columns:40px 1fr auto}.grid-cols-\[44px_1fr_60px\]{grid-template-columns:44px 1fr 60px}.grid-cols-\[46px_minmax\(0\,1fr\)_auto\]{grid-template-columns:46px minmax(0,1fr) auto}.grid-cols-\[48px_1fr_auto_auto\]{grid-template-columns:48px 1fr auto auto}.grid-cols-\[56px_1fr_auto_auto\]{grid-template-columns:56px 1fr auto auto}.grid-cols-\[84px_minmax\(0\,1fr\)\]{grid-template-columns:84px minmax(0,1fr)}.grid-cols-\[130px_1fr_auto\]{grid-template-columns:130px 1fr auto}.grid-cols-\[auto_1fr_auto\]{grid-template-columns:auto 1fr auto}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.place-items-center{place-items:center}.items-baseline{align-items:baseline}.items-center{align-items:center}.items-end{align-items:flex-end}.items-start{align-items:flex-start}.items-stretch{align-items:stretch}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.justify-end{justify-content:flex-end}.gap-\[7px\]{gap:7px}.gap-px{gap:1px}.gap-x-\[13px\]{column-gap:13px}:where(.divide-y>:not(:last-child)){--tw-divide-y-reverse:0;border-bottom-style:var(--tw-border-style);border-top-style:var(--tw-border-style);border-top-width:calc(1px * var(--tw-divide-y-reverse));border-bottom-width:calc(1px * calc(1 - var(--tw-divide-y-reverse)))}:where(.divide-border>:not(:last-child)){border-color:var(--color-border,oklch(90% 0 0))}:where(.divide-border\/60>:not(:last-child)){border-color:#dedede99}@supports (color:color-mix(in lab, red, red)){:where(.divide-border\/60>:not(:last-child)){border-color:color-mix(in oklab, var(--color-border,oklch(90% 0 0)) 60%, transparent)}}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.overflow-y-auto{overflow-y:auto}.rounded{border-radius:var(--radius,.5rem)}.rounded-\[8px\]{border-radius:8px}.rounded-\[9px\]{border-radius:9px}.rounded-\[10px\]{border-radius:10px}.rounded-\[12px\]{border-radius:12px}.rounded-\[14px\]{border-radius:14px}.rounded-\[16px\]{border-radius:16px}.rounded-\[inherit\]{border-radius:inherit}.rounded-\[var\(--radius\,12px\)\]{border-radius:var(--radius,12px)}.rounded-full{border-radius:3.40282e38px}.rounded-tl{border-top-left-radius:var(--radius,.5rem)}.rounded-tr{border-top-right-radius:var(--radius,.5rem)}.rounded-br{border-bottom-right-radius:var(--radius,.5rem)}.rounded-bl{border-bottom-left-radius:var(--radius,.5rem)}.border{border-style:var(--tw-border-style);border-width:1px}.border-0{border-style:var(--tw-border-style);border-width:0}.border-2{border-style:var(--tw-border-style);border-width:2px}.border-\[1\.5px\]{border-style:var(--tw-border-style);border-width:1.5px}.border-\[2\.5px\]{border-style:var(--tw-border-style);border-width:2.5px}.border-y{border-block-style:var(--tw-border-style);border-block-width:1px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-r{border-right-style:var(--tw-border-style);border-right-width:1px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-b-2{border-bottom-style:var(--tw-border-style);border-bottom-width:2px}.border-l{border-left-style:var(--tw-border-style);border-left-width:1px}.border-l-2{border-left-style:var(--tw-border-style);border-left-width:2px}.border-dashed{--tw-border-style:dashed;border-style:dashed}.border-none{--tw-border-style:none;border-style:none}.border-\[color-mix\(in_oklch\,var\(--color-primary\)_18\%\,transparent\)\]{border-color:#934c3a2e}@supports (color:color-mix(in lab, red, red)){.border-\[color-mix\(in_oklch\,var\(--color-primary\)_18\%\,transparent\)\]{border-color:color-mix(in oklch,var(--color-primary) 18%,transparent)}}.border-border{border-color:var(--color-border,oklch(90% 0 0))}.border-border\/40{border-color:#dedede66}@supports (color:color-mix(in lab, red, red)){.border-border\/40{border-color:color-mix(in oklab, var(--color-border,oklch(90% 0 0)) 40%, transparent)}}.border-border\/60{border-color:#dedede99}@supports (color:color-mix(in lab, red, red)){.border-border\/60{border-color:color-mix(in oklab, var(--color-border,oklch(90% 0 0)) 60%, transparent)}}.border-foreground{border-color:var(--color-foreground,oklch(15% 0 0))}.border-input{border-color:var(--color-input,oklch(90% 0 0))}.border-muted-foreground\/30{border-color:#6363634d}@supports (color:color-mix(in lab, red, red)){.border-muted-foreground\/30{border-color:color-mix(in oklab, var(--color-muted-foreground,oklch(50% 0 0)) 30%, transparent)}}.border-primary{border-color:var(--color-primary,oklch(50% .1 35))}.border-primary\/20{border-color:#934c3a33}@supports (color:color-mix(in lab, red, red)){.border-primary\/20{border-color:color-mix(in oklab, var(--color-primary,oklch(50% .1 35)) 20%, transparent)}}.border-transparent{border-color:#0000}.bg-background{background-color:var(--color-background,oklch(99% 0 0))}.bg-background\/50{background-color:#fcfcfc80}@supports (color:color-mix(in lab, red, red)){.bg-background\/50{background-color:color-mix(in oklab, var(--color-background,oklch(99% 0 0)) 50%, transparent)}}.bg-background\/90{background-color:#fcfcfce6}@supports (color:color-mix(in lab, red, red)){.bg-background\/90{background-color:color-mix(in oklab, var(--color-background,oklch(99% 0 0)) 90%, transparent)}}.bg-background\/92{background-color:#fcfcfceb}@supports (color:color-mix(in lab, red, red)){.bg-background\/92{background-color:color-mix(in oklab, var(--color-background,oklch(99% 0 0)) 92%, transparent)}}.bg-border{background-color:var(--color-border,oklch(90% 0 0))}.bg-border\/60{background-color:#dedede99}@supports (color:color-mix(in lab, red, red)){.bg-border\/60{background-color:color-mix(in oklab, var(--color-border,oklch(90% 0 0)) 60%, transparent)}}.bg-current{background-color:currentColor}.bg-destructive{background-color:var(--color-destructive,oklch(50% .2 25))}.bg-destructive\/10{background-color:#bb061e1a}@supports (color:color-mix(in lab, red, red)){.bg-destructive\/10{background-color:color-mix(in oklab, var(--color-destructive,oklch(50% .2 25)) 10%, transparent)}}.bg-foreground{background-color:var(--color-foreground,oklch(15% 0 0))}.bg-foreground\/40{background-color:#0b0b0b66}@supports (color:color-mix(in lab, red, red)){.bg-foreground\/40{background-color:color-mix(in oklab, var(--color-foreground,oklch(15% 0 0)) 40%, transparent)}}.bg-muted{background-color:var(--color-muted,oklch(95% 0 0))}.bg-muted-foreground\/40{background-color:#63636366}@supports (color:color-mix(in lab, red, red)){.bg-muted-foreground\/40{background-color:color-mix(in oklab, var(--color-muted-foreground,oklch(50% 0 0)) 40%, transparent)}}.bg-muted\/30{background-color:#eeeeee4d}@supports (color:color-mix(in lab, red, red)){.bg-muted\/30{background-color:color-mix(in oklab, var(--color-muted,oklch(95% 0 0)) 30%, transparent)}}.bg-muted\/40{background-color:#eee6}@supports (color:color-mix(in lab, red, red)){.bg-muted\/40{background-color:color-mix(in oklab, var(--color-muted,oklch(95% 0 0)) 40%, transparent)}}.bg-muted\/50{background-color:#eeeeee80}@supports (color:color-mix(in lab, red, red)){.bg-muted\/50{background-color:color-mix(in oklab, var(--color-muted,oklch(95% 0 0)) 50%, transparent)}}.bg-muted\/60{background-color:#eee9}@supports (color:color-mix(in lab, red, red)){.bg-muted\/60{background-color:color-mix(in oklab, var(--color-muted,oklch(95% 0 0)) 60%, transparent)}}.bg-muted\/70{background-color:#eeeeeeb3}@supports (color:color-mix(in lab, red, red)){.bg-muted\/70{background-color:color-mix(in oklab, var(--color-muted,oklch(95% 0 0)) 70%, transparent)}}.bg-primary{background-color:var(--color-primary,oklch(50% .1 35))}.bg-primary\/5{background-color:#934c3a0d}@supports (color:color-mix(in lab, red, red)){.bg-primary\/5{background-color:color-mix(in oklab, var(--color-primary,oklch(50% .1 35)) 5%, transparent)}}.bg-primary\/10{background-color:#934c3a1a}@supports (color:color-mix(in lab, red, red)){.bg-primary\/10{background-color:color-mix(in oklab, var(--color-primary,oklch(50% .1 35)) 10%, transparent)}}.bg-primary\/\[0\.12\]{background-color:#934c3a1f}@supports (color:color-mix(in lab, red, red)){.bg-primary\/\[0\.12\]{background-color:color-mix(in oklab, var(--color-primary,oklch(50% .1 35)) 12%, transparent)}}.bg-transparent{background-color:#0000}.bg-gradient-to-t{--tw-gradient-position:to top in oklab;background-image:linear-gradient(var(--tw-gradient-stops))}.bg-\[linear-gradient\(135deg\,color-mix\(in_oklch\,var\(--color-primary\)_8\%\,transparent\)\,var\(--color-background\)\)\]{background-image:linear-gradient(135deg,#934c3a14,var(--color-background))}@supports (color:color-mix(in lab, red, red)){.bg-\[linear-gradient\(135deg\,color-mix\(in_oklch\,var\(--color-primary\)_8\%\,transparent\)\,var\(--color-background\)\)\]{background-image:linear-gradient(135deg,color-mix(in oklch,var(--color-primary) 8%,transparent),var(--color-background))}}.bg-\[linear-gradient\(135deg\,oklch\(0\.92_0\.05_80\)\,oklch\(0\.84_0\.10_60\)\)\]{background-image:linear-gradient(135deg,oklch(92% .05 80),oklch(84% .1 60))}.bg-\[radial-gradient\(900px_480px_at_50\%_0\%\,color-mix\(in_oklch\,var\(--color-primary\)_8\%\,transparent\)\,transparent_70\%\)\,var\(--color-background\)\]{background-image:radial-gradient(900px 480px at 50% 0%,#934c3a14,transparent 70%),var(--color-background)}@supports (color:color-mix(in lab, red, red)){.bg-\[radial-gradient\(900px_480px_at_50\%_0\%\,color-mix\(in_oklch\,var\(--color-primary\)_8\%\,transparent\)\,transparent_70\%\)\,var\(--color-background\)\]{background-image:radial-gradient(900px 480px at 50% 0%,color-mix(in oklch,var(--color-primary) 8%,transparent),transparent 70%),var(--color-background)}}.to-transparent{--tw-gradient-to:transparent;--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position))}.object-cover{object-fit:cover}.px-\[13px\]{padding-inline:13px}.px-\[18px\]{padding-inline:18px}.px-\[22px\]{padding-inline:22px}.py-\[7px\]{padding-block:7px}.py-\[10px\]{padding-block:10px}.py-\[15px\]{padding-block:15px}.py-\[18px\]{padding-block:18px}.pb-\[13px\]{padding-bottom:13px}.pb-\[22px\]{padding-bottom:22px}.text-center{text-align:center}.text-left{text-align:left}.text-right{text-align:right}.\[font-family\:inherit\],.font-\[inherit\]{font-family:inherit}.text-\[9px\]{font-size:9px}.text-\[10\.5px\]{font-size:10.5px}.text-\[10px\]{font-size:10px}.text-\[11\.5px\]{font-size:11.5px}.text-\[11px\]{font-size:11px}.text-\[12\.5px\]{font-size:12.5px}.text-\[12px\]{font-size:12px}.text-\[13\.5px\]{font-size:13.5px}.text-\[13px\]{font-size:13px}.text-\[14\.5px\]{font-size:14.5px}.text-\[14px\]{font-size:14px}.text-\[15px\]{font-size:15px}.text-\[16px\]{font-size:16px}.text-\[17px\]{font-size:17px}.text-\[18px\]{font-size:18px}.text-\[22px\]{font-size:22px}.text-\[24px\]{font-size:24px}.text-\[28px\]{font-size:28px}.text-\[30px\]{font-size:30px}.text-\[clamp\(26px\,2\.8vw\,34px\)\]{font-size:clamp(26px,2.8vw,34px)}.text-\[clamp\(28px\,3vw\,40px\)\]{font-size:clamp(28px,3vw,40px)}.leading-\[1\.1\]{--tw-leading:1.1;line-height:1.1}.leading-\[1\.2\]{--tw-leading:1.2;line-height:1.2}.leading-\[1\.4\]{--tw-leading:1.4;line-height:1.4}.leading-\[1\.05\]{--tw-leading:1.05;line-height:1.05}.leading-\[1\.5\]{--tw-leading:1.5;line-height:1.5}.leading-\[1\.15\]{--tw-leading:1.15;line-height:1.15}.leading-\[1\.55\]{--tw-leading:1.55;line-height:1.55}.leading-none{--tw-leading:1;line-height:1}.tracking-\[-0\.01em\]{--tw-tracking:-.01em;letter-spacing:-.01em}.tracking-\[-0\.02em\]{--tw-tracking:-.02em;letter-spacing:-.02em}.tracking-\[-0\.015em\]{--tw-tracking:-.015em;letter-spacing:-.015em}.tracking-\[-0\.025em\]{--tw-tracking:-.025em;letter-spacing:-.025em}.tracking-\[0\.1em\]{--tw-tracking:.1em;letter-spacing:.1em}.tracking-\[0\.06em\]{--tw-tracking:.06em;letter-spacing:.06em}.tracking-\[0\.08em\]{--tw-tracking:.08em;letter-spacing:.08em}.tracking-\[0\.12em\]{--tw-tracking:.12em;letter-spacing:.12em}.tracking-\[0\.16em\]{--tw-tracking:.16em;letter-spacing:.16em}.whitespace-nowrap{white-space:nowrap}.whitespace-pre-line{white-space:pre-line}.whitespace-pre-wrap{white-space:pre-wrap}.text-\[inherit\]{color:inherit}.text-\[var\(--color-primary-foreground\,\#fff\)\]{color:var(--color-primary-foreground,#fff)}.text-background{color:var(--color-background,oklch(99% 0 0))}.text-background\/60{color:#fcfcfc99}@supports (color:color-mix(in lab, red, red)){.text-background\/60{color:color-mix(in oklab, var(--color-background,oklch(99% 0 0)) 60%, transparent)}}.text-border{color:var(--color-border,oklch(90% 0 0))}.text-destructive{color:var(--color-destructive,oklch(50% .2 25))}.text-destructive-foreground{color:var(--color-destructive-foreground,oklch(99% 0 0))}.text-foreground{color:var(--color-foreground,oklch(15% 0 0))}.text-foreground\/35{color:#0b0b0b59}@supports (color:color-mix(in lab, red, red)){.text-foreground\/35{color:color-mix(in oklab, var(--color-foreground,oklch(15% 0 0)) 35%, transparent)}}.text-foreground\/45{color:#0b0b0b73}@supports (color:color-mix(in lab, red, red)){.text-foreground\/45{color:color-mix(in oklab, var(--color-foreground,oklch(15% 0 0)) 45%, transparent)}}.text-foreground\/55{color:#0b0b0b8c}@supports (color:color-mix(in lab, red, red)){.text-foreground\/55{color:color-mix(in oklab, var(--color-foreground,oklch(15% 0 0)) 55%, transparent)}}.text-foreground\/60{color:#0b0b0b99}@supports (color:color-mix(in lab, red, red)){.text-foreground\/60{color:color-mix(in oklab, var(--color-foreground,oklch(15% 0 0)) 60%, transparent)}}.text-foreground\/70{color:#0b0b0bb3}@supports (color:color-mix(in lab, red, red)){.text-foreground\/70{color:color-mix(in oklab, var(--color-foreground,oklch(15% 0 0)) 70%, transparent)}}.text-foreground\/80{color:#0b0b0bcc}@supports (color:color-mix(in lab, red, red)){.text-foreground\/80{color:color-mix(in oklab, var(--color-foreground,oklch(15% 0 0)) 80%, transparent)}}.text-foreground\/90{color:#0b0b0be6}@supports (color:color-mix(in lab, red, red)){.text-foreground\/90{color:color-mix(in oklab, var(--color-foreground,oklch(15% 0 0)) 90%, transparent)}}.text-muted-foreground{color:var(--color-muted-foreground,oklch(50% 0 0))}.text-muted-foreground\/30{color:#6363634d}@supports (color:color-mix(in lab, red, red)){.text-muted-foreground\/30{color:color-mix(in oklab, var(--color-muted-foreground,oklch(50% 0 0)) 30%, transparent)}}.text-muted-foreground\/40{color:#63636366}@supports (color:color-mix(in lab, red, red)){.text-muted-foreground\/40{color:color-mix(in oklab, var(--color-muted-foreground,oklch(50% 0 0)) 40%, transparent)}}.text-muted-foreground\/50{color:#63636380}@supports (color:color-mix(in lab, red, red)){.text-muted-foreground\/50{color:color-mix(in oklab, var(--color-muted-foreground,oklch(50% 0 0)) 50%, transparent)}}.text-muted-foreground\/60{color:#63636399}@supports (color:color-mix(in lab, red, red)){.text-muted-foreground\/60{color:color-mix(in oklab, var(--color-muted-foreground,oklch(50% 0 0)) 60%, transparent)}}.text-muted-foreground\/70{color:#636363b3}@supports (color:color-mix(in lab, red, red)){.text-muted-foreground\/70{color:color-mix(in oklab, var(--color-muted-foreground,oklch(50% 0 0)) 70%, transparent)}}.text-primary{color:var(--color-primary,oklch(50% .1 35))}.text-primary-foreground{color:var(--color-primary-foreground,oklch(99% 0 0))}.capitalize{text-transform:capitalize}.uppercase{text-transform:uppercase}.italic{font-style:italic}.tabular-nums{--tw-numeric-spacing:tabular-nums;font-variant-numeric:var(--tw-ordinal,) var(--tw-slashed-zero,) var(--tw-numeric-figure,) var(--tw-numeric-spacing,) var(--tw-numeric-fraction,)}.line-through{text-decoration-line:line-through}.no-underline{text-decoration-line:none}.underline{text-decoration-line:underline}.accent-foreground{accent-color:var(--color-foreground,oklch(15% 0 0))}.accent-primary{accent-color:var(--color-primary,oklch(50% .1 35))}.opacity-0{opacity:0}.opacity-50{opacity:.5}.opacity-60{opacity:.6}.opacity-70{opacity:.7}.opacity-75{opacity:.75}.opacity-85{opacity:.85}.opacity-100{opacity:1}.shadow-\[0_0_0_1px_var\(--color-border\)\]{--tw-shadow:0 0 0 1px var(--tw-shadow-color,var(--color-border));box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-\[0_0_0_2px_var\(--color-card\)\]{--tw-shadow:0 0 0 2px var(--tw-shadow-color,var(--color-card));box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-\[0_0_0_6px_color-mix\(in_oklch\,var\(--color-primary\)_18\%\,transparent\)\]{--tw-shadow:0 0 0 6px var(--tw-shadow-color,#934c3a2e)}@supports (color:color-mix(in lab, red, red)){.shadow-\[0_0_0_6px_color-mix\(in_oklch\,var\(--color-primary\)_18\%\,transparent\)\]{--tw-shadow:0 0 0 6px var(--tw-shadow-color,color-mix(in oklch,var(--color-primary) 18%,transparent))}}.shadow-\[0_0_0_6px_color-mix\(in_oklch\,var\(--color-primary\)_18\%\,transparent\)\]{box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-\[0_1px_0_rgba\(0\,0\,0\,0\.04\)\,0_8px_24px_rgba\(0\,0\,0\,0\.12\)\]{--tw-shadow:0 1px 0 var(--tw-shadow-color,#0000000a), 0 8px 24px var(--tw-shadow-color,#0000001f);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-\[0_1px_0_rgba\(0\,0\,0\,0\.04\)\,0_16px_48px_rgba\(0\,0\,0\,0\.08\)\]{--tw-shadow:0 1px 0 var(--tw-shadow-color,#0000000a), 0 16px 48px var(--tw-shadow-color,#00000014);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-\[0_1px_2px_rgba\(16\,24\,40\,0\.04\)\,0_16px_40px_-16px_rgba\(16\,24\,40\,0\.24\)\]{--tw-shadow:0 1px 2px var(--tw-shadow-color,#1018280a), 0 16px 40px -16px var(--tw-shadow-color,#1018283d);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-\[0_1px_2px_rgba\(16\,24\,40\,0\.06\)\]{--tw-shadow:0 1px 2px var(--tw-shadow-color,#1018280f);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-\[0_1px_3px_rgba\(0\,0\,0\,0\.04\)\,0_6px_24px_rgba\(0\,0\,0\,0\.06\)\]{--tw-shadow:0 1px 3px var(--tw-shadow-color,#0000000a), 0 6px 24px var(--tw-shadow-color,#0000000f);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-\[0_1px_4px_rgba\(0\,0\,0\,0\.10\)\,0_4px_12px_rgba\(0\,0\,0\,0\.08\)\]{--tw-shadow:0 1px 4px var(--tw-shadow-color,#0000001a), 0 4px 12px var(--tw-shadow-color,#00000014);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-\[0_10px_30px_-16px_rgba\(16\,24\,40\,0\.32\)\]{--tw-shadow:0 10px 30px -16px var(--tw-shadow-color,#10182852);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.ring-1{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.ring-2{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.ring-4{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(4px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.ring-background{--tw-ring-color:var(--color-background,oklch(99% 0 0))}.ring-primary\/15{--tw-ring-color:#934c3a26}@supports (color:color-mix(in lab, red, red)){.ring-primary\/15{--tw-ring-color:color-mix(in oklab, var(--color-primary,oklch(50% .1 35)) 15%, transparent)}}.ring-primary\/40{--tw-ring-color:#934c3a66}@supports (color:color-mix(in lab, red, red)){.ring-primary\/40{--tw-ring-color:color-mix(in oklab, var(--color-primary,oklch(50% .1 35)) 40%, transparent)}}.outline{outline-style:var(--tw-outline-style);outline-width:1px}.filter{filter:var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,)}.backdrop-blur-\[1px\]{--tw-backdrop-blur:blur(1px);-webkit-backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,)}.transition{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,ease);transition-duration:var(--tw-duration,0s)}.transition-\[width\]{transition-property:width;transition-timing-function:var(--tw-ease,ease);transition-duration:var(--tw-duration,0s)}.transition-all{transition-property:all;transition-timing-function:var(--tw-ease,ease);transition-duration:var(--tw-duration,0s)}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,ease);transition-duration:var(--tw-duration,0s)}.transition-opacity{transition-property:opacity;transition-timing-function:var(--tw-ease,ease);transition-duration:var(--tw-duration,0s)}.transition-shadow{transition-property:box-shadow;transition-timing-function:var(--tw-ease,ease);transition-duration:var(--tw-duration,0s)}.transition-transform{transition-property:transform,translate,scale,rotate;transition-timing-function:var(--tw-ease,ease);transition-duration:var(--tw-duration,0s)}.duration-200{--tw-duration:.2s;transition-duration:.2s}.duration-300{--tw-duration:.3s;transition-duration:.3s}.duration-500{--tw-duration:.5s;transition-duration:.5s}.duration-700{--tw-duration:.7s;transition-duration:.7s}.ease-\[cubic-bezier\(0\.19\,1\,0\.22\,1\)\]{--tw-ease:cubic-bezier(.19,1,.22,1);transition-timing-function:cubic-bezier(.19,1,.22,1)}.\[transition-timing-function\:cubic-bezier\(0\.16\,1\,0\.3\,1\)\]{transition-timing-function:cubic-bezier(.16,1,.3,1)}.outline-none{--tw-outline-style:none;outline-style:none}.select-none{-webkit-user-select:none;user-select:none}.\[cimplify\:checkout\]{cimplify:checkout}.ring-inset{--tw-ring-inset:inset}@media (hover:hover){.group-hover\:scale-105:is(:where(.group):hover *){--tw-scale-x:105%;--tw-scale-y:105%;--tw-scale-z:105%;scale:var(--tw-scale-x) var(--tw-scale-y)}.group-hover\:scale-\[1\.04\]:is(:where(.group):hover *){scale:1.04}.group-hover\:text-foreground:is(:where(.group):hover *){color:var(--color-foreground,oklch(15% 0 0))}.group-hover\:text-primary:is(:where(.group):hover *){color:var(--color-primary,oklch(50% .1 35))}.group-hover\:opacity-100:is(:where(.group):hover *){opacity:1}}.placeholder\:text-muted-foreground::placeholder{color:var(--color-muted-foreground,oklch(50% 0 0))}.last\:border-b-0:last-child{border-bottom-style:var(--tw-border-style);border-bottom-width:0}.focus-within\:border-foreground:focus-within{border-color:var(--color-foreground,oklch(15% 0 0))}.focus-within\:bg-background:focus-within{background-color:var(--color-background,oklch(99% 0 0))}@media (hover:hover){.hover\:-translate-y-\[1px\]:hover{--tw-translate-y:calc(1px * -1);translate:var(--tw-translate-x) var(--tw-translate-y)}.hover\:-translate-y-px:hover{--tw-translate-y:-1px;translate:var(--tw-translate-x) var(--tw-translate-y)}.hover\:\!scale-110:hover{--tw-scale-x:110%!important;--tw-scale-y:110%!important;--tw-scale-z:110%!important;scale:var(--tw-scale-x) var(--tw-scale-y)!important}.hover\:scale-105:hover{--tw-scale-x:105%;--tw-scale-y:105%;--tw-scale-z:105%;scale:var(--tw-scale-x) var(--tw-scale-y)}.hover\:scale-110:hover{--tw-scale-x:110%;--tw-scale-y:110%;--tw-scale-z:110%;scale:var(--tw-scale-x) var(--tw-scale-y)}.hover\:scale-\[1\.04\]:hover{scale:1.04}.hover\:scale-\[1\.08\]:hover{scale:1.08}.hover\:border-destructive:hover{border-color:var(--color-destructive,oklch(50% .2 25))}.hover\:border-foreground:hover{border-color:var(--color-foreground,oklch(15% 0 0))}.hover\:border-foreground\/30:hover{border-color:#0b0b0b4d}@supports (color:color-mix(in lab, red, red)){.hover\:border-foreground\/30:hover{border-color:color-mix(in oklab, var(--color-foreground,oklch(15% 0 0)) 30%, transparent)}}.hover\:border-foreground\/40:hover{border-color:#0b0b0b66}@supports (color:color-mix(in lab, red, red)){.hover\:border-foreground\/40:hover{border-color:color-mix(in oklab, var(--color-foreground,oklch(15% 0 0)) 40%, transparent)}}.hover\:border-primary:hover{border-color:var(--color-primary,oklch(50% .1 35))}.hover\:border-primary\/20:hover{border-color:#934c3a33}@supports (color:color-mix(in lab, red, red)){.hover\:border-primary\/20:hover{border-color:color-mix(in oklab, var(--color-primary,oklch(50% .1 35)) 20%, transparent)}}.hover\:border-primary\/40:hover{border-color:#934c3a66}@supports (color:color-mix(in lab, red, red)){.hover\:border-primary\/40:hover{border-color:color-mix(in oklab, var(--color-primary,oklch(50% .1 35)) 40%, transparent)}}.hover\:border-primary\/50:hover{border-color:#934c3a80}@supports (color:color-mix(in lab, red, red)){.hover\:border-primary\/50:hover{border-color:color-mix(in oklab, var(--color-primary,oklch(50% .1 35)) 50%, transparent)}}.hover\:\!bg-foreground:hover{background-color:var(--color-foreground,oklch(15% 0 0))!important}.hover\:bg-background:hover{background-color:var(--color-background,oklch(99% 0 0))}.hover\:bg-destructive\/10:hover{background-color:#bb061e1a}@supports (color:color-mix(in lab, red, red)){.hover\:bg-destructive\/10:hover{background-color:color-mix(in oklab, var(--color-destructive,oklch(50% .2 25)) 10%, transparent)}}.hover\:bg-foreground\/90:hover{background-color:#0b0b0be6}@supports (color:color-mix(in lab, red, red)){.hover\:bg-foreground\/90:hover{background-color:color-mix(in oklab, var(--color-foreground,oklch(15% 0 0)) 90%, transparent)}}.hover\:bg-muted:hover{background-color:var(--color-muted,oklch(95% 0 0))}.hover\:bg-muted\/40:hover{background-color:#eee6}@supports (color:color-mix(in lab, red, red)){.hover\:bg-muted\/40:hover{background-color:color-mix(in oklab, var(--color-muted,oklch(95% 0 0)) 40%, transparent)}}.hover\:bg-muted\/50:hover{background-color:#eeeeee80}@supports (color:color-mix(in lab, red, red)){.hover\:bg-muted\/50:hover{background-color:color-mix(in oklab, var(--color-muted,oklch(95% 0 0)) 50%, transparent)}}.hover\:bg-muted\/70:hover{background-color:#eeeeeeb3}@supports (color:color-mix(in lab, red, red)){.hover\:bg-muted\/70:hover{background-color:color-mix(in oklab, var(--color-muted,oklch(95% 0 0)) 70%, transparent)}}.hover\:bg-muted\/80:hover{background-color:#eeec}@supports (color:color-mix(in lab, red, red)){.hover\:bg-muted\/80:hover{background-color:color-mix(in oklab, var(--color-muted,oklch(95% 0 0)) 80%, transparent)}}.hover\:bg-primary\/90:hover{background-color:#934c3ae6}@supports (color:color-mix(in lab, red, red)){.hover\:bg-primary\/90:hover{background-color:color-mix(in oklab, var(--color-primary,oklch(50% .1 35)) 90%, transparent)}}.hover\:\!text-background:hover{color:var(--color-background,oklch(99% 0 0))!important}.hover\:text-background:hover{color:var(--color-background,oklch(99% 0 0))}.hover\:text-destructive:hover{color:var(--color-destructive,oklch(50% .2 25))}.hover\:text-foreground:hover{color:var(--color-foreground,oklch(15% 0 0))}.hover\:text-primary:hover{color:var(--color-primary,oklch(50% .1 35))}.hover\:text-primary\/80:hover{color:#934c3acc}@supports (color:color-mix(in lab, red, red)){.hover\:text-primary\/80:hover{color:color-mix(in oklab, var(--color-primary,oklch(50% .1 35)) 80%, transparent)}}.hover\:underline:hover{text-decoration-line:underline}.hover\:shadow-\[0_2px_6px_rgba\(0\,0\,0\,0\.04\)\,0_12px_40px_rgba\(0\,0\,0\,0\.10\)\]:hover{--tw-shadow:0 2px 6px var(--tw-shadow-color,#0000000a), 0 12px 40px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.hover\:brightness-105:hover{--tw-brightness:brightness(105%);filter:var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,)}}.focus\:border-primary:focus{border-color:var(--color-primary,oklch(50% .1 35))}.focus\:border-primary\/30:focus{border-color:#934c3a4d}@supports (color:color-mix(in lab, red, red)){.focus\:border-primary\/30:focus{border-color:color-mix(in oklab, var(--color-primary,oklch(50% .1 35)) 30%, transparent)}}.focus\:bg-foreground:focus{background-color:var(--color-foreground,oklch(15% 0 0))}.focus\:ring-1:focus{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.focus\:ring-2:focus{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.focus\:ring-primary\/10:focus{--tw-ring-color:#934c3a1a}@supports (color:color-mix(in lab, red, red)){.focus\:ring-primary\/10:focus{--tw-ring-color:color-mix(in oklab, var(--color-primary,oklch(50% .1 35)) 10%, transparent)}}.focus\:ring-primary\/20:focus{--tw-ring-color:#934c3a33}@supports (color:color-mix(in lab, red, red)){.focus\:ring-primary\/20:focus{--tw-ring-color:color-mix(in oklab, var(--color-primary,oklch(50% .1 35)) 20%, transparent)}}.focus\:ring-ring:focus{--tw-ring-color:var(--color-ring,oklch(50% .1 35))}.focus\:outline-none:focus{--tw-outline-style:none;outline-style:none}.focus-visible\:ring-2:focus-visible{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.focus-visible\:ring-primary\/40:focus-visible{--tw-ring-color:#934c3a66}@supports (color:color-mix(in lab, red, red)){.focus-visible\:ring-primary\/40:focus-visible{--tw-ring-color:color-mix(in oklab, var(--color-primary,oklch(50% .1 35)) 40%, transparent)}}.focus-visible\:ring-ring:focus-visible{--tw-ring-color:var(--color-ring,oklch(50% .1 35))}.focus-visible\:outline-none:focus-visible{--tw-outline-style:none;outline-style:none}.active\:scale-95:active{--tw-scale-x:95%;--tw-scale-y:95%;--tw-scale-z:95%;scale:var(--tw-scale-x) var(--tw-scale-y)}.active\:scale-\[0\.99\]:active{scale:.99}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:opacity-30:disabled{opacity:.3}.disabled\:opacity-40:disabled{opacity:.4}.disabled\:opacity-50:disabled{opacity:.5}.aria-selected\:bg-foreground[aria-selected=true]{background-color:var(--color-foreground,oklch(15% 0 0))}.aria-selected\:text-background[aria-selected=true]{color:var(--color-background,oklch(99% 0 0))}@media (hover:hover){.aria-selected\:hover\:bg-foreground\/90[aria-selected=true]:hover{background-color:#0b0b0be6}@supports (color:color-mix(in lab, red, red)){.aria-selected\:hover\:bg-foreground\/90[aria-selected=true]:hover{background-color:color-mix(in oklab, var(--color-foreground,oklch(15% 0 0)) 90%, transparent)}}}.data-\[checked\]\:border-primary[data-checked]{border-color:var(--color-primary,oklch(50% .1 35))}.data-\[checked\]\:bg-primary\/5[data-checked]{background-color:#934c3a0d}@supports (color:color-mix(in lab, red, red)){.data-\[checked\]\:bg-primary\/5[data-checked]{background-color:color-mix(in oklab, var(--color-primary,oklch(50% .1 35)) 5%, transparent)}}.data-\[fully-booked\]\:cursor-not-allowed[data-fully-booked]{cursor:not-allowed}.data-\[fully-booked\]\:opacity-40[data-fully-booked]{opacity:.4}.data-\[selected\]\:border-foreground[data-selected]{border-color:var(--color-foreground,oklch(15% 0 0))}.data-\[selected\]\:bg-foreground[data-selected]{background-color:var(--color-foreground,oklch(15% 0 0))}.data-\[selected\]\:text-background[data-selected]{color:var(--color-background,oklch(99% 0 0))}.data-\[unavailable\]\:cursor-not-allowed[data-unavailable]{cursor:not-allowed}.data-\[unavailable\]\:line-through[data-unavailable]{text-decoration-line:line-through}.data-\[unavailable\]\:opacity-40[data-unavailable]{opacity:.4}.\[\&_a\]\:text-primary a{color:var(--color-primary,oklch(50% .1 35))}.\[\&_a\]\:underline a{text-decoration-line:underline}.\[\&_a\]\:underline-offset-2 a{text-underline-offset:2px}.\[\&_b\]\:text-foreground b{color:var(--color-foreground,oklch(15% 0 0))}.\[\&_blockquote\]\:border-l-2 blockquote{border-left-style:var(--tw-border-style);border-left-width:2px}.\[\&_blockquote\]\:border-border blockquote{border-color:var(--color-border,oklch(90% 0 0))}.\[\&_blockquote\]\:italic blockquote{font-style:italic}.\[\&_caption\]\:caption-bottom caption{caption-side:bottom}.\[\&_caption\]\:text-muted-foreground caption{color:var(--color-muted-foreground,oklch(50% 0 0))}.\[\&_code\]\:rounded code{border-radius:var(--radius,.5rem)}.\[\&_code\]\:bg-muted code{background-color:var(--color-muted,oklch(95% 0 0))}.\[\&_code\]\:text-\[0\.85em\] code{font-size:.85em}.\[\&_del\]\:line-through del{text-decoration-line:line-through}.\[\&_details\]\:border details{border-style:var(--tw-border-style);border-width:1px}.\[\&_details\]\:border-border details{border-color:var(--color-border,oklch(90% 0 0))}.\[\&_dt\]\:text-foreground dt{color:var(--color-foreground,oklch(15% 0 0))}.\[\&_em\]\:italic em{font-style:italic}.\[\&_figcaption\]\:text-center figcaption{text-align:center}.\[\&_figcaption\]\:text-muted-foreground figcaption{color:var(--color-muted-foreground,oklch(50% 0 0))}.\[\&_h1\]\:text-foreground h1,.\[\&_h2\]\:text-foreground h2,.\[\&_h3\]\:text-foreground h3,.\[\&_h4\]\:text-foreground h4,.\[\&_h5\]\:text-foreground h5,.\[\&_h6\]\:text-foreground h6{color:var(--color-foreground,oklch(15% 0 0))}.\[\&_hr\]\:border-border hr{border-color:var(--color-border,oklch(90% 0 0))}.\[\&_i\]\:italic i{font-style:italic}.\[\&_iframe\]\:w-full iframe{width:100%}.\[\&_img\]\:h-auto img{height:auto}.\[\&_img\]\:max-w-full img{max-width:100%}.\[\&_ins\]\:underline ins{text-decoration-line:underline}.\[\&_mark\]\:rounded mark{border-radius:var(--radius,.5rem)}.\[\&_ol\]\:list-decimal ol{list-style-type:decimal}.\[\&_pre\]\:overflow-x-auto pre{overflow-x:auto}.\[\&_pre\]\:bg-muted pre{background-color:var(--color-muted,oklch(95% 0 0))}.\[\&_pre\]\:text-\[0\.85em\] pre{font-size:.85em}.\[\&_pre\>code\]\:bg-transparent pre>code{background-color:#0000}.\[\&_s\]\:line-through s{text-decoration-line:line-through}.\[\&_strong\]\:text-foreground strong{color:var(--color-foreground,oklch(15% 0 0))}.\[\&_sub\]\:align-sub sub{vertical-align:sub}.\[\&_sub\]\:text-\[0\.75em\] sub{font-size:.75em}.\[\&_summary\]\:cursor-pointer summary{cursor:pointer}.\[\&_summary\]\:text-foreground summary{color:var(--color-foreground,oklch(15% 0 0))}.\[\&_sup\]\:align-super sup{vertical-align:super}.\[\&_sup\]\:text-\[0\.75em\] sup{font-size:.75em}.\[\&_table\]\:w-full table{width:100%}.\[\&_table\]\:border-collapse table{border-collapse:collapse}.\[\&_td\]\:border td{border-style:var(--tw-border-style);border-width:1px}.\[\&_td\]\:border-border td{border-color:var(--color-border,oklch(90% 0 0))}.\[\&_td\]\:align-top td{vertical-align:top}.\[\&_th\]\:border th{border-style:var(--tw-border-style);border-width:1px}.\[\&_th\]\:border-border th{border-color:var(--color-border,oklch(90% 0 0))}.\[\&_th\]\:bg-muted th{background-color:var(--color-muted,oklch(95% 0 0))}.\[\&_th\]\:text-left th{text-align:left}.\[\&_th\]\:text-foreground th{color:var(--color-foreground,oklch(15% 0 0))}.\[\&_u\]\:underline u{text-decoration-line:underline}.\[\&_ul\]\:list-disc ul{list-style-type:disc}.\[\&_ul_ul\]\:list-\[circle\] ul ul{list-style-type:circle}.\[\&\:\:-webkit-details-marker\]\:hidden::-webkit-details-marker{display:none}.\[\&\:\:-webkit-inner-spin-button\]\:appearance-none::-webkit-inner-spin-button{appearance:none}.\[\&\:\:-webkit-outer-spin-button\]\:appearance-none::-webkit-outer-spin-button{appearance:none}.\[\&\:not\(\:first-child\)\]\:border-t:not(:first-child){border-top-style:var(--tw-border-style);border-top-width:1px}.\[\&\:not\(\:first-child\)\]\:border-border\/50:not(:first-child){border-color:#dedede80}@supports (color:color-mix(in lab, red, red)){.\[\&\:not\(\:first-child\)\]\:border-border\/50:not(:first-child){border-color:color-mix(in oklab, var(--color-border,oklch(90% 0 0)) 50%, transparent)}}[open]>.\[\[open\]\>\&\]\:rotate-180{rotate:180deg}.cimplify-cols-2,.cimplify-cols-3,.cimplify-cols-4,.cimplify-media{gap:1.5rem;display:grid}.cimplify-media{align-items:center}.cimplify-media--reverse>:first-child{order:2}@media (min-width:640px){.cimplify-cols-2,.cimplify-cols-3,.cimplify-cols-4,.cimplify-media{grid-template-columns:repeat(2,minmax(0,1fr))}}@media (min-width:1024px){.cimplify-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.cimplify-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}}.cimplify-cols-2>*>:first-child,.cimplify-cols-3>*>:first-child,.cimplify-cols-4>*>:first-child,.cimplify-media>*>:first-child,.cimplify-media>img,.cimplify-cols-2>img,.cimplify-cols-3>img,.cimplify-cols-4>img{margin-top:0}.cimplify-card{border:1px solid var(--color-border);border-radius:var(--radius);padding:1rem}.cimplify-banner{border-radius:var(--radius);position:relative;overflow:hidden}.cimplify-banner>img{width:100%;height:auto;margin:0;display:block}.cimplify-banner__content{flex-direction:column;justify-content:center;gap:.5rem;padding:1.5rem 2rem;display:flex;position:absolute;inset:0}@property --tw-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-z{syntax:"*";inherits:false;initial-value:0}@property --tw-rotate-x{syntax:"*";inherits:false}@property --tw-rotate-y{syntax:"*";inherits:false}@property --tw-rotate-z{syntax:"*";inherits:false}@property --tw-skew-x{syntax:"*";inherits:false}@property --tw-skew-y{syntax:"*";inherits:false}@property --tw-divide-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-gradient-position{syntax:"*";inherits:false}@property --tw-gradient-from{syntax:"<color>";inherits:false;initial-value:#0000}@property --tw-gradient-via{syntax:"<color>";inherits:false;initial-value:#0000}@property --tw-gradient-to{syntax:"<color>";inherits:false;initial-value:#0000}@property --tw-gradient-stops{syntax:"*";inherits:false}@property --tw-gradient-via-stops{syntax:"*";inherits:false}@property --tw-gradient-from-position{syntax:"<length-percentage>";inherits:false;initial-value:0%}@property --tw-gradient-via-position{syntax:"<length-percentage>";inherits:false;initial-value:50%}@property --tw-gradient-to-position{syntax:"<length-percentage>";inherits:false;initial-value:100%}@property --tw-leading{syntax:"*";inherits:false}@property --tw-tracking{syntax:"*";inherits:false}@property --tw-ordinal{syntax:"*";inherits:false}@property --tw-slashed-zero{syntax:"*";inherits:false}@property --tw-numeric-figure{syntax:"*";inherits:false}@property --tw-numeric-spacing{syntax:"*";inherits:false}@property --tw-numeric-fraction{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"<length>";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-outline-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-drop-shadow{syntax:"*";inherits:false}@property --tw-drop-shadow-color{syntax:"*";inherits:false}@property --tw-drop-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:"*";inherits:false}@property --tw-backdrop-blur{syntax:"*";inherits:false}@property --tw-backdrop-brightness{syntax:"*";inherits:false}@property --tw-backdrop-contrast{syntax:"*";inherits:false}@property --tw-backdrop-grayscale{syntax:"*";inherits:false}@property --tw-backdrop-hue-rotate{syntax:"*";inherits:false}@property --tw-backdrop-invert{syntax:"*";inherits:false}@property --tw-backdrop-opacity{syntax:"*";inherits:false}@property --tw-backdrop-saturate{syntax:"*";inherits:false}@property --tw-backdrop-sepia{syntax:"*";inherits:false}@property --tw-duration{syntax:"*";inherits:false}@property --tw-ease{syntax:"*";inherits:false}@property --tw-scale-x{syntax:"*";inherits:false;initial-value:1}@property --tw-scale-y{syntax:"*";inherits:false;initial-value:1}@property --tw-scale-z{syntax:"*";inherits:false;initial-value:1}
2
+ @layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0;--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-divide-y-reverse:0;--tw-border-style:solid;--tw-gradient-position:initial;--tw-gradient-from:#0000;--tw-gradient-via:#0000;--tw-gradient-to:#0000;--tw-gradient-stops:initial;--tw-gradient-via-stops:initial;--tw-gradient-from-position:0%;--tw-gradient-via-position:50%;--tw-gradient-to-position:100%;--tw-leading:initial;--tw-tracking:initial;--tw-ordinal:initial;--tw-slashed-zero:initial;--tw-numeric-figure:initial;--tw-numeric-spacing:initial;--tw-numeric-fraction:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-outline-style:solid;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial;--tw-backdrop-blur:initial;--tw-backdrop-brightness:initial;--tw-backdrop-contrast:initial;--tw-backdrop-grayscale:initial;--tw-backdrop-hue-rotate:initial;--tw-backdrop-invert:initial;--tw-backdrop-opacity:initial;--tw-backdrop-saturate:initial;--tw-backdrop-sepia:initial;--tw-duration:initial;--tw-ease:initial;--tw-scale-x:1;--tw-scale-y:1;--tw-scale-z:1}}}.pointer-events-auto{pointer-events:auto}.pointer-events-none{pointer-events:none}.collapse{visibility:collapse}.visible{visibility:visible}.sr-only{clip-path:inset(50%);white-space:nowrap;border-width:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.static{position:static}.sticky{position:sticky}.top-1\/2{top:50%}.top-\[18px\]{top:18px}.top-\[calc\(100\%\+8px\)\]{top:calc(100% + 8px)}.top-full{top:100%}.top-px{top:1px}.-right-px{right:-1px}.-bottom-px{bottom:-1px}.-left-\[9px\]{left:-9px}.left-\[14px\]{left:14px}.isolate{isolation:isolate}.z-10{z-index:10}.z-20{z-index:20}.z-30{z-index:30}.z-50{z-index:50}.z-\[1\]{z-index:1}.z-\[2\]{z-index:2}.z-\[200\]{z-index:200}.z-\[9999\]{z-index:9999}.container{width:100%}.m-auto{margin:auto}.mx-auto{margin-inline:auto}.-mt-px{margin-top:-1px}.mt-auto{margin-top:auto}.mt-px{margin-top:1px}.mr-auto{margin-right:auto}.-mb-px{margin-bottom:-1px}.ml-\[1px\]{margin-left:1px}.ml-\[9px\]{margin-left:9px}.ml-auto{margin-left:auto}.line-clamp-1{-webkit-line-clamp:1;-webkit-box-orient:vertical;display:-webkit-box;overflow:hidden}.line-clamp-2{-webkit-line-clamp:2;-webkit-box-orient:vertical;display:-webkit-box;overflow:hidden}.block{display:block}.contents{display:contents}.flex{display:flex}.grid{display:grid}.hidden{display:none}.inline{display:inline}.inline-block{display:inline-block}.inline-flex{display:inline-flex}.table{display:table}.aspect-\[3\/4\]{aspect-ratio:3/4}.aspect-\[4\/3\]{aspect-ratio:4/3}.aspect-\[5\/2\]{aspect-ratio:5/2}.aspect-\[16\/9\]{aspect-ratio:16/9}.aspect-square{aspect-ratio:1}.size-\[7px\]{width:7px;height:7px}.size-\[18px\]{width:18px;height:18px}.size-\[22px\]{width:22px;height:22px}.size-\[26px\]{width:26px;height:26px}.size-\[38px\]{width:38px;height:38px}.size-\[46px\]{width:46px;height:46px}.size-full{width:100%;height:100%}.h-\[6px\]{height:6px}.h-\[7px\]{height:7px}.h-\[11px\]{height:11px}.h-\[18px\]{height:18px}.h-\[72px\]{height:72px}.h-\[216px\]{height:216px}.h-\[min\(600px\,calc\(100vh-6rem\)\)\]{height:min(600px,100vh - 6rem)}.h-fit{height:fit-content}.h-full{height:100%}.h-px{height:1px}.max-h-\[85vh\]{max-height:85vh}.max-h-\[100px\]{max-height:100px}.min-h-\[20px\]{min-height:20px}.min-h-\[480px\]{min-height:480px}.min-h-\[720px\]{min-height:720px}.min-h-screen{min-height:100vh}.w-1\/2{width:50%}.w-2\/5{width:40%}.w-3\/4{width:75%}.w-3\/5{width:60%}.w-4\/5{width:80%}.w-\[6px\]{width:6px}.w-\[7px\]{width:7px}.w-\[11px\]{width:11px}.w-\[18px\]{width:18px}.w-\[72px\]{width:72px}.w-\[280px\]{width:280px}.w-\[400px\]{width:400px}.w-fit{width:fit-content}.w-full{width:100%}.max-w-\[85\%\]{max-width:85%}.max-w-\[120px\]{max-width:120px}.max-w-\[260px\]{max-width:260px}.max-w-\[280px\]{max-width:280px}.max-w-\[300px\]{max-width:300px}.max-w-\[380px\]{max-width:380px}.max-w-\[420px\]{max-width:420px}.max-w-\[460px\]{max-width:460px}.max-w-\[calc\(100vw-1\.5rem\)\]{max-width:calc(100vw - 1.5rem)}.max-w-\[calc\(100vw-3rem\)\]{max-width:calc(100vw - 3rem)}.max-w-full{max-width:100%}.flex-1{flex:1}.flex-shrink-0,.shrink-0{flex-shrink:0}.border-collapse{border-collapse:collapse}.origin-bottom-left{transform-origin:0 100%}.origin-bottom-right{transform-origin:100% 100%}.translate-x-full{--tw-translate-x:100%;translate:var(--tw-translate-x) var(--tw-translate-y)}.-translate-y-1\/2{--tw-translate-y:calc(calc(1 / 2 * 100%) * -1);translate:var(--tw-translate-x) var(--tw-translate-y)}.rotate-90{rotate:90deg}.rotate-180{rotate:180deg}.transform{transform:var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,)}.cursor-crosshair{cursor:crosshair}.cursor-default{cursor:default}.cursor-not-allowed{cursor:not-allowed}.cursor-pointer{cursor:pointer}.touch-none{touch-action:none}.resize-none{resize:none}.list-none{list-style-type:none}.\[appearance\:textfield\]{appearance:textfield}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.grid-cols-7{grid-template-columns:repeat(7,minmax(0,1fr))}.grid-cols-\[16px_1fr_auto\]{grid-template-columns:16px 1fr auto}.grid-cols-\[22px_1fr_auto_auto\]{grid-template-columns:22px 1fr auto auto}.grid-cols-\[40px_1fr\]{grid-template-columns:40px 1fr}.grid-cols-\[40px_1fr_auto\]{grid-template-columns:40px 1fr auto}.grid-cols-\[44px_1fr_60px\]{grid-template-columns:44px 1fr 60px}.grid-cols-\[46px_minmax\(0\,1fr\)_auto\]{grid-template-columns:46px minmax(0,1fr) auto}.grid-cols-\[48px_1fr_auto_auto\]{grid-template-columns:48px 1fr auto auto}.grid-cols-\[56px_1fr_auto_auto\]{grid-template-columns:56px 1fr auto auto}.grid-cols-\[84px_minmax\(0\,1fr\)\]{grid-template-columns:84px minmax(0,1fr)}.grid-cols-\[130px_1fr_auto\]{grid-template-columns:130px 1fr auto}.grid-cols-\[auto_1fr_auto\]{grid-template-columns:auto 1fr auto}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.place-items-center{place-items:center}.items-baseline{align-items:baseline}.items-center{align-items:center}.items-end{align-items:flex-end}.items-start{align-items:flex-start}.items-stretch{align-items:stretch}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.justify-end{justify-content:flex-end}.gap-\[7px\]{gap:7px}.gap-px{gap:1px}.gap-x-\[13px\]{column-gap:13px}:where(.divide-y>:not(:last-child)){--tw-divide-y-reverse:0;border-bottom-style:var(--tw-border-style);border-top-style:var(--tw-border-style);border-top-width:calc(1px * var(--tw-divide-y-reverse));border-bottom-width:calc(1px * calc(1 - var(--tw-divide-y-reverse)))}:where(.divide-border>:not(:last-child)){border-color:var(--color-border,oklch(90% 0 0))}:where(.divide-border\/60>:not(:last-child)){border-color:#dedede99}@supports (color:color-mix(in lab, red, red)){:where(.divide-border\/60>:not(:last-child)){border-color:color-mix(in oklab, var(--color-border,oklch(90% 0 0)) 60%, transparent)}}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.overflow-y-auto{overflow-y:auto}.rounded{border-radius:var(--radius,.5rem)}.rounded-\[8px\]{border-radius:8px}.rounded-\[9px\]{border-radius:9px}.rounded-\[10px\]{border-radius:10px}.rounded-\[12px\]{border-radius:12px}.rounded-\[14px\]{border-radius:14px}.rounded-\[16px\]{border-radius:16px}.rounded-\[inherit\]{border-radius:inherit}.rounded-\[var\(--radius\,12px\)\]{border-radius:var(--radius,12px)}.rounded-full{border-radius:3.40282e38px}.rounded-tl{border-top-left-radius:var(--radius,.5rem)}.rounded-tr{border-top-right-radius:var(--radius,.5rem)}.rounded-br{border-bottom-right-radius:var(--radius,.5rem)}.rounded-bl{border-bottom-left-radius:var(--radius,.5rem)}.border{border-style:var(--tw-border-style);border-width:1px}.border-0{border-style:var(--tw-border-style);border-width:0}.border-2{border-style:var(--tw-border-style);border-width:2px}.border-\[1\.5px\]{border-style:var(--tw-border-style);border-width:1.5px}.border-\[2\.5px\]{border-style:var(--tw-border-style);border-width:2.5px}.border-y{border-block-style:var(--tw-border-style);border-block-width:1px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-r{border-right-style:var(--tw-border-style);border-right-width:1px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-b-2{border-bottom-style:var(--tw-border-style);border-bottom-width:2px}.border-l{border-left-style:var(--tw-border-style);border-left-width:1px}.border-l-2{border-left-style:var(--tw-border-style);border-left-width:2px}.border-dashed{--tw-border-style:dashed;border-style:dashed}.border-none{--tw-border-style:none;border-style:none}.border-\[color-mix\(in_oklch\,var\(--color-primary\)_18\%\,transparent\)\]{border-color:#934c3a2e}@supports (color:color-mix(in lab, red, red)){.border-\[color-mix\(in_oklch\,var\(--color-primary\)_18\%\,transparent\)\]{border-color:color-mix(in oklch,var(--color-primary) 18%,transparent)}}.border-border{border-color:var(--color-border,oklch(90% 0 0))}.border-border\/40{border-color:#dedede66}@supports (color:color-mix(in lab, red, red)){.border-border\/40{border-color:color-mix(in oklab, var(--color-border,oklch(90% 0 0)) 40%, transparent)}}.border-border\/60{border-color:#dedede99}@supports (color:color-mix(in lab, red, red)){.border-border\/60{border-color:color-mix(in oklab, var(--color-border,oklch(90% 0 0)) 60%, transparent)}}.border-foreground{border-color:var(--color-foreground,oklch(15% 0 0))}.border-input{border-color:var(--color-input,oklch(90% 0 0))}.border-muted-foreground\/30{border-color:#6363634d}@supports (color:color-mix(in lab, red, red)){.border-muted-foreground\/30{border-color:color-mix(in oklab, var(--color-muted-foreground,oklch(50% 0 0)) 30%, transparent)}}.border-primary{border-color:var(--color-primary,oklch(50% .1 35))}.border-primary\/20{border-color:#934c3a33}@supports (color:color-mix(in lab, red, red)){.border-primary\/20{border-color:color-mix(in oklab, var(--color-primary,oklch(50% .1 35)) 20%, transparent)}}.border-transparent{border-color:#0000}.bg-background{background-color:var(--color-background,oklch(99% 0 0))}.bg-background\/50{background-color:#fcfcfc80}@supports (color:color-mix(in lab, red, red)){.bg-background\/50{background-color:color-mix(in oklab, var(--color-background,oklch(99% 0 0)) 50%, transparent)}}.bg-background\/90{background-color:#fcfcfce6}@supports (color:color-mix(in lab, red, red)){.bg-background\/90{background-color:color-mix(in oklab, var(--color-background,oklch(99% 0 0)) 90%, transparent)}}.bg-background\/92{background-color:#fcfcfceb}@supports (color:color-mix(in lab, red, red)){.bg-background\/92{background-color:color-mix(in oklab, var(--color-background,oklch(99% 0 0)) 92%, transparent)}}.bg-border{background-color:var(--color-border,oklch(90% 0 0))}.bg-border\/60{background-color:#dedede99}@supports (color:color-mix(in lab, red, red)){.bg-border\/60{background-color:color-mix(in oklab, var(--color-border,oklch(90% 0 0)) 60%, transparent)}}.bg-current{background-color:currentColor}.bg-destructive{background-color:var(--color-destructive,oklch(50% .2 25))}.bg-destructive\/10{background-color:#bb061e1a}@supports (color:color-mix(in lab, red, red)){.bg-destructive\/10{background-color:color-mix(in oklab, var(--color-destructive,oklch(50% .2 25)) 10%, transparent)}}.bg-foreground{background-color:var(--color-foreground,oklch(15% 0 0))}.bg-foreground\/40{background-color:#0b0b0b66}@supports (color:color-mix(in lab, red, red)){.bg-foreground\/40{background-color:color-mix(in oklab, var(--color-foreground,oklch(15% 0 0)) 40%, transparent)}}.bg-muted{background-color:var(--color-muted,oklch(95% 0 0))}.bg-muted-foreground\/40{background-color:#63636366}@supports (color:color-mix(in lab, red, red)){.bg-muted-foreground\/40{background-color:color-mix(in oklab, var(--color-muted-foreground,oklch(50% 0 0)) 40%, transparent)}}.bg-muted\/30{background-color:#eeeeee4d}@supports (color:color-mix(in lab, red, red)){.bg-muted\/30{background-color:color-mix(in oklab, var(--color-muted,oklch(95% 0 0)) 30%, transparent)}}.bg-muted\/40{background-color:#eee6}@supports (color:color-mix(in lab, red, red)){.bg-muted\/40{background-color:color-mix(in oklab, var(--color-muted,oklch(95% 0 0)) 40%, transparent)}}.bg-muted\/50{background-color:#eeeeee80}@supports (color:color-mix(in lab, red, red)){.bg-muted\/50{background-color:color-mix(in oklab, var(--color-muted,oklch(95% 0 0)) 50%, transparent)}}.bg-muted\/60{background-color:#eee9}@supports (color:color-mix(in lab, red, red)){.bg-muted\/60{background-color:color-mix(in oklab, var(--color-muted,oklch(95% 0 0)) 60%, transparent)}}.bg-muted\/70{background-color:#eeeeeeb3}@supports (color:color-mix(in lab, red, red)){.bg-muted\/70{background-color:color-mix(in oklab, var(--color-muted,oklch(95% 0 0)) 70%, transparent)}}.bg-primary{background-color:var(--color-primary,oklch(50% .1 35))}.bg-primary\/5{background-color:#934c3a0d}@supports (color:color-mix(in lab, red, red)){.bg-primary\/5{background-color:color-mix(in oklab, var(--color-primary,oklch(50% .1 35)) 5%, transparent)}}.bg-primary\/10{background-color:#934c3a1a}@supports (color:color-mix(in lab, red, red)){.bg-primary\/10{background-color:color-mix(in oklab, var(--color-primary,oklch(50% .1 35)) 10%, transparent)}}.bg-primary\/\[0\.12\]{background-color:#934c3a1f}@supports (color:color-mix(in lab, red, red)){.bg-primary\/\[0\.12\]{background-color:color-mix(in oklab, var(--color-primary,oklch(50% .1 35)) 12%, transparent)}}.bg-transparent{background-color:#0000}.bg-gradient-to-t{--tw-gradient-position:to top in oklab;background-image:linear-gradient(var(--tw-gradient-stops))}.bg-\[linear-gradient\(135deg\,color-mix\(in_oklch\,var\(--color-primary\)_8\%\,transparent\)\,var\(--color-background\)\)\]{background-image:linear-gradient(135deg,#934c3a14,var(--color-background))}@supports (color:color-mix(in lab, red, red)){.bg-\[linear-gradient\(135deg\,color-mix\(in_oklch\,var\(--color-primary\)_8\%\,transparent\)\,var\(--color-background\)\)\]{background-image:linear-gradient(135deg,color-mix(in oklch,var(--color-primary) 8%,transparent),var(--color-background))}}.bg-\[linear-gradient\(135deg\,oklch\(0\.92_0\.05_80\)\,oklch\(0\.84_0\.10_60\)\)\]{background-image:linear-gradient(135deg,oklch(92% .05 80),oklch(84% .1 60))}.bg-\[radial-gradient\(900px_480px_at_50\%_0\%\,color-mix\(in_oklch\,var\(--color-primary\)_8\%\,transparent\)\,transparent_70\%\)\,var\(--color-background\)\]{background-image:radial-gradient(900px 480px at 50% 0%,#934c3a14,transparent 70%),var(--color-background)}@supports (color:color-mix(in lab, red, red)){.bg-\[radial-gradient\(900px_480px_at_50\%_0\%\,color-mix\(in_oklch\,var\(--color-primary\)_8\%\,transparent\)\,transparent_70\%\)\,var\(--color-background\)\]{background-image:radial-gradient(900px 480px at 50% 0%,color-mix(in oklch,var(--color-primary) 8%,transparent),transparent 70%),var(--color-background)}}.to-transparent{--tw-gradient-to:transparent;--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position))}.object-cover{object-fit:cover}.px-\[13px\]{padding-inline:13px}.px-\[18px\]{padding-inline:18px}.px-\[22px\]{padding-inline:22px}.py-\[7px\]{padding-block:7px}.py-\[10px\]{padding-block:10px}.py-\[15px\]{padding-block:15px}.py-\[18px\]{padding-block:18px}.pb-\[13px\]{padding-bottom:13px}.pb-\[22px\]{padding-bottom:22px}.text-center{text-align:center}.text-left{text-align:left}.text-right{text-align:right}.\[font-family\:inherit\],.font-\[inherit\]{font-family:inherit}.text-\[9px\]{font-size:9px}.text-\[10\.5px\]{font-size:10.5px}.text-\[10px\]{font-size:10px}.text-\[11\.5px\]{font-size:11.5px}.text-\[11px\]{font-size:11px}.text-\[12\.5px\]{font-size:12.5px}.text-\[12px\]{font-size:12px}.text-\[13\.5px\]{font-size:13.5px}.text-\[13px\]{font-size:13px}.text-\[14\.5px\]{font-size:14.5px}.text-\[14px\]{font-size:14px}.text-\[15px\]{font-size:15px}.text-\[16px\]{font-size:16px}.text-\[17px\]{font-size:17px}.text-\[18px\]{font-size:18px}.text-\[22px\]{font-size:22px}.text-\[24px\]{font-size:24px}.text-\[28px\]{font-size:28px}.text-\[30px\]{font-size:30px}.text-\[clamp\(26px\,2\.8vw\,34px\)\]{font-size:clamp(26px,2.8vw,34px)}.text-\[clamp\(28px\,3vw\,40px\)\]{font-size:clamp(28px,3vw,40px)}.leading-\[1\.1\]{--tw-leading:1.1;line-height:1.1}.leading-\[1\.2\]{--tw-leading:1.2;line-height:1.2}.leading-\[1\.4\]{--tw-leading:1.4;line-height:1.4}.leading-\[1\.05\]{--tw-leading:1.05;line-height:1.05}.leading-\[1\.5\]{--tw-leading:1.5;line-height:1.5}.leading-\[1\.15\]{--tw-leading:1.15;line-height:1.15}.leading-\[1\.55\]{--tw-leading:1.55;line-height:1.55}.leading-none{--tw-leading:1;line-height:1}.tracking-\[-0\.01em\]{--tw-tracking:-.01em;letter-spacing:-.01em}.tracking-\[-0\.02em\]{--tw-tracking:-.02em;letter-spacing:-.02em}.tracking-\[-0\.015em\]{--tw-tracking:-.015em;letter-spacing:-.015em}.tracking-\[-0\.025em\]{--tw-tracking:-.025em;letter-spacing:-.025em}.tracking-\[0\.1em\]{--tw-tracking:.1em;letter-spacing:.1em}.tracking-\[0\.06em\]{--tw-tracking:.06em;letter-spacing:.06em}.tracking-\[0\.08em\]{--tw-tracking:.08em;letter-spacing:.08em}.tracking-\[0\.12em\]{--tw-tracking:.12em;letter-spacing:.12em}.tracking-\[0\.16em\]{--tw-tracking:.16em;letter-spacing:.16em}.whitespace-nowrap{white-space:nowrap}.whitespace-pre-line{white-space:pre-line}.whitespace-pre-wrap{white-space:pre-wrap}.text-\[inherit\]{color:inherit}.text-\[var\(--color-primary-foreground\,\#fff\)\]{color:var(--color-primary-foreground,#fff)}.text-background{color:var(--color-background,oklch(99% 0 0))}.text-background\/60{color:#fcfcfc99}@supports (color:color-mix(in lab, red, red)){.text-background\/60{color:color-mix(in oklab, var(--color-background,oklch(99% 0 0)) 60%, transparent)}}.text-border{color:var(--color-border,oklch(90% 0 0))}.text-destructive{color:var(--color-destructive,oklch(50% .2 25))}.text-destructive-foreground{color:var(--color-destructive-foreground,oklch(99% 0 0))}.text-foreground{color:var(--color-foreground,oklch(15% 0 0))}.text-foreground\/35{color:#0b0b0b59}@supports (color:color-mix(in lab, red, red)){.text-foreground\/35{color:color-mix(in oklab, var(--color-foreground,oklch(15% 0 0)) 35%, transparent)}}.text-foreground\/45{color:#0b0b0b73}@supports (color:color-mix(in lab, red, red)){.text-foreground\/45{color:color-mix(in oklab, var(--color-foreground,oklch(15% 0 0)) 45%, transparent)}}.text-foreground\/55{color:#0b0b0b8c}@supports (color:color-mix(in lab, red, red)){.text-foreground\/55{color:color-mix(in oklab, var(--color-foreground,oklch(15% 0 0)) 55%, transparent)}}.text-foreground\/60{color:#0b0b0b99}@supports (color:color-mix(in lab, red, red)){.text-foreground\/60{color:color-mix(in oklab, var(--color-foreground,oklch(15% 0 0)) 60%, transparent)}}.text-foreground\/70{color:#0b0b0bb3}@supports (color:color-mix(in lab, red, red)){.text-foreground\/70{color:color-mix(in oklab, var(--color-foreground,oklch(15% 0 0)) 70%, transparent)}}.text-foreground\/80{color:#0b0b0bcc}@supports (color:color-mix(in lab, red, red)){.text-foreground\/80{color:color-mix(in oklab, var(--color-foreground,oklch(15% 0 0)) 80%, transparent)}}.text-foreground\/90{color:#0b0b0be6}@supports (color:color-mix(in lab, red, red)){.text-foreground\/90{color:color-mix(in oklab, var(--color-foreground,oklch(15% 0 0)) 90%, transparent)}}.text-muted-foreground{color:var(--color-muted-foreground,oklch(50% 0 0))}.text-muted-foreground\/30{color:#6363634d}@supports (color:color-mix(in lab, red, red)){.text-muted-foreground\/30{color:color-mix(in oklab, var(--color-muted-foreground,oklch(50% 0 0)) 30%, transparent)}}.text-muted-foreground\/40{color:#63636366}@supports (color:color-mix(in lab, red, red)){.text-muted-foreground\/40{color:color-mix(in oklab, var(--color-muted-foreground,oklch(50% 0 0)) 40%, transparent)}}.text-muted-foreground\/50{color:#63636380}@supports (color:color-mix(in lab, red, red)){.text-muted-foreground\/50{color:color-mix(in oklab, var(--color-muted-foreground,oklch(50% 0 0)) 50%, transparent)}}.text-muted-foreground\/60{color:#63636399}@supports (color:color-mix(in lab, red, red)){.text-muted-foreground\/60{color:color-mix(in oklab, var(--color-muted-foreground,oklch(50% 0 0)) 60%, transparent)}}.text-muted-foreground\/70{color:#636363b3}@supports (color:color-mix(in lab, red, red)){.text-muted-foreground\/70{color:color-mix(in oklab, var(--color-muted-foreground,oklch(50% 0 0)) 70%, transparent)}}.text-primary{color:var(--color-primary,oklch(50% .1 35))}.text-primary-foreground{color:var(--color-primary-foreground,oklch(99% 0 0))}.capitalize{text-transform:capitalize}.uppercase{text-transform:uppercase}.italic{font-style:italic}.tabular-nums{--tw-numeric-spacing:tabular-nums;font-variant-numeric:var(--tw-ordinal,) var(--tw-slashed-zero,) var(--tw-numeric-figure,) var(--tw-numeric-spacing,) var(--tw-numeric-fraction,)}.line-through{text-decoration-line:line-through}.no-underline{text-decoration-line:none}.underline{text-decoration-line:underline}.accent-foreground{accent-color:var(--color-foreground,oklch(15% 0 0))}.accent-primary{accent-color:var(--color-primary,oklch(50% .1 35))}.opacity-0{opacity:0}.opacity-50{opacity:.5}.opacity-60{opacity:.6}.opacity-70{opacity:.7}.opacity-75{opacity:.75}.opacity-85{opacity:.85}.opacity-100{opacity:1}.shadow-\[0_0_0_1px_var\(--color-border\)\]{--tw-shadow:0 0 0 1px var(--tw-shadow-color,var(--color-border));box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-\[0_0_0_2px_var\(--color-card\)\]{--tw-shadow:0 0 0 2px var(--tw-shadow-color,var(--color-card));box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-\[0_0_0_6px_color-mix\(in_oklch\,var\(--color-primary\)_18\%\,transparent\)\]{--tw-shadow:0 0 0 6px var(--tw-shadow-color,#934c3a2e)}@supports (color:color-mix(in lab, red, red)){.shadow-\[0_0_0_6px_color-mix\(in_oklch\,var\(--color-primary\)_18\%\,transparent\)\]{--tw-shadow:0 0 0 6px var(--tw-shadow-color,color-mix(in oklch,var(--color-primary) 18%,transparent))}}.shadow-\[0_0_0_6px_color-mix\(in_oklch\,var\(--color-primary\)_18\%\,transparent\)\]{box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-\[0_1px_0_rgba\(0\,0\,0\,0\.04\)\,0_8px_24px_rgba\(0\,0\,0\,0\.12\)\]{--tw-shadow:0 1px 0 var(--tw-shadow-color,#0000000a), 0 8px 24px var(--tw-shadow-color,#0000001f);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-\[0_1px_0_rgba\(0\,0\,0\,0\.04\)\,0_16px_48px_rgba\(0\,0\,0\,0\.08\)\]{--tw-shadow:0 1px 0 var(--tw-shadow-color,#0000000a), 0 16px 48px var(--tw-shadow-color,#00000014);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-\[0_1px_2px_rgba\(16\,24\,40\,0\.04\)\,0_16px_40px_-16px_rgba\(16\,24\,40\,0\.24\)\]{--tw-shadow:0 1px 2px var(--tw-shadow-color,#1018280a), 0 16px 40px -16px var(--tw-shadow-color,#1018283d);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-\[0_1px_2px_rgba\(16\,24\,40\,0\.06\)\]{--tw-shadow:0 1px 2px var(--tw-shadow-color,#1018280f);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-\[0_1px_3px_rgba\(0\,0\,0\,0\.04\)\,0_6px_24px_rgba\(0\,0\,0\,0\.06\)\]{--tw-shadow:0 1px 3px var(--tw-shadow-color,#0000000a), 0 6px 24px var(--tw-shadow-color,#0000000f);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-\[0_1px_4px_rgba\(0\,0\,0\,0\.10\)\,0_4px_12px_rgba\(0\,0\,0\,0\.08\)\]{--tw-shadow:0 1px 4px var(--tw-shadow-color,#0000001a), 0 4px 12px var(--tw-shadow-color,#00000014);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-\[0_10px_30px_-16px_rgba\(16\,24\,40\,0\.32\)\]{--tw-shadow:0 10px 30px -16px var(--tw-shadow-color,#10182852);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.ring,.ring-1{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.ring-2{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.ring-4{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(4px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.ring-background{--tw-ring-color:var(--color-background,oklch(99% 0 0))}.ring-foreground{--tw-ring-color:var(--color-foreground,oklch(15% 0 0))}.ring-primary\/15{--tw-ring-color:#934c3a26}@supports (color:color-mix(in lab, red, red)){.ring-primary\/15{--tw-ring-color:color-mix(in oklab, var(--color-primary,oklch(50% .1 35)) 15%, transparent)}}.ring-primary\/40{--tw-ring-color:#934c3a66}@supports (color:color-mix(in lab, red, red)){.ring-primary\/40{--tw-ring-color:color-mix(in oklab, var(--color-primary,oklch(50% .1 35)) 40%, transparent)}}.ring-offset-2{--tw-ring-offset-width:2px;--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color)}.ring-offset-background{--tw-ring-offset-color:var(--color-background,oklch(99% 0 0))}.outline{outline-style:var(--tw-outline-style);outline-width:1px}.filter{filter:var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,)}.backdrop-blur-\[1px\]{--tw-backdrop-blur:blur(1px);-webkit-backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,)}.transition{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,ease);transition-duration:var(--tw-duration,0s)}.transition-\[width\]{transition-property:width;transition-timing-function:var(--tw-ease,ease);transition-duration:var(--tw-duration,0s)}.transition-all{transition-property:all;transition-timing-function:var(--tw-ease,ease);transition-duration:var(--tw-duration,0s)}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,ease);transition-duration:var(--tw-duration,0s)}.transition-opacity{transition-property:opacity;transition-timing-function:var(--tw-ease,ease);transition-duration:var(--tw-duration,0s)}.transition-shadow{transition-property:box-shadow;transition-timing-function:var(--tw-ease,ease);transition-duration:var(--tw-duration,0s)}.transition-transform{transition-property:transform,translate,scale,rotate;transition-timing-function:var(--tw-ease,ease);transition-duration:var(--tw-duration,0s)}.duration-200{--tw-duration:.2s;transition-duration:.2s}.duration-300{--tw-duration:.3s;transition-duration:.3s}.duration-500{--tw-duration:.5s;transition-duration:.5s}.duration-700{--tw-duration:.7s;transition-duration:.7s}.ease-\[cubic-bezier\(0\.19\,1\,0\.22\,1\)\]{--tw-ease:cubic-bezier(.19,1,.22,1);transition-timing-function:cubic-bezier(.19,1,.22,1)}.\[transition-timing-function\:cubic-bezier\(0\.16\,1\,0\.3\,1\)\]{transition-timing-function:cubic-bezier(.16,1,.3,1)}.outline-none{--tw-outline-style:none;outline-style:none}.select-none{-webkit-user-select:none;user-select:none}.\[cimplify\:checkout\]{cimplify:checkout}.ring-inset{--tw-ring-inset:inset}@media (hover:hover){.group-hover\:scale-105:is(:where(.group):hover *){--tw-scale-x:105%;--tw-scale-y:105%;--tw-scale-z:105%;scale:var(--tw-scale-x) var(--tw-scale-y)}.group-hover\:scale-\[1\.04\]:is(:where(.group):hover *){scale:1.04}.group-hover\:text-foreground:is(:where(.group):hover *){color:var(--color-foreground,oklch(15% 0 0))}.group-hover\:text-primary:is(:where(.group):hover *){color:var(--color-primary,oklch(50% .1 35))}.group-hover\:opacity-100:is(:where(.group):hover *){opacity:1}}.placeholder\:text-muted-foreground::placeholder{color:var(--color-muted-foreground,oklch(50% 0 0))}.last\:border-b-0:last-child{border-bottom-style:var(--tw-border-style);border-bottom-width:0}.focus-within\:border-foreground:focus-within{border-color:var(--color-foreground,oklch(15% 0 0))}.focus-within\:bg-background:focus-within{background-color:var(--color-background,oklch(99% 0 0))}@media (hover:hover){.hover\:-translate-y-\[1px\]:hover{--tw-translate-y:calc(1px * -1);translate:var(--tw-translate-x) var(--tw-translate-y)}.hover\:-translate-y-px:hover{--tw-translate-y:-1px;translate:var(--tw-translate-x) var(--tw-translate-y)}.hover\:\!scale-110:hover{--tw-scale-x:110%!important;--tw-scale-y:110%!important;--tw-scale-z:110%!important;scale:var(--tw-scale-x) var(--tw-scale-y)!important}.hover\:scale-105:hover{--tw-scale-x:105%;--tw-scale-y:105%;--tw-scale-z:105%;scale:var(--tw-scale-x) var(--tw-scale-y)}.hover\:scale-110:hover{--tw-scale-x:110%;--tw-scale-y:110%;--tw-scale-z:110%;scale:var(--tw-scale-x) var(--tw-scale-y)}.hover\:scale-\[1\.04\]:hover{scale:1.04}.hover\:scale-\[1\.08\]:hover{scale:1.08}.hover\:border-destructive:hover{border-color:var(--color-destructive,oklch(50% .2 25))}.hover\:border-foreground:hover{border-color:var(--color-foreground,oklch(15% 0 0))}.hover\:border-foreground\/30:hover{border-color:#0b0b0b4d}@supports (color:color-mix(in lab, red, red)){.hover\:border-foreground\/30:hover{border-color:color-mix(in oklab, var(--color-foreground,oklch(15% 0 0)) 30%, transparent)}}.hover\:border-foreground\/40:hover{border-color:#0b0b0b66}@supports (color:color-mix(in lab, red, red)){.hover\:border-foreground\/40:hover{border-color:color-mix(in oklab, var(--color-foreground,oklch(15% 0 0)) 40%, transparent)}}.hover\:border-primary:hover{border-color:var(--color-primary,oklch(50% .1 35))}.hover\:border-primary\/20:hover{border-color:#934c3a33}@supports (color:color-mix(in lab, red, red)){.hover\:border-primary\/20:hover{border-color:color-mix(in oklab, var(--color-primary,oklch(50% .1 35)) 20%, transparent)}}.hover\:border-primary\/40:hover{border-color:#934c3a66}@supports (color:color-mix(in lab, red, red)){.hover\:border-primary\/40:hover{border-color:color-mix(in oklab, var(--color-primary,oklch(50% .1 35)) 40%, transparent)}}.hover\:border-primary\/50:hover{border-color:#934c3a80}@supports (color:color-mix(in lab, red, red)){.hover\:border-primary\/50:hover{border-color:color-mix(in oklab, var(--color-primary,oklch(50% .1 35)) 50%, transparent)}}.hover\:\!bg-foreground:hover{background-color:var(--color-foreground,oklch(15% 0 0))!important}.hover\:bg-background:hover{background-color:var(--color-background,oklch(99% 0 0))}.hover\:bg-destructive\/10:hover{background-color:#bb061e1a}@supports (color:color-mix(in lab, red, red)){.hover\:bg-destructive\/10:hover{background-color:color-mix(in oklab, var(--color-destructive,oklch(50% .2 25)) 10%, transparent)}}.hover\:bg-foreground\/90:hover{background-color:#0b0b0be6}@supports (color:color-mix(in lab, red, red)){.hover\:bg-foreground\/90:hover{background-color:color-mix(in oklab, var(--color-foreground,oklch(15% 0 0)) 90%, transparent)}}.hover\:bg-muted:hover{background-color:var(--color-muted,oklch(95% 0 0))}.hover\:bg-muted\/40:hover{background-color:#eee6}@supports (color:color-mix(in lab, red, red)){.hover\:bg-muted\/40:hover{background-color:color-mix(in oklab, var(--color-muted,oklch(95% 0 0)) 40%, transparent)}}.hover\:bg-muted\/50:hover{background-color:#eeeeee80}@supports (color:color-mix(in lab, red, red)){.hover\:bg-muted\/50:hover{background-color:color-mix(in oklab, var(--color-muted,oklch(95% 0 0)) 50%, transparent)}}.hover\:bg-muted\/70:hover{background-color:#eeeeeeb3}@supports (color:color-mix(in lab, red, red)){.hover\:bg-muted\/70:hover{background-color:color-mix(in oklab, var(--color-muted,oklch(95% 0 0)) 70%, transparent)}}.hover\:bg-muted\/80:hover{background-color:#eeec}@supports (color:color-mix(in lab, red, red)){.hover\:bg-muted\/80:hover{background-color:color-mix(in oklab, var(--color-muted,oklch(95% 0 0)) 80%, transparent)}}.hover\:bg-primary\/90:hover{background-color:#934c3ae6}@supports (color:color-mix(in lab, red, red)){.hover\:bg-primary\/90:hover{background-color:color-mix(in oklab, var(--color-primary,oklch(50% .1 35)) 90%, transparent)}}.hover\:\!text-background:hover{color:var(--color-background,oklch(99% 0 0))!important}.hover\:text-background:hover{color:var(--color-background,oklch(99% 0 0))}.hover\:text-destructive:hover{color:var(--color-destructive,oklch(50% .2 25))}.hover\:text-foreground:hover{color:var(--color-foreground,oklch(15% 0 0))}.hover\:text-primary:hover{color:var(--color-primary,oklch(50% .1 35))}.hover\:text-primary\/80:hover{color:#934c3acc}@supports (color:color-mix(in lab, red, red)){.hover\:text-primary\/80:hover{color:color-mix(in oklab, var(--color-primary,oklch(50% .1 35)) 80%, transparent)}}.hover\:underline:hover{text-decoration-line:underline}.hover\:shadow-\[0_2px_6px_rgba\(0\,0\,0\,0\.04\)\,0_12px_40px_rgba\(0\,0\,0\,0\.10\)\]:hover{--tw-shadow:0 2px 6px var(--tw-shadow-color,#0000000a), 0 12px 40px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.hover\:brightness-105:hover{--tw-brightness:brightness(105%);filter:var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,)}}.focus\:border-primary:focus{border-color:var(--color-primary,oklch(50% .1 35))}.focus\:border-primary\/30:focus{border-color:#934c3a4d}@supports (color:color-mix(in lab, red, red)){.focus\:border-primary\/30:focus{border-color:color-mix(in oklab, var(--color-primary,oklch(50% .1 35)) 30%, transparent)}}.focus\:bg-foreground:focus{background-color:var(--color-foreground,oklch(15% 0 0))}.focus\:ring-1:focus{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.focus\:ring-2:focus{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.focus\:ring-primary\/10:focus{--tw-ring-color:#934c3a1a}@supports (color:color-mix(in lab, red, red)){.focus\:ring-primary\/10:focus{--tw-ring-color:color-mix(in oklab, var(--color-primary,oklch(50% .1 35)) 10%, transparent)}}.focus\:ring-primary\/20:focus{--tw-ring-color:#934c3a33}@supports (color:color-mix(in lab, red, red)){.focus\:ring-primary\/20:focus{--tw-ring-color:color-mix(in oklab, var(--color-primary,oklch(50% .1 35)) 20%, transparent)}}.focus\:ring-ring:focus{--tw-ring-color:var(--color-ring,oklch(50% .1 35))}.focus\:outline-none:focus{--tw-outline-style:none;outline-style:none}.focus-visible\:ring-2:focus-visible{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.focus-visible\:ring-primary\/40:focus-visible{--tw-ring-color:#934c3a66}@supports (color:color-mix(in lab, red, red)){.focus-visible\:ring-primary\/40:focus-visible{--tw-ring-color:color-mix(in oklab, var(--color-primary,oklch(50% .1 35)) 40%, transparent)}}.focus-visible\:ring-ring:focus-visible{--tw-ring-color:var(--color-ring,oklch(50% .1 35))}.focus-visible\:outline-none:focus-visible{--tw-outline-style:none;outline-style:none}.active\:scale-95:active{--tw-scale-x:95%;--tw-scale-y:95%;--tw-scale-z:95%;scale:var(--tw-scale-x) var(--tw-scale-y)}.active\:scale-\[0\.99\]:active{scale:.99}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:opacity-30:disabled{opacity:.3}.disabled\:opacity-40:disabled{opacity:.4}.disabled\:opacity-50:disabled{opacity:.5}.aria-selected\:bg-foreground[aria-selected=true]{background-color:var(--color-foreground,oklch(15% 0 0))}.aria-selected\:text-background[aria-selected=true]{color:var(--color-background,oklch(99% 0 0))}@media (hover:hover){.aria-selected\:hover\:bg-foreground\/90[aria-selected=true]:hover{background-color:#0b0b0be6}@supports (color:color-mix(in lab, red, red)){.aria-selected\:hover\:bg-foreground\/90[aria-selected=true]:hover{background-color:color-mix(in oklab, var(--color-foreground,oklch(15% 0 0)) 90%, transparent)}}}.data-\[checked\]\:border-primary[data-checked]{border-color:var(--color-primary,oklch(50% .1 35))}.data-\[checked\]\:bg-primary\/5[data-checked]{background-color:#934c3a0d}@supports (color:color-mix(in lab, red, red)){.data-\[checked\]\:bg-primary\/5[data-checked]{background-color:color-mix(in oklab, var(--color-primary,oklch(50% .1 35)) 5%, transparent)}}.data-\[fully-booked\]\:cursor-not-allowed[data-fully-booked]{cursor:not-allowed}.data-\[fully-booked\]\:opacity-40[data-fully-booked]{opacity:.4}.data-\[selected\]\:border-foreground[data-selected]{border-color:var(--color-foreground,oklch(15% 0 0))}.data-\[selected\]\:bg-foreground[data-selected]{background-color:var(--color-foreground,oklch(15% 0 0))}.data-\[selected\]\:text-background[data-selected]{color:var(--color-background,oklch(99% 0 0))}.data-\[unavailable\]\:cursor-not-allowed[data-unavailable]{cursor:not-allowed}.data-\[unavailable\]\:line-through[data-unavailable]{text-decoration-line:line-through}.data-\[unavailable\]\:opacity-40[data-unavailable]{opacity:.4}.\[\&_a\]\:text-primary a{color:var(--color-primary,oklch(50% .1 35))}.\[\&_a\]\:underline a{text-decoration-line:underline}.\[\&_a\]\:underline-offset-2 a{text-underline-offset:2px}.\[\&_b\]\:text-foreground b{color:var(--color-foreground,oklch(15% 0 0))}.\[\&_blockquote\]\:border-l-2 blockquote{border-left-style:var(--tw-border-style);border-left-width:2px}.\[\&_blockquote\]\:border-border blockquote{border-color:var(--color-border,oklch(90% 0 0))}.\[\&_blockquote\]\:italic blockquote{font-style:italic}.\[\&_caption\]\:caption-bottom caption{caption-side:bottom}.\[\&_caption\]\:text-muted-foreground caption{color:var(--color-muted-foreground,oklch(50% 0 0))}.\[\&_code\]\:rounded code{border-radius:var(--radius,.5rem)}.\[\&_code\]\:bg-muted code{background-color:var(--color-muted,oklch(95% 0 0))}.\[\&_code\]\:text-\[0\.85em\] code{font-size:.85em}.\[\&_del\]\:line-through del{text-decoration-line:line-through}.\[\&_details\]\:border details{border-style:var(--tw-border-style);border-width:1px}.\[\&_details\]\:border-border details{border-color:var(--color-border,oklch(90% 0 0))}.\[\&_dt\]\:text-foreground dt{color:var(--color-foreground,oklch(15% 0 0))}.\[\&_em\]\:italic em{font-style:italic}.\[\&_figcaption\]\:text-center figcaption{text-align:center}.\[\&_figcaption\]\:text-muted-foreground figcaption{color:var(--color-muted-foreground,oklch(50% 0 0))}.\[\&_h1\]\:text-foreground h1,.\[\&_h2\]\:text-foreground h2,.\[\&_h3\]\:text-foreground h3,.\[\&_h4\]\:text-foreground h4,.\[\&_h5\]\:text-foreground h5,.\[\&_h6\]\:text-foreground h6{color:var(--color-foreground,oklch(15% 0 0))}.\[\&_hr\]\:border-border hr{border-color:var(--color-border,oklch(90% 0 0))}.\[\&_i\]\:italic i{font-style:italic}.\[\&_iframe\]\:w-full iframe{width:100%}.\[\&_img\]\:h-auto img{height:auto}.\[\&_img\]\:max-w-full img{max-width:100%}.\[\&_ins\]\:underline ins{text-decoration-line:underline}.\[\&_mark\]\:rounded mark{border-radius:var(--radius,.5rem)}.\[\&_ol\]\:list-decimal ol{list-style-type:decimal}.\[\&_pre\]\:overflow-x-auto pre{overflow-x:auto}.\[\&_pre\]\:bg-muted pre{background-color:var(--color-muted,oklch(95% 0 0))}.\[\&_pre\]\:text-\[0\.85em\] pre{font-size:.85em}.\[\&_pre\>code\]\:bg-transparent pre>code{background-color:#0000}.\[\&_s\]\:line-through s{text-decoration-line:line-through}.\[\&_strong\]\:text-foreground strong{color:var(--color-foreground,oklch(15% 0 0))}.\[\&_sub\]\:align-sub sub{vertical-align:sub}.\[\&_sub\]\:text-\[0\.75em\] sub{font-size:.75em}.\[\&_summary\]\:cursor-pointer summary{cursor:pointer}.\[\&_summary\]\:text-foreground summary{color:var(--color-foreground,oklch(15% 0 0))}.\[\&_sup\]\:align-super sup{vertical-align:super}.\[\&_sup\]\:text-\[0\.75em\] sup{font-size:.75em}.\[\&_table\]\:w-full table{width:100%}.\[\&_table\]\:border-collapse table{border-collapse:collapse}.\[\&_td\]\:border td{border-style:var(--tw-border-style);border-width:1px}.\[\&_td\]\:border-border td{border-color:var(--color-border,oklch(90% 0 0))}.\[\&_td\]\:align-top td{vertical-align:top}.\[\&_th\]\:border th{border-style:var(--tw-border-style);border-width:1px}.\[\&_th\]\:border-border th{border-color:var(--color-border,oklch(90% 0 0))}.\[\&_th\]\:bg-muted th{background-color:var(--color-muted,oklch(95% 0 0))}.\[\&_th\]\:text-left th{text-align:left}.\[\&_th\]\:text-foreground th{color:var(--color-foreground,oklch(15% 0 0))}.\[\&_u\]\:underline u{text-decoration-line:underline}.\[\&_ul\]\:list-disc ul{list-style-type:disc}.\[\&_ul_ul\]\:list-\[circle\] ul ul{list-style-type:circle}.\[\&\:\:-webkit-details-marker\]\:hidden::-webkit-details-marker{display:none}.\[\&\:\:-webkit-inner-spin-button\]\:appearance-none::-webkit-inner-spin-button{appearance:none}.\[\&\:\:-webkit-outer-spin-button\]\:appearance-none::-webkit-outer-spin-button{appearance:none}.\[\&\:not\(\:first-child\)\]\:border-t:not(:first-child){border-top-style:var(--tw-border-style);border-top-width:1px}.\[\&\:not\(\:first-child\)\]\:border-border\/50:not(:first-child){border-color:#dedede80}@supports (color:color-mix(in lab, red, red)){.\[\&\:not\(\:first-child\)\]\:border-border\/50:not(:first-child){border-color:color-mix(in oklab, var(--color-border,oklch(90% 0 0)) 50%, transparent)}}[open]>.\[\[open\]\>\&\]\:rotate-180{rotate:180deg}.cimplify-cols-2,.cimplify-cols-3,.cimplify-cols-4,.cimplify-media{gap:1.5rem;display:grid}.cimplify-media{align-items:center}.cimplify-media--reverse>:first-child{order:2}@media (min-width:640px){.cimplify-cols-2,.cimplify-cols-3,.cimplify-cols-4,.cimplify-media{grid-template-columns:repeat(2,minmax(0,1fr))}}@media (min-width:1024px){.cimplify-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.cimplify-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}}.cimplify-cols-2>*>:first-child,.cimplify-cols-3>*>:first-child,.cimplify-cols-4>*>:first-child,.cimplify-media>*>:first-child,.cimplify-media>img,.cimplify-cols-2>img,.cimplify-cols-3>img,.cimplify-cols-4>img{margin-top:0}.cimplify-card{border:1px solid var(--color-border);border-radius:var(--radius);padding:1rem}.cimplify-banner{border-radius:var(--radius);position:relative;overflow:hidden}.cimplify-banner>img{width:100%;height:auto;margin:0;display:block}.cimplify-banner__content{flex-direction:column;justify-content:center;gap:.5rem;padding:1.5rem 2rem;display:flex;position:absolute;inset:0}@property --tw-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-z{syntax:"*";inherits:false;initial-value:0}@property --tw-rotate-x{syntax:"*";inherits:false}@property --tw-rotate-y{syntax:"*";inherits:false}@property --tw-rotate-z{syntax:"*";inherits:false}@property --tw-skew-x{syntax:"*";inherits:false}@property --tw-skew-y{syntax:"*";inherits:false}@property --tw-divide-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-gradient-position{syntax:"*";inherits:false}@property --tw-gradient-from{syntax:"<color>";inherits:false;initial-value:#0000}@property --tw-gradient-via{syntax:"<color>";inherits:false;initial-value:#0000}@property --tw-gradient-to{syntax:"<color>";inherits:false;initial-value:#0000}@property --tw-gradient-stops{syntax:"*";inherits:false}@property --tw-gradient-via-stops{syntax:"*";inherits:false}@property --tw-gradient-from-position{syntax:"<length-percentage>";inherits:false;initial-value:0%}@property --tw-gradient-via-position{syntax:"<length-percentage>";inherits:false;initial-value:50%}@property --tw-gradient-to-position{syntax:"<length-percentage>";inherits:false;initial-value:100%}@property --tw-leading{syntax:"*";inherits:false}@property --tw-tracking{syntax:"*";inherits:false}@property --tw-ordinal{syntax:"*";inherits:false}@property --tw-slashed-zero{syntax:"*";inherits:false}@property --tw-numeric-figure{syntax:"*";inherits:false}@property --tw-numeric-spacing{syntax:"*";inherits:false}@property --tw-numeric-fraction{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"<length>";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-outline-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-drop-shadow{syntax:"*";inherits:false}@property --tw-drop-shadow-color{syntax:"*";inherits:false}@property --tw-drop-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:"*";inherits:false}@property --tw-backdrop-blur{syntax:"*";inherits:false}@property --tw-backdrop-brightness{syntax:"*";inherits:false}@property --tw-backdrop-contrast{syntax:"*";inherits:false}@property --tw-backdrop-grayscale{syntax:"*";inherits:false}@property --tw-backdrop-hue-rotate{syntax:"*";inherits:false}@property --tw-backdrop-invert{syntax:"*";inherits:false}@property --tw-backdrop-opacity{syntax:"*";inherits:false}@property --tw-backdrop-saturate{syntax:"*";inherits:false}@property --tw-backdrop-sepia{syntax:"*";inherits:false}@property --tw-duration{syntax:"*";inherits:false}@property --tw-ease{syntax:"*";inherits:false}@property --tw-scale-x{syntax:"*";inherits:false;initial-value:1}@property --tw-scale-y{syntax:"*";inherits:false;initial-value:1}@property --tw-scale-z{syntax:"*";inherits:false;initial-value:1}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cimplify/sdk",
3
- "version": "0.72.0",
3
+ "version": "0.73.0",
4
4
  "description": "Cimplify Commerce SDK for storefronts",
5
5
  "keywords": [
6
6
  "cimplify",
@@ -7,7 +7,7 @@
7
7
  "files": [
8
8
  {
9
9
  "path": "product-image-gallery.tsx",
10
- "content": "\"use client\";\n\nimport React, { useEffect, useMemo, useState } from \"react\";\nimport { RadioGroup } from \"@base-ui/react/radio-group\";\nimport { Radio } from \"@base-ui/react/radio\";\n\nexport interface ProductImageGalleryProps {\n images: string[];\n productName: string;\n aspectRatio?: \"square\" | \"4/3\" | \"16/10\" | \"3/4\";\n className?: string;\n}\n\nconst ASPECT_STYLES: Record<string, React.CSSProperties> = {\n square: { aspectRatio: \"1/1\" },\n \"4/3\": { aspectRatio: \"4/3\" },\n \"16/10\": { aspectRatio: \"16/10\" },\n \"3/4\": { aspectRatio: \"3/4\" },\n};\n\n/**\n * ProductImageGallery — main image + thumbnail strip.\n *\n * Uses plain `<img>` for framework-agnostic rendering (not Next.js Image).\n */\nexport function ProductImageGallery({\n images,\n productName,\n aspectRatio = \"4/3\",\n className,\n}: ProductImageGalleryProps): React.ReactElement | null {\n const normalizedImages = useMemo(\n () =>\n images.filter(\n (image): image is string =>\n typeof image === \"string\" && image.trim().length > 0,\n ),\n [images],\n );\n\n const [selectedImage, setSelectedImage] = useState(0);\n\n useEffect(() => {\n setSelectedImage(0);\n }, [normalizedImages.length, productName]);\n\n if (normalizedImages.length === 0) {\n return null;\n }\n\n const activeImage = normalizedImages[selectedImage] || normalizedImages[0];\n\n return (\n <div data-cimplify-image-gallery className={className}>\n <div\n data-cimplify-image-gallery-main\n style={{ position: \"relative\", overflow: \"hidden\", ...ASPECT_STYLES[aspectRatio] }}\n >\n <img\n src={activeImage}\n alt={productName}\n style={{ width: \"100%\", height: \"100%\", objectFit: \"cover\" }}\n data-cimplify-image-gallery-active\n />\n </div>\n\n {normalizedImages.length > 1 && (\n <RadioGroup\n aria-label={`${productName} image thumbnails`}\n value={String(selectedImage)}\n onValueChange={(value) => setSelectedImage(Number(value))}\n data-cimplify-image-gallery-thumbnails\n style={{ display: \"flex\", gap: \"0.5rem\", marginTop: \"0.75rem\" }}\n >\n {normalizedImages.map((image, index) => {\n const isSelected = selectedImage === index;\n return (\n <Radio.Root\n key={`${image}-${index}`}\n value={String(index)}\n data-cimplify-image-gallery-thumb\n data-selected={isSelected || undefined}\n style={{\n width: \"4rem\",\n height: \"4rem\",\n overflow: \"hidden\",\n padding: 0,\n border: \"none\",\n cursor: \"pointer\",\n }}\n >\n <img\n src={image}\n alt=\"\"\n style={{ width: \"100%\", height: \"100%\", objectFit: \"cover\" }}\n />\n </Radio.Root>\n );\n })}\n </RadioGroup>\n )}\n </div>\n );\n}\n"
10
+ "content": "\"use client\";\n\nimport React, { useEffect, useMemo, useState } from \"react\";\nimport { RadioGroup } from \"@base-ui/react/radio-group\";\nimport { Radio } from \"@base-ui/react/radio\";\n\nexport interface ProductImageGalleryProps {\n images: string[];\n productName: string;\n aspectRatio?: \"square\" | \"4/3\" | \"16/10\" | \"3/4\";\n className?: string;\n}\n\nconst ASPECT_STYLES: Record<string, React.CSSProperties> = {\n square: { aspectRatio: \"1/1\" },\n \"4/3\": { aspectRatio: \"4/3\" },\n \"16/10\": { aspectRatio: \"16/10\" },\n \"3/4\": { aspectRatio: \"3/4\" },\n};\n\n/**\n * ProductImageGallery — main image + thumbnail strip.\n *\n * Uses plain `<img>` for framework-agnostic rendering (not Next.js Image).\n */\nexport function ProductImageGallery({\n images,\n productName,\n aspectRatio = \"4/3\",\n className,\n}: ProductImageGalleryProps): React.ReactElement | null {\n const normalizedImages = useMemo(\n () =>\n images.filter(\n (image): image is string =>\n typeof image === \"string\" && image.trim().length > 0,\n ),\n [images],\n );\n\n const [selectedImage, setSelectedImage] = useState(0);\n const [fadeIn, setFadeIn] = useState(true);\n\n useEffect(() => {\n setSelectedImage(0);\n }, [normalizedImages.length, productName]);\n\n // Cross-fade the main image whenever the selection changes (thumbnail click\n // or a variant swapping in its own gallery).\n useEffect(() => {\n setFadeIn(false);\n const id = requestAnimationFrame(() => setFadeIn(true));\n return () => cancelAnimationFrame(id);\n }, [selectedImage]);\n\n if (normalizedImages.length === 0) {\n return null;\n }\n\n const activeImage = normalizedImages[selectedImage] || normalizedImages[0];\n\n return (\n <div data-cimplify-image-gallery className={className}>\n <div\n data-cimplify-image-gallery-main\n style={{ position: \"relative\", overflow: \"hidden\", ...ASPECT_STYLES[aspectRatio] }}\n >\n <img\n src={activeImage}\n alt={productName}\n style={{\n width: \"100%\",\n height: \"100%\",\n objectFit: \"cover\",\n opacity: fadeIn ? 1 : 0,\n transition: \"opacity 300ms ease\",\n }}\n data-cimplify-image-gallery-active\n />\n </div>\n\n {normalizedImages.length > 1 && (\n <RadioGroup\n aria-label={`${productName} image thumbnails`}\n value={String(selectedImage)}\n onValueChange={(value) => setSelectedImage(Number(value))}\n data-cimplify-image-gallery-thumbnails\n style={{ display: \"flex\", gap: \"0.5rem\", marginTop: \"0.75rem\" }}\n >\n {normalizedImages.map((image, index) => {\n const isSelected = selectedImage === index;\n return (\n <Radio.Root\n key={`${image}-${index}`}\n value={String(index)}\n data-cimplify-image-gallery-thumb\n data-selected={isSelected || undefined}\n style={{\n width: \"4rem\",\n height: \"4rem\",\n overflow: \"hidden\",\n padding: 0,\n border: \"none\",\n cursor: \"pointer\",\n }}\n >\n <img\n src={image}\n alt=\"\"\n style={{ width: \"100%\", height: \"100%\", objectFit: \"cover\" }}\n />\n </Radio.Root>\n );\n })}\n </RadioGroup>\n )}\n </div>\n );\n}\n"
11
11
  }
12
12
  ]
13
13
  }
@@ -10,7 +10,7 @@
10
10
  "files": [
11
11
  {
12
12
  "path": "slot-picker.tsx",
13
- "content": "\"use client\";\n\nimport { Radio } from \"@base-ui/react/radio\";\nimport { RadioGroup } from \"@base-ui/react/radio-group\";\nimport React, { useMemo } from \"react\";\nimport type { AvailableSlot } from \"@cimplify/sdk\";\nimport type { DurationUnit, SchedulingMode } from \"@cimplify/sdk\";\nimport type { CurrencyCode } from \"@cimplify/sdk\";\nimport { useAvailableSlots } from \"@cimplify/sdk/react\";\nimport { Price } from \"@cimplify/sdk/react\";\nimport { cn } from \"@cimplify/sdk/react\";\n\nexport interface SlotPickerClassNames {\n root?: string;\n group?: string;\n groupLabel?: string;\n slot?: string;\n slotTime?: string;\n slotPrice?: string;\n loading?: string;\n empty?: string;\n}\n\nexport interface SlotPickerProps {\n /** Pre-fetched slots (skips fetch). */\n slots?: AvailableSlot[];\n /** Service ID — used to fetch slots when `slots` prop is not provided. */\n serviceId?: string;\n /** Date string (YYYY-MM-DD) — used to fetch slots when `slots` prop is not provided. */\n date?: string;\n /** Number of participants for capacity-based availability. */\n participantCount?: number;\n /** Currently selected slot. */\n selectedSlot?: AvailableSlot | null;\n /** Called when a slot is selected. */\n onSlotSelect?: (slot: AvailableSlot) => void;\n /** Whether to group slots by time of day. Default: true. Ignored when `schedulingMode` is `\"multi_day\"`. */\n groupByTimeOfDay?: boolean;\n /** Show price on each slot. Default: true. */\n showPrice?: boolean;\n /** Currency the slot prices are denominated in. */\n currency?: CurrencyCode;\n /**\n * Hide slots whose `start_time` is already in the past. Default: true.\n * Set to false to show elapsed slots greyed-out (still un-selectable).\n */\n hideElapsedSlots?: boolean;\n /**\n * Minimum lead time (in minutes) before a slot can be booked. Slots whose\n * start is sooner than `now + minLeadMinutes` are filtered out (when\n * `hideElapsedSlots` is true) or marked unavailable. Default: 0.\n */\n minLeadMinutes?: number;\n /**\n * Service scheduling mode. When `\"multi_day\"`, each slot renders as a\n * stay summary (`\"3 nights: Fri Apr 5, 3:00 PM → Mon Apr 8, 11:00 AM\"`)\n * instead of the time-of-day label. Defaults to `\"intraday\"`.\n */\n schedulingMode?: SchedulingMode;\n /** Service duration unit — used for the stay summary in multi-day mode. */\n durationUnit?: DurationUnit;\n /** Service duration value — used for the stay summary in multi-day mode. */\n durationValue?: number;\n /** Text shown when no slots available. */\n emptyMessage?: string;\n className?: string;\n classNames?: SlotPickerClassNames;\n}\n\ninterface SlotGroup {\n label: string;\n slots: AvailableSlot[];\n}\n\nfunction getTimeOfDay(timeStr: string): \"morning\" | \"afternoon\" | \"evening\" {\n const hour = parseInt(timeStr.split(\"T\").pop()?.split(\":\")[0] ?? timeStr.split(\":\")[0], 10);\n if (hour < 12) return \"morning\";\n if (hour < 17) return \"afternoon\";\n return \"evening\";\n}\n\nconst TIME_OF_DAY_LABELS: Record<string, string> = {\n morning: \"Morning\",\n afternoon: \"Afternoon\",\n evening: \"Evening\",\n};\n\nfunction groupSlots(slots: AvailableSlot[]): SlotGroup[] {\n const groups: Record<string, AvailableSlot[]> = {};\n for (const slot of slots) {\n const tod = getTimeOfDay(slot.start_time);\n if (!groups[tod]) groups[tod] = [];\n groups[tod].push(slot);\n }\n return ([\"morning\", \"afternoon\", \"evening\"] as const)\n .filter((tod) => groups[tod]?.length)\n .map((tod) => ({ label: TIME_OF_DAY_LABELS[tod], slots: groups[tod] }));\n}\n\nfunction formatTime(timeStr: string): string {\n try {\n const date = new Date(timeStr);\n if (!isNaN(date.getTime())) {\n return date.toLocaleTimeString(undefined, { hour: \"numeric\", minute: \"2-digit\" });\n }\n } catch {\n // noop\n }\n\n const parts = timeStr.split(\":\");\n if (parts.length >= 2) {\n const hour = parseInt(parts[0], 10);\n const minute = parts[1];\n const ampm = hour >= 12 ? \"PM\" : \"AM\";\n const displayHour = hour % 12 || 12;\n return `${displayHour}:${minute} ${ampm}`;\n }\n return timeStr;\n}\n\nfunction pluralizeUnit(unit: DurationUnit | undefined, value: number | undefined): string {\n if (!unit) return value === 1 ? \"day\" : \"days\";\n const v = value ?? 1;\n if (unit === \"minutes\") return v === 1 ? \"minute\" : \"minutes\";\n if (unit === \"hours\") return v === 1 ? \"hour\" : \"hours\";\n if (unit === \"days\") return v === 1 ? \"day\" : \"days\";\n if (unit === \"weeks\") return v === 1 ? \"week\" : \"weeks\";\n if (unit === \"months\") return v === 1 ? \"month\" : \"months\";\n return unit;\n}\n\nfunction formatStaySummary(\n slot: AvailableSlot,\n durationUnit: DurationUnit | undefined,\n durationValue: number | undefined,\n): string {\n const start = new Date(slot.start_time);\n const end = new Date(slot.end_time);\n const startLabel = start.toLocaleString(undefined, {\n weekday: \"short\",\n month: \"short\",\n day: \"numeric\",\n hour: \"numeric\",\n minute: \"2-digit\",\n });\n const endLabel = end.toLocaleString(undefined, {\n weekday: \"short\",\n month: \"short\",\n day: \"numeric\",\n hour: \"numeric\",\n minute: \"2-digit\",\n });\n const unitLabel = pluralizeUnit(durationUnit, durationValue);\n if (durationValue !== undefined) {\n return `${durationValue} ${unitLabel}: ${startLabel} → ${endLabel}`;\n }\n return `${startLabel} → ${endLabel}`;\n}\n\nfunction slotToValue(slot: AvailableSlot): string {\n return `${slot.start_time}|${slot.end_time}`;\n}\n\nexport function SlotPicker({\n slots: slotsProp,\n serviceId,\n date,\n participantCount,\n selectedSlot,\n onSlotSelect,\n groupByTimeOfDay = true,\n showPrice = true,\n currency,\n schedulingMode = \"intraday\",\n durationUnit,\n durationValue,\n hideElapsedSlots = true,\n minLeadMinutes = 0,\n emptyMessage = \"No available slots\",\n className,\n classNames,\n}: SlotPickerProps): React.ReactElement {\n const isMultiDay = schedulingMode === \"multi_day\";\n const { slots: fetched, isLoading } = useAvailableSlots(\n serviceId ?? null,\n date ?? null,\n {\n participantCount,\n enabled: slotsProp === undefined && !!serviceId && !!date,\n },\n );\n\n const rawSlots = slotsProp ?? fetched;\n // Drop slots that have already elapsed (or fall within the lead-time\n // window). Default behaviour because nothing the merchant can do at\n // the backend stops a client clock from being slightly ahead of the\n // last availability response — this is the same defence other\n // booking flows ship by default.\n const slots = useMemo(() => {\n if (!hideElapsedSlots) return rawSlots;\n const cutoff = Date.now() + minLeadMinutes * 60_000;\n return rawSlots.filter((slot) => {\n const start = Date.parse(slot.start_time);\n return Number.isNaN(start) || start >= cutoff;\n });\n }, [rawSlots, hideElapsedSlots, minLeadMinutes]);\n\n if (isLoading && slots.length === 0) {\n return (\n <div\n data-cimplify-slot-picker\n aria-busy=\"true\"\n className={cn(className, classNames?.root, classNames?.loading)}\n />\n );\n }\n\n if (slots.length === 0) {\n return (\n <div\n data-cimplify-slot-picker\n data-empty\n className={cn(className, classNames?.root, classNames?.empty)}\n >\n <p>{emptyMessage}</p>\n </div>\n );\n }\n\n const groups = groupByTimeOfDay && !isMultiDay\n ? groupSlots(slots)\n : [{ label: \"\", slots }];\n\n const slotsByValue = new Map<string, AvailableSlot>();\n for (const slot of slots) {\n slotsByValue.set(slotToValue(slot), slot);\n }\n\n const selectedValue = selectedSlot ? slotToValue(selectedSlot) : \"\";\n\n return (\n <RadioGroup\n data-cimplify-slot-picker\n className={cn(\"flex flex-col gap-4\", className, classNames?.root)}\n value={selectedValue}\n onValueChange={(value: string) => {\n const slot = slotsByValue.get(value);\n // Slots default to available; treat as unavailable only when the\n // backend explicitly returns `is_available: false`.\n if (slot && slot.is_available !== false) {\n onSlotSelect?.(slot);\n }\n }}\n >\n {groups.map((group) => (\n <div\n key={group.label || \"all\"}\n data-cimplify-slot-group\n className={cn(\"flex flex-col gap-2\", classNames?.group)}\n >\n {group.label && (\n <div\n data-cimplify-slot-group-label\n className={cn(\n \"text-xs font-medium uppercase tracking-[0.12em] text-muted-foreground\",\n classNames?.groupLabel,\n )}\n >\n {group.label}\n </div>\n )}\n <div\n className={cn(\n isMultiDay\n ? \"flex flex-col gap-2\"\n : \"grid grid-cols-3 sm:grid-cols-4 gap-2\",\n )}\n >\n {group.slots.map((slot) => {\n const value = slotToValue(slot);\n const isSelected =\n selectedSlot?.start_time === slot.start_time &&\n selectedSlot?.end_time === slot.end_time;\n return (\n <Radio.Root\n key={value}\n value={value}\n disabled={slot.is_available === false}\n data-cimplify-slot\n data-selected={isSelected || undefined}\n data-unavailable={slot.is_available === false || undefined}\n className={cn(\n \"inline-flex items-center justify-center gap-2 rounded-md border border-border bg-background px-3 py-2 text-sm font-medium text-foreground transition-colors hover:border-foreground/40 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring data-[selected]:border-foreground data-[selected]:bg-foreground data-[selected]:text-background data-[unavailable]:cursor-not-allowed data-[unavailable]:opacity-40 data-[unavailable]:line-through\",\n isMultiDay && \"justify-between text-left\",\n classNames?.slot,\n )}\n >\n <span data-cimplify-slot-time className={classNames?.slotTime}>\n {isMultiDay\n ? formatStaySummary(slot, durationUnit, durationValue)\n : formatTime(slot.start_time)}\n </span>\n {showPrice && slot.price && (\n <span\n data-cimplify-slot-price\n className={cn(\"text-xs opacity-70\", classNames?.slotPrice)}\n >\n <Price amount={slot.price} currency={currency} />\n </span>\n )}\n </Radio.Root>\n );\n })}\n </div>\n </div>\n ))}\n </RadioGroup>\n );\n}\n"
13
+ "content": "\"use client\";\n\nimport { Radio } from \"@base-ui/react/radio\";\nimport { RadioGroup } from \"@base-ui/react/radio-group\";\nimport React, { useMemo } from \"react\";\nimport type { AvailableSlot } from \"@cimplify/sdk\";\nimport type { DurationUnit, SchedulingMode } from \"@cimplify/sdk\";\nimport type { CurrencyCode } from \"@cimplify/sdk\";\nimport { useAvailableSlots } from \"@cimplify/sdk/react\";\nimport { Price } from \"@cimplify/sdk/react\";\nimport { cn } from \"@cimplify/sdk/react\";\n\nexport interface SlotPickerClassNames {\n root?: string;\n group?: string;\n groupLabel?: string;\n slot?: string;\n slotTime?: string;\n slotPrice?: string;\n slotScarcity?: string;\n loading?: string;\n empty?: string;\n}\n\nexport interface SlotPickerProps {\n /** Pre-fetched slots (skips fetch). */\n slots?: AvailableSlot[];\n /** Service ID — used to fetch slots when `slots` prop is not provided. */\n serviceId?: string;\n /** Date string (YYYY-MM-DD) — used to fetch slots when `slots` prop is not provided. */\n date?: string;\n /** Number of participants for capacity-based availability. */\n participantCount?: number;\n /** Currently selected slot. */\n selectedSlot?: AvailableSlot | null;\n /** Called when a slot is selected. */\n onSlotSelect?: (slot: AvailableSlot) => void;\n /** Whether to group slots by time of day. Default: true. Ignored when `schedulingMode` is `\"multi_day\"`. */\n groupByTimeOfDay?: boolean;\n /** Show price on each slot. Default: true. */\n showPrice?: boolean;\n /**\n * Show a \"N left\" urgency tag when a slot's remaining capacity is at or below\n * this number (and above zero). Slots at zero capacity render as sold out.\n * Default: 3. Set to 0 to disable scarcity tags.\n */\n lowCapacityThreshold?: number;\n /** Currency the slot prices are denominated in. */\n currency?: CurrencyCode;\n /**\n * Hide slots whose `start_time` is already in the past. Default: true.\n * Set to false to show elapsed slots greyed-out (still un-selectable).\n */\n hideElapsedSlots?: boolean;\n /**\n * Minimum lead time (in minutes) before a slot can be booked. Slots whose\n * start is sooner than `now + minLeadMinutes` are filtered out (when\n * `hideElapsedSlots` is true) or marked unavailable. Default: 0.\n */\n minLeadMinutes?: number;\n /**\n * Service scheduling mode. When `\"multi_day\"`, each slot renders as a\n * stay summary (`\"3 nights: Fri Apr 5, 3:00 PM → Mon Apr 8, 11:00 AM\"`)\n * instead of the time-of-day label. Defaults to `\"intraday\"`.\n */\n schedulingMode?: SchedulingMode;\n /** Service duration unit — used for the stay summary in multi-day mode. */\n durationUnit?: DurationUnit;\n /** Service duration value — used for the stay summary in multi-day mode. */\n durationValue?: number;\n /** Text shown when no slots available. */\n emptyMessage?: string;\n className?: string;\n classNames?: SlotPickerClassNames;\n}\n\ninterface SlotGroup {\n label: string;\n slots: AvailableSlot[];\n}\n\nfunction getTimeOfDay(timeStr: string): \"morning\" | \"afternoon\" | \"evening\" {\n const hour = parseInt(timeStr.split(\"T\").pop()?.split(\":\")[0] ?? timeStr.split(\":\")[0], 10);\n if (hour < 12) return \"morning\";\n if (hour < 17) return \"afternoon\";\n return \"evening\";\n}\n\nconst TIME_OF_DAY_LABELS: Record<string, string> = {\n morning: \"Morning\",\n afternoon: \"Afternoon\",\n evening: \"Evening\",\n};\n\nfunction groupSlots(slots: AvailableSlot[]): SlotGroup[] {\n const groups: Record<string, AvailableSlot[]> = {};\n for (const slot of slots) {\n const tod = getTimeOfDay(slot.start_time);\n if (!groups[tod]) groups[tod] = [];\n groups[tod].push(slot);\n }\n return ([\"morning\", \"afternoon\", \"evening\"] as const)\n .filter((tod) => groups[tod]?.length)\n .map((tod) => ({ label: TIME_OF_DAY_LABELS[tod], slots: groups[tod] }));\n}\n\nfunction formatTime(timeStr: string): string {\n try {\n const date = new Date(timeStr);\n if (!isNaN(date.getTime())) {\n return date.toLocaleTimeString(undefined, { hour: \"numeric\", minute: \"2-digit\" });\n }\n } catch {\n // noop\n }\n\n const parts = timeStr.split(\":\");\n if (parts.length >= 2) {\n const hour = parseInt(parts[0], 10);\n const minute = parts[1];\n const ampm = hour >= 12 ? \"PM\" : \"AM\";\n const displayHour = hour % 12 || 12;\n return `${displayHour}:${minute} ${ampm}`;\n }\n return timeStr;\n}\n\nfunction pluralizeUnit(unit: DurationUnit | undefined, value: number | undefined): string {\n if (!unit) return value === 1 ? \"day\" : \"days\";\n const v = value ?? 1;\n if (unit === \"minutes\") return v === 1 ? \"minute\" : \"minutes\";\n if (unit === \"hours\") return v === 1 ? \"hour\" : \"hours\";\n if (unit === \"days\") return v === 1 ? \"day\" : \"days\";\n if (unit === \"weeks\") return v === 1 ? \"week\" : \"weeks\";\n if (unit === \"months\") return v === 1 ? \"month\" : \"months\";\n return unit;\n}\n\nfunction formatStaySummary(\n slot: AvailableSlot,\n durationUnit: DurationUnit | undefined,\n durationValue: number | undefined,\n): string {\n const start = new Date(slot.start_time);\n const end = new Date(slot.end_time);\n const startLabel = start.toLocaleString(undefined, {\n weekday: \"short\",\n month: \"short\",\n day: \"numeric\",\n hour: \"numeric\",\n minute: \"2-digit\",\n });\n const endLabel = end.toLocaleString(undefined, {\n weekday: \"short\",\n month: \"short\",\n day: \"numeric\",\n hour: \"numeric\",\n minute: \"2-digit\",\n });\n const unitLabel = pluralizeUnit(durationUnit, durationValue);\n if (durationValue !== undefined) {\n return `${durationValue} ${unitLabel}: ${startLabel} → ${endLabel}`;\n }\n return `${startLabel} → ${endLabel}`;\n}\n\nfunction slotToValue(slot: AvailableSlot): string {\n return `${slot.start_time}|${slot.end_time}`;\n}\n\nexport function SlotPicker({\n slots: slotsProp,\n serviceId,\n date,\n participantCount,\n selectedSlot,\n onSlotSelect,\n groupByTimeOfDay = true,\n showPrice = true,\n lowCapacityThreshold = 3,\n currency,\n schedulingMode = \"intraday\",\n durationUnit,\n durationValue,\n hideElapsedSlots = true,\n minLeadMinutes = 0,\n emptyMessage = \"No available slots\",\n className,\n classNames,\n}: SlotPickerProps): React.ReactElement {\n const isMultiDay = schedulingMode === \"multi_day\";\n const { slots: fetched, isLoading } = useAvailableSlots(\n serviceId ?? null,\n date ?? null,\n {\n participantCount,\n enabled: slotsProp === undefined && !!serviceId && !!date,\n },\n );\n\n const rawSlots = slotsProp ?? fetched;\n // Drop slots that have already elapsed (or fall within the lead-time\n // window). Default behaviour because nothing the merchant can do at\n // the backend stops a client clock from being slightly ahead of the\n // last availability response — this is the same defence other\n // booking flows ship by default.\n const slots = useMemo(() => {\n if (!hideElapsedSlots) return rawSlots;\n const cutoff = Date.now() + minLeadMinutes * 60_000;\n return rawSlots.filter((slot) => {\n const start = Date.parse(slot.start_time);\n return Number.isNaN(start) || start >= cutoff;\n });\n }, [rawSlots, hideElapsedSlots, minLeadMinutes]);\n\n if (isLoading && slots.length === 0) {\n return (\n <div\n data-cimplify-slot-picker\n aria-busy=\"true\"\n className={cn(className, classNames?.root, classNames?.loading)}\n />\n );\n }\n\n if (slots.length === 0) {\n return (\n <div\n data-cimplify-slot-picker\n data-empty\n className={cn(className, classNames?.root, classNames?.empty)}\n >\n <p>{emptyMessage}</p>\n </div>\n );\n }\n\n const groups = groupByTimeOfDay && !isMultiDay\n ? groupSlots(slots)\n : [{ label: \"\", slots }];\n\n const slotsByValue = new Map<string, AvailableSlot>();\n for (const slot of slots) {\n slotsByValue.set(slotToValue(slot), slot);\n }\n\n const selectedValue = selectedSlot ? slotToValue(selectedSlot) : \"\";\n\n return (\n <RadioGroup\n data-cimplify-slot-picker\n className={cn(\"flex flex-col gap-4\", className, classNames?.root)}\n value={selectedValue}\n onValueChange={(value: string) => {\n const slot = slotsByValue.get(value);\n // Slots default to available; treat as unavailable only when the\n // backend explicitly returns `is_available: false`.\n if (slot && slot.is_available !== false) {\n onSlotSelect?.(slot);\n }\n }}\n >\n {groups.map((group) => (\n <div\n key={group.label || \"all\"}\n data-cimplify-slot-group\n className={cn(\"flex flex-col gap-2\", classNames?.group)}\n >\n {group.label && (\n <div\n data-cimplify-slot-group-label\n className={cn(\n \"text-xs font-medium uppercase tracking-[0.12em] text-muted-foreground\",\n classNames?.groupLabel,\n )}\n >\n {group.label}\n </div>\n )}\n <div\n className={cn(\n isMultiDay\n ? \"flex flex-col gap-2\"\n : \"grid grid-cols-3 sm:grid-cols-4 gap-2\",\n )}\n >\n {group.slots.map((slot) => {\n const value = slotToValue(slot);\n const isSelected =\n selectedSlot?.start_time === slot.start_time &&\n selectedSlot?.end_time === slot.end_time;\n const capacity = slot.capacity_available ?? slot.remaining_capacity;\n const soldOut = capacity === 0;\n const unavailable = slot.is_available === false || soldOut;\n const lowCapacity =\n lowCapacityThreshold > 0 &&\n capacity != null &&\n capacity > 0 &&\n capacity <= lowCapacityThreshold;\n return (\n <Radio.Root\n key={value}\n value={value}\n disabled={unavailable}\n data-cimplify-slot\n data-selected={isSelected || undefined}\n data-unavailable={unavailable || undefined}\n className={cn(\n \"inline-flex items-center justify-center gap-2 rounded-md border border-border bg-background px-3 py-2 text-sm font-medium text-foreground transition-colors hover:border-foreground/40 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring data-[selected]:border-foreground data-[selected]:bg-foreground data-[selected]:text-background data-[unavailable]:cursor-not-allowed data-[unavailable]:opacity-40 data-[unavailable]:line-through\",\n isMultiDay && \"justify-between text-left\",\n classNames?.slot,\n )}\n >\n <span data-cimplify-slot-time className={classNames?.slotTime}>\n {isMultiDay\n ? formatStaySummary(slot, durationUnit, durationValue)\n : formatTime(slot.start_time)}\n </span>\n {showPrice && slot.price && (\n <span\n data-cimplify-slot-price\n className={cn(\"text-xs opacity-70\", classNames?.slotPrice)}\n >\n <Price amount={slot.price} currency={currency} />\n </span>\n )}\n {lowCapacity && (\n <span\n data-cimplify-slot-scarcity\n className={cn(\"text-xs font-medium text-amber-600\", classNames?.slotScarcity)}\n >\n {capacity} left\n </span>\n )}\n </Radio.Root>\n );\n })}\n </div>\n </div>\n ))}\n </RadioGroup>\n );\n}\n"
14
14
  }
15
15
  ]
16
16
  }
@@ -9,7 +9,7 @@
9
9
  "files": [
10
10
  {
11
11
  "path": "variant-selector.tsx",
12
- "content": "\"use client\";\n\nimport React, { useState, useEffect, useRef, useId } from \"react\";\nimport { RadioGroup } from \"@base-ui/react/radio-group\";\nimport { Radio } from \"@base-ui/react/radio\";\nimport type { VariantView, VariantAxisWithValues } from \"@cimplify/sdk\";\nimport type { Money, CurrencyCode } from \"@cimplify/sdk\";\nimport { parsePrice } from \"@cimplify/sdk\";\nimport { getVariantDisplayName } from \"@cimplify/sdk\";\nimport { Price } from \"@cimplify/sdk/react\";\nimport { cn } from \"@cimplify/sdk/react\";\n\nexport interface VariantSelectorClassNames {\n root?: string;\n axisLabel?: string;\n axisOptions?: string;\n option?: string;\n optionSelected?: string;\n listLabel?: string;\n list?: string;\n name?: string;\n pricing?: string;\n adjustment?: string;\n}\n\nexport interface VariantSelectorProps {\n variants: VariantView[];\n variantAxes?: VariantAxisWithValues[];\n basePrice?: Money;\n currency?: CurrencyCode;\n selectedVariantId?: string;\n onVariantChange: (variantId: string | undefined, variant: VariantView | undefined) => void;\n productName?: string;\n className?: string;\n classNames?: VariantSelectorClassNames;\n}\n\nexport function VariantSelector({\n variants,\n variantAxes,\n basePrice,\n currency,\n selectedVariantId,\n onVariantChange,\n productName,\n className,\n classNames,\n}: VariantSelectorProps): React.ReactElement | null {\n const [axisSelections, setAxisSelections] = useState<Record<string, string>>({});\n const initialized = useRef(false);\n const idPrefix = useId();\n\n useEffect(() => {\n initialized.current = false;\n }, [variants]);\n\n useEffect(() => {\n if (initialized.current) return;\n if (!variants || variants.length === 0) return;\n\n const defaultVariant = variants.find((v) => v.is_default) || variants[0];\n if (!defaultVariant) return;\n\n initialized.current = true;\n onVariantChange(defaultVariant.id, defaultVariant);\n\n if (defaultVariant.display_attributes) {\n const initial: Record<string, string> = {};\n for (const attr of defaultVariant.display_attributes) {\n initial[attr.axis_id] = attr.value_id;\n }\n setAxisSelections(initial);\n }\n }, [variants, onVariantChange]);\n\n useEffect(() => {\n if (!initialized.current) return;\n if (!variantAxes || variantAxes.length === 0) return;\n\n const match = variants.find((v) => {\n if (!v.display_attributes) return false;\n return v.display_attributes.every(\n (attr) => axisSelections[attr.axis_id] === attr.value_id,\n );\n });\n\n if (match && match.id !== selectedVariantId) {\n onVariantChange(match.id, match);\n }\n }, [axisSelections, variants, variantAxes, selectedVariantId, onVariantChange]);\n\n if (!variants || variants.length <= 1) {\n return null;\n }\n\n const basePriceNum = basePrice != null ? parsePrice(basePrice) : 0;\n\n if (variantAxes && variantAxes.length > 0) {\n return (\n <div data-cimplify-variant-selector className={cn(\"space-y-5\", className, classNames?.root)}>\n {variantAxes.map((axis) => {\n const labelId = `${idPrefix}-axis-${axis.id}`;\n return (\n <div key={axis.id} data-cimplify-variant-axis>\n <label\n id={labelId}\n data-cimplify-variant-axis-label\n className={cn(\"block text-xs font-medium uppercase tracking-wider text-muted-foreground mb-3\", classNames?.axisLabel)}\n >\n {axis.name}\n </label>\n <RadioGroup\n aria-labelledby={labelId}\n value={axisSelections[axis.id] ?? \"\"}\n onValueChange={(value) => {\n setAxisSelections((prev) => ({\n ...prev,\n [axis.id]: value,\n }));\n }}\n data-cimplify-variant-axis-options\n className={cn(\"flex flex-wrap gap-2\", classNames?.axisOptions)}\n >\n {axis.values.map((value) => {\n const isSelected = axisSelections[axis.id] === value.id;\n return (\n <Radio.Root\n key={value.id}\n value={value.id}\n data-cimplify-variant-option\n data-selected={isSelected || undefined}\n className={cn(\n \"px-4 py-2 border text-sm font-medium transition-colors border-border hover:border-primary/50\",\n isSelected && \"bg-primary text-primary-foreground border-primary\",\n isSelected ? classNames?.optionSelected : classNames?.option,\n )}\n >\n {value.name}\n </Radio.Root>\n );\n })}\n </RadioGroup>\n </div>\n );\n })}\n </div>\n );\n }\n\n const listLabelId = `${idPrefix}-variant-list`;\n\n return (\n <div data-cimplify-variant-selector className={cn(className, classNames?.root)}>\n <div\n data-cimplify-variant-list-header\n className={cn(\"flex items-center justify-between py-3\", classNames?.listLabel)}\n >\n <label id={listLabelId} className=\"text-base font-bold\">\n Options\n </label>\n <span className=\"text-xs font-semibold text-destructive bg-destructive/10 px-2.5 py-1 rounded\">\n Required\n </span>\n </div>\n <RadioGroup\n aria-labelledby={listLabelId}\n value={selectedVariantId ?? \"\"}\n onValueChange={(value) => {\n const variant = variants.find((v) => v.id === value);\n onVariantChange(variant?.id, variant);\n }}\n data-cimplify-variant-list\n className={cn(\"divide-y divide-border\", classNames?.list)}\n >\n {variants.map((variant) => {\n const isSelected = selectedVariantId === variant.id;\n const adjustment = parsePrice(variant.price_adjustment);\n\n return (\n <Radio.Root\n key={variant.id}\n value={variant.id}\n data-cimplify-variant-option\n data-selected={isSelected || undefined}\n className={cn(\n \"w-full flex items-center gap-3 py-4 transition-colors cursor-pointer\",\n isSelected ? classNames?.optionSelected : classNames?.option,\n )}\n >\n <span\n data-cimplify-variant-radio\n className={cn(\n \"w-5 h-5 rounded-full border-2 flex items-center justify-center shrink-0 transition-colors\",\n isSelected ? \"border-primary\" : \"border-muted-foreground/30\",\n )}\n >\n {isSelected && <span className=\"w-2.5 h-2.5 rounded-full bg-primary\" />}\n </span>\n <span\n data-cimplify-variant-name\n className={cn(\"flex-1 min-w-0 text-sm\", classNames?.name)}\n >\n {getVariantDisplayName(variant, productName)}\n </span>\n <span data-cimplify-variant-pricing className={cn(\"text-sm text-muted-foreground\", classNames?.pricing)}>\n {adjustment > 0 ? \"+\" : adjustment < 0 ? \"\" : \"+\"}\n <Price amount={variant.price_adjustment} currency={currency} />\n </span>\n </Radio.Root>\n );\n })}\n </RadioGroup>\n </div>\n );\n}\n"
12
+ "content": "\"use client\";\n\nimport React, { useState, useEffect, useRef, useId } from \"react\";\nimport { RadioGroup } from \"@base-ui/react/radio-group\";\nimport { Radio } from \"@base-ui/react/radio\";\nimport type { VariantView, VariantAxisWithValues } from \"@cimplify/sdk\";\nimport type { Money, CurrencyCode } from \"@cimplify/sdk\";\nimport { parsePrice } from \"@cimplify/sdk\";\nimport { getVariantDisplayName } from \"@cimplify/sdk\";\nimport { Price } from \"@cimplify/sdk/react\";\nimport { cn } from \"@cimplify/sdk/react\";\n\nexport interface VariantSelectorClassNames {\n root?: string;\n axisLabel?: string;\n axisOptions?: string;\n option?: string;\n optionSelected?: string;\n swatch?: string;\n swatchSelected?: string;\n listLabel?: string;\n list?: string;\n name?: string;\n pricing?: string;\n adjustment?: string;\n}\n\nexport interface VariantSelectorProps {\n variants: VariantView[];\n variantAxes?: VariantAxisWithValues[];\n basePrice?: Money;\n currency?: CurrencyCode;\n selectedVariantId?: string;\n onVariantChange: (variantId: string | undefined, variant: VariantView | undefined) => void;\n productName?: string;\n className?: string;\n classNames?: VariantSelectorClassNames;\n}\n\nexport function VariantSelector({\n variants,\n variantAxes,\n basePrice,\n currency,\n selectedVariantId,\n onVariantChange,\n productName,\n className,\n classNames,\n}: VariantSelectorProps): React.ReactElement | null {\n const [axisSelections, setAxisSelections] = useState<Record<string, string>>({});\n const initialized = useRef(false);\n const idPrefix = useId();\n\n useEffect(() => {\n initialized.current = false;\n }, [variants]);\n\n useEffect(() => {\n if (initialized.current) return;\n if (!variants || variants.length === 0) return;\n\n const defaultVariant = variants.find((v) => v.is_default) || variants[0];\n if (!defaultVariant) return;\n\n initialized.current = true;\n onVariantChange(defaultVariant.id, defaultVariant);\n\n if (defaultVariant.display_attributes) {\n const initial: Record<string, string> = {};\n for (const attr of defaultVariant.display_attributes) {\n initial[attr.axis_id] = attr.value_id;\n }\n setAxisSelections(initial);\n }\n }, [variants, onVariantChange]);\n\n useEffect(() => {\n if (!initialized.current) return;\n if (!variantAxes || variantAxes.length === 0) return;\n\n const match = variants.find((v) => {\n if (!v.display_attributes) return false;\n return v.display_attributes.every(\n (attr) => axisSelections[attr.axis_id] === attr.value_id,\n );\n });\n\n if (match && match.id !== selectedVariantId) {\n onVariantChange(match.id, match);\n }\n }, [axisSelections, variants, variantAxes, selectedVariantId, onVariantChange]);\n\n if (!variants || variants.length <= 1) {\n return null;\n }\n\n const basePriceNum = basePrice != null ? parsePrice(basePrice) : 0;\n\n if (variantAxes && variantAxes.length > 0) {\n return (\n <div data-cimplify-variant-selector className={cn(\"space-y-5\", className, classNames?.root)}>\n {variantAxes.map((axis) => {\n const labelId = `${idPrefix}-axis-${axis.id}`;\n return (\n <div key={axis.id} data-cimplify-variant-axis>\n <label\n id={labelId}\n data-cimplify-variant-axis-label\n className={cn(\"block text-xs font-medium uppercase tracking-wider text-muted-foreground mb-3\", classNames?.axisLabel)}\n >\n {axis.name}\n </label>\n <RadioGroup\n aria-labelledby={labelId}\n value={axisSelections[axis.id] ?? \"\"}\n onValueChange={(value) => {\n setAxisSelections((prev) => ({\n ...prev,\n [axis.id]: value,\n }));\n }}\n data-cimplify-variant-axis-options\n className={cn(\"flex flex-wrap gap-2\", classNames?.axisOptions)}\n >\n {axis.values.map((value) => {\n const isSelected = axisSelections[axis.id] === value.id;\n\n // Color/image axis values render as swatches; selection is a ring\n // so the swatch keeps its own fill or photo.\n if (value.image_url || value.color_hex) {\n const isImage = Boolean(value.image_url);\n return (\n <Radio.Root\n key={value.id}\n value={value.id}\n data-cimplify-variant-option\n data-cimplify-variant-swatch\n data-selected={isSelected || undefined}\n aria-label={value.name}\n title={value.name}\n style={isImage ? undefined : { backgroundColor: value.color_hex }}\n className={cn(\n \"relative overflow-hidden border border-border transition-shadow\",\n isImage ? \"h-12 w-12 rounded-md\" : \"h-9 w-9 rounded-full\",\n isSelected && \"ring-2 ring-foreground ring-offset-2 ring-offset-background border-transparent\",\n isSelected ? classNames?.swatchSelected : classNames?.swatch,\n )}\n >\n {isImage && (\n <img\n src={value.image_url}\n alt=\"\"\n className=\"h-full w-full object-cover\"\n />\n )}\n </Radio.Root>\n );\n }\n\n return (\n <Radio.Root\n key={value.id}\n value={value.id}\n data-cimplify-variant-option\n data-selected={isSelected || undefined}\n className={cn(\n \"px-4 py-2 border text-sm font-medium transition-colors border-border hover:border-primary/50\",\n isSelected && \"bg-primary text-primary-foreground border-primary\",\n isSelected ? classNames?.optionSelected : classNames?.option,\n )}\n >\n {value.name}\n </Radio.Root>\n );\n })}\n </RadioGroup>\n </div>\n );\n })}\n </div>\n );\n }\n\n const listLabelId = `${idPrefix}-variant-list`;\n\n return (\n <div data-cimplify-variant-selector className={cn(className, classNames?.root)}>\n <div\n data-cimplify-variant-list-header\n className={cn(\"flex items-center justify-between py-3\", classNames?.listLabel)}\n >\n <label id={listLabelId} className=\"text-base font-bold\">\n Options\n </label>\n <span className=\"text-xs font-semibold text-destructive bg-destructive/10 px-2.5 py-1 rounded\">\n Required\n </span>\n </div>\n <RadioGroup\n aria-labelledby={listLabelId}\n value={selectedVariantId ?? \"\"}\n onValueChange={(value) => {\n const variant = variants.find((v) => v.id === value);\n onVariantChange(variant?.id, variant);\n }}\n data-cimplify-variant-list\n className={cn(\"divide-y divide-border\", classNames?.list)}\n >\n {variants.map((variant) => {\n const isSelected = selectedVariantId === variant.id;\n const adjustment = parsePrice(variant.price_adjustment);\n\n return (\n <Radio.Root\n key={variant.id}\n value={variant.id}\n data-cimplify-variant-option\n data-selected={isSelected || undefined}\n className={cn(\n \"w-full flex items-center gap-3 py-4 transition-colors cursor-pointer\",\n isSelected ? classNames?.optionSelected : classNames?.option,\n )}\n >\n <span\n data-cimplify-variant-radio\n className={cn(\n \"w-5 h-5 rounded-full border-2 flex items-center justify-center shrink-0 transition-colors\",\n isSelected ? \"border-primary\" : \"border-muted-foreground/30\",\n )}\n >\n {isSelected && <span className=\"w-2.5 h-2.5 rounded-full bg-primary\" />}\n </span>\n <span\n data-cimplify-variant-name\n className={cn(\"flex-1 min-w-0 text-sm\", classNames?.name)}\n >\n {getVariantDisplayName(variant, productName)}\n </span>\n <span data-cimplify-variant-pricing className={cn(\"text-sm text-muted-foreground\", classNames?.pricing)}>\n {adjustment > 0 ? \"+\" : adjustment < 0 ? \"\" : \"+\"}\n <Price amount={variant.price_adjustment} currency={currency} />\n </span>\n </Radio.Root>\n );\n })}\n </RadioGroup>\n </div>\n );\n}\n"
13
13
  }
14
14
  ]
15
15
  }