@flamingo-stack/openframe-frontend-core 0.0.407 → 0.0.408

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.
Files changed (116) hide show
  1. package/dist/{chunk-4UZH3MT2.js → chunk-5HOII3WB.js} +2 -2
  2. package/dist/{chunk-SY3QS2E5.cjs → chunk-A3RW7M6B.cjs} +26 -26
  3. package/dist/{chunk-SY3QS2E5.cjs.map → chunk-A3RW7M6B.cjs.map} +1 -1
  4. package/dist/{chunk-43H2WOAW.js → chunk-E4J5KKHH.js} +2 -2
  5. package/dist/{chunk-LPC3C7MG.cjs → chunk-F4KE5AZO.cjs} +37 -37
  6. package/dist/{chunk-LPC3C7MG.cjs.map → chunk-F4KE5AZO.cjs.map} +1 -1
  7. package/dist/{chunk-NSF7JUXF.js → chunk-IK5AR6QG.js} +4 -4
  8. package/dist/{chunk-CVYSW33D.js → chunk-IVM47EGI.js} +149 -109
  9. package/dist/chunk-IVM47EGI.js.map +1 -0
  10. package/dist/{chunk-KLBEIJVZ.js → chunk-J6M2G6TD.js} +4 -4
  11. package/dist/{chunk-R4MXLJUS.cjs → chunk-KPGKNUJF.cjs} +31 -31
  12. package/dist/{chunk-R4MXLJUS.cjs.map → chunk-KPGKNUJF.cjs.map} +1 -1
  13. package/dist/{chunk-74FWQI73.cjs → chunk-KRLBVBYU.cjs} +11 -11
  14. package/dist/{chunk-74FWQI73.cjs.map → chunk-KRLBVBYU.cjs.map} +1 -1
  15. package/dist/{chunk-HB63TQQO.js → chunk-KZPVN7AZ.js} +2 -2
  16. package/dist/{chunk-XFP43YKG.js → chunk-L6OPVKVR.js} +4 -4
  17. package/dist/{chunk-H66L2265.js → chunk-LQWYXIKB.js} +4 -4
  18. package/dist/{chunk-DOBNDDNE.cjs → chunk-NEMUCNCG.cjs} +59 -59
  19. package/dist/{chunk-DOBNDDNE.cjs.map → chunk-NEMUCNCG.cjs.map} +1 -1
  20. package/dist/{chunk-GJSLKATJ.js → chunk-O5W26SCL.js} +2 -2
  21. package/dist/{chunk-5M5W6XDY.cjs → chunk-RL344I7V.cjs} +7 -7
  22. package/dist/{chunk-5M5W6XDY.cjs.map → chunk-RL344I7V.cjs.map} +1 -1
  23. package/dist/{chunk-Q2MC3CBI.cjs → chunk-RPGFIUN3.cjs} +26 -26
  24. package/dist/{chunk-Q2MC3CBI.cjs.map → chunk-RPGFIUN3.cjs.map} +1 -1
  25. package/dist/{chunk-GGDM5J4B.cjs → chunk-SOALFYU6.cjs} +149 -109
  26. package/dist/chunk-SOALFYU6.cjs.map +1 -0
  27. package/dist/{chunk-PRKMOF2U.cjs → chunk-T6ZUBXPA.cjs} +9 -9
  28. package/dist/{chunk-PRKMOF2U.cjs.map → chunk-T6ZUBXPA.cjs.map} +1 -1
  29. package/dist/{chunk-WCPUJA3Y.cjs → chunk-V3EZQWHQ.cjs} +5 -5
  30. package/dist/{chunk-WCPUJA3Y.cjs.map → chunk-V3EZQWHQ.cjs.map} +1 -1
  31. package/dist/{chunk-HJIRG7R6.js → chunk-VUW4G6SU.js} +2 -2
  32. package/dist/{chunk-YX7C5JD7.cjs → chunk-WGOATV3P.cjs} +62 -62
  33. package/dist/{chunk-YX7C5JD7.cjs.map → chunk-WGOATV3P.cjs.map} +1 -1
  34. package/dist/{chunk-LC6RRLFA.cjs → chunk-YRKPMYI3.cjs} +15 -15
  35. package/dist/{chunk-LC6RRLFA.cjs.map → chunk-YRKPMYI3.cjs.map} +1 -1
  36. package/dist/{chunk-7XVFSGQA.js → chunk-ZF5O3KUQ.js} +2 -2
  37. package/dist/{chunk-GMZL4T7C.js → chunk-ZMFQWMM7.js} +2 -2
  38. package/dist/components/case-studies/index.cjs +9 -8
  39. package/dist/components/case-studies/index.cjs.map +1 -1
  40. package/dist/components/case-studies/index.js +3 -2
  41. package/dist/components/case-studies/index.js.map +1 -1
  42. package/dist/components/chat/index.cjs +3 -2
  43. package/dist/components/chat/index.cjs.map +1 -1
  44. package/dist/components/chat/index.js +2 -1
  45. package/dist/components/chat/quick-action-chip.d.ts +11 -2
  46. package/dist/components/chat/quick-action-chip.d.ts.map +1 -1
  47. package/dist/components/contact/index.cjs +4 -3
  48. package/dist/components/contact/index.cjs.map +1 -1
  49. package/dist/components/contact/index.js +3 -2
  50. package/dist/components/docs/index.cjs +6 -6
  51. package/dist/components/docs/index.js +5 -5
  52. package/dist/components/embeds/index.cjs +4 -3
  53. package/dist/components/embeds/index.cjs.map +1 -1
  54. package/dist/components/embeds/index.js +3 -2
  55. package/dist/components/embeds/reddit-embed-client.d.ts.map +1 -1
  56. package/dist/components/faq/index.cjs +4 -3
  57. package/dist/components/faq/index.cjs.map +1 -1
  58. package/dist/components/faq/index.js +3 -2
  59. package/dist/components/features/index.cjs +3 -2
  60. package/dist/components/features/index.cjs.map +1 -1
  61. package/dist/components/features/index.js +2 -1
  62. package/dist/components/help-center-pages/index.cjs +21 -21
  63. package/dist/components/help-center-pages/index.js +12 -12
  64. package/dist/components/index.cjs +126 -126
  65. package/dist/components/index.cjs.map +1 -1
  66. package/dist/components/index.d.ts +1 -0
  67. package/dist/components/index.d.ts.map +1 -1
  68. package/dist/components/index.js +10 -10
  69. package/dist/components/index.js.map +1 -1
  70. package/dist/components/media-carousel.d.ts +28 -4
  71. package/dist/components/media-carousel.d.ts.map +1 -1
  72. package/dist/components/navigation/index.cjs +3 -2
  73. package/dist/components/navigation/index.cjs.map +1 -1
  74. package/dist/components/navigation/index.js +2 -1
  75. package/dist/components/onboarding-guides/index.cjs +6 -6
  76. package/dist/components/onboarding-guides/index.js +5 -5
  77. package/dist/components/related-content/index.cjs +4 -3
  78. package/dist/components/related-content/index.cjs.map +1 -1
  79. package/dist/components/related-content/index.js +3 -2
  80. package/dist/components/tickets/index.cjs +6 -6
  81. package/dist/components/tickets/index.js +5 -5
  82. package/dist/components/ui/index.cjs +3 -2
  83. package/dist/components/ui/index.cjs.map +1 -1
  84. package/dist/components/ui/index.js +2 -1
  85. package/dist/components/ui/tag.d.ts +3 -2
  86. package/dist/components/ui/tag.d.ts.map +1 -1
  87. package/dist/index.cjs +3 -2
  88. package/dist/index.cjs.map +1 -1
  89. package/dist/index.js +2 -1
  90. package/dist/utils/media-carousel-utils-stub.d.ts +3 -1
  91. package/dist/utils/media-carousel-utils-stub.d.ts.map +1 -1
  92. package/package.json +1 -1
  93. package/src/components/chat/quick-action-chip.tsx +18 -4
  94. package/src/components/embeds/reddit-embed-client.tsx +0 -3
  95. package/src/components/index.ts +5 -0
  96. package/src/components/media-carousel.tsx +195 -149
  97. package/src/components/ui/tag.tsx +21 -3
  98. package/src/styles/ods-design-tokens.css +2 -0
  99. package/src/utils/media-carousel-utils-stub.ts +3 -1
  100. package/dist/chunk-CVYSW33D.js.map +0 -1
  101. package/dist/chunk-GGDM5J4B.cjs.map +0 -1
  102. package/dist/utils/media-carousel-utils.d.ts +0 -10
  103. package/dist/utils/media-carousel-utils.d.ts.map +0 -1
  104. package/src/utils/.media-carousel-utils.md +0 -31
  105. package/src/utils/media-carousel-utils.ts +0 -22
  106. /package/dist/{chunk-4UZH3MT2.js.map → chunk-5HOII3WB.js.map} +0 -0
  107. /package/dist/{chunk-43H2WOAW.js.map → chunk-E4J5KKHH.js.map} +0 -0
  108. /package/dist/{chunk-NSF7JUXF.js.map → chunk-IK5AR6QG.js.map} +0 -0
  109. /package/dist/{chunk-KLBEIJVZ.js.map → chunk-J6M2G6TD.js.map} +0 -0
  110. /package/dist/{chunk-HB63TQQO.js.map → chunk-KZPVN7AZ.js.map} +0 -0
  111. /package/dist/{chunk-XFP43YKG.js.map → chunk-L6OPVKVR.js.map} +0 -0
  112. /package/dist/{chunk-H66L2265.js.map → chunk-LQWYXIKB.js.map} +0 -0
  113. /package/dist/{chunk-GJSLKATJ.js.map → chunk-O5W26SCL.js.map} +0 -0
  114. /package/dist/{chunk-HJIRG7R6.js.map → chunk-VUW4G6SU.js.map} +0 -0
  115. /package/dist/{chunk-7XVFSGQA.js.map → chunk-ZF5O3KUQ.js.map} +0 -0
  116. /package/dist/{chunk-GMZL4T7C.js.map → chunk-ZMFQWMM7.js.map} +0 -0
@@ -90,6 +90,7 @@ import {
90
90
  GraduationCapIcon,
91
91
  HeadphoneIcon,
92
92
  HubspotLogoGreyIcon,
93
+ ImageOffIcon,
93
94
  ImagePlusIcon,
94
95
  InfoCircleIcon,
95
96
  LayersIcon,
@@ -424,11 +425,18 @@ init_cn();
424
425
  import { jsx, jsxs } from "react/jsx-runtime";
425
426
  var tagVariants = cva(
426
427
  [
427
- "text-h5 h-8 inline-flex items-center justify-center gap-[var(--spacing-system-xxs)] p-[var(--spacing-system-xsf)] rounded-md",
428
+ "inline-flex items-center justify-center rounded-md",
428
429
  "transition-colors duration-150"
429
430
  ],
430
431
  {
431
432
  variants: {
433
+ // Chip scale. `default` is the classic 32px mono-uppercase tag; `large`
434
+ // is the Figma "Feature Item" chip (48px, h3 bold body label) used by
435
+ // chip groups acting as tabs (OpenFrame categories).
436
+ size: {
437
+ default: "text-h5 h-8 gap-[var(--spacing-system-xxs)] p-[var(--spacing-system-xsf)]",
438
+ large: "text-h3 font-bold h-12 gap-[var(--spacing-system-xs)] p-[var(--spacing-system-s)]"
439
+ },
432
440
  variant: {
433
441
  primary: [
434
442
  "bg-[var(--ods-open-yellow-base)] text-[var(--ods-system-greys-black)]",
@@ -459,6 +467,15 @@ var tagVariants = cva(
459
467
  "bg-[var(--ods-system-greys-soft-grey)] text-[var(--ods-system-greys-grey)]",
460
468
  "hover:bg-[var(--ods-system-greys-soft-grey-hover)] active:bg-[var(--ods-system-greys-soft-grey-action)]"
461
469
  ],
470
+ // Active/selected chip state (Figma "Feature Item" active): pink
471
+ // border + pink-secondary fill. A dedicated variant (not appended
472
+ // utilities) so its own hover rules win — the outline variant's
473
+ // hover:bg/hover:border would otherwise repaint an active chip grey.
474
+ selected: [
475
+ "bg-[var(--ods-flamingo-pink-secondary)] text-[var(--ods-system-greys-white)] border border-[var(--ods-flamingo-pink-base)]",
476
+ "hover:bg-[var(--ods-flamingo-pink-secondary-hover)] hover:border-[var(--ods-flamingo-pink-base)]",
477
+ "active:bg-[var(--ods-flamingo-pink-secondary-action)]"
478
+ ],
462
479
  // Matches the EntityTagBadges / StatusBadge tag skin (ods-card + ods-border,
463
480
  // mono uppercase) so the tag-editor chips render identically to the public
464
481
  // tag badges. Used for FilterChipData variant 'tag' (see search-input).
@@ -469,7 +486,8 @@ var tagVariants = cva(
469
486
  }
470
487
  },
471
488
  defaultVariants: {
472
- variant: "primary"
489
+ variant: "primary",
490
+ size: "default"
473
491
  }
474
492
  }
475
493
  );
@@ -482,6 +500,7 @@ var disabledTagClasses = [
482
500
  function Tag({
483
501
  label,
484
502
  variant,
503
+ size: size2,
485
504
  icon,
486
505
  onClose,
487
506
  className,
@@ -494,14 +513,14 @@ function Tag({
494
513
  Comp,
495
514
  {
496
515
  className: cn(
497
- tagVariants({ variant }),
516
+ tagVariants({ variant, size: size2 }),
498
517
  disabled && disabledTagClasses,
499
518
  className
500
519
  ),
501
520
  "aria-disabled": disabled || void 0,
502
521
  ...props,
503
522
  children: [
504
- icon && /* @__PURE__ */ jsx("span", { className: "flex items-center justify-center size-5 shrink-0", children: icon }),
523
+ icon && /* @__PURE__ */ jsx("span", { className: cn("flex items-center justify-center shrink-0", size2 === "large" ? "size-6" : "size-5"), children: icon }),
505
524
  /* @__PURE__ */ jsx("span", { className: cn("truncate", labelClassName), title: typeof label === "string" ? label : void 0, children: label }),
506
525
  onClose && /* @__PURE__ */ jsx(
507
526
  "button",
@@ -6504,13 +6523,14 @@ function composeChipLabel(label, lozenge) {
6504
6523
  function ChipSkelBar({ className, style }) {
6505
6524
  return /* @__PURE__ */ jsx34("span", { "aria-hidden": true, className: cn("animate-pulse rounded-md bg-ods-border", className), style });
6506
6525
  }
6507
- function QuickActionChipSkeleton({ labelCh = 16, icon = true, lozenge = false, className }) {
6526
+ function QuickActionChipSkeleton({ labelCh = 16, icon = true, lozenge = false, size: size2 = "default", className }) {
6508
6527
  return /* @__PURE__ */ jsx34(
6509
6528
  Tag,
6510
6529
  {
6511
6530
  variant: "outline",
6531
+ size: size2,
6512
6532
  className,
6513
- icon: icon ? /* @__PURE__ */ jsx34(ChipSkelBar, { className: "block size-4" }) : void 0,
6533
+ icon: icon ? /* @__PURE__ */ jsx34(ChipSkelBar, { className: size2 === "large" ? "block size-5" : "block size-4" }) : void 0,
6514
6534
  label: /* @__PURE__ */ jsxs28(Fragment8, { children: [
6515
6535
  lozenge && /* @__PURE__ */ jsx34(ChipSkelBar, { className: "mr-2 inline-block h-[16px] w-[26px] translate-y-[2px]" }),
6516
6536
  /* @__PURE__ */ jsx34(ChipSkelBar, { className: "inline-block h-[0.9em] translate-y-[0.08em]", style: { width: `${labelCh}ch` } })
@@ -6523,6 +6543,8 @@ function QuickActionChipButton({
6523
6543
  icon,
6524
6544
  lozenge,
6525
6545
  variant = "outline",
6546
+ selected = false,
6547
+ size: size2 = "default",
6526
6548
  onSelect,
6527
6549
  onHoverStart,
6528
6550
  onHoverEnd,
@@ -6531,8 +6553,9 @@ function QuickActionChipButton({
6531
6553
  }) {
6532
6554
  const resolvedIcon = renderQuickActionIcon(icon);
6533
6555
  const resolvedLabel = composeChipLabel(label, lozenge);
6556
+ const tagVariant = selected ? "selected" : variant;
6534
6557
  if (!interactive) {
6535
- return /* @__PURE__ */ jsx34(Tag, { variant, icon: resolvedIcon, label: resolvedLabel, className });
6558
+ return /* @__PURE__ */ jsx34(Tag, { variant: tagVariant, size: size2, icon: resolvedIcon, label: resolvedLabel, className });
6536
6559
  }
6537
6560
  return /* @__PURE__ */ jsx34(
6538
6561
  "button",
@@ -6543,11 +6566,12 @@ function QuickActionChipButton({
6543
6566
  onMouseLeave: onHoverEnd,
6544
6567
  onFocus: onHoverStart,
6545
6568
  onBlur: onHoverEnd,
6569
+ "aria-pressed": selected || void 0,
6546
6570
  className: cn(
6547
6571
  "shrink-0 rounded-md focus:outline-none focus-visible:ring-2 focus-visible:ring-ods-accent",
6548
6572
  className
6549
6573
  ),
6550
- children: /* @__PURE__ */ jsx34(Tag, { variant, icon: resolvedIcon, label: resolvedLabel })
6574
+ children: /* @__PURE__ */ jsx34(Tag, { variant: tagVariant, size: size2, icon: resolvedIcon, label: resolvedLabel })
6551
6575
  }
6552
6576
  );
6553
6577
  }
@@ -18684,6 +18708,7 @@ var socialCache = SocialEmbedCache.getInstance();
18684
18708
  // src/components/media-carousel.tsx
18685
18709
  init_cn();
18686
18710
  import { useState as useState39, useRef as useRef23, useEffect as useEffect32, memo as memo4, useCallback as useCallback19 } from "react";
18711
+ init_button2();
18687
18712
  import { Fragment as Fragment30, jsx as jsx135, jsxs as jsxs104 } from "react/jsx-runtime";
18688
18713
  var ChevronLeftIcon = () => /* @__PURE__ */ jsx135("svg", { width: "24", height: "24", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx135("polyline", { points: "15,18 9,12 15,6" }) });
18689
18714
  var ChevronRightIcon = () => /* @__PURE__ */ jsx135("svg", { width: "24", height: "24", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx135("polyline", { points: "9,18 15,12 9,6" }) });
@@ -18691,27 +18716,28 @@ var MediaCarousel = memo4(function MediaCarousel2({
18691
18716
  media,
18692
18717
  className,
18693
18718
  aspectRatio = "16/9",
18694
- showThumbnails = true,
18695
- autoPlay = false,
18696
- objectFit = "contain"
18719
+ showArrows = true,
18720
+ objectFit = "contain",
18721
+ posterPriority = false,
18722
+ transformImageSrc,
18723
+ reserveDotRow = false
18697
18724
  }) {
18698
18725
  const [currentIndex, setCurrentIndex] = useState39(0);
18699
18726
  const [touchStart, setTouchStart] = useState39(null);
18700
18727
  const [touchEnd, setTouchEnd] = useState39(null);
18728
+ const [brokenResourceUrls, setBrokenResourceUrls] = useState39({});
18729
+ const [loadedImageSrc, setLoadedImageSrc] = useState39(null);
18701
18730
  const carouselRef = useRef23(null);
18702
- const thumbnailsRef = useRef23(null);
18731
+ const onImageError = useCallback19((originalUrl) => {
18732
+ const key = originalUrl.trim() || "__missing_src__";
18733
+ setBrokenResourceUrls((b) => b[key] ? b : { ...b, [key]: true });
18734
+ }, []);
18703
18735
  useEffect32(() => {
18704
18736
  if (currentIndex >= media.length && media.length > 0) {
18705
18737
  setCurrentIndex(media.length - 1);
18706
18738
  }
18707
18739
  }, [media.length, currentIndex]);
18708
- if (!media || media.length === 0) {
18709
- return null;
18710
- }
18711
18740
  const currentItem = media[currentIndex] || media[0];
18712
- if (!currentItem) {
18713
- return null;
18714
- }
18715
18741
  const nextSlide = useCallback19(() => {
18716
18742
  setCurrentIndex((prev) => (prev + 1) % media.length);
18717
18743
  }, [media.length]);
@@ -18719,9 +18745,8 @@ var MediaCarousel = memo4(function MediaCarousel2({
18719
18745
  setCurrentIndex((prev) => (prev - 1 + media.length) % media.length);
18720
18746
  }, [media.length]);
18721
18747
  const selectSlide = useCallback19((index) => {
18722
- if (index === currentIndex) return;
18723
- setCurrentIndex(index);
18724
- }, [currentIndex]);
18748
+ setCurrentIndex((prev) => index === prev ? prev : index);
18749
+ }, []);
18725
18750
  const handleKeyDown = useCallback19((e) => {
18726
18751
  if (media.length <= 1) return;
18727
18752
  if (e.key === "ArrowLeft") {
@@ -18732,6 +18757,12 @@ var MediaCarousel = memo4(function MediaCarousel2({
18732
18757
  nextSlide();
18733
18758
  }
18734
18759
  }, [nextSlide, prevSlide, media.length]);
18760
+ if (!media || media.length === 0) {
18761
+ return null;
18762
+ }
18763
+ if (!currentItem) {
18764
+ return null;
18765
+ }
18735
18766
  const minSwipeDistance = 50;
18736
18767
  const onTouchStart = (e) => {
18737
18768
  setTouchEnd(null);
@@ -18741,7 +18772,7 @@ var MediaCarousel = memo4(function MediaCarousel2({
18741
18772
  setTouchEnd(e.targetTouches[0].clientX);
18742
18773
  };
18743
18774
  const onTouchEnd = () => {
18744
- if (!touchStart || !touchEnd) return;
18775
+ if (touchStart === null || touchEnd === null) return;
18745
18776
  const distance = touchStart - touchEnd;
18746
18777
  const isLeftSwipe = distance > minSwipeDistance;
18747
18778
  const isRightSwipe = distance < -minSwipeDistance;
@@ -18752,43 +18783,77 @@ var MediaCarousel = memo4(function MediaCarousel2({
18752
18783
  prevSlide();
18753
18784
  }
18754
18785
  };
18755
- const renderYouTubeEmbed = (item, index) => /* @__PURE__ */ jsx135(
18756
- Video2,
18757
- {
18758
- kind: "youtube",
18759
- url: item.src,
18760
- title: item.alt || `Video ${index + 1}`,
18761
- layout: "fill",
18762
- priority: index === currentIndex
18763
- }
18764
- );
18786
+ const displayImageSrc = (url) => transformImageSrc ? transformImageSrc(url) : url;
18765
18787
  const renderVideo = (item, index) => /* @__PURE__ */ jsx135(
18766
18788
  Video2,
18767
18789
  {
18768
18790
  url: item.src,
18769
- poster: item.poster,
18791
+ poster: item.poster ? displayImageSrc(item.poster) : void 0,
18792
+ title: item.alt || `Video ${index + 1}`,
18770
18793
  muted: true,
18771
18794
  layout: "fill",
18772
- priority: index === currentIndex
18773
- }
18795
+ priority: Boolean(posterPriority && index === 0),
18796
+ className: "w-full h-full bg-black"
18797
+ },
18798
+ `video-${index}-${item.src}`
18774
18799
  );
18775
- const renderImage = (item, index) => /* @__PURE__ */ jsx135("div", { className: "absolute inset-0 bg-black", children: /* @__PURE__ */ jsx135(
18776
- "img",
18777
- {
18778
- src: item.src,
18779
- alt: item.alt || `Media ${index + 1}`,
18780
- className: `w-full h-full object-${objectFit}`,
18781
- loading: "lazy",
18782
- onError: (e) => {
18783
- const target = e.target;
18784
- target.style.display = "none";
18800
+ const renderImageUnavailable = (failedUrl) => /* @__PURE__ */ jsxs104("div", { className: "absolute inset-0 flex flex-col items-center justify-center gap-3 bg-ods-card px-6 text-center", children: [
18801
+ /* @__PURE__ */ jsx135(ImageOffIcon, { className: "size-8 text-ods-text-secondary" }),
18802
+ /* @__PURE__ */ jsx135("p", { className: "text-ods-text-secondary text-sm max-w-md", children: "This image is no longer available at the original URL." }),
18803
+ /* @__PURE__ */ jsx135(
18804
+ next_link_default,
18805
+ {
18806
+ href: failedUrl,
18807
+ target: "_blank",
18808
+ rel: "noopener noreferrer",
18809
+ className: "text-ods-accent text-sm underline break-all",
18810
+ children: "Open link"
18785
18811
  }
18786
- }
18787
- ) });
18812
+ )
18813
+ ] });
18814
+ const renderImage = (item, index) => {
18815
+ const rawSrc = typeof item.src === "string" ? item.src.trim() : "";
18816
+ if (!rawSrc) {
18817
+ return /* @__PURE__ */ jsx135("div", { className: "absolute inset-0 flex flex-col items-center justify-center gap-3 bg-ods-card px-6 text-center", children: /* @__PURE__ */ jsx135("p", { className: "text-ods-text-secondary text-sm max-w-md", children: "No image URL for this slide." }) });
18818
+ }
18819
+ if (brokenResourceUrls[rawSrc]) {
18820
+ return renderImageUnavailable(rawSrc);
18821
+ }
18822
+ const mainImagePriority = Boolean(posterPriority && index === 0);
18823
+ const imageLoaded = loadedImageSrc === rawSrc;
18824
+ return /* @__PURE__ */ jsxs104("div", { className: "absolute inset-0 bg-ods-bg", children: [
18825
+ !imageLoaded && /* @__PURE__ */ jsx135(
18826
+ "div",
18827
+ {
18828
+ className: "absolute inset-0 z-[1] bg-ods-card/90 animate-pulse",
18829
+ "aria-hidden": true
18830
+ }
18831
+ ),
18832
+ /* @__PURE__ */ jsx135(
18833
+ next_image_default,
18834
+ {
18835
+ src: displayImageSrc(rawSrc),
18836
+ alt: item.alt || `Media ${index + 1}`,
18837
+ className: cn(
18838
+ `w-full h-full object-${objectFit} relative z-[2]`,
18839
+ !imageLoaded && "opacity-0",
18840
+ imageLoaded && "opacity-100 transition-opacity duration-200"
18841
+ ),
18842
+ priority: mainImagePriority,
18843
+ loading: mainImagePriority ? "eager" : "lazy",
18844
+ sizes: "(max-width: 1279px) 100vw, 1428px",
18845
+ width: 1428,
18846
+ height: 802,
18847
+ unoptimized: true,
18848
+ onLoad: () => setLoadedImageSrc(rawSrc),
18849
+ onError: () => onImageError(rawSrc)
18850
+ }
18851
+ )
18852
+ ] });
18853
+ };
18788
18854
  const renderMainMedia = (item, index) => {
18789
18855
  switch (item.type) {
18790
18856
  case "youtube":
18791
- return renderYouTubeEmbed(item, index);
18792
18857
  case "video":
18793
18858
  return renderVideo(item, index);
18794
18859
  case "image":
@@ -18796,41 +18861,6 @@ var MediaCarousel = memo4(function MediaCarousel2({
18796
18861
  return renderImage(item, index);
18797
18862
  }
18798
18863
  };
18799
- const renderThumbnail = (item, index) => {
18800
- const isActive = index === currentIndex;
18801
- let thumbnailSrc = item.src;
18802
- if (item.type === "youtube") {
18803
- const videoId = extractYouTubeId(item.src);
18804
- thumbnailSrc = videoId ? `https://img.youtube.com/vi/${videoId}/mqdefault.jpg` : item.src;
18805
- } else if (item.type === "video" && item.poster) {
18806
- thumbnailSrc = item.poster;
18807
- }
18808
- return /* @__PURE__ */ jsxs104(
18809
- "button",
18810
- {
18811
- onClick: () => selectSlide(index),
18812
- className: cn(
18813
- "relative flex-shrink-0 overflow-hidden transition-all duration-200",
18814
- "w-20 h-20 md:w-24 md:h-24 rounded-lg border-2",
18815
- isActive ? "border-[#FFC008] ring-2 ring-[#FFC008]/20" : "border-ods-border hover:border-[#888888]"
18816
- ),
18817
- children: [
18818
- /* @__PURE__ */ jsx135(
18819
- "img",
18820
- {
18821
- src: thumbnailSrc,
18822
- alt: item.alt || `Thumbnail ${index + 1}`,
18823
- className: "w-full h-full object-cover",
18824
- loading: "lazy"
18825
- }
18826
- ),
18827
- (item.type === "video" || item.type === "youtube") && /* @__PURE__ */ jsx135("div", { className: "absolute inset-0 flex items-center justify-center bg-black/30", children: /* @__PURE__ */ jsx135(VideoPlayBadge, { size: "sm" }) }),
18828
- isActive && /* @__PURE__ */ jsx135("div", { className: "absolute bottom-1 right-1 w-2 h-2 bg-[#FFC008] rounded-full" })
18829
- ]
18830
- },
18831
- index
18832
- );
18833
- };
18834
18864
  const getAspectRatioClass = () => {
18835
18865
  switch (aspectRatio) {
18836
18866
  case "4/3":
@@ -18844,13 +18874,14 @@ var MediaCarousel = memo4(function MediaCarousel2({
18844
18874
  return "aspect-video";
18845
18875
  }
18846
18876
  };
18847
- return /* @__PURE__ */ jsxs104("div", { className: cn("space-y-4", className), children: [
18877
+ return /* @__PURE__ */ jsxs104("div", { className: cn("flex flex-col items-center gap-[var(--spacing-system-l)]", className), children: [
18848
18878
  /* @__PURE__ */ jsxs104(
18849
18879
  "div",
18850
18880
  {
18851
18881
  ref: carouselRef,
18852
18882
  className: cn(
18853
- "relative bg-ods-bg border border-ods-border rounded-2xl overflow-hidden group w-full",
18883
+ "relative bg-ods-bg border border-ods-border rounded-md overflow-hidden group w-full",
18884
+ "[box-shadow:var(--shadow-media-frame)]",
18854
18885
  getAspectRatioClass()
18855
18886
  ),
18856
18887
  onTouchStart,
@@ -18862,43 +18893,54 @@ var MediaCarousel = memo4(function MediaCarousel2({
18862
18893
  "aria-label": media.length > 1 ? "Media carousel, use arrow keys to navigate" : void 0,
18863
18894
  children: [
18864
18895
  renderMainMedia(currentItem, currentIndex),
18865
- media.length > 1 && /* @__PURE__ */ jsxs104(Fragment30, { children: [
18896
+ showArrows && media.length > 1 && /* @__PURE__ */ jsxs104(Fragment30, { children: [
18866
18897
  /* @__PURE__ */ jsx135(
18867
- "button",
18898
+ Button,
18868
18899
  {
18900
+ variant: "transparent",
18869
18901
  onClick: prevSlide,
18870
- className: "absolute left-3 top-1/2 transform -translate-y-1/2 bg-black/50 text-white rounded-full p-2 opacity-0 group-hover:opacity-100 transition-opacity duration-200 hover:bg-black/70 z-10",
18902
+ className: "absolute left-3 top-1/2 h-auto md:h-auto -translate-y-1/2 rounded-full bg-black/50 p-2 text-white opacity-0 transition-opacity duration-200 group-hover:opacity-100 hover:bg-black/70 z-10",
18871
18903
  "aria-label": "Previous media",
18872
18904
  children: /* @__PURE__ */ jsx135(ChevronLeftIcon, {})
18873
18905
  }
18874
18906
  ),
18875
18907
  /* @__PURE__ */ jsx135(
18876
- "button",
18908
+ Button,
18877
18909
  {
18910
+ variant: "transparent",
18878
18911
  onClick: nextSlide,
18879
- className: "absolute right-3 top-1/2 transform -translate-y-1/2 bg-black/50 text-white rounded-full p-2 opacity-0 group-hover:opacity-100 transition-opacity duration-200 hover:bg-black/70 z-10",
18912
+ className: "absolute right-3 top-1/2 h-auto md:h-auto -translate-y-1/2 rounded-full bg-black/50 p-2 text-white opacity-0 transition-opacity duration-200 group-hover:opacity-100 hover:bg-black/70 z-10",
18880
18913
  "aria-label": "Next media",
18881
18914
  children: /* @__PURE__ */ jsx135(ChevronRightIcon, {})
18882
18915
  }
18883
- ),
18884
- /* @__PURE__ */ jsxs104("div", { className: "absolute top-3 right-3 bg-black/70 text-white px-3 py-1 rounded-lg text-sm font-medium", children: [
18885
- currentIndex + 1,
18886
- " / ",
18887
- media.length
18888
- ] })
18916
+ )
18889
18917
  ] })
18890
18918
  ]
18891
18919
  }
18892
18920
  ),
18893
- media.length > 1 && showThumbnails && /* @__PURE__ */ jsx135("div", { className: "w-full", children: /* @__PURE__ */ jsx135(
18894
- "div",
18895
- {
18896
- ref: thumbnailsRef,
18897
- className: "flex gap-2 overflow-x-auto scrollbar-none py-2",
18898
- style: { scrollbarWidth: "none", msOverflowStyle: "none" },
18899
- children: media.map((item, index) => renderThumbnail(item, index))
18900
- }
18901
- ) })
18921
+ (media.length > 1 || reserveDotRow) && /* @__PURE__ */ jsx135("div", { className: "flex h-6 items-center gap-[var(--spacing-system-xs)]", role: "group", "aria-label": "Choose slide", children: media.length > 1 && media.map((item, index) => {
18922
+ const isActive = index === currentIndex;
18923
+ return /* @__PURE__ */ jsx135(
18924
+ Button,
18925
+ {
18926
+ variant: "transparent",
18927
+ "aria-current": isActive ? "true" : void 0,
18928
+ "aria-label": `Go to slide ${index + 1}`,
18929
+ onClick: () => selectSlide(index),
18930
+ className: "flex h-6 w-6 md:h-6 shrink-0 items-center justify-center rounded-full p-0",
18931
+ children: /* @__PURE__ */ jsx135(
18932
+ "span",
18933
+ {
18934
+ className: cn(
18935
+ "size-2 rounded-full transition-colors duration-150",
18936
+ isActive ? "bg-[var(--ods-flamingo-pink-base)]" : "bg-[var(--ods-system-greys-soft-grey)] hover:bg-[var(--ods-system-greys-soft-grey-hover)]"
18937
+ )
18938
+ }
18939
+ )
18940
+ },
18941
+ index
18942
+ );
18943
+ }) })
18902
18944
  ] });
18903
18945
  });
18904
18946
 
@@ -19234,7 +19276,6 @@ function RedditEmbedClient({ url, maxWidth = 700 }) {
19234
19276
  width: m.width,
19235
19277
  height: m.height
19236
19278
  }));
19237
- console.log("\u{1F3AC} MediaCarousel will render with:", mediaContent.length, "items", mediaContent);
19238
19279
  const formatTimeAgo = (timestamp) => {
19239
19280
  const now = Math.floor(Date.now() / 1e3);
19240
19281
  const diffSeconds = now - timestamp;
@@ -19281,8 +19322,7 @@ function RedditEmbedClient({ url, maxWidth = 700 }) {
19281
19322
  MediaCarousel,
19282
19323
  {
19283
19324
  media: carouselItems,
19284
- aspectRatio: "16/9",
19285
- showThumbnails: carouselItems.length > 1
19325
+ aspectRatio: "16/9"
19286
19326
  }
19287
19327
  ),
19288
19328
  /* @__PURE__ */ jsxs105("div", { className: "flex items-center space-x-6 text-ods-text-secondary text-sm", children: [
@@ -53369,4 +53409,4 @@ export {
53369
53409
  LogsList,
53370
53410
  assets
53371
53411
  };
53372
- //# sourceMappingURL=chunk-CVYSW33D.js.map
53412
+ //# sourceMappingURL=chunk-IVM47EGI.js.map