@nuskin/marketing-components 1.22.0 → 1.23.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/content-card/ContentCard.styled.d.ts +0 -10
- package/dist/content-card/Media.d.ts +1 -4
- package/dist/content-card/Media.styled.d.ts +6 -0
- package/dist/content-card/constants.d.ts +4 -4
- package/dist/content-card/types.d.ts +6 -4
- package/dist/content-card/utils/helpers.d.ts +3 -24
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1 -1
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/text/CsText.tsx","../src/hooks/useRouteReplacer.tsx","../src/utils/route-utils.ts","../src/hooks/use-toggle-font-color/useMainContrast.tsx","../src/hooks/use-toggle-font-color/useToggleFontColor.ts","../src/image/CsImage.tsx","../src/image/CsImage.styled.tsx","../src/marketing-banner/constants.ts","../src/marketing-banner/components/BannerText.styled.tsx","../src/marketing-banner/styles/theme.ts","../src/marketing-banner/styles/mixins.ts","../src/marketing-banner/components/BannerText.tsx","../src/bynder-media/BynderMedia.tsx","../src/bynder-media/utils.ts","../src/bynder-media/BynderMedia.styled.tsx","../src/marketing-banner/hooks/useCarousel.ts","../src/marketing-banner/hooks/useReducedMotion.ts","../src/marketing-banner/utils/utils.ts","../src/button/Button.tsx","../src/button/Button.styled.tsx","../src/button/helpers.ts","../src/marketing-banner/MarketingBanner.styled.tsx","../src/marketing-banner/MarketingBanner.tsx","../src/spacing-divider/SpacingDivider.styled.tsx","../src/spacing-divider/types.ts","../src/spacing-divider/utils/utils.ts","../src/spacing-divider/SpacingDivider.tsx","../src/column-control/ColumnControl.tsx","../src/column-control/shared.tsx","../src/column-control/ColumnControl.styled.tsx","../src/column-control/types.ts","../src/column-control/utils.ts","../src/column-control/hooks/useColumnControl.ts","../src/column-control/hooks/useColumnControlResize.ts","../src/column-control/Carousel.tsx","../src/content-card/ContentCard.tsx","../src/content-card/ContentCard.styled.ts","../src/content-card/utils/helpers.ts","../src/content-card/Media.tsx","../src/content-card/Media.styled.tsx","../src/hero-banner/components/Typography.tsx","../src/hero-banner/constants.ts","../src/hero-banner/components/TypographyFields.tsx","../src/hero-banner/components/Media.tsx","../src/hero-banner/HeroBanner.styled.tsx","../src/hero-banner/helpers.ts","../src/hero-banner/HeroBanner.tsx","../src/rich-text/RichText.tsx"],"names":["useMemo","styled","languageReplaceExpression","languageReplaceExpressionUppercase","regionReplaceExpression","regionReplaceExpressionUppercase","replaceRegionAndLanguage","text","replacer","region","replace","toUpperCase","language","DEFAULT_REGION","DEFAULT_LANGUAGE","getRegionAndLanguageFromSearch","search","startsWith","params","URLSearchParams","get","getRegionAndLanguageFromPath","pathname","parts","split","filter","Boolean","length","getRegionAndLanguageFromLocation","window","location","useTheme","ColorUtils","getGenomeColor","useToggleFontColor","toggleValue","theme","useToggleFontColor_default","jsx","useRegionLanguage","rewriteUrl","url","rewriteLinks","html","doc","DOMParser","parseFromString","querySelectorAll","forEach","link","href","getAttribute","setAttribute","body","innerHTML","Container","div","fullWidth","bgColor","alignment","color","extractColorFromObject","obj","brandColor","colorObj","light","trim","parseJsonColor","jsonString","JSON","parse","resolveBackgroundColor","value","trimmed","CsText","full_width","container_background_color","text_editor","font_color","$","fontColor","regionLang","backgroundColor","updatedHtml","children","dangerouslySetInnerHTML","__html","CsText_default","NsImage","StyledCsImageWrapper","image_alignment","width","height","display","justifyContent","left","right","center","maxWidth","objectFit","objectPosition","PLACEHOLDER_IMAGE_SRC","encodeURIComponent","allowedImageProps","CsImage","props","align","image","parent$","isEditing","rest","selectedImage","fileMeta","contentstackAsset","parsed","entry","selected","files","err","console","warn","resolvedSrc","resolvedAlt","resolvedWidth","resolvedHeight","imageType","fileSource","altText","title","filename","imageProps","src","alt","key","containerClassForNSImage","className","CsImage_default","DEFAULT_BANNER_CONFIG","position","textColor","showGradient","gradientDepth","mediaType","ctaVariant","DEFAULT_CAROUSEL_CONFIG","rotationInterval","DEFAULT_ROTATION_INTERVAL","PLACEHOLDER_VALUES","header","subtitle","BREAKPOINTS","mobile","tablet","desktop","wide","FONT_STACKS","lora","inter","FONT_SIZES","cta","SPACING","headerMargin","titleMargin","subtitleMargin","bodyMargin","textGap","desktopPadding","mobilePadding","carouselGap","ctaPaddingDesktop","ctaPaddingTablet","ctaPaddingWide","DIMENSIONS","bannerHeightDesktop","bannerHeightMobile","textMaxWidth","indicatorSize","indicatorBorder","COLORS","textWhite","textDark","textGray","ctaDark","ctaBorder","fallbackBg","indicatorActive","indicatorInactive","TEXT_COLOR_MAP","white","dark","TRANSITIONS","fast","default","slow","Z_INDEX","background","media","gradient","content","controls","MEDIA_QUERIES","mobileAndBelow","desktopAndUp","css","responsiveFontSize","sizes","centerOnMobile","smoothTransition","properties","map","prop","join","absoluteFill","absoluteFullSize","centerHorizontal","flexCenter","resetSpacing","gradientOverlay","direction","startOpacity","endOpacity","baseColor","radialGradientOverlay","TextContainer","textAlignment","HeaderText","p","Title","h2","Subtitle","h3","BodyText","jsxs","getDisplayText","placeholderValue","BannerText","headerText","bodyText","testId","titleDisplay","subtitleDisplay","header_text","body_text","React","getMediaUrl","isPublic","previewUrls","fileType","type","generateResponsiveUrl","baseUrl","aspectRatio","URL","ioParam","searchParams","updatedIo","push","origin","error","addDefaultTransform","has","extractBynderMedia","mediaJson","firstImage","mediaUrl","toLowerCase","endsWith","isResponsive","result","desktopUrl","mobileUrl","MediaContainer","StyledImage","img","StyledVideo","video","PictureElement","picture","SourceElement","source","BynderMedia","bynder_media","useState","mediaInfo","setMediaInfo","hasError","setHasError","useEffect","extracted","handleMediaError","mediaAlt","onError","autoPlay","muted","loop","playsInline","srcSet","loading","useCallback","useReducedMotion","prefersReducedMotion","setPrefersReducedMotion","matchMedia","mediaQuery","matches","handleChange","event","addEventListener","removeEventListener","useCarousel","options","totalSlides","autoRotate","pauseOnHover","initialIndex","currentIndex","setCurrentIndex","isPaused","setIsPaused","goToNext","prev","goToPrevious","goToSlide","index","pause","resume","handleKeyDown","preventDefault","intervalId","setInterval","clearInterval","hasCTA","banner","cta_button","label","isCarouselMode","Array","isArray","banners","hasMedia","NsIcon","NsIconVariants","NsButton","ROUNDED_BORDER_RADIUS","REL_NOOPENER_NOREFERRER","PROTOCOL_HTTP","PROTOCOL_HTTPS","DISABLED_STATE_STRING","DEFAULT_VARIANT","DEFAULT_SIZE","DEFAULT_ALIGNMENT","DEFAULT_ICON_POSITION","DEFAULT_BUTTON_TYPE","DEFAULT_PLACEHOLDER_TEXT","DEFAULT_TARGET","BUTTON_TYPE_ROUNDED","BUTTON_TYPE_SQUARE","BORDER_COLOR_TRANSPARENT","isValidDestination","dest","protocol","resolveTarget","target","resolveDisabled","disabled","iconAliasMap","arrow","resolveIconName","iconName","variantDefaults","primary","bg","hover","pressed","disabledBg","disabledText","focusRing","secondary","border","widthBySize","large","medium","small","DEFAULT_BUTTON_WIDTH","getButtonWidth","size","iconSizeByButtonSize","DEFAULT_ICON_SIZE","getIconSize","BUTTON_GAP","BUTTON_MIN_WIDTH","BUTTON_MIN_HEIGHT","DESKTOP_BREAKPOINT","TABLET_BREAKPOINT","MOBILE_BREAKPOINT","DESKTOP_FONT_SIZE","TABLET_FONT_SIZE","MOBILE_FONT_SIZE","DESKTOP_PADDING","TABLET_PADDING","MOBILE_PADDING","DESKTOP_FONT_WEIGHT","TABLET_MOBILE_FONT_WEIGHT","FOCUS_OUTLINE_WIDTH","FONT_FAMILY_LORA","JUSTIFY_CONTENT_CENTER","JUSTIFY_CONTENT_FLEX_END","JUSTIFY_CONTENT_FLEX_START","getJustifyContent","ButtonContainer","StyledButton","$bg","$hover","$pressed","$text","$border","$disabledBg","$disabledText","$focusRing","$buttonWidth","$buttonType","StyledLabelText","span","ICON_MARGIN_PX","StyledIconWrapper","Button","open_in_new_tab","variant","button_size","buttonType","buttontype","icon","iconposition","iconPosition","button_state","placeholderText","placeholder_text","resolvedVariant","resolvedSize","resolvedAlignment","resolvedIconPosition","resolvedButtonType","resolvedUrl","hrefProp","variantDefault","buttonWidth","resolvedTarget","resolvedDisabled","buttonBorder","IconName","isValidNsIcon","iconSize","renderIcon","iconColor","name","colorOverride","getLabelText","labelTitle","$variant","rel","Button_default","BannerContainer","CarouselWrapper","CarouselTrack","BannerSlide","BannerContent","MediaWrapper","TextContentWrapper","GradientOverlay","depth","opacities","sm","start","end","md","lg","ButtonWrapper","CarouselControls","Indicator","button","active","renderBanner","showMedia","showCTA","baseTestId","resolvedTextColor","text_color","show_gradient","content_position","gradientColor","gradientDirection","gradient_depth","MarketingBannerComponent","rotation_interval","isCarousel","carousel","onKeyDown","onMouseEnter","onMouseLeave","onClick","THICKNESS_PX","thin","thick","ultra","StyledSpacingContainer","vertical_padding","divider_alignment","v","none","flexDirection","alignItems","paddingTop","paddingBottom","StyledDividerLine","divider_style","divider_thickness_px","divider_color","divider_gradient","divider_width_percent","base","Math","max","min","backgroundImage","backgroundSize","dashLength","gapLength","maskImage","WebkitMaskImage","dotSize","spacing","radius","maskSize","WebkitMaskSize","maskRepeat","WebkitMaskRepeat","maskPosition","WebkitMaskPosition","borderBottomStyle","borderBottomWidth","borderBottomColor","isValidHex","test","hexToRgb","hex","r","parseInt","slice","g","b","gradientPresetCss","preset","baseHex","rgb","DEFAULT_HEX","SpacingDivider","divider_thickness","divider_gradient_preset","finalDividerColor","SpacingDivider_default","SliderImport","GAP_PRESET_VALUES","getGapPx","gap","DEVICE_SIZES","ULTRA_SMALL","EXTRA_SMALL","SMALL","MEDIUM","LARGE","EXTRA_LARGE","ULTRA_LARGE","SUPER_LARGE","MIN_SLIDE_WIDTH_PX","MIN_SLIDE_HEIGHT_PX","MAX_SLIDE_HEIGHT_PX","MIN_EMPTY_PLACEHOLDER_HEIGHT_PX","MAX_ALLOWED_COLUMN_CONTROL_ITEMS","getArrowButtonPosition","fullVal","nonFullVal","ColumnControlContainer","columnHeight","maxColumnHeight","dotsInside","textAlign","padding","boxSizing","overflow","minHeight","margin","maxHeight","bottom","listStyle","li","borderRadius","textIndent","cursor","transition","TabletGridContainer","flexWrap","SlideSection","useFlexLayout","stackedVerticalGap","stackedItemHeight","stackedItemMaxHeight","slideWidth","flexBasis","isVariableWidth","flex","minWidth","SlideInner","SlideContentInner","ArrowButton","top","transform","zIndex","fontSize","lineHeight","verticalAlign","outline","outlineOffset","opacity","InnerWrapper","EmptyPlaceholderWrapper","getViewportLayoutState","isGridLayout","windowWidth","gapPx","isStackedViewport","isTabletGridViewport","containerHeight","getSlidesMeta","slides","presetColumns","presetSlidesToShow","effectiveShowPagination","gridSlides","slidesToShow","shouldShowDots","unwrapComponent","mod","EmptyPlaceholder","emptyBlockParentClass","createElement","getPresetColumns","isVariableWidthPreset","getVariableSlideWidth","pos","getSlidesToShowByViewport","EMPTY_SLIDE_SENTINEL","__emptyPlaceholder","isEmptySlide","slide","isRealSlide","padSlidesToPreset","targetCount","padCount","fill","getSlidesForRender","buildResponsiveSettings","effectiveSlidesCount","slideCount","hasPlaceholders","gridSlidesToShow","maxCols","carouselSlidesToShow","breakpoint","settings","slidesToScroll","swipeToSlide","arrows","dots","variableWidth","Slider","CONTAINER_CLASS","getSlideKey","isPlaceholder","id","String","getSlideContent","renderSlide","emptyPlaceholderText","renderSlidesContent","slidesForRender","getSlideWidth","addSlideEditTags","slides__parent","renderContentOrEmpty","hasSlides","useRef","useColumnControlResize","innerWidth","setWindowWidth","Date","now","carouselKey","setCarouselKey","timeoutId","handleResize","clearTimeout","setTimeout","useColumnControl","layout","autoplayEnabled","autoplayDuration","showPagination","onSlideChange","slickSettings","emptyPlaceholderTextProp","effectiveFullWidth","effectiveAutoplayEnabled","showArrowsOnDesktop","viewportLayout","effectiveShouldShowDots","sliderRef","current","slickPrev","slickNext","containerClassName","slidesForRenderPadded","effectivePresetColumns","effectiveSlidesToShow","responsiveSettings","sliderSettings","infinite","speed","autoplay","autoplaySpeed","swipe","draggable","beforeChange","_","next","responsive","renderSlides","slidesLength","GridLayoutContent","ref","ColumnControl","gridProps","ColumnControl_default","Fragment","Carousel","dotsPosition","carouselProps","HEX_COLOR_REGEX","validateHex","defaultColor","hexToRgba","defaultRgba","safeOpacity","Number","isFinite","hexRaw","hexStr","c","n","isNaN","toCardBackgroundRgba","backgroundOpacity","toCardTextRgba","textOpacity","calculateMediaHeight","round","getMaxHeight","getTitle","normalizeContentAlignment","normalizeCtaStyle","ctaStyle","includes","normalizeContentCardMedia","bynder","calculateContentMinHeight","mediaHeight","ctaHeight","Card","article","$maxHeight","$mediaHeight","Content","Body","CtaWrapper","$height","MediaPlaceholderWrapper","ContentInner","$contentMinHeight","FallbackMessage","Media","fallbackMediaUrl","currentUrl","setCurrentUrl","renderMedia","ContentCard","cta_style","content_alignment","max_height","background_color","background_opacity","text_opacity","border_radius","ctaStyleNormalized","normalizedMedia","hasCtaHref","hasCtaLabel","isCardLink","showButton","contentMinHeight","cardTarget","contentTitle","as","ContentCard_default","NsTypography","Typography","placeholder","typographyProps","displayValue","PLACEHOLDER_BRAND_CAPTION","PLACEHOLDER_TITLE","PLACEHOLDER_SUBTITLE","PLACEHOLDER_BODY","ARIA_LABEL_HERO_BANNER","IMAGE_LOADING_LAZY","getTypographyFields","brandcaption","noSpacing","editTagKey","weight","TypographyFields","editTags","fields","field","additionalProps","FULL_SIZE_PERCENT","isMediaObject","parseMedia","resolveContentAlignment","contentAlignment","resolveGradientDepth","resolveTextColor","getGradientColor","gradientDirectionMap","getGradientDirection","GRADIENT_OPACITIES","getGradientBackground","Overlay","HERO_CTA_WRAPPER_CLASS","forwardRef","parsedMedia","mediaAttributes","renderImage","commonImageProps","mediaContent","preload","style","displayName","HeroBanner","class_name","gradientEnabled","gradient_enabled","resolvedContentAlignment","resolvedGradientDepth","shouldRenderButton","HeroBanner_default","DOMPurify","SANITIZATION_CONFIG","ALLOWED_TAGS","ALLOWED_ATTR","sanitizeHtml","sanitize","KEEP_CONTENT","RETURN_DOM","RETURN_DOM_FRAGMENT","FORCE_BODY","SANITIZE_DOM","IN_PLACE","RichText","restProps","sanitizedHtml","fontColorBoolean","RichText_default"],"mappings":"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","sourcesContent":["import { ReactElement, useMemo } from 'react';\nimport styled from '@emotion/styled';\nimport { useToggleFontColor } from '../hooks';\nimport { getRegionAndLanguageFromLocation, RegionLanguageQuery, replaceRegionAndLanguage } from '../utils/route-utils';\n\ninterface CsTextProps {\n full_width?: boolean;\n container_background_color?: unknown;\n alignment?: 'left' | 'center' | 'right';\n text_editor: string;\n font_color?: boolean;\n $?: {\n text_editor?: Record<string, unknown>;\n };\n}\n\n// Get region + language once\nconst useRegionLanguage = () => {\n return useMemo(() => getRegionAndLanguageFromLocation(), []);\n};\n\n// Replace region and language in a single URL\nconst rewriteUrl = (url: string, replacer?: RegionLanguageQuery): string => {\n if (!replacer || !url) return url;\n return replaceRegionAndLanguage(url, replacer);\n};\n\n// Rewrite all <a> links inside CMS HTML\nexport const rewriteLinks = (html: string, replacer?: RegionLanguageQuery): string => {\n if (typeof window === 'undefined' || !html || !replacer) return html;\n\n const parser = new DOMParser();\n const doc = parser.parseFromString(html, 'text/html');\n\n doc.querySelectorAll('a').forEach((link) => {\n const href = link.getAttribute('href');\n if (!href) return;\n link.setAttribute('href', rewriteUrl(href, replacer));\n });\n\n return doc.body.innerHTML;\n};\n\n// Styled container for CMS text\nconst Container = styled.div<{\n fullWidth: boolean;\n bgColor: string;\n alignment: string;\n color: string;\n}>`\n width: ${({ fullWidth }) => (fullWidth ? '100%' : 'auto')};\n background-color: ${({ bgColor }) => bgColor};\n text-align: ${({ alignment }) => alignment};\n color: ${({ color }) => color};\n padding: 16px 32px;\n\n h1,\n h2,\n h3,\n h4,\n h5,\n h6 {\n font-family: 'Lora', serif;\n }\n\n h1 {\n font-size: 42px;\n line-height: 48px;\n }\n h2 {\n font-size: 36px;\n line-height: 42px;\n }\n h3 {\n font-size: 32px;\n line-height: 38px;\n }\n h4 {\n font-size: 26px;\n line-height: 34px;\n }\n h5 {\n font-size: 22px;\n line-height: 28px;\n }\n h6 {\n font-size: 18px;\n line-height: 24px;\n }\n\n p {\n margin: 0;\n padding: 0;\n }\n`;\n\n// Safely resolve CMS background color\nconst extractColorFromObject = (obj: any): string | null => {\n const color = obj?.brandColor?.colorObj?.light ?? obj?.color;\n return typeof color === 'string' && color.trim() ? color : null;\n};\n\nconst parseJsonColor = (jsonString: string): string | null => {\n try {\n const parsed = JSON.parse(jsonString);\n const color = parsed?.brandColor?.colorObj?.light;\n return typeof color === 'string' && color.trim() ? color : null;\n } catch {\n return null;\n }\n};\n\nconst resolveBackgroundColor = (value: unknown): string => {\n // null, undefined, false, 0, '' → transparent\n if (!value) return 'transparent';\n\n // CMS object\n if (typeof value === 'object') {\n const color = extractColorFromObject(value);\n return color ?? 'transparent';\n }\n\n // CMS string\n if (typeof value === 'string') {\n const trimmed = value.trim();\n if (!trimmed) return 'transparent';\n\n // JSON string\n if (trimmed.startsWith('{')) {\n const color = parseJsonColor(trimmed);\n return color ?? 'transparent';\n }\n\n // Normal CSS color\n return trimmed;\n }\n\n // numbers, booleans, etc\n return 'transparent';\n};\n\nconst CsText = ({\n full_width = false,\n container_background_color,\n alignment = 'left',\n text_editor,\n font_color = false,\n $\n}: CsTextProps): ReactElement | null => {\n const fontColor = useToggleFontColor(font_color);\n const regionLang = useRegionLanguage();\n\n const backgroundColor = useMemo(\n () => resolveBackgroundColor(container_background_color),\n [container_background_color],\n );\n\n const updatedHtml = useMemo(() => rewriteLinks(text_editor, regionLang), [text_editor, regionLang]);\n\n if (!text_editor) return null;\n\n return (\n <Container fullWidth={full_width} bgColor={backgroundColor} alignment={alignment} color={fontColor}>\n <div dangerouslySetInnerHTML={{ __html: updatedHtml }} {...$?.text_editor} />\n </Container>\n );\n};\n\nexport default CsText;\n","import { useMemo } from 'react';\nimport { getRegionAndLanguageFromLocation, replaceRegionAndLanguage, RegionLanguageQuery } from '../utils/route-utils';\n\n/**\n * Simply use this hook to update the region and language in the url\n * Note: urlToParse should have {%region} or {%language} or {%rREGION} or {%LANGUAGE}\n * @param urlToParse url to be parsed\n * @returns urlToParse after conditionally replacing the region and language\n */\nconst useRouteReplacer = (urlToParse?: string): { url?: string } => {\n const replacer: RegionLanguageQuery | undefined = useMemo(() => getRegionAndLanguageFromLocation(), []);\n\n const url = useMemo(() => {\n if (!urlToParse || !replacer) return undefined;\n return replaceRegionAndLanguage(urlToParse, replacer);\n }, [urlToParse, replacer]);\n\n return { url };\n};\n\nexport default useRouteReplacer;\n","const languageReplaceExpression = '{%language}';\nconst languageReplaceExpressionUppercase = '{%LANGUAGE}';\nconst regionReplaceExpression = '{%region}';\nconst regionReplaceExpressionUppercase = '{%REGION}';\n\nexport type RegionLanguageQuery = {\n region?: string;\n language?: string;\n slug?: string;\n};\n\n/**\n * Replace {%region}, {%language} placeholders in text\n */\nexport const replaceRegionAndLanguage = (text: string, replacer: RegionLanguageQuery = {}): string => {\n if (typeof text !== 'string') {\n return '';\n }\n\n if (replacer.region) {\n text = text.replace(regionReplaceExpression, replacer.region);\n text = text.replace(regionReplaceExpressionUppercase, replacer.region.toUpperCase());\n }\n\n if (replacer.language) {\n text = text.replace(languageReplaceExpression, replacer.language);\n text = text.replace(languageReplaceExpressionUppercase, replacer.language.toUpperCase());\n }\n\n return text;\n};\n\n/**\n * Replace dynamic pathname segments like [region], [language]\n */\nexport const replacePathnameWithQueryParams = (pathname: string, queryParams: RegionLanguageQuery): string => {\n if (!pathname || typeof pathname !== 'string') {\n return '';\n }\n\n let formattedUrl = pathname;\n\n if (queryParams.region) {\n formattedUrl = formattedUrl.replace('[region]', queryParams.region);\n }\n\n if (queryParams.language) {\n formattedUrl = formattedUrl.replace('[language]', queryParams.language);\n }\n\n if (queryParams.slug) {\n formattedUrl = formattedUrl.replace('[[...slug]]', queryParams.slug);\n }\n\n return formattedUrl;\n};\n\n/**\n * Extract region & language from a query object\n */\nexport const getRegionAndLanguageFromQuery = (\n query?: Record<string, string | string[] | undefined>,\n): RegionLanguageQuery | undefined => {\n if (!query) return undefined;\n\n const region = Array.isArray(query.region) ? query.region[0] : query.region;\n\n const language = Array.isArray(query.language) ? query.language[0] : query.language;\n\n if (region || language) {\n return { region, language };\n }\n\n return undefined;\n};\n\n/**\n * ✅ Next.js Router replacement\n * Reads from browser URL safely\n */\nconst DEFAULT_REGION = 'us';\nconst DEFAULT_LANGUAGE = 'en';\n\nfunction getRegionAndLanguageFromSearch(search?: string | null): RegionLanguageQuery | undefined {\n if (!search?.startsWith?.('?')) {\n return undefined;\n }\n\n const params = new URLSearchParams(search);\n const region = params.get('region');\n const language = params.get('language');\n\n if (!region && !language) {\n return undefined;\n }\n\n return {\n region: region ?? DEFAULT_REGION,\n language: language ?? DEFAULT_LANGUAGE\n };\n}\n\nfunction getRegionAndLanguageFromPath(pathname?: string | null): RegionLanguageQuery | undefined {\n if (!pathname) {\n return undefined;\n }\n\n const parts = pathname.split('/').filter(Boolean);\n if (parts.length < 2) {\n return undefined;\n }\n\n const [region, language] = parts;\n if (region?.length === 2 && language?.length === 2) {\n return { region, language };\n }\n\n return undefined;\n}\n\nexport const getRegionAndLanguageFromLocation = (): RegionLanguageQuery => {\n // ---------- SSR ----------\n if (typeof window === 'undefined' || !window.location) {\n return { region: DEFAULT_REGION, language: DEFAULT_LANGUAGE };\n }\n\n const { search, pathname } = window.location;\n\n // Try query params first, then path, then defaults\n return (\n getRegionAndLanguageFromSearch(search) ??\n getRegionAndLanguageFromPath(pathname) ?? {\n region: DEFAULT_REGION,\n language: DEFAULT_LANGUAGE\n }\n );\n};","import { useMemo } from 'react';\n\nimport { useTheme } from '@mui/material';\nimport { ColorUtils } from '@nuskin/foundation-theme';\n\nconst { getGenomeColor } = ColorUtils;\n\n/**\n * @returns {main:#FFFFFF, contrast:#252525} when passed true\n */\nconst useMainContrast = (toggleValue: boolean = false): { main: string; contrast: string } => {\n const theme = useTheme();\n\n return useMemo(() => {\n const main = getGenomeColor(theme, 'N10', toggleValue ? 'light' : 'dark');\n const contrast = getGenomeColor(theme, 'N10', toggleValue ? 'dark' : 'light');\n return { main, contrast };\n }, [toggleValue, theme]);\n};\n\nexport default useMainContrast;\n","import { useTheme } from '@mui/material';\nimport { ColorUtils } from '@nuskin/foundation-theme';\nimport { useMemo } from 'react';\n\nconst { getGenomeColor } = ColorUtils;\n/**\n * Used to fetch the appropriate theme color for primary and contrast.\n * Usually black or similar, and white for contrast.\n * @param toggleValue the CS toggle value between black and white font color.\n * @returns hex value of the color.\n */\nconst useToggleFontColor = (toggleValue: boolean = false): string => {\n const theme = useTheme();\n\n return useMemo(\n () => getGenomeColor(theme, 'N10', toggleValue ? 'light' : 'dark'),\n [toggleValue, theme]\n );\n};\n\nexport default useToggleFontColor;\n","import { NsImage } from '@nuskin/foundation-ui-components';\nimport { StyledCsImageWrapper } from './CsImage.styled';\nimport type { ContentstackAsset, CsImageProps, ImageFile, ImageFileMeta, NsImageProps } from './types';\n\n// Inline SVG data URL used as a safe placeholder when the main image is unavailable\nexport const PLACEHOLDER_IMAGE_SRC =\n 'data:image/svg+xml;utf8,' +\n encodeURIComponent(\n `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 400 300\" role=\"img\" aria-label=\"Image not available\">\n <defs>\n <linearGradient id=\"csImagePlaceholderGradient\" x1=\"0\" y1=\"0\" x2=\"1\" y2=\"1\">\n <stop offset=\"0%\" stop-color=\"#f3f4f6\" />\n <stop offset=\"100%\" stop-color=\"#e5e7eb\" />\n </linearGradient>\n </defs>\n <rect width=\"400\" height=\"300\" fill=\"url(#csImagePlaceholderGradient)\" />\n <g stroke=\"#d1d5db\" stroke-width=\"4\" stroke-linecap=\"round\" stroke-linejoin=\"round\" fill=\"none\">\n <rect x=\"60\" y=\"60\" width=\"280\" height=\"180\" rx=\"12\" />\n <path d=\"M120 200 L180 140 L230 185 L260 160 L320 210\" />\n <circle cx=\"160\" cy=\"120\" r=\"20\" />\n </g>\n </svg>`,\n );\n\nconst allowedImageProps: (keyof NsImageProps)[] = [\n 'alt',\n 'className',\n 'fill',\n 'height',\n 'id',\n 'src',\n 'variant',\n 'width'\n];\n\nconst CsImage = (props: CsImageProps) => {\n const { image_alignment: align = 'center', image, parent$, isEditing, $, ...rest } = props;\n\n let selectedImage: ImageFile | null = null;\n let fileMeta: Record<string, ImageFileMeta> | null = null;\n let contentstackAsset: ContentstackAsset | null = null;\n\n try {\n const parsed = typeof image === 'string' ? JSON.parse(image) : image;\n \n // Try Bynder format first: { image: [{ selected, files }] }\n const entry = parsed?.image?.[0];\n if (entry?.selected || entry?.files) {\n selectedImage = entry?.selected;\n fileMeta = entry?.files;\n } else if (parsed?.url) {\n // Fallback: Contentstack native asset format\n contentstackAsset = parsed;\n }\n } catch (err) {\n console.warn('[CsImage] Failed to parse image prop:', err);\n }\n\n let resolvedSrc = PLACEHOLDER_IMAGE_SRC;\n let resolvedAlt = 'Image not available';\n let resolvedWidth: number | string = '100%';\n let resolvedHeight: number | string = '100%';\n\n // Bynder format\n if (selectedImage || fileMeta) {\n const imageType = selectedImage?.imageType ?? 'transformBaseUrl';\n const fileSource = fileMeta?.[imageType];\n\n \n if (fileSource?.url) {\n resolvedSrc = fileSource.url;\n resolvedAlt = selectedImage?.altText ?? 'Image';\n resolvedWidth = selectedImage?.width ?? '100%';\n resolvedHeight = selectedImage?.height ?? '100%';\n }\n } \n // Contentstack asset fallback\n else if (contentstackAsset?.url) {\n resolvedSrc = contentstackAsset.url;\n resolvedAlt = contentstackAsset.title || contentstackAsset.filename || 'Image';\n // Contentstack assets don't provide width/height in metadata, keep defaults\n }\n\n const imageProps: NsImageProps = {\n src: resolvedSrc,\n alt: resolvedAlt,\n width: resolvedWidth,\n height: resolvedHeight\n };\n\n // Add any other valid props from rest\n allowedImageProps.forEach((key) => {\n if (rest[key] !== undefined) {\n (imageProps as Record<string, unknown>)[key] = rest[key];\n }\n });\n\n const containerClassForNSImage = rest?.full_width ? 'container !p-0' : '';\n\n return (\n <StyledCsImageWrapper\n image_alignment={align}\n width={imageProps.width}\n height={imageProps.height}\n className={containerClassForNSImage}\n >\n <NsImage {...imageProps} {...($?.image || {})} />\n </StyledCsImageWrapper>\n );\n};\n\nexport default CsImage;\n","import { styled } from '@nuskin/foundation-theme';\nimport type { CsImageProps } from './types';\n\nexport const StyledCsImageWrapper = styled('div')<\n Pick<CsImageProps, 'image_alignment'> & { width?: string | number; height?: string | number }\n>(({ image_alignment = 'center', width, height }) => ({\n display: 'flex',\n justifyContent: {\n left: 'flex-start',\n right: 'flex-end',\n center: 'center'\n }[image_alignment],\n '& img': {\n maxWidth: 'fit-content',\n objectFit: 'contain',\n objectPosition: 'center'\n }\n}));\n","/**\n * Default Configurations\n * Marketing Banner Component\n */\n\nexport const DEFAULT_BANNER_CONFIG = {\n position: 'left' as const,\n textColor: 'white' as const,\n showGradient: false,\n gradientDepth: 'md' as const,\n mediaType: 'image' as const,\n ctaVariant: 'dark' as const\n};\n\nexport const DEFAULT_CAROUSEL_CONFIG = {\n rotationInterval: 5000\n};\n\nexport const DEFAULT_ROTATION_INTERVAL = 5000;\n\nexport const PLACEHOLDER_VALUES = {\n header: 'Enter Header',\n title: 'Enter Title',\n subtitle: 'Enter Subtitle',\n body: 'Enter Body Text'\n} as const;\n","import styled from '@emotion/styled';\nimport type { TextAlignment } from '../types';\nimport { FONT_STACKS, FONT_SIZES, SPACING } from '../styles/theme';\nimport { responsiveFontSize, centerOnMobile } from '../styles/mixins';\n\nexport const TextContainer = styled.div<{\n textAlignment: TextAlignment;\n}>`\n text-align: ${({ textAlignment }) => textAlignment};\n ${centerOnMobile}\n`;\n\nexport const HeaderText = styled.p<{\n fontColor: string;\n}>`\n margin: ${SPACING.headerMargin};\n font-weight: 500;\n font-family: ${FONT_STACKS.inter};\n color: ${({ fontColor }) => fontColor};\n letter-spacing: 0.05em;\n ${responsiveFontSize(FONT_SIZES.header)}\n`;\n\nexport const Title = styled.h2<{\n fontColor: string;\n}>`\n margin: ${SPACING.titleMargin};\n font-weight: 700;\n font-family: ${FONT_STACKS.lora};\n color: ${({ fontColor }) => fontColor};\n ${responsiveFontSize(FONT_SIZES.title)}\n`;\n\nexport const Subtitle = styled.h3<{\n fontColor: string;\n}>`\n margin: ${SPACING.subtitleMargin};\n font-weight: 600;\n font-family: ${FONT_STACKS.inter};\n color: ${({ fontColor }) => fontColor};\n ${responsiveFontSize(FONT_SIZES.subtitle)}\n`;\n\nexport const BodyText = styled.p<{\n fontColor: string;\n}>`\n margin: ${SPACING.bodyMargin};\n line-height: 1.6;\n font-family: ${FONT_STACKS.inter};\n color: ${({ fontColor }) => fontColor};\n ${responsiveFontSize(FONT_SIZES.body)}\n`;\n","/**\n * Marketing Banner Theme Constants\n * Centralized design tokens for all components\n */\n\nexport const BREAKPOINTS = {\n mobile: 0,\n tablet: 768,\n desktop: 1024,\n wide: 1440\n} as const;\n\nexport const FONT_STACKS = {\n lora: \"'Lora', Georgia, 'Times New Roman', serif\",\n inter: \"'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif\"\n} as const;\n\nexport const FONT_SIZES = {\n header: {\n mobile: '12px',\n tablet: '14px',\n desktop: '14px',\n wide: '16px'\n },\n title: {\n mobile: '24px',\n tablet: '32px',\n desktop: '40px',\n wide: '48px'\n },\n subtitle: {\n mobile: '16px',\n tablet: '18px',\n desktop: '20px',\n wide: '22px'\n },\n body: {\n mobile: '14px',\n tablet: '16px',\n desktop: '18px',\n wide: '20px'\n },\n cta: {\n mobile: '18px',\n tablet: '22px',\n wide: '24px'\n }\n} as const;\n\nexport const SPACING = {\n // Text component spacing\n headerMargin: '0 0 0.25rem 0',\n titleMargin: '0 0 0.75rem 0',\n subtitleMargin: '0 0 0.5rem 0',\n bodyMargin: '0',\n\n // Layout spacing\n textGap: '1.5rem',\n desktopPadding: '3rem',\n mobilePadding: '2rem',\n carouselGap: '0.75rem',\n\n // CTA spacing\n ctaPaddingDesktop: '16px 32px',\n ctaPaddingTablet: '12px 28px',\n ctaPaddingWide: '18px 36px'\n} as const;\n\nexport const DIMENSIONS = {\n // Banner height\n bannerHeightDesktop: '600px',\n bannerHeightMobile: '400px',\n\n // Text container\n textMaxWidth: '600px',\n\n // Carousel indicators\n indicatorSize: '12px',\n indicatorBorder: '2px'\n} as const;\n\nexport const COLORS = {\n // Text colors\n textWhite: '#ffffff',\n textDark: '#1D1D1B',\n textGray: '#666',\n\n // CTA colors\n ctaDark: '#888888',\n ctaBorder: '#888888',\n\n // Media fallback\n fallbackBg: '#f0f0f0',\n\n // Indicator colors\n indicatorBorder: 'rgba(255, 255, 255, 0.9)',\n indicatorActive: 'rgba(255, 255, 255, 0.9)',\n indicatorInactive: 'transparent'\n} as const;\n\nexport const TEXT_COLOR_MAP = {\n white: COLORS.textWhite,\n dark: COLORS.textDark\n} as const;\n\nexport const TRANSITIONS = {\n fast: '0.1s ease',\n default: '0.3s ease',\n slow: '0.6s cubic-bezier(0.4, 0, 0.2, 1)'\n} as const;\n\nexport const Z_INDEX = {\n background: 0,\n media: 0,\n gradient: 1,\n content: 2,\n controls: 3\n} as const;\n\nexport const MEDIA_QUERIES = {\n tablet: `@media (min-width: ${BREAKPOINTS.tablet + 1}px) and (max-width: ${BREAKPOINTS.desktop - 1}px)`,\n desktop: `@media (min-width: ${BREAKPOINTS.desktop}px) and (max-width: ${BREAKPOINTS.wide - 1}px)`,\n wide: `@media (min-width: ${BREAKPOINTS.wide}px)`,\n mobileAndBelow: `@media (max-width: ${BREAKPOINTS.tablet}px)`,\n desktopAndUp: `@media (min-width: ${BREAKPOINTS.desktop}px)`\n} as const;\n","/**\n * Marketing Banner Styled Component Mixins\n * Reusable CSS patterns and helper functions\n */\n\nimport { css } from '@emotion/react';\nimport { MEDIA_QUERIES, TRANSITIONS } from './theme';\n\n/**\n * Responsive font sizing\n * Applies font-size at different breakpoints\n */\nexport const responsiveFontSize = (sizes: Record<string, string>) => css`\n font-size: ${sizes.mobile};\n\n ${MEDIA_QUERIES.tablet} {\n font-size: ${sizes.tablet || sizes.mobile};\n }\n ${MEDIA_QUERIES.desktop} {\n font-size: ${sizes.desktop || sizes.tablet || sizes.mobile};\n }\n ${MEDIA_QUERIES.wide} {\n font-size: ${sizes.wide || sizes.desktop || sizes.tablet || sizes.mobile};\n }\n`;\n\n/**\n * Center text on mobile, preserve positioning on desktop\n */\nexport const centerOnMobile = css`\n ${MEDIA_QUERIES.mobileAndBelow} {\n text-align: center;\n }\n`;\n\n/**\n * Smooth transitions for interactive elements\n */\nexport const smoothTransition = (\n properties: string[] = ['background-color', 'color', 'border-color', 'transform', 'text-decoration']\n) => css`\n transition: ${properties.map((prop) => `${prop} ${TRANSITIONS.default}`).join(', ')};\n`;\n\n/**\n * Focus outline styling for accessibility\n */\nexport const focusOutline = (color: string) => css`\n &:focus-visible {\n outline: 2px solid ${color};\n outline-offset: 4px;\n }\n`;\n\n/**\n * Absolute fill (cover parent completely)\n */\nexport const absoluteFill = css`\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n`;\n\n/**\n * Absolute positioning with dimensions\n */\nexport const absoluteFullSize = css`\n ${absoluteFill}\n width: 100%;\n height: 100%;\n`;\n\n/**\n * Center positioning (horizontal only)\n */\nexport const centerHorizontal = css`\n position: absolute;\n left: 50%;\n transform: translateX(-50%);\n`;\n\n/**\n * Flex center alignment\n */\nexport const flexCenter = css`\n display: flex;\n align-items: center;\n justify-content: center;\n`;\n\n/**\n * Removes all margins and padding\n */\nexport const resetSpacing = css`\n margin: 0;\n padding: 0;\n`;\n\n/**\n * CTA hover state with transform\n */\nexport const ctaHoverState = (backgroundColor: string, borderColor: string, textColor: string) => css`\n &:hover {\n background-color: ${backgroundColor};\n color: ${textColor};\n border-color: ${borderColor};\n text-decoration: underline;\n transform: translateY(-2px);\n }\n`;\n\n/**\n * Gradient overlay mixin\n */\nexport const gradientOverlay = (direction: string, startOpacity: number, endOpacity: number, baseColor: string) => css`\n background: linear-gradient(${direction}, rgba(${baseColor}, ${startOpacity}), rgba(${baseColor}, ${endOpacity}));\n`;\n\n/**\n * Radial gradient overlay mixin\n */\nexport const radialGradientOverlay = (startOpacity: number, endOpacity: number, baseColor: string) => css`\n background: radial-gradient(circle, rgba(${baseColor}, ${startOpacity}), rgba(${baseColor}, ${endOpacity}));\n`;\n","/**\n * BannerText Sub-Component\n * Renders text content (title, subtitle, bodyText) with responsive styling\n */\n\nimport React from 'react';\nimport type { BannerTextProps } from '../types';\nimport { PLACEHOLDER_VALUES } from '../constants';\nimport { TextContainer, HeaderText, Title, Subtitle, BodyText } from './BannerText.styled';\n\nfunction getDisplayText(text: string | undefined, placeholderValue: string, isEditing?: boolean): string | undefined {\n if (isEditing === true && (!text || text === placeholderValue)) {\n return placeholderValue;\n }\n if (isEditing === false && text === placeholderValue) {\n return undefined;\n }\n return text;\n}\n\nexport function BannerText({\n headerText,\n title,\n subtitle,\n bodyText,\n textColor = '#ffffff',\n textAlignment = 'left',\n testId,\n $,\n isEditing\n}: Readonly<BannerTextProps>): React.ReactElement | null {\n const header = getDisplayText(headerText, PLACEHOLDER_VALUES.header, isEditing);\n const titleDisplay = getDisplayText(title, PLACEHOLDER_VALUES.title, isEditing);\n const subtitleDisplay = getDisplayText(subtitle, PLACEHOLDER_VALUES.subtitle, isEditing);\n const body = getDisplayText(bodyText, PLACEHOLDER_VALUES.body, isEditing);\n\n if (!header && !titleDisplay && !subtitleDisplay && !body) {\n return null;\n }\n\n return (\n <TextContainer textAlignment={textAlignment} data-testid={testId}>\n {header && (\n <HeaderText fontColor={textColor} aria-label={header} {...($?.header_text ?? {})}>\n {header}\n </HeaderText>\n )}\n {titleDisplay && (\n <Title fontColor={textColor} aria-label={titleDisplay} {...($?.title ?? {})}>\n {titleDisplay}\n </Title>\n )}\n {subtitleDisplay && (\n <Subtitle fontColor={textColor} aria-label={subtitleDisplay} {...($?.subtitle ?? {})}>\n {subtitleDisplay}\n </Subtitle>\n )}\n {body && (\n <BodyText fontColor={textColor} aria-label={body} {...($?.body_text ?? {})}>\n {body}\n </BodyText>\n )}\n </TextContainer>\n );\n}\n","import React from 'react';\nimport { extractBynderMedia } from './utils';\nimport { MediaContainer, StyledImage, StyledVideo, PictureElement, SourceElement } from './BynderMedia.styled';\nimport type { BynderMediaProps } from './types';\n\nexport function BynderMedia({ bynder_media, $ }: Readonly<BynderMediaProps>): React.ReactElement | null {\n const [mediaInfo, setMediaInfo] = React.useState<ReturnType<typeof extractBynderMedia>>(null);\n const [hasError, setHasError] = React.useState(false);\n\n // Extract media data from bynder_media JSON string\n React.useEffect(() => {\n const extracted = extractBynderMedia(bynder_media);\n setMediaInfo(extracted);\n setHasError(!extracted);\n }, [bynder_media]);\n\n const handleMediaError = () => {\n setHasError(true);\n };\n\n if (!mediaInfo || hasError) {\n return null;\n }\n\n const mediaType = mediaInfo.type;\n const mediaAlt = mediaInfo.alt;\n const isResponsive = mediaInfo.isResponsive ?? false;\n const desktopUrl = mediaInfo.desktopUrl;\n const mobileUrl = mediaInfo.mobileUrl;\n const mediaUrl = mediaInfo.url;\n\n if (mediaType === 'video') {\n return (\n <MediaContainer {...($?.bynder_media ?? {})}>\n <StyledVideo\n src={mediaUrl}\n onError={handleMediaError}\n autoPlay\n muted\n loop\n playsInline\n {...($?.bynder_media ?? {})}\n />\n </MediaContainer>\n );\n }\n\n // Responsive image with picture element\n if (isResponsive && mobileUrl && desktopUrl) {\n return (\n <MediaContainer {...($?.bynder_media ?? {})}>\n <PictureElement>\n <SourceElement media=\"(max-width: 768px)\" srcSet={mobileUrl} />\n <SourceElement media=\"(min-width: 769px)\" srcSet={desktopUrl} />\n <StyledImage\n src={desktopUrl}\n alt={mediaAlt}\n onError={handleMediaError}\n loading=\"lazy\"\n {...($?.bynder_media ?? {})}\n />\n </PictureElement>\n </MediaContainer>\n );\n }\n\n // Standard image\n return (\n <MediaContainer {...($?.bynder_media ?? {})}>\n <StyledImage\n src={mediaUrl}\n alt={mediaAlt}\n onError={handleMediaError}\n loading=\"lazy\"\n {...($?.bynder_media ?? {})}\n />\n </MediaContainer>\n );\n}\n","import { BynderImageDataType, BynderMediaExtracted, BynderMediaType } from './types';\n\nexport function getMediaUrl(\n selected: BynderImageDataType['selected'],\n isPublic: boolean,\n previewUrls: BynderImageDataType['previewUrls']\n): string {\n const { url = '', type: fileType = '' } = selected ?? {};\n if (fileType === 'VIDEO') {\n if (isPublic) {\n return url;\n } else {\n return previewUrls?.[0] ?? '';\n }\n }\n return url;\n}\n\nfunction generateResponsiveUrl(baseUrl: string, aspectRatio: string): string {\n try {\n const url = new URL(baseUrl);\n const ioParam = url.searchParams.get('io');\n\n if (!ioParam) return baseUrl;\n\n const updatedIo = `${ioParam},aspectratio:${aspectRatio}`;\n\n const params: string[] = [];\n params.push(`io=${updatedIo}`);\n params.push('quality=95');\n\n url.searchParams.forEach((value, key) => {\n if (key !== 'io') {\n params.push(`${key}=${value}`);\n }\n });\n\n return `${url.origin}${url.pathname}?${params.join('&')}`;\n } catch (error) {\n console.warn('Failed to generate responsive URL:', error);\n return baseUrl;\n }\n}\n\nfunction addDefaultTransform(baseUrl: string): string {\n try {\n const url = new URL(baseUrl);\n if (!url.searchParams.has('io')) {\n return `${baseUrl}?io=transform:fill&quality=95`;\n }\n return baseUrl;\n } catch (error) {\n return baseUrl;\n }\n}\n\nexport function extractBynderMedia(mediaJson?: string): BynderMediaExtracted | null {\n if (!mediaJson) {\n return null;\n }\n try {\n const parsed = JSON.parse(mediaJson);\n const firstImage = parsed?.image?.[0];\n const selected = firstImage?.selected;\n\n const mediaUrl = getMediaUrl(selected, firstImage?.isPublic, firstImage?.previewUrls);\n\n let mediaType: BynderMediaType = 'image';\n if (selected?.type === 'VIDEO') {\n mediaType = 'video';\n } else if (selected?.type === 'IMAGE' && mediaUrl?.toLowerCase().endsWith('.gif')) {\n mediaType = 'gif';\n }\n\n const isResponsive = selected?.imageType === 'customTransformation';\n const result: BynderMediaExtracted = {\n url: mediaUrl,\n type: mediaType,\n alt: selected?.altText ?? ''\n };\n\n if (isResponsive && mediaType === 'image') {\n result.isResponsive = true;\n result.desktopUrl = generateResponsiveUrl(mediaUrl, '16x9');\n result.mobileUrl = generateResponsiveUrl(mediaUrl, '3x4');\n result.url = result.desktopUrl;\n } else if (mediaType === 'image') {\n result.url = addDefaultTransform(mediaUrl);\n }\n\n return result;\n } catch (error) {\n console.warn('Failed to parse bynder_media JSON:', error);\n return null;\n }\n}\n","import styled from '@emotion/styled';\n\nexport const MediaContainer = styled.div`\n width: 100%;\n height: 100%;\n overflow: hidden;\n display: block;\n`;\n\nexport const StyledImage = styled.img`\n width: 100%;\n height: 100%;\n object-fit: cover;\n display: block;\n`;\n\nexport const StyledVideo = styled.video`\n width: 100%;\n height: 100%;\n object-fit: cover;\n display: block;\n`;\n\nexport const PictureElement = styled.picture`\n width: 100%;\n height: 100%;\n display: block;\n`;\n\nexport const SourceElement = styled.source`\n display: block;\n`;\n","/**\n * useCarousel Hook\n * Manages carousel state and keyboard navigation\n */\n\nimport { useCallback, useEffect, useState, KeyboardEvent } from 'react';\nimport type { UseCarouselReturn } from '../types';\nimport { useReducedMotion } from './useReducedMotion';\n\ninterface UseCarouselOptions {\n totalSlides: number;\n autoRotate?: boolean;\n rotationInterval?: number;\n pauseOnHover?: boolean;\n initialIndex?: number;\n}\n\nexport function useCarousel(options: UseCarouselOptions): UseCarouselReturn {\n const { totalSlides, autoRotate = false, rotationInterval = 5000, pauseOnHover = true, initialIndex = 0 } = options;\n\n const [currentIndex, setCurrentIndex] = useState(initialIndex);\n const [isPaused, setIsPaused] = useState(false);\n const prefersReducedMotion = useReducedMotion();\n\n const goToNext = useCallback(() => {\n setCurrentIndex((prev) => (prev + 1) % totalSlides);\n }, [totalSlides]);\n\n const goToPrevious = useCallback(() => {\n setCurrentIndex((prev) => (prev - 1 + totalSlides) % totalSlides);\n }, [totalSlides]);\n\n const goToSlide = useCallback(\n (index: number) => {\n if (index >= 0 && index < totalSlides) {\n setCurrentIndex(index);\n }\n },\n [totalSlides]\n );\n\n const pause = useCallback(() => {\n setIsPaused(true);\n }, []);\n\n const resume = useCallback(() => {\n setIsPaused(false);\n }, []);\n\n const handleKeyDown = useCallback(\n (event: KeyboardEvent) => {\n switch (event.key) {\n case 'ArrowLeft':\n event.preventDefault();\n goToPrevious();\n break;\n case 'ArrowRight':\n event.preventDefault();\n goToNext();\n break;\n case 'Home':\n event.preventDefault();\n goToSlide(0);\n break;\n case 'End':\n event.preventDefault();\n goToSlide(totalSlides - 1);\n break;\n }\n },\n [goToNext, goToPrevious, goToSlide, totalSlides]\n );\n\n // Auto-rotation effect\n useEffect(() => {\n if (!autoRotate || isPaused || prefersReducedMotion) return;\n\n const intervalId = setInterval(goToNext, rotationInterval);\n return () => clearInterval(intervalId);\n }, [autoRotate, isPaused, prefersReducedMotion, rotationInterval, goToNext]);\n\n return {\n currentIndex,\n isPaused,\n totalSlides,\n goToNext,\n goToPrevious,\n goToSlide,\n pause,\n resume,\n handleKeyDown\n };\n}\n","/**\n * useReducedMotion Hook\n * Detects user's prefers-reduced-motion preference\n */\n\nimport { useEffect, useState } from 'react';\n\nexport function useReducedMotion(): boolean {\n const [prefersReducedMotion, setPrefersReducedMotion] = useState(false);\n\n useEffect(() => {\n // SSR-safe: Check if window is available\n if (typeof window === 'undefined' || !window.matchMedia) {\n return;\n }\n\n const mediaQuery = window.matchMedia('(prefers-reduced-motion: reduce)');\n setPrefersReducedMotion(mediaQuery.matches);\n\n const handleChange = (event: MediaQueryListEvent) => {\n setPrefersReducedMotion(event.matches);\n };\n\n mediaQuery.addEventListener('change', handleChange);\n return () => mediaQuery.removeEventListener('change', handleChange);\n }, []);\n\n return prefersReducedMotion;\n}\n","import { MarketingBannerProps, BannerData } from '../types';\n\nexport function hasCTA(banner: BannerData): boolean {\n return Boolean(banner?.cta_button?.label?.href);\n}\n\nexport function isCarouselMode(props: MarketingBannerProps): boolean {\n return Array.isArray(props?.banners) && props?.banners?.length > 1;\n}\n\nexport function hasMedia(banner: BannerData): boolean {\n return Boolean(banner?.bynder_media);\n}\n","import React from 'react';\nimport { NsIcon, NsIconVariants } from '@nuskin/foundation-ui-components';\nimport { ButtonContainer, StyledButton, StyledLabelText, StyledIconWrapper } from './Button.styled';\nimport {\n getButtonWidth,\n getIconSize,\n isValidDestination,\n resolveDisabled,\n resolveIconName,\n resolveTarget,\n variantDefaults,\n REL_NOOPENER_NOREFERRER,\n DEFAULT_VARIANT,\n DEFAULT_SIZE,\n DEFAULT_ALIGNMENT,\n DEFAULT_ICON_POSITION,\n DEFAULT_BUTTON_TYPE,\n DEFAULT_PLACEHOLDER_TEXT,\n DEFAULT_TARGET,\n BUTTON_TYPE_ROUNDED,\n BUTTON_TYPE_SQUARE,\n BORDER_COLOR_TRANSPARENT\n} from './helpers';\nimport { ButtonProps, ButtonType } from './types';\n\nconst Button: React.FC<ButtonProps> = ({\n label,\n open_in_new_tab: target = DEFAULT_TARGET,\n variant,\n button_size: size,\n alignment,\n buttontype: buttonType = DEFAULT_BUTTON_TYPE,\n icon,\n iconposition: iconPosition,\n button_state: disabled,\n placeholder_text: placeholderText = DEFAULT_PLACEHOLDER_TEXT,\n isEditing,\n $,\n parent$\n}) => {\n const resolvedVariant = variant ?? DEFAULT_VARIANT;\n const resolvedSize = size ?? DEFAULT_SIZE;\n const resolvedAlignment = alignment ?? DEFAULT_ALIGNMENT;\n const resolvedIconPosition = iconPosition ?? DEFAULT_ICON_POSITION;\n\n const resolvedButtonType: ButtonType =\n buttonType === BUTTON_TYPE_ROUNDED ? BUTTON_TYPE_ROUNDED : BUTTON_TYPE_SQUARE;\n\n const resolvedUrl = label?.href?.trim() ?? undefined;\n const hrefProp = isValidDestination(resolvedUrl) ? resolvedUrl : undefined;\n\n const variantDefault =\n variantDefaults[resolvedVariant as keyof typeof variantDefaults] ?? variantDefaults[DEFAULT_VARIANT];\n const buttonWidth = getButtonWidth(resolvedSize);\n const resolvedTarget = resolveTarget(target);\n const resolvedDisabled = resolveDisabled(disabled);\n const buttonBorder = ('border' in variantDefault ? variantDefault.border : undefined) ?? BORDER_COLOR_TRANSPARENT;\n\n const IconName = resolveIconName(icon);\n const isValidNsIcon = typeof IconName === 'string' && IconName in NsIconVariants;\n const iconSize = getIconSize(resolvedSize);\n\n const renderIcon = (position: 'left' | 'right') => {\n if (!IconName || !isValidNsIcon || resolvedIconPosition !== position) return null;\n\n const iconColor = resolvedDisabled ? variantDefault.disabledText : variantDefault.text;\n\n return (\n <StyledIconWrapper position={position}>\n <NsIcon name={IconName} size={iconSize} colorOverride={iconColor} {...($?.icon ?? {})} />\n </StyledIconWrapper>\n );\n };\n\n const getLabelText = () => {\n let labelTitle = label?.title;\n\n if (labelTitle === '') {\n return placeholderText;\n }\n if (!isEditing && labelTitle !== placeholderText) {\n return labelTitle;\n }\n return labelTitle;\n };\n\n return (\n <ButtonContainer alignment={resolvedAlignment}>\n <StyledButton\n $variant={resolvedVariant}\n $buttonWidth={buttonWidth}\n $buttonType={resolvedButtonType}\n $bg={variantDefault.bg}\n $hover={variantDefault.hover}\n $pressed={variantDefault.pressed}\n $text={variantDefault.text}\n $border={buttonBorder}\n $disabledBg={variantDefault.disabledBg}\n $disabledText={variantDefault.disabledText}\n $focusRing={variantDefault.focusRing}\n href={hrefProp}\n data-variant={resolvedVariant}\n {...(resolvedTarget === '_blank' ? { target: '_blank', rel: REL_NOOPENER_NOREFERRER } : {})}\n aria-disabled={resolvedDisabled}\n disabled={resolvedDisabled}\n {...(parent$ ?? {})}\n >\n {renderIcon('left')}\n <StyledLabelText {...(label?.$?.title ?? {})}>{getLabelText()}</StyledLabelText>\n {renderIcon('right')}\n </StyledButton>\n </ButtonContainer>\n );\n};\n\nexport default Button;\n","import React from 'react';\nimport { NsButton } from '@nuskin/foundation-ui-components';\nimport { styled } from '@nuskin/foundation-theme';\nimport type { ButtonAlignment, ButtonVariant } from './types';\nimport { ROUNDED_BORDER_RADIUS, ICON_MARGIN, BUTTON_TYPE_ROUNDED } from './helpers';\n\nconst BUTTON_GAP = '2px';\nconst BUTTON_MIN_WIDTH = '70px';\nconst BUTTON_MIN_HEIGHT = '30px';\nconst DESKTOP_BREAKPOINT = '769px';\nconst TABLET_BREAKPOINT = '768px';\nconst MOBILE_BREAKPOINT = '425px';\nconst DESKTOP_FONT_SIZE = '13px';\nconst TABLET_FONT_SIZE = '12px';\nconst MOBILE_FONT_SIZE = '10px';\nconst DESKTOP_PADDING = '10px 6px';\nconst TABLET_PADDING = '8px 6px';\nconst MOBILE_PADDING = '4px 8px';\nconst DESKTOP_FONT_WEIGHT = 500;\nconst TABLET_MOBILE_FONT_WEIGHT = 400;\nconst FOCUS_OUTLINE_WIDTH = '2px';\nconst FONT_FAMILY_LORA = 'Lora, sans-serif';\nconst BORDER_COLOR_TRANSPARENT = 'transparent';\nconst JUSTIFY_CONTENT_CENTER = 'center';\nconst JUSTIFY_CONTENT_FLEX_END = 'flex-end';\nconst JUSTIFY_CONTENT_FLEX_START = 'flex-start';\n\nconst getJustifyContent = (alignment: ButtonAlignment): string => {\n if (alignment === 'center') return JUSTIFY_CONTENT_CENTER;\n if (alignment === 'right') return JUSTIFY_CONTENT_FLEX_END;\n return JUSTIFY_CONTENT_FLEX_START;\n};\n\nexport const ButtonContainer = styled('div')<{ alignment: ButtonAlignment }>`\n display: flex;\n justify-content: ${props => getJustifyContent(props.alignment)};\n width: 100%;\n`;\n\ninterface StyledButtonProps {\n $variant: ButtonVariant;\n $buttonWidth: string;\n $buttonType: 'square' | 'rounded';\n $bg: string;\n $hover: string;\n $pressed: string;\n $text: string;\n $border: string;\n $disabledBg: string;\n $disabledText: string;\n $focusRing: string;\n href?: string;\n}\n\nexport const StyledButton = styled(NsButton)<StyledButtonProps>`\n --btn-bg: ${props => props.$bg};\n --btn-hover: ${props => props.$hover};\n --btn-pressed: ${props => props.$pressed};\n --btn-color: ${props => props.$text};\n --btn-border: ${props => props.$border};\n --btn-disabled-bg: ${props => props.$disabledBg};\n --btn-disabled-color: ${props => props.$disabledText};\n --btn-focus: ${props => props.$focusRing};\n \n &&&:link:not(:disabled):not([aria-disabled='true']),\n &&&:visited:not(:disabled):not([aria-disabled='true']) {\n color: var(--btn-color);\n text-decoration: none;\n }\n\n && {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: ${BUTTON_GAP};\n text-decoration: none;\n background: var(--btn-bg);\n color: var(--btn-color);\n border: 1px solid var(--btn-border);\n font-family: ${FONT_FAMILY_LORA};\n min-width: ${BUTTON_MIN_WIDTH};\n min-height: ${BUTTON_MIN_HEIGHT};\n white-space: normal;\n overflow: hidden;\n box-sizing: border-box;\n width: ${props => props.$buttonWidth};\n ${props => props.$buttonType === BUTTON_TYPE_ROUNDED && `border-radius: ${ROUNDED_BORDER_RADIUS};`}\n }\n\n @media (min-width: ${DESKTOP_BREAKPOINT}) {\n && {\n font-size: ${DESKTOP_FONT_SIZE};\n padding: ${DESKTOP_PADDING};\n font-weight: ${DESKTOP_FONT_WEIGHT};\n }\n }\n \n @media (max-width: ${TABLET_BREAKPOINT}) {\n && {\n font-size: ${TABLET_FONT_SIZE};\n padding: ${TABLET_PADDING};\n font-weight: ${TABLET_MOBILE_FONT_WEIGHT};\n }\n }\n\n @media (max-width: ${MOBILE_BREAKPOINT}) {\n && {\n font-size: ${MOBILE_FONT_SIZE};\n padding: ${MOBILE_PADDING};\n font-weight: ${TABLET_MOBILE_FONT_WEIGHT};\n }\n }\n \n &&:hover {\n background: var(--btn-hover);\n }\n \n &&:active {\n background: var(--btn-pressed);\n }\n\n &&:focus {\n border: 1px solid var(--btn-border);\n }\n\n &&:not(:disabled):hover {\n background: var(--btn-hover);\n border-color: var(--btn-border);\n }\n\n &&:not(:disabled):active {\n background: var(--btn-pressed);\n border-color: var(--btn-border);\n }\n \n &&:focus-visible {\n outline: ${FOCUS_OUTLINE_WIDTH} solid var(--btn-focus);\n background: var(--btn-pressed);\n border: 1px solid ${BORDER_COLOR_TRANSPARENT};\n }\n \n &&:disabled:focus-visible {\n box-shadow: none;\n }\n\n &&[aria-disabled='true'],\n &&:disabled {\n pointer-events: none;\n cursor: not-allowed;\n background: var(--btn-disabled-bg);\n color: var(--btn-disabled-color);\n border-color: var(--btn-border);\n box-shadow: none;\n }\n\n &&&&:link[aria-disabled='true'],\n &&&&:link:disabled,\n &&&&:visited[aria-disabled='true'],\n &&&&:visited:disabled {\n color: var(--btn-disabled-color);\n text-decoration: none;\n }\n \n &&[data-variant='secondary'][aria-disabled='true'],\n &&[data-variant='secondary']:disabled {\n border-color: var(--btn-border);\n }\n`;\n\nexport const StyledLabelText = styled.span`\n word-wrap: break-word;\n overflow-wrap: break-word;\n min-width: 0;\n`;\n\ninterface StyledIconWrapperProps {\n position: 'left' | 'right';\n}\n\nconst ICON_MARGIN_PX = `${ICON_MARGIN}px`;\n\nexport const StyledIconWrapper = styled.span<StyledIconWrapperProps>`\n flex-shrink: 0;\n ${props => props.position === 'left' && `margin-right: ${ICON_MARGIN_PX};`}\n ${props => props.position === 'right' && `margin-left: ${ICON_MARGIN_PX};`}\n`;\n","import type { ButtonSize, LinkTarget } from './types';\n\nexport const ROUNDED_BORDER_RADIUS = '25px';\nexport const ICON_MARGIN = 2;\nexport const FLEX_SHRINK_ZERO = 0;\nexport const REL_NOOPENER_NOREFERRER = 'noopener noreferrer';\nexport const CSS_WORD_BREAK = 'break-word';\nexport const PROTOCOL_HTTP = 'http:';\nexport const PROTOCOL_HTTPS = 'https:';\nexport const DISABLED_STATE_STRING = 'disabled';\nexport const DEFAULT_VARIANT = 'primary';\nexport const DEFAULT_SIZE = 'small';\nexport const DEFAULT_ALIGNMENT = 'left';\nexport const DEFAULT_ICON_POSITION = 'left';\nexport const DEFAULT_BUTTON_TYPE = 'square';\nexport const DEFAULT_PLACEHOLDER_TEXT = 'Enter Label';\nexport const DEFAULT_TARGET = 'No';\nexport const BUTTON_TYPE_ROUNDED = 'rounded';\nexport const BUTTON_TYPE_SQUARE = 'square';\nexport const BORDER_COLOR_TRANSPARENT = 'transparent';\n\nexport function isValidDestination(dest?: string): boolean {\n if (!dest || dest.trim() === '') return false;\n \n const trimmed = dest.trim();\n \n if (trimmed.startsWith('#')) return true;\n if (trimmed.startsWith('/')) return true;\n if (trimmed.startsWith('//')) return true;\n \n try {\n const url = new URL(trimmed);\n return url.protocol === PROTOCOL_HTTP || url.protocol === PROTOCOL_HTTPS;\n } catch {\n return false;\n }\n}\n\nexport function resolveTarget(target?: 'Yes' | 'No' | null): LinkTarget | undefined {\n if (target === 'Yes') {\n return '_blank';\n }\n return '_self';\n}\n\nexport function resolveDisabled(disabled?: boolean | string | null): boolean {\n if (disabled == null) {\n return false;\n }\n if (typeof disabled === 'string') {\n return disabled === DISABLED_STATE_STRING;\n }\n return disabled;\n}\n\nconst iconAliasMap: Record<string, string> = {\n arrow: 'arrowRight'\n};\n\nexport function resolveIconName(iconName?: string): string | undefined {\n if (!iconName) return undefined;\n return iconAliasMap[iconName] ?? iconName;\n}\n\nexport const variantDefaults = {\n primary: {\n bg: '#1f1f1f',\n hover: '#3a3530',\n pressed: '#000000',\n text: '#ffffff',\n disabledBg: '#e6e6e6',\n disabledText: '#9e9e9e',\n focusRing: '#4f84b4'\n },\n secondary: {\n bg: '#ffffff',\n hover: '#f2f2f2',\n pressed: '#e6e6e6',\n text: '#000000',\n border: '#626262',\n disabledBg: '#f2f2f2',\n disabledText: '#b0b0b0',\n focusRing: '#4f84b4'\n }\n} as const;\n\nconst widthBySize: Record<ButtonSize, string> = {\n large: '400px',\n medium: '250px',\n small: '130px'\n};\n\nconst DEFAULT_BUTTON_WIDTH = '130px';\n\nexport function getButtonWidth(size: string): string {\n return widthBySize[size] ?? DEFAULT_BUTTON_WIDTH;\n}\n\nconst iconSizeByButtonSize: Record<ButtonSize, ButtonSize> = {\n small: 'small',\n medium: 'medium',\n large: 'medium'\n};\n\nconst DEFAULT_ICON_SIZE: ButtonSize = 'medium';\n\nexport function getIconSize(size: string): ButtonSize {\n return iconSizeByButtonSize[size] ?? DEFAULT_ICON_SIZE;\n}\n","/**\n * MarketingBanner Styled Components\n * All styling for the Marketing Banner component\n */\n\nimport styled from '@emotion/styled';\nimport type { GradientDirection, GradientDepth } from './types';\nimport { DIMENSIONS, SPACING, COLORS, Z_INDEX, TRANSITIONS, MEDIA_QUERIES } from './styles/theme';\nimport {\n absoluteFill,\n centerHorizontal,\n gradientOverlay,\n radialGradientOverlay,\n smoothTransition\n} from './styles/mixins';\n\nexport const BannerContainer = styled.div`\n position: relative;\n width: 100%;\n overflow: hidden;\n`;\n\nexport const CarouselWrapper = styled.div`\n position: relative;\n width: 100%;\n`;\n\nexport const CarouselTrack = styled.div<{ currentIndex: number; totalSlides: number }>`\n display: flex;\n transition: transform ${TRANSITIONS.slow};\n transform: translateX(-${({ currentIndex }) => currentIndex * 100}%);\n`;\n\nexport const BannerSlide = styled.div`\n min-width: 100%;\n position: relative;\n`;\n\nexport const BannerContent = styled.div<{ hasMedia: boolean }>`\n position: relative;\n min-height: ${({ hasMedia }) => (hasMedia ? DIMENSIONS.bannerHeightDesktop : 'auto')};\n display: flex;\n align-items: center;\n justify-content: flex-start;\n\n ${MEDIA_QUERIES.mobileAndBelow} {\n min-height: ${({ hasMedia }) => (hasMedia ? DIMENSIONS.bannerHeightMobile : 'auto')};\n }\n`;\n\nexport const MediaWrapper = styled.div`\n ${absoluteFill}\n z-index: ${Z_INDEX.media};\n`;\n\nexport const TextContentWrapper = styled.div<{\n position?: 'left' | 'center' | 'right';\n}>`\n position: relative;\n z-index: ${Z_INDEX.content};\n display: flex;\n flex-direction: column;\n gap: ${SPACING.textGap};\n justify-content: center;\n padding: ${SPACING.desktopPadding};\n max-width: ${DIMENSIONS.textMaxWidth};\n width: auto;\n\n /* Base positioning from props (applies to desktop/tablet) */\n ${({ position = 'left' }) => {\n if (position === 'center') {\n return `\n margin: 0 auto;\n align-items: center;\n text-align: center;\n `;\n }\n if (position === 'right') {\n return `\n margin-left: auto;\n margin-right: 0;\n align-items: flex-end;\n text-align: right;\n `;\n }\n return `\n margin-right: auto;\n align-items: flex-start;\n text-align: left;\n `;\n }}\n\n /* Mobile: Override to always center content */\n ${MEDIA_QUERIES.mobileAndBelow} {\n padding: ${SPACING.mobilePadding};\n max-width: 100%;\n margin: 0 auto;\n align-items: center;\n text-align: center;\n }\n`;\n\nexport const GradientOverlay = styled.div<{\n direction: GradientDirection;\n depth: GradientDepth;\n color: 'black' | 'white';\n}>`\n ${absoluteFill}\n z-index: ${Z_INDEX.gradient};\n pointer-events: none;\n\n /* Base gradient from props (applies to desktop/tablet) */\n ${({ direction, depth, color }) => {\n const opacities = {\n sm: { start: 0.3, end: 0 },\n md: { start: 0.6, end: 0 },\n lg: { start: 0.9, end: 0 }\n };\n const { start, end } = opacities[depth];\n const baseColor = color === 'black' ? '0, 0, 0' : '255, 255, 255';\n\n if (direction === 'leftToRight') {\n return gradientOverlay('to right', start, end, baseColor);\n }\n if (direction === 'rightToLeft') {\n return gradientOverlay('to left', start, end, baseColor);\n }\n if (direction === 'radial') {\n return radialGradientOverlay(start, end, baseColor);\n }\n return '';\n }}\n\n /* Mobile: Override to always use radial gradient */\n ${MEDIA_QUERIES.mobileAndBelow} {\n ${({ depth, color }) => {\n const opacities = {\n sm: { start: 0.3, end: 0 },\n md: { start: 0.6, end: 0 },\n lg: { start: 0.9, end: 0 }\n };\n const { start, end } = opacities[depth];\n const baseColor = color === 'black' ? '0, 0, 0' : '255, 255, 255';\n return radialGradientOverlay(start, end, baseColor);\n }}\n }\n`;\n\nexport const ButtonWrapper = styled.div`\n /* Mobile: Always center the button */\n display: flex;\n justify-content: center;\n\n /* Desktop: Follow parent alignment from TextContentWrapper */\n ${MEDIA_QUERIES.tablet} {\n justify-content: inherit;\n }\n\n ${MEDIA_QUERIES.desktop} {\n justify-content: inherit;\n }\n`;\n\nexport const CarouselControls = styled.div`\n position: absolute;\n bottom: ${SPACING.carouselGap};\n ${centerHorizontal}\n z-index: ${Z_INDEX.controls};\n display: flex;\n gap: ${SPACING.carouselGap};\n align-items: center;\n\n ${MEDIA_QUERIES.mobileAndBelow} {\n bottom: 1.5rem;\n }\n`;\n\nexport const Indicator = styled.button<{ active: boolean }>`\n width: ${DIMENSIONS.indicatorSize};\n height: ${DIMENSIONS.indicatorSize};\n border-radius: 50%;\n border: ${DIMENSIONS.indicatorBorder} solid ${COLORS.indicatorBorder};\n background-color: ${({ active }) => (active ? COLORS.indicatorActive : COLORS.indicatorInactive)};\n cursor: pointer;\n padding: 0;\n ${smoothTransition(['all'])}\n\n &:hover {\n background-color: ${COLORS.indicatorActive};\n transform: scale(1.15);\n }\n`;\n","/**\n * MarketingBanner Component\n * Main component with single banner and automatic carousel mode\n */\n\nimport React from 'react';\nimport { BannerText } from './components';\nimport { BynderMedia } from '../bynder-media';\nimport { useCarousel } from './hooks';\nimport { hasCTA, hasMedia, isCarouselMode } from './utils/utils';\nimport type { MarketingBannerProps, BannerData } from './types';\nimport { TEXT_COLOR_MAP } from './styles/theme';\nimport { Button } from '../button';\nimport {\n BannerContainer,\n CarouselWrapper,\n CarouselTrack,\n BannerSlide,\n BannerContent,\n MediaWrapper,\n TextContentWrapper,\n GradientOverlay,\n ButtonWrapper,\n CarouselControls,\n Indicator\n} from './MarketingBanner.styled';\n\nconst renderBanner = (banner: BannerData, isEditing: boolean, index: number) => {\n const showMedia = hasMedia(banner);\n const showCTA = hasCTA(banner);\n\n const baseTestId = 'marketing-banner';\n const resolvedTextColor = TEXT_COLOR_MAP[banner.text_color ?? 'white'];\n\n const showGradient = banner.gradient?.show_gradient === true;\n const position = banner.content_position ?? banner.position ?? 'left';\n\n // Derive gradient color from text color (inverse)\n const gradientColor = banner.text_color === 'dark' ? 'white' : 'black';\n\n // Derive gradient direction from position\n let gradientDirection: 'leftToRight' | 'rightToLeft' | 'radial';\n if (position === 'left') {\n gradientDirection = 'leftToRight';\n } else if (position === 'right') {\n gradientDirection = 'rightToLeft';\n } else {\n gradientDirection = 'radial';\n }\n\n // Determine text alignment based on position\n let textAlignment: 'left' | 'center' | 'right';\n if (position === 'center') {\n textAlignment = 'center';\n } else if (position === 'right') {\n textAlignment = 'right';\n } else {\n textAlignment = 'left';\n }\n\n const gradientDepth = banner.gradient?.gradient_depth ?? 'md';\n\n return (\n <BannerSlide key={`${baseTestId}-${index}`}>\n <BannerContent hasMedia={showMedia}>\n {showMedia && (\n <MediaWrapper>\n <BynderMedia {...banner} />\n </MediaWrapper>\n )}\n\n {showGradient && (\n <GradientOverlay direction={gradientDirection} depth={gradientDepth} color={gradientColor} />\n )}\n\n <TextContentWrapper position={position}>\n <BannerText\n headerText={banner.header_text}\n title={banner.title}\n subtitle={banner.subtitle}\n bodyText={banner.body_text}\n textColor={resolvedTextColor}\n textAlignment={textAlignment}\n testId={`${baseTestId}-${index}-text`}\n $={banner.$}\n isEditing={isEditing}\n />\n\n {showCTA && banner?.cta_button && (\n <ButtonWrapper>\n <Button\n {...banner?.cta_button}\n alignment={textAlignment}\n parent$={banner?.$?.cta_button}\n isEditing={isEditing}\n />\n </ButtonWrapper>\n )}\n </TextContentWrapper>\n </BannerContent>\n </BannerSlide>\n );\n};\n\nexport default function MarketingBannerComponent(props: Readonly<MarketingBannerProps>): React.ReactElement {\n const { banners, rotation_interval, isEditing = false } = props;\n\n const isCarousel = isCarouselMode(props);\n\n const carousel = useCarousel({\n totalSlides: banners.length,\n autoRotate: isCarousel,\n rotationInterval: rotation_interval ?? 5000,\n pauseOnHover: true,\n initialIndex: 0\n });\n\n return (\n <BannerContainer\n data-testid={'marketing-banner'}\n onKeyDown={isCarousel ? carousel.handleKeyDown : undefined}\n onMouseEnter={isCarousel ? carousel.pause : undefined}\n onMouseLeave={isCarousel ? carousel.resume : undefined}\n >\n <CarouselWrapper>\n <CarouselTrack currentIndex={carousel.currentIndex} totalSlides={banners.length}>\n {banners.map((banner, index) => renderBanner(banner, isEditing, index))}\n </CarouselTrack>\n </CarouselWrapper>\n\n {isCarousel && (\n <CarouselControls>\n {banners.map((banner, index) => (\n <Indicator\n key={`${'banner'}-indicator-${index}-${banner.title ?? ''}`}\n active={index === carousel.currentIndex}\n onClick={() => carousel.goToSlide(index)}\n aria-label={`Go to slide ${index + 1}`}\n />\n ))}\n </CarouselControls>\n )}\n </BannerContainer>\n );\n}\n","import { styled } from '@nuskin/foundation-theme';\nimport type { StyledSpacingProps, StyledDividerProps } from './types';\nimport { BREAKPOINTS } from './types';\n\nexport const StyledSpacingContainer = styled('div')<StyledSpacingProps>(\n ({ vertical_padding, divider_alignment }) => {\n const verticalScaleMap = {\n none: { mobile: 0, tablet: 0, desktop: 0, ultra: 0 },\n small: { mobile: 8, tablet: 8, desktop: 8, ultra: 12 },\n medium: { mobile: 12, tablet: 12, desktop: 16, ultra: 20 },\n large: { mobile: 16, tablet: 16, desktop: 24, ultra: 32 }\n } as const;\n\n\n const v = verticalScaleMap[vertical_padding];\n\n return {\n display: 'flex',\n flexDirection: 'column',\n alignItems: divider_alignment === 'center' ? 'center' : divider_alignment === 'right' ? 'flex-end' : 'flex-start',\n\n paddingTop: `${v.mobile}px`,\n paddingBottom: `${v.mobile}px`,\n\n [`@media ${BREAKPOINTS.tablet}`]: {\n paddingTop: `${v.tablet}px`,\n paddingBottom: `${v.tablet}px`\n },\n\n [`@media ${BREAKPOINTS.desktop}`]: {\n paddingTop: `${v.desktop}px`,\n paddingBottom: `${v.desktop}px`\n },\n\n [`@media ${BREAKPOINTS.ultra}`]: {\n paddingTop: `${v.ultra}px`,\n paddingBottom: `${v.ultra}px`\n }\n };\n }\n);\n\nexport const StyledDividerLine = styled('div')<StyledDividerProps>(\n ({ divider_style, divider_thickness_px, divider_color, divider_gradient, divider_width_percent }) => {\n const base: Record<string, any> = {\n width: `${Math.max(0, Math.min(100, divider_width_percent))}%`\n };\n \n if (divider_gradient && divider_style !== 'none') {\n base.height = `${divider_thickness_px}px`;\n base.backgroundImage = divider_gradient;\n base.backgroundSize = '100% 100%';\n \n if (divider_style === 'dashed') {\n const dashLength = Math.max(12, divider_thickness_px * 4);\n const gapLength = Math.max(6, divider_thickness_px * 2);\n base.maskImage = `repeating-linear-gradient(90deg, black 0px, black ${dashLength}px, ` +\n `transparent ${dashLength}px, transparent ${dashLength + gapLength}px)`;\n base.WebkitMaskImage = `repeating-linear-gradient(90deg, black 0px, black ${dashLength}px, ` +\n `transparent ${dashLength}px, transparent ${dashLength + gapLength}px)`;\n } else if (divider_style === 'dotted') {\n const dotSize = Math.max(2, divider_thickness_px);\n const spacing = Math.max(8, dotSize * 3);\n const radius = dotSize / 2;\n \n base.maskImage = `radial-gradient(circle ${radius}px at 50% 50%, ` +\n `black 99%, transparent 100%)`;\n base.WebkitMaskImage = `radial-gradient(circle ${radius}px at 50% 50%, ` +\n `black 99%, transparent 100%)`;\n base.maskSize = `${spacing}px ${divider_thickness_px}px`;\n base.WebkitMaskSize = `${spacing}px ${divider_thickness_px}px`;\n base.maskRepeat = 'repeat-x';\n base.WebkitMaskRepeat = 'repeat-x';\n base.maskPosition = '0 center';\n base.WebkitMaskPosition = '0 center';\n }\n } else if (divider_style === 'none') {\n base.height = `${divider_thickness_px}px`;\n base.backgroundImage = divider_gradient;\n } else {\n base.borderBottomStyle = divider_style;\n base.borderBottomWidth = `${divider_thickness_px}px`;\n base.borderBottomColor = divider_color;\n base.height = 0;\n }\n \n return base;\n }\n)\n","export type PaddingScale = 'none' | 'small' | 'medium' | 'large';\nexport type DividerStyle = 'solid' | 'dashed' | 'dotted' | 'none';\nexport type DividerThickness = 'thin' | 'medium' | 'thick';\nexport type BreakpointName = 'mobile' | 'tablet' | 'desktop' | 'ultra';\n\nexport interface SpacingDividerProps {\n vertical_padding?: PaddingScale;\n divider_style?: DividerStyle;\n divider_thickness?: DividerThickness;\n divider_color?: string;\n divider_gradient_preset?: 'none' | 'soft' | 'bold' | 'faint';\n divider_width_percent?: number;\n divider_alignment?: 'left' | 'center' | 'right';\n}\n\nexport interface StyledSpacingProps {\n vertical_padding: PaddingScale;\n divider_alignment: 'left' | 'center' | 'right';\n}\n\nexport interface StyledDividerProps {\n divider_style: DividerStyle;\n divider_thickness_px: number;\n divider_color: string;\n divider_gradient?: string;\n divider_width_percent: number;\n}\n\nexport const THICKNESS_PX: Record<DividerThickness, number> = {\n thin: 1,\n medium: 2,\n thick: 4\n};\n\nexport const BREAKPOINTS: Record<BreakpointName, string> = {\n mobile: '(max-width: 768px)',\n tablet: '(min-width: 769px) and (max-width: 1024px)',\n desktop: '(min-width: 1025px) and (max-width: 1439px)',\n ultra: '(min-width: 1440px)'\n};\n","/**\n * Validates if a string is a valid hex color\n * @param value - The string to validate\n * @returns true if valid hex color, false otherwise\n */\nexport const isValidHex = (value?: string): boolean => {\n if (!value) return false;\n return /^#([A-Fa-f0-9]{6})$/.test(value);\n};\n\n/**\n * Converts hex color to RGB object\n * @param hex - The hex color string (e.g., '#FF0000')\n * @returns RGB object or undefined if invalid hex\n */\nconst hexToRgb = (hex?: string): { r: number; g: number; b: number } | undefined => {\n if (!hex || !/^#([A-Fa-f0-9]{6})$/.test(hex)) return undefined;\n const r = parseInt(hex.slice(1, 3), 16);\n const g = parseInt(hex.slice(3, 5), 16);\n const b = parseInt(hex.slice(5, 7), 16);\n return { r, g, b };\n};\n\n/**\n * Generates CSS gradient string based on preset and base color\n * @param preset - The gradient preset type\n * @param baseHex - The base hex color for the gradient\n * @returns CSS gradient string or undefined\n */\nexport const gradientPresetCss = (\n preset?: 'none' | 'soft' | 'bold' | 'faint',\n baseHex?: string\n): string | undefined => {\n if (!preset || preset === 'none') return undefined;\n const rgb = hexToRgb(baseHex) ?? { r: 0, g: 0, b: 0 };\n switch (preset) {\n case 'soft':\n return `linear-gradient(90deg, rgba(${rgb.r},${rgb.g},${rgb.b},0.3), rgba(${rgb.r},${rgb.g},${rgb.b},0.8))`;\n case 'bold':\n return `linear-gradient(90deg, rgba(${rgb.r},${rgb.g},${rgb.b},0.6), rgba(${rgb.r},${rgb.g},${rgb.b},1.0))`;\n case 'faint':\n return `linear-gradient(90deg, rgba(${rgb.r},${rgb.g},${rgb.b},0.4), rgba(${rgb.r},${rgb.g},${rgb.b},0.4))`;\n default:\n return undefined;\n }\n};","import React from 'react';\nimport { StyledSpacingContainer, StyledDividerLine } from './SpacingDivider.styled';\nimport type { SpacingDividerProps } from './types';\nimport { THICKNESS_PX } from './types';\nimport { isValidHex, gradientPresetCss } from './utils/utils';\n\nconst DEFAULT_HEX = '#000000';\n\nconst SpacingDivider = (props: SpacingDividerProps): React.ReactElement | null => {\n const {\n vertical_padding = 'small',\n divider_style = 'solid',\n divider_thickness = 'thin',\n divider_color,\n divider_gradient_preset = 'none',\n divider_width_percent = 100,\n divider_alignment = 'left'\n } = props;\n\n const divider_thickness_px = THICKNESS_PX[divider_thickness];\n const finalDividerColor = isValidHex(divider_color) ? divider_color! : DEFAULT_HEX;\n const divider_gradient = gradientPresetCss(divider_gradient_preset, finalDividerColor);\n\n return (\n <StyledSpacingContainer vertical_padding={vertical_padding} divider_alignment={divider_alignment}>\n {divider_style !== 'none' && (\n <StyledDividerLine\n divider_style={divider_style}\n divider_thickness_px={divider_thickness_px}\n divider_color={finalDividerColor}\n divider_gradient={divider_gradient}\n divider_width_percent={divider_width_percent ?? 100}\n aria-hidden=\"true\"\n />\n )}\n </StyledSpacingContainer>\n );\n};\n\nexport default SpacingDivider;\n","import React, { useMemo } from 'react';\n\nimport {\n CONTAINER_CLASS,\n Slider,\n ColumnControlContainer,\n InnerWrapper,\n TabletGridContainer,\n renderContentOrEmpty\n} from './shared';\nimport { useColumnControl } from './hooks/useColumnControl';\n\nimport type { ColumnControlProps } from './types';\n\ninterface GridLayoutContentProps {\n addSlideEditTags?: Record<string, unknown>;\n $?: Record<string, unknown>;\n emptyBlockParentClass?: string;\n emptyPlaceholderText?: string;\n slidesForRender: unknown[];\n hasSlides: boolean;\n isStackedViewport: boolean;\n isTabletGridViewport: boolean;\n renderSlides: (useFlexLayout?: boolean) => React.ReactNode;\n sliderRef: React.RefObject<{ slickPrev: () => void; slickNext: () => void } | null>;\n sliderSettings: object;\n carouselKey: string;\n preset: string;\n gap: number;\n}\n\nfunction GridLayoutContent(props: Readonly<GridLayoutContentProps>) {\n const {\n emptyBlockParentClass,\n emptyPlaceholderText,\n hasSlides,\n isStackedViewport,\n isTabletGridViewport,\n slidesForRender,\n renderSlides,\n sliderRef,\n sliderSettings,\n carouselKey,\n preset,\n gap,\n $ = {},\n addSlideEditTags\n } = props;\n\n if (isStackedViewport) {\n return (\n <div className={CONTAINER_CLASS} {...(slidesForRender.length > 0 ? addSlideEditTags : {})}>\n {renderContentOrEmpty(hasSlides, renderSlides(), emptyBlockParentClass, emptyPlaceholderText, $)}\n </div>\n );\n }\n if (isTabletGridViewport) {\n return (\n <TabletGridContainer\n className={CONTAINER_CLASS}\n gap={gap}\n {...(slidesForRender.length > 0 ? addSlideEditTags : {})}\n >\n {renderContentOrEmpty(hasSlides, renderSlides(true), emptyBlockParentClass, emptyPlaceholderText, $)}\n </TabletGridContainer>\n );\n }\n return renderContentOrEmpty(\n hasSlides,\n <Slider ref={sliderRef} {...sliderSettings} key={`${carouselKey}-${preset}`}>\n {renderSlides(true)}\n </Slider>,\n emptyBlockParentClass,\n emptyPlaceholderText,\n $\n );\n}\n\n/** Column control (grid layout only). Use Carousel component for carousel. */\nfunction ColumnControl<T = unknown>(props: ColumnControlProps<T>) {\n const gridProps = { ...props, layout: 'grid' as const };\n const {\n gapPx,\n containerHeight,\n stackedItemHeight,\n stackedItemMaxHeight,\n isVariableWidth,\n containerClassName,\n effectiveFullWidth,\n parent$,\n $,\n emptyBlockParentClass,\n emptyPlaceholderText,\n sliderRef,\n sliderSettings,\n carouselKey,\n renderSlides,\n slidesForRender,\n hasSlides,\n isStackedViewport,\n isTabletGridViewport,\n preset\n } = useColumnControl(gridProps);\n\n const addSlideEditTags = useMemo(() => {\n return {\n ...($?.['slides'] ?? {}),\n ...($?.['slides__parent'] ?? {}),\n ...{ 'data-add-direction': 'horizontal' }\n };\n }, [$]);\n\n return (\n <ColumnControlContainer\n gap={gapPx}\n height={containerHeight}\n columnHeight={stackedItemHeight}\n maxColumnHeight={stackedItemMaxHeight}\n isVariableWidth={isVariableWidth}\n className={containerClassName}\n aria-label=\"Column Control\"\n fullWidth={effectiveFullWidth}\n {...(parent$ ?? {})}\n >\n <InnerWrapper>\n <div\n {...addSlideEditTags}\n >\n <GridLayoutContent\n emptyBlockParentClass={emptyBlockParentClass}\n emptyPlaceholderText={emptyPlaceholderText}\n slidesForRender={slidesForRender}\n hasSlides={hasSlides}\n isStackedViewport={isStackedViewport}\n isTabletGridViewport={isTabletGridViewport}\n renderSlides={renderSlides}\n sliderRef={sliderRef}\n sliderSettings={sliderSettings}\n carouselKey={carouselKey}\n preset={preset}\n gap={gapPx}\n $={$}\n addSlideEditTags={addSlideEditTags}\n />\n </div>\n </InnerWrapper>\n </ColumnControlContainer>\n );\n}\n\nexport default ColumnControl as React.FC<ColumnControlProps>;\n","import React from 'react';\n\nimport SliderImport from 'react-slick';\nimport * as Styled from './ColumnControl.styled';\n\nimport {\n unwrapComponent,\n EmptyPlaceholder,\n isEmptySlide,\n isRealSlide\n} from './utils';\n\nconst Slider = unwrapComponent(SliderImport);\nconst ColumnControlContainer = unwrapComponent(Styled.ColumnControlContainer);\nconst ArrowButton = unwrapComponent(Styled.ArrowButton);\nconst InnerWrapper = unwrapComponent(Styled.InnerWrapper);\nconst TabletGridContainer = unwrapComponent(Styled.TabletGridContainer);\nconst SlideSection = unwrapComponent(Styled.SlideSection);\nconst SlideInner = unwrapComponent(Styled.SlideInner);\nconst SlideContentInner = unwrapComponent(Styled.SlideContentInner);\n\nexport const CONTAINER_CLASS = 'column-control-container';\n\nexport {\n Slider,\n ColumnControlContainer,\n ArrowButton,\n InnerWrapper,\n TabletGridContainer,\n SlideSection,\n SlideInner,\n SlideContentInner\n};\n\nexport interface SliderRefInstance {\n slickPrev: () => void;\n slickNext: () => void;\n}\n\nexport function getSlideKey(slide: unknown, index: number, isPlaceholder: boolean): string {\n if (isPlaceholder) return `placeholder-${index}`;\n const id = (slide as { id?: string | number } | null)?.id;\n return id !== undefined && id !== null ? String(id) : `slide-${index}`;\n}\n\nexport function getSlideContent<T>(\n slide: T | { __emptyPlaceholder: true },\n index: number,\n isPlaceholder: boolean,\n emptyBlockParentClass: string | undefined,\n renderSlide: (slide: T, index: number) => React.ReactNode,\n emptyPlaceholderText?: string\n): React.ReactNode {\n if (isPlaceholder)\n return (\n <EmptyPlaceholder\n emptyBlockParentClass={emptyBlockParentClass}\n text={emptyPlaceholderText}\n />\n );\n if (isRealSlide(slide)) return renderSlide(slide as T, index);\n return null;\n}\n\nexport function renderSlidesContent<T>(params: {\n slidesForRender: (T | { __emptyPlaceholder: true })[];\n renderSlide: (slide: T, index: number) => React.ReactNode;\n presetColumns: number;\n gap: number;\n isVariableWidth: boolean;\n getSlideWidth: (index: number) => string;\n stackedVerticalGap: number;\n stackedItemHeight: string;\n stackedItemMaxHeight?: number;\n useFlexLayout?: boolean;\n emptyBlockParentClass?: string;\n emptyPlaceholderText?: string;\n $?: Record<string, unknown>;\n}) {\n const {\n slidesForRender,\n renderSlide,\n presetColumns,\n gap,\n isVariableWidth,\n getSlideWidth,\n stackedVerticalGap,\n stackedItemHeight,\n stackedItemMaxHeight,\n useFlexLayout = false,\n emptyBlockParentClass,\n emptyPlaceholderText,\n $ = {}\n } = params;\n\n const addSlideEditTags = {\n ...($?.['slides'] ?? {}),\n ...($?.['slides__parent'] ?? {}),\n ...{ 'data-add-direction': 'horizontal' }\n };\n\n const flexBasis =\n presetColumns === 1\n ? '100%'\n : `calc((100% - ${(presetColumns - 1) * gap}px) / ${presetColumns})`;\n\n return slidesForRender.map((slide, index) => {\n const isPlaceholder = isEmptySlide(slide);\n const slideWidth = !useFlexLayout && isVariableWidth ? getSlideWidth(index) : undefined;\n\n return (\n <SlideSection\n key={getSlideKey(slide, index, isPlaceholder)}\n aria-roledescription=\"slide\"\n aria-label={`Slide ${index + 1} of ${slidesForRender.length}`}\n useFlexLayout={useFlexLayout}\n stackedVerticalGap={stackedVerticalGap}\n stackedItemHeight={stackedItemHeight}\n stackedItemMaxHeight={stackedItemMaxHeight}\n slideWidth={slideWidth}\n flexBasis={flexBasis}\n isVariableWidth={isVariableWidth}\n {...addSlideEditTags}\n {...($?.[`slides__${index}`] ?? {})}\n >\n <SlideInner stackedItemHeight={stackedItemHeight} stackedItemMaxHeight={stackedItemMaxHeight}>\n <SlideContentInner>\n {getSlideContent(\n slide,\n index,\n isPlaceholder,\n emptyBlockParentClass,\n renderSlide,\n emptyPlaceholderText\n )}\n </SlideContentInner>\n </SlideInner>\n </SlideSection>\n );\n });\n}\n\nexport function renderContentOrEmpty(\n hasSlides: boolean,\n content: React.ReactNode,\n emptyBlockParentClass: string | undefined,\n emptyPlaceholderText?: string,\n $?: Record<string, unknown>\n): React.ReactNode {\n return hasSlides ? (\n content\n ) : (\n <EmptyPlaceholder\n emptyBlockParentClass={emptyBlockParentClass}\n text={emptyPlaceholderText}\n />\n );\n}\n","import { styled } from '@nuskin/foundation-theme';\nimport { DEVICE_SIZES, MIN_EMPTY_PLACEHOLDER_HEIGHT_PX, MIN_SLIDE_WIDTH_PX } from './types';\n\nfunction getArrowButtonPosition(\n fullWidth: boolean | undefined,\n direction: 'prev' | 'next',\n fullVal: number,\n nonFullVal: number\n): { left?: number; right?: number } {\n if (fullWidth && direction === 'prev') return { left: fullVal };\n if (fullWidth && direction !== 'prev') return { right: fullVal };\n if (!fullWidth && direction === 'prev') return { left: nonFullVal };\n return { right: nonFullVal };\n}\n\nexport const ColumnControlContainer = styled('section')<{\n gap: number;\n height: string;\n columnHeight: string;\n maxColumnHeight?: number;\n isVariableWidth: boolean;\n fullWidth?: boolean;\n dotsInside?: boolean;\n}>(({ gap, height, columnHeight, maxColumnHeight, fullWidth, dotsInside = true }) => ({\n position: 'relative',\n width: '100%',\n textAlign: 'center',\n padding: '0 80px 50px',\n height,\n boxSizing: 'border-box',\n\n ...(fullWidth && {\n padding: '0'\n }),\n\n [`@media (max-width: ${DEVICE_SIZES.MEDIUM}px)`]: {\n padding: '0 40px 50px',\n ...(fullWidth && {\n padding: '0'\n })\n },\n\n [`@media (max-width: ${DEVICE_SIZES.SMALL}px)`]: {\n padding: '0 20px 40px',\n ...(fullWidth && {\n padding: '0'\n })\n },\n\n '.slick-slider': {\n position: 'relative',\n display: 'block',\n height: '100%'\n },\n\n '.slick-list': {\n position: 'relative',\n overflow: 'hidden',\n height: '100%',\n ...(columnHeight === 'auto' && { minHeight: 280 }),\n margin: `0 -${gap / 2}px`,\n // Add a subtle buffer so slides don't touch the container edges\n padding: '1px 0'\n },\n\n '.slick-track': {\n display: 'flex',\n height: '100%'\n },\n\n '.slick-slide': {\n padding: `0 ${gap / 2}px`,\n // When auto, fill track height so slide content can occupy full height; otherwise use fixed columnHeight\n height: columnHeight === 'auto' ? '100%' : columnHeight,\n minHeight: 0,\n ...(maxColumnHeight != null && { maxHeight: `${maxColumnHeight}px` }),\n\n '& > div': {\n height: '100%',\n width: '100%',\n\n '& > div': {\n height: '100%',\n width: '100%'\n }\n }\n },\n\n '.slick-dots': {\n position: dotsInside ? 'absolute' : 'static',\n // When inside, overlay within the slider; when outside, place below as part of layout\n bottom: dotsInside ? 12 : 'auto',\n display: 'flex',\n justifyContent: 'center',\n gap: 8,\n listStyle: 'none',\n padding: 0,\n margin: dotsInside ? 0 : '16px 0 0',\n width: '100%',\n left: 0,\n\n li: {\n margin: 0,\n width: 12,\n height: 12,\n\n button: {\n width: 12,\n height: 12,\n padding: 0,\n borderRadius: '50%',\n border: 'none',\n background: '#ccc',\n textIndent: -9999,\n cursor: 'pointer',\n transition: 'background 0.2s ease, transform 0.2s ease',\n\n '&:before': {\n display: 'none'\n }\n },\n\n '&.slick-active button': {\n background: '#4A90E2'\n }\n }\n },\n\n [`@media (max-width: ${DEVICE_SIZES.SMALL}px)`]: {\n '.slick-dots': {\n bottom: dotsInside ? 8 : 'auto',\n gap: 6,\n\n li: {\n width: 10,\n height: 10,\n\n button: {\n width: 10,\n height: 10\n }\n }\n }\n }\n}));\n\nexport const TabletGridContainer = styled('div')<{ gap: number }>(({ gap }) => ({\n display: 'flex',\n flexWrap: 'wrap',\n gap: `${gap}px`,\n width: '100%'\n}));\n\nexport const SlideSection = styled('section')<{\n useFlexLayout: boolean;\n stackedVerticalGap: number;\n stackedItemHeight: string;\n stackedItemMaxHeight?: number;\n slideWidth?: string;\n flexBasis?: string;\n isVariableWidth: boolean;\n}>(\n ({\n useFlexLayout,\n stackedVerticalGap,\n stackedItemHeight,\n stackedItemMaxHeight,\n slideWidth,\n flexBasis,\n isVariableWidth\n }) => ({\n maxWidth: 'none',\n margin: useFlexLayout ? 0 : `0 0 ${stackedVerticalGap}px`,\n // Fill parent height so renderSlide content can occupy full slide height\n height: stackedItemHeight === 'auto' ? '100%' : stackedItemHeight,\n minHeight: 0,\n ...(stackedItemMaxHeight != null && { maxHeight: stackedItemMaxHeight }),\n width: slideWidth,\n flex: useFlexLayout && flexBasis ? `0 0 ${flexBasis}` : undefined,\n boxSizing: useFlexLayout ? 'border-box' : undefined,\n // Prevent slides from shrinking too small for readability (non-variable presets)\n minWidth: isVariableWidth ? 0 : MIN_SLIDE_WIDTH_PX,\n position: 'relative'\n })\n);\n\nexport const SlideInner = styled('div')<{\n stackedItemHeight: string;\n stackedItemMaxHeight?: number;\n}>(({ stackedItemHeight }) => ({\n width: '100%',\n // Fill slide section so content wrapper can stretch to full height\n height: stackedItemHeight === 'auto' ? '100%' : stackedItemHeight,\n minHeight: 0,\n boxSizing: 'border-box',\n display: 'flex',\n flexDirection: 'column',\n // Remove justifyContent: center so SlideContentInner can fill full height\n alignItems: 'stretch',\n textAlign: 'left',\n overflow: 'hidden',\n minWidth: 0,\n position: 'relative'\n}));\n\nexport const SlideContentInner = styled('div')({\n maxWidth: '100%',\n width: '100%',\n flex: 1,\n minHeight: 0,\n overflow: 'hidden',\n display: 'flex',\n flexDirection: 'column'\n});\n\nexport const ArrowButton = styled('button')<{\n direction: 'prev' | 'next';\n fullWidth?: boolean;\n}>(({ direction, fullWidth }) => ({\n position: 'absolute',\n top: '50%',\n transform: 'translateY(-50%)',\n background: 'rgba(0, 0, 0, 0.5)',\n color: '#fff',\n border: 'none',\n borderRadius: '50%',\n width: 48,\n height: 48,\n padding: 0,\n margin: 0,\n cursor: 'pointer',\n zIndex: 10,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n transition: 'background 0.2s ease',\n fontSize: 24,\n lineHeight: 1,\n verticalAlign: 'middle',\n ...getArrowButtonPosition(fullWidth, direction, 8, -60),\n\n '&:hover': {\n background: 'rgba(0, 0, 0, 0.7)'\n },\n\n '&:focus': {\n outline: '2px solid #4A90E2',\n outlineOffset: 2\n },\n\n '&:disabled': {\n opacity: 0.3,\n cursor: 'not-allowed'\n },\n\n [`@media (max-width: ${DEVICE_SIZES.MEDIUM}px)`]: {\n width: 40,\n height: 40,\n ...getArrowButtonPosition(fullWidth, direction, 4, -45)\n },\n\n [`@media (max-width: ${DEVICE_SIZES.SMALL}px)`]: {\n width: 32,\n height: 32,\n fontSize: 20,\n ...getArrowButtonPosition(fullWidth, direction, 2, -35)\n }\n}));\n\nexport const InnerWrapper = styled('div')({\n position: 'relative',\n height: '100%'\n});\n\n\nexport const EmptyPlaceholderWrapper = styled('div')({\n padding: '10px',\n display: 'flex',\n justifyContent: 'center',\n alignItems: 'center',\n minHeight: `${MIN_EMPTY_PLACEHOLDER_HEIGHT_PX}px`,\n border: '1px dashed #ccc',\n boxSizing: 'border-box'\n});","import React from 'react';\n\n/** Gap between columns/slides: preset name → px (none: 0, small: 8, medium: 12, large: 16) */\nexport type GapPreset = 'none' | 'small' | 'medium' | 'large';\n\nexport const GAP_PRESET_VALUES: Record<GapPreset, number> = {\n none: 0,\n small: 8,\n medium: 12,\n large: 16\n};\n\n/** Resolve gap to pixels. Accepts preset name or legacy number (for backward compatibility). */\nexport function getGapPx(gap?: GapPreset | number): number {\n if (gap === undefined) return GAP_PRESET_VALUES.large;\n if (typeof gap === 'number') return gap;\n return GAP_PRESET_VALUES[gap];\n}\n\nexport type SlidePreset =\n | 'single-full'\n | 'two-equal'\n | 'two-small-large'\n | 'three-equal'\n | 'three-small-medium-large'\n | 'four-equal';\n\nexport type Alignment = 'left' | 'center' | 'right';\n\n/** Render callback: consumer renders each slide from their data. */\nexport type RenderSlideCallback<T = unknown> = (slide: T, index: number) => React.ReactNode;\n\nexport type ColumnControlProps<T = unknown> = Readonly<{\n /** Slide data (CMS/consumer shape). Rendered via renderSlide. */\n slides: T[];\n /** Called to render each slide. Receives slide data and index. */\n renderSlide: RenderSlideCallback<T>;\n preset?: SlidePreset;\n /** Layout mode: grid behaves like stacked list on small/tablet; carousel uses full slider behavior */\n layout?: 'grid' | 'carousel';\n /** Convenience props that override autoplay.enabled */\n autoplayEnabled?: boolean;\n /** Autoplay interval in seconds (e.g. 3 = 3s). Passed to slider as ms internally. */\n autoplayDuration?: number;\n /** Convenience props that override navigation.showArrows */\n showArrows?: boolean;\n /** Convenience props that override navigation.showPagination */\n showPagination?: boolean;\n onSlideChange?: (index: number) => void;\n className?: string;\n slickSettings?: any;\n /** Spacing between columns/slides: 'none'|'small'|'medium'|'large' (0,8,12,16px) or legacy number */\n gap?: GapPreset | number;\n height?: string;\n fullWidth?: boolean;\n emptyBlockParentClass?: string;\n /** Override empty placeholder label. Defaults: \"Add items to the column control\" (grid) or \"Add items to the carousel\" (carousel). */\n emptyPlaceholderText?: string;\n /** Position of slider dots: 'inside' overlays within the slider; 'outside' places them below as part of the height. Defaults to 'inside'. */\n dotsPosition?: 'inside' | 'outside';\n isEditing?: boolean;\n parent$?: Record<string, unknown>;\n $?: Record<string, unknown>;\n}>;\n\nexport interface ColumnControlSlideProps {\n children: React.ReactNode;\n isActive: boolean;\n preset: SlidePreset;\n alignment: Alignment;\n index: number;\n slideCount: number;\n}\n\nexport const DEVICE_SIZES = {\n ULTRA_SMALL: 320,\n EXTRA_SMALL: 480,\n SMALL: 600,\n MEDIUM: 768,\n LARGE: 1024,\n EXTRA_LARGE: 1200,\n ULTRA_LARGE: 1440,\n SUPER_LARGE: 1920\n} as const;\n\nexport type DeviceSize = keyof typeof DEVICE_SIZES;\n\n// Minimum slide width (in px) for non-variable width presets (CMS-friendly default)\nexport const MIN_SLIDE_WIDTH_PX = 280;\n\nexport const MIN_SLIDE_HEIGHT_PX = 320;\n\n/** Max height of a slide/card when height is content-driven. Authoring guide recommends designing for 400px. */\nexport const MAX_SLIDE_HEIGHT_PX = 650;\n\n/** Minimum height (px) for empty placeholder slots in column control/carousel. */\nexport const MIN_EMPTY_PLACEHOLDER_HEIGHT_PX = 220;\n\n// Max number of items allowed when using grid/column-control style layout\nexport const MAX_ALLOWED_COLUMN_CONTROL_ITEMS = 4;\n","import React from 'react';\n\nimport { EmptyPlaceholderWrapper } from './ColumnControl.styled';\nimport type { ColumnControlProps } from './types';\nimport { DEVICE_SIZES, MAX_ALLOWED_COLUMN_CONTROL_ITEMS, MAX_SLIDE_HEIGHT_PX } from './types';\n\nexport interface ViewportLayoutState {\n isStackedViewport: boolean;\n isTabletGridViewport: boolean;\n stackedItemHeight: string;\n stackedItemMaxHeight: number;\n stackedVerticalGap: number;\n containerHeight: string;\n}\n\nexport function getViewportLayoutState(\n isGridLayout: boolean,\n windowWidth: number,\n gapPx: number,\n height: string = 'auto'\n): ViewportLayoutState {\n const isStackedViewport = windowWidth <= DEVICE_SIZES.SMALL;\n const isTabletGridViewport =\n isGridLayout && windowWidth > DEVICE_SIZES.SMALL && windowWidth <= DEVICE_SIZES.LARGE;\n const stackedItemHeight = '100%';\n const stackedItemMaxHeight = MAX_SLIDE_HEIGHT_PX;\n const stackedVerticalGap = isGridLayout && isStackedViewport ? gapPx : 0;\n return {\n isStackedViewport,\n isTabletGridViewport,\n stackedItemHeight,\n stackedItemMaxHeight,\n stackedVerticalGap,\n containerHeight: height\n };\n}\n\nexport interface SlidesMeta<T> {\n gridSlides: T[];\n slidesToShow: number;\n shouldShowDots: boolean;\n}\n\nexport function getSlidesMeta<T>(\n slides: T[],\n isGridLayout: boolean,\n presetColumns: number,\n presetSlidesToShow: number,\n effectiveShowPagination: boolean\n): SlidesMeta<T> {\n const gridSlides = isGridLayout ? slides.slice(0, MAX_ALLOWED_COLUMN_CONTROL_ITEMS) : slides;\n const slidesToShow = isGridLayout\n ? Math.min(gridSlides.length, presetColumns, MAX_ALLOWED_COLUMN_CONTROL_ITEMS)\n : presetSlidesToShow;\n const shouldShowDots = isGridLayout\n ? effectiveShowPagination && gridSlides.length > 1\n : gridSlides.length > 1;\n return { gridSlides, slidesToShow, shouldShowDots };\n}\n\nexport function unwrapComponent<T>(mod: T): any {\n if (!mod) return mod;\n\n // already a component/function\n if (typeof mod === 'function') return mod;\n\n // default export wrapped\n if (typeof mod === 'object' && (mod as any).default) {\n return (mod as any).default;\n }\n\n return mod;\n}\n\nexport const EmptyPlaceholder: React.FC<Readonly<{ emptyBlockParentClass?: string; text?: string }>> = ({\n emptyBlockParentClass,\n text = 'Add items'\n}) =>\n React.createElement(\n EmptyPlaceholderWrapper as React.ComponentType<any>,\n { className: emptyBlockParentClass },\n text\n );\n\nexport function getPresetColumns(preset: ColumnControlProps['preset']): number {\n switch (preset) {\n case 'single-full':\n return 1;\n case 'two-equal':\n case 'two-small-large':\n return 2;\n case 'three-equal':\n case 'three-small-medium-large':\n return 3;\n case 'four-equal':\n return 4;\n default:\n return 1;\n }\n}\n\nexport function isVariableWidthPreset(preset: ColumnControlProps['preset'], windowWidth: number): boolean {\n if (windowWidth <= DEVICE_SIZES.MEDIUM) return false;\n return preset === 'two-small-large' || preset === 'three-small-medium-large';\n}\n\nexport function getVariableSlideWidth(\n preset: ColumnControlProps['preset'],\n index: number,\n windowWidth: number\n): string {\n if (windowWidth <= DEVICE_SIZES.MEDIUM) return 'auto';\n\n if (preset === 'two-small-large') {\n return index % 2 === 0 ? '33.33%' : '66.67%';\n }\n\n if (preset === 'three-small-medium-large') {\n const pos = index % 3;\n if (pos === 0 || pos === 2) return '25%';\n return '50%';\n }\n\n return 'auto';\n}\n\nexport function getSlidesToShowByViewport(windowWidth: number, presetColumns: number): number {\n if (windowWidth >= DEVICE_SIZES.EXTRA_LARGE) return Math.min(presetColumns, 4);\n if (windowWidth >= DEVICE_SIZES.LARGE) return Math.min(presetColumns, 3);\n if (windowWidth >= DEVICE_SIZES.SMALL) return Math.min(presetColumns, 2);\n return 1;\n}\n\n/** Sentinel used in the slides array to represent an empty slot when slides.length < preset. */\nexport const EMPTY_SLIDE_SENTINEL = { __emptyPlaceholder: true } as const;\n\nexport function isEmptySlide(slide: unknown): slide is typeof EMPTY_SLIDE_SENTINEL {\n return (\n typeof slide === 'object' &&\n slide !== null &&\n '__emptyPlaceholder' in slide &&\n (slide as { __emptyPlaceholder?: boolean }).__emptyPlaceholder === true\n );\n}\n\n/** Type guard: true when slide is a real slide (not the empty placeholder sentinel). */\nexport function isRealSlide<T>(slide: T | typeof EMPTY_SLIDE_SENTINEL): slide is T {\n return !isEmptySlide(slide);\n}\n\n/** Pads the slides array with EMPTY_SLIDE_SENTINEL so length equals targetCount when slides.length < targetCount. */\nexport function padSlidesToPreset<T>(\n slides: T[],\n targetCount: number\n): (T | typeof EMPTY_SLIDE_SENTINEL)[] {\n if (slides.length >= targetCount) return slides;\n const padCount = targetCount - slides.length;\n return [...slides, ...new Array(padCount).fill(EMPTY_SLIDE_SENTINEL)];\n}\n\nexport function getSlidesForRender<T>(params: {\n isGridLayout: boolean;\n isStackedViewport: boolean;\n isTabletGridViewport: boolean;\n gridSlides: T[];\n presetColumns: number;\n slidesToShow: number;\n}): T[] {\n const { isGridLayout, isStackedViewport, isTabletGridViewport, gridSlides, presetColumns, slidesToShow } = params;\n if (isGridLayout && (isStackedViewport || isTabletGridViewport)) {\n return gridSlides.slice(0, Math.min(presetColumns, gridSlides.length));\n }\n if (isGridLayout) return gridSlides.slice(0, slidesToShow);\n return gridSlides;\n}\n\nexport function buildResponsiveSettings(params: {\n isGridLayout: boolean;\n presetSlidesToShow: number;\n gridSlides: unknown[];\n presetColumns: number;\n shouldShowDots: boolean;\n /** When set (e.g. after padding to preset), use this as the slide count cap so placeholders are visible. */\n effectiveSlidesCount?: number;\n}) {\n const {\n isGridLayout,\n presetSlidesToShow,\n gridSlides,\n presetColumns,\n shouldShowDots,\n effectiveSlidesCount\n } = params;\n const slideCount = effectiveSlidesCount ?? gridSlides.length;\n const hasPlaceholders = effectiveSlidesCount != null && effectiveSlidesCount > gridSlides.length;\n const gridSlidesToShow = (maxCols: number) =>\n hasPlaceholders\n ? Math.min(slideCount, presetColumns)\n : Math.min(slideCount, presetColumns, maxCols);\n const carouselSlidesToShow = (maxCols: number) =>\n Math.min(presetSlidesToShow, slideCount, maxCols);\n return [\n {\n breakpoint: DEVICE_SIZES.SMALL,\n settings: {\n slidesToShow: isGridLayout\n ? gridSlidesToShow(1)\n : Math.min(presetSlidesToShow, 1),\n slidesToScroll: 1,\n swipeToSlide: !isGridLayout,\n arrows: false,\n dots: shouldShowDots,\n variableWidth: false\n }\n },\n {\n breakpoint: DEVICE_SIZES.MEDIUM,\n settings: {\n slidesToShow: isGridLayout ? gridSlidesToShow(2) : carouselSlidesToShow(2),\n slidesToScroll: 1,\n swipeToSlide: !isGridLayout,\n arrows: false,\n dots: shouldShowDots,\n variableWidth: false\n }\n },\n {\n breakpoint: DEVICE_SIZES.LARGE,\n settings: {\n slidesToShow: isGridLayout\n ? gridSlidesToShow(MAX_ALLOWED_COLUMN_CONTROL_ITEMS)\n : carouselSlidesToShow(3),\n slidesToScroll: 1,\n swipeToSlide: !isGridLayout,\n arrows: false,\n dots: shouldShowDots,\n variableWidth: false\n }\n }\n ];\n}\n","import React, { useRef, useMemo } from 'react';\n\nimport {\n getViewportLayoutState,\n getSlidesMeta,\n buildResponsiveSettings,\n getSlidesForRender,\n padSlidesToPreset,\n getPresetColumns,\n getSlidesToShowByViewport,\n isVariableWidthPreset,\n getVariableSlideWidth\n} from '../utils';\nimport { renderSlidesContent, CONTAINER_CLASS } from '../shared';\nimport { useColumnControlResize } from './useColumnControlResize';\n\nimport type { ColumnControlProps } from '../types';\nimport { DEVICE_SIZES, getGapPx } from '../types';\nimport type { SliderRefInstance } from '../shared';\n\n/** Shared hook for column control (grid) and carousel. Layout drives grid vs carousel behavior. */\nexport function useColumnControl<T>(props: ColumnControlProps<T>) {\n const {\n slides,\n renderSlide,\n preset = 'single-full',\n layout = 'grid',\n autoplayEnabled = false,\n autoplayDuration = 3,\n showPagination = true,\n onSlideChange,\n className,\n slickSettings,\n gap = 'medium',\n height,\n fullWidth,\n emptyBlockParentClass,\n emptyPlaceholderText: emptyPlaceholderTextProp,\n parent$,\n $\n } = props;\n\n const gapPx = getGapPx(gap);\n const isGridLayout = layout === 'grid';\n const emptyPlaceholderText =\n emptyPlaceholderTextProp ??\n (isGridLayout ? 'Add items to the column control' : 'Add items to the carousel');\n const effectiveFullWidth = fullWidth ?? isGridLayout;\n\n const { windowWidth, carouselKey } = useColumnControlResize(preset, slides.length);\n\n const presetColumns = useMemo(() => getPresetColumns(preset), [preset]);\n const presetSlidesToShow = getSlidesToShowByViewport(windowWidth, presetColumns);\n const isVariableWidth = isVariableWidthPreset(preset, windowWidth);\n const getSlideWidth = useMemo(\n () => (index: number) => getVariableSlideWidth(preset, index, windowWidth),\n [preset, windowWidth]\n );\n\n const effectiveAutoplayEnabled = isGridLayout ? false : autoplayEnabled;\n const effectiveShowPagination = isGridLayout ? false : showPagination;\n const showArrowsOnDesktop = !isGridLayout && windowWidth > DEVICE_SIZES.LARGE;\n\n const viewportLayout = getViewportLayoutState(isGridLayout, windowWidth, gapPx, height);\n const {\n isStackedViewport,\n isTabletGridViewport,\n stackedItemHeight,\n stackedItemMaxHeight,\n stackedVerticalGap,\n containerHeight\n } = viewportLayout;\n\n const { gridSlides, slidesToShow, shouldShowDots } = getSlidesMeta(\n slides,\n isGridLayout,\n presetColumns,\n presetSlidesToShow,\n effectiveShowPagination\n );\n const effectiveShouldShowDots =\n isGridLayout\n ? false\n : (effectiveShowPagination && shouldShowDots && windowWidth <= DEVICE_SIZES.LARGE);\n\n const sliderRef = useRef<SliderRefInstance | null>(null);\n const goToPrevious = () => sliderRef.current?.slickPrev();\n const goToNext = () => sliderRef.current?.slickNext();\n\n const containerClassName = [className, isGridLayout ? CONTAINER_CLASS : undefined].filter(Boolean).join(' ');\n\n const slidesForRender = getSlidesForRender({\n isGridLayout,\n isStackedViewport,\n isTabletGridViewport,\n gridSlides,\n presetColumns,\n slidesToShow\n });\n\n const slidesForRenderPadded =\n slidesForRender.length < presetColumns\n ? padSlidesToPreset(slidesForRender, presetColumns)\n : slidesForRender;\n const effectivePresetColumns = presetColumns;\n const effectiveSlidesToShow = isGridLayout\n ? Math.min(presetColumns, slidesForRenderPadded.length)\n : Math.min(presetSlidesToShow, slidesForRenderPadded.length);\n\n const responsiveSettings = useMemo(\n () =>\n buildResponsiveSettings({\n isGridLayout,\n presetSlidesToShow,\n gridSlides,\n presetColumns,\n shouldShowDots,\n effectiveSlidesCount: slidesForRenderPadded.length\n }),\n [\n isGridLayout,\n presetSlidesToShow,\n gridSlides,\n presetColumns,\n shouldShowDots,\n slidesForRenderPadded.length\n ]\n );\n\n const sliderSettings = {\n dots: effectiveShouldShowDots,\n infinite: !isGridLayout && slidesForRenderPadded.length > effectiveSlidesToShow,\n speed: 500,\n slidesToShow: effectiveSlidesToShow,\n slidesToScroll: 1,\n autoplay: effectiveAutoplayEnabled,\n autoplaySpeed: autoplayDuration * 1000,\n pauseOnHover: true,\n arrows: false,\n variableWidth: isVariableWidth,\n swipe: !isGridLayout,\n draggable: !isGridLayout,\n beforeChange: (_: number, next: number) => onSlideChange?.(next),\n responsive: responsiveSettings,\n ...slickSettings\n };\n\n const renderSlides = (useFlexLayout = false) =>\n renderSlidesContent({\n slidesForRender: slidesForRenderPadded,\n renderSlide,\n presetColumns: effectivePresetColumns,\n gap: gapPx,\n isVariableWidth,\n getSlideWidth,\n stackedVerticalGap,\n stackedItemHeight,\n stackedItemMaxHeight,\n useFlexLayout,\n emptyBlockParentClass,\n emptyPlaceholderText,\n $\n });\n\n return {\n gapPx,\n containerHeight,\n stackedItemHeight,\n stackedItemMaxHeight,\n isVariableWidth,\n containerClassName,\n layout,\n effectiveFullWidth,\n parent$,\n $,\n emptyBlockParentClass,\n emptyPlaceholderText,\n sliderRef,\n sliderSettings,\n carouselKey,\n renderSlides,\n slidesForRender,\n hasSlides: slidesForRenderPadded.length > 0,\n isStackedViewport,\n isTabletGridViewport,\n preset,\n showArrowsOnDesktop,\n slidesToShow,\n slidesLength: slides.length,\n goToPrevious,\n goToNext\n };\n}\n","import { useEffect, useState } from 'react';\n\nimport type { ColumnControlProps } from '../types';\n\nexport interface UseColumnControlResizeResult {\n windowWidth: number;\n carouselKey: string;\n}\n\nexport function useColumnControlResize(\n preset: ColumnControlProps['preset'],\n slideCount: number\n): UseColumnControlResizeResult {\n const [windowWidth, setWindowWidth] = useState(\n typeof window !== 'undefined' ? window.innerWidth : 0\n );\n\n const [carouselKey, setCarouselKey] = useState(\n `carousel-${preset}-${slideCount}-${Date.now()}`\n );\n\n useEffect(() => {\n if (typeof window === 'undefined') {\n return;\n }\n\n let timeoutId: NodeJS.Timeout;\n\n const handleResize = () => {\n clearTimeout(timeoutId);\n timeoutId = setTimeout(() => {\n setWindowWidth(window.innerWidth);\n setCarouselKey(`carousel-${preset}-${slideCount}-${Date.now()}`);\n }, 150);\n };\n\n window.addEventListener('resize', handleResize);\n\n return () => {\n clearTimeout(timeoutId);\n window.removeEventListener('resize', handleResize);\n };\n }, [preset, slideCount]);\n\n return { windowWidth, carouselKey };\n}\n\n","import React from 'react';\n\nimport {\n ColumnControlContainer,\n InnerWrapper,\n Slider,\n ArrowButton,\n renderContentOrEmpty\n} from './shared';\nimport { useColumnControl } from './hooks/useColumnControl';\n\nimport type { ColumnControlProps } from './types';\n\nimport 'slick-carousel/slick/slick.css';\nimport 'slick-carousel/slick/slick-theme.css';\n\n/** Carousel layout: slider with arrows and dots. Uses shared hook and UI with ColumnControl. */\nexport function Carousel<T = unknown>(props: Readonly<Omit<ColumnControlProps<T>, 'layout'>>) {\n const { dotsPosition } = props;\n const carouselProps = { ...props, layout: 'carousel' as const };\n const {\n gapPx,\n containerHeight,\n stackedItemHeight,\n stackedItemMaxHeight,\n isVariableWidth,\n containerClassName,\n effectiveFullWidth,\n parent$,\n $,\n emptyBlockParentClass,\n emptyPlaceholderText,\n sliderRef,\n sliderSettings,\n carouselKey,\n renderSlides,\n hasSlides,\n showArrowsOnDesktop,\n slidesToShow,\n slidesLength,\n goToPrevious,\n goToNext\n } = useColumnControl(carouselProps);\n\n return (\n <ColumnControlContainer\n gap={gapPx}\n height={containerHeight}\n columnHeight={stackedItemHeight}\n maxColumnHeight={stackedItemMaxHeight}\n isVariableWidth={isVariableWidth}\n className={containerClassName}\n aria-label=\"Carousel Control\"\n fullWidth={effectiveFullWidth}\n dotsInside={dotsPosition !== 'outside'}\n {...(parent$ ?? {})}\n >\n <InnerWrapper>\n <div\n {...($?.['slides'] ?? {})}\n {...($?.['slides__parent'] ?? {})}\n {...{ 'data-add-direction': 'horizontal' }}\n >\n <Slider ref={sliderRef} {...sliderSettings} key={carouselKey}>\n {renderContentOrEmpty(\n hasSlides,\n renderSlides(),\n emptyBlockParentClass,\n emptyPlaceholderText,\n $\n )}\n </Slider>\n </div>\n\n {showArrowsOnDesktop && slidesLength > slidesToShow && (\n <>\n <ArrowButton\n direction=\"prev\"\n onClick={goToPrevious}\n aria-label=\"Previous slide\"\n fullWidth={effectiveFullWidth}\n >\n ‹\n </ArrowButton>\n <ArrowButton\n direction=\"next\"\n onClick={goToNext}\n aria-label=\"Next slide\"\n fullWidth={effectiveFullWidth}\n >\n ›\n </ArrowButton>\n </>\n )}\n </InnerWrapper>\n </ColumnControlContainer>\n );\n}\n\nexport default Carousel;\n","import React, { useMemo } from 'react';\nimport { ContentCardProps, MediaProps } from './types';\nimport { \n Card, \n MediaWrapper, \n Content, \n Title, \n Subtitle, \n Body, \n CtaWrapper, \n ContentInner \n} from './ContentCard.styled';\nimport Button from '../button/Button';\nimport { Media } from './Media';\nimport {\n calculateContentMinHeight,\n calculateMediaHeight,\n resolveTarget,\n getMaxHeight,\n getTitle,\n normalizeContentAlignment,\n normalizeContentCardMedia,\n normalizeCtaStyle,\n validateHex\n} from './utils/helpers';\nimport { CTA_BUTTON_HEIGHT } from './constants';\n\n/* ===================== COMPONENT ===================== */\nconst ContentCard: React.FC<ContentCardProps> = (props) => {\n const {\n title,\n subtitle = '',\n body = '',\n media,\n cta,\n cta_style = 'none',\n content_alignment = 'left',\n max_height = 450,\n background_color = '#ffffff',\n background_opacity = 1,\n text_color = '#000000',\n text_opacity = 1,\n border_radius = '0px',\n parent$ = {},\n isEditing = false,\n $ = {}\n } = props;\n\n const alignment = normalizeContentAlignment(content_alignment);\n const ctaStyleNormalized = normalizeCtaStyle(cta_style);\n\n /* ===================== MEDIA NORMALIZATION ===================== */\n const normalizedMedia: MediaProps | undefined = useMemo(\n () => normalizeContentCardMedia(media, $),\n [media, $]\n );\n /* ===================== SHOW MEDIA ===================== */\n const showMedia = Boolean(normalizedMedia?.mediaUrl);\n\n const hasCtaHref = Boolean(cta?.label?.href);\n const hasCtaLabel = Boolean(cta?.label?.title);\n\n const isCardLink = ctaStyleNormalized === 'card' && hasCtaHref;\n const showButton = ctaStyleNormalized === 'button' && hasCtaLabel;\n const maxHeight = getMaxHeight(max_height);\n const mediaHeight = calculateMediaHeight(maxHeight);\n const ctaHeight = showButton ? CTA_BUTTON_HEIGHT : 0;\n const contentMinHeight = calculateContentMinHeight(maxHeight, mediaHeight, ctaHeight);\n const cardTarget = resolveTarget(cta?.open_in_new_tab);\n\n const contentTitle = getTitle(title ?? '', isEditing);\n\n return (\n <Card\n align={alignment}\n borderRadius={border_radius}\n backgroundColor={validateHex(background_color ?? '', '#ffffff')}\n backgroundOpacity={background_opacity}\n textColor={validateHex(text_color ?? '', '#000000')}\n textOpacity={text_opacity}\n $maxHeight={maxHeight}\n as={isCardLink ? 'a' : 'article'}\n {...(isCardLink\n ? { href: cta?.label?.href, target: cardTarget }\n : {})}\n data-cta-style={ctaStyleNormalized}\n {...parent$}\n >\n <MediaWrapper\n $mediaHeight={mediaHeight}\n data-testid=\"card-media\"\n >\n {showMedia && normalizedMedia && <Media {...normalizedMedia} />}\n </MediaWrapper>\n\n <Content data-testid=\"card-content\">\n <ContentInner\n $contentMinHeight={contentMinHeight}\n data-testid=\"card-content-inner\"\n >\n {/* $ = CMS/extension passthrough props for each slot */}\n <Title {...($?.title ?? {})}>{contentTitle}</Title>\n {subtitle && <Subtitle {...($?.subtitle ?? {})}>{subtitle}</Subtitle>}\n {body && <Body {...($?.body ?? {})}>{body}</Body>}\n </ContentInner>\n\n {showButton && (\n <CtaWrapper $height={ctaHeight}>\n <Button {...cta} alignment={alignment} />\n </CtaWrapper>\n )}\n </Content>\n </Card>\n );\n};\n\nexport default ContentCard;\n","import styled from '@emotion/styled';\nimport { toCardBackgroundRgba, toCardTextRgba } from './utils/helpers';\n\n/* ===================== CARD ===================== */\nexport const Card = styled.article<{\n align?: 'left' | 'center' | 'right';\n borderRadius?: string;\n backgroundColor?: string;\n backgroundOpacity?: number;\n textColor?: string;\n textOpacity?: number;\n $maxHeight?: number;\n}>`\n display: flex;\n flex-direction: column;\n width: 100%;\n max-height: ${({ $maxHeight }) => ($maxHeight ? `${$maxHeight}px` : 'none')};\n\n height: auto;\n min-height: unset;\n flex: 0 0 auto;\n overflow: hidden;\n\n text-align: ${({ align }) => align || 'left'};\n border-radius: ${({ borderRadius }) => borderRadius || '12px'};\n background-color: ${({ backgroundColor, backgroundOpacity }) =>\n toCardBackgroundRgba(backgroundColor, backgroundOpacity)};\n color: ${({ textColor, textOpacity }) =>\n toCardTextRgba(textColor, textOpacity)};\n\n box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.06);\n text-decoration: none;\n\n &[data-cta-style='card'] {\n cursor: pointer;\n }\n\n &[data-cta-style='card'],\n &[data-cta-style='card'] * {\n color: ${({ textColor, textOpacity }) =>\n toCardTextRgba(textColor, textOpacity)};\n text-decoration: none;\n }\n`;\n\n/* ===================== MEDIA ===================== */\nexport const MediaWrapper = styled.div<{ $mediaHeight?: number }>`\n position: relative;\n width: 100%;\n height: ${({ $mediaHeight }) => ($mediaHeight ? `${$mediaHeight}px` : 'auto')};\n flex-shrink: 0;\n\n background: #f4f4f4;\n overflow: hidden;\n\n border-top-left-radius: inherit;\n border-top-right-radius: inherit;\n\n & > img {\n width: 100%;\n height: 100%;\n object-fit: cover;\n display: block;\n }\n`;\n\n/* ===================== CONTENT ===================== */\nexport const Content = styled.div`\n display: flex;\n flex-direction: column;\n flex: 1 1 auto;\n min-height: 0;\n min-width: 0;\n padding: 16px;\n gap: 8px;\n justify-content: flex-start;\n align-items: stretch;\n`;\n\n/* ===================== TEXT ===================== */\nexport const Title = styled.h3`\n font-size: 18px;\n font-weight: 600;\n line-height: 1.3;\n margin: 0;\n word-break: break-word;\n color: inherit;\n`;\n\nexport const Subtitle = styled.p`\n font-size: 14px;\n margin: 0;\n color: inherit;\n opacity: 1;\n word-break: break-word;\n`;\n\nexport const Body = styled.p`\n font-size: 14px;\n line-height: 1.5;\n margin: 0;\n flex: 1 1 auto;\n min-height: 0;\n display: -webkit-box;\n -webkit-line-clamp: 4;\n -webkit-box-orient: vertical;\n`;\n\n/* ===================== CTA WRAPPER ===================== */\nexport const CtaWrapper = styled.div<{ $height?: number }>`\n margin-top: auto;\n height: ${({ $height }) => ($height == null ? 'auto' : `${$height}px`)};\n`;\n\n/* ===================== MEDIA PLACEHOLDER ===================== */\n\nexport const MediaPlaceholderWrapper = styled.div`\n width: 100%;\n height: 100%;\n background: linear-gradient(135deg, #f4f4f4, #eaeaea);\n display: flex;\n align-items: center;\n justify-content: center;\n color: #aaa;\n`;\n\n/* ===================== CONTENT INNER ===================== */\nexport const ContentInner = styled.div<{ $contentMinHeight?: number }>`\n display: flex;\n flex-direction: column;\n gap: 8px;\n min-height: ${({ $contentMinHeight }) =>\n ($contentMinHeight ? `${$contentMinHeight}px` : '0')};\n max-height: ${({ $contentMinHeight }) =>\n ($contentMinHeight ? `${$contentMinHeight}px` : '100%')};\n overflow: hidden;\n overflow-y: auto;\n`;\n","import { extractBynderMedia } from '../../bynder-media/utils';\nimport { CONTENT_VERTICAL_SPACE, MEDIA_RATIO } from '../constants';\nimport type { ContentAlignment, CtaStyle, LinkTarget, MediaProps } from '../types';\n\n/** Matches #rgb or #rrggbb (3 or 6 hex digits). */\nconst HEX_COLOR_REGEX = /^#([0-9A-Fa-f]{3}|[0-9A-Fa-f]{6})$/;\n\n/**\n * Validates that the value is a hex color (#rgb or #rrggbb).\n * Returns the trimmed hex string, or defaultColor when invalid.\n */\nexport function validateHex(color: string, defaultColor: string): string {\n if (color === '') return defaultColor;\n const trimmed = color.trim();\n return HEX_COLOR_REGEX.test(trimmed) ? trimmed : defaultColor;\n}\n\n/**\n * Converts a hex color to rgba using the given opacity.\n * If hex is invalid or empty, returns defRgba when provided.\n */\nexport function hexToRgba(hex: string, opacity: number, defaultRgba?: string): string {\n const safeOpacity = Number.isFinite(opacity)\n ? Math.min(1, Math.max(0, opacity))\n : 1;\n if (hex?.startsWith('#')) {\n const hexRaw = hex.replace('#', '');\n const hexStr = hexRaw.length === 3\n ? hexRaw.split('').map((c) => c + c).join('')\n : hexRaw;\n const n = Number.parseInt(hexStr, 16);\n if (Number.isNaN(n)) {\n return defaultRgba ?? `rgba(255, 255, 255, ${safeOpacity})`;\n }\n const r = (n >> 16) & 255;\n const g = (n >> 8) & 255;\n const b = n & 255;\n return `rgba(${r}, ${g}, ${b}, ${safeOpacity})`;\n }\n return defaultRgba ?? `rgba(255, 255, 255, ${safeOpacity})`;\n}\n\n/** Card background as rgba; uses hex default and fallback. */\nexport function toCardBackgroundRgba(\n backgroundColor?: string, \n backgroundOpacity?: number\n): string {\n return hexToRgba(\n backgroundColor ?? '#ffffff',\n backgroundOpacity ?? 1,\n 'rgba(255, 255, 255, 1)'\n );\n}\n\n/** Card text color as rgba; uses hex default and fallback. */\nexport function toCardTextRgba(\n textColor?: string, \n textOpacity?: number\n): string {\n return hexToRgba(textColor ?? '#000000', textOpacity ?? 1, 'rgba(0, 0, 0, 1)');\n}\n\nexport const calculateMediaHeight = (maxHeight: number = 450) => {\n return Math.round((maxHeight ?? 450) * MEDIA_RATIO);\n};\n\nexport const getMaxHeight = (maxHeight: number) => {\n return typeof maxHeight === 'number' ? maxHeight : 450;\n};\n\nexport const getTitle = (title: string, isEditing: boolean) => {\n if (title) return title;\n if (isEditing) return 'Enter Title';\n return '';\n};\n\n/** Normalize content alignment string to 'left' | 'center' | 'right'. */\nexport function normalizeContentAlignment(\n alignment?: string | null\n): ContentAlignment {\n if (alignment === 'centre' || alignment === 'center') return 'center';\n if (alignment === 'right') return 'right';\n return 'left';\n}\n\n/** Normalize CTA style string to 'card' | 'button' | 'none'. */\nexport function normalizeCtaStyle(\n value?: string | null\n): CtaStyle {\n const ctaStyle = typeof value === 'string' ? value.toLowerCase().trim() : '';\n if (['card', 'button', 'none'].includes(ctaStyle)) {\n return ctaStyle as CtaStyle;\n }\n return 'button';\n}\n\n/**\n * Normalize media prop (string or object) to MediaProps or undefined.\n * - string: parsed as Bynder JSON, then mapped to MediaProps (with $ passthrough).\n * - object with mediaUrl: returned as-is.\n * - other: returned as MediaProps for legacy/custom shapes.\n */\nexport function normalizeContentCardMedia(\n media: MediaProps | string | undefined,\n $: Record<string, unknown>\n): MediaProps | undefined {\n if (!media) return undefined;\n if (typeof media === 'string') {\n const bynder = extractBynderMedia(media);\n if (!bynder) return undefined;\n return {\n mediaUrl: bynder.url,\n mediaType: bynder.type,\n mediaAlt: bynder.alt,\n isResponsive: bynder.isResponsive,\n desktopUrl: bynder.desktopUrl,\n mobileUrl: bynder.mobileUrl,\n $\n };\n }\n if (\n typeof media === 'object' &&\n media !== null &&\n 'mediaUrl' in media &&\n typeof media.mediaUrl === 'string'\n ) {\n return media;\n }\n return media as MediaProps | undefined;\n}\n\n/** Content inner min/max height so card total height fits within maxHeight. */\nexport function calculateContentMinHeight(\n maxHeight: number,\n mediaHeight: number,\n ctaHeight: number\n): number {\n return Math.max(\n 0,\n maxHeight - mediaHeight - ctaHeight - CONTENT_VERTICAL_SPACE\n );\n}\n\n/** Resolve target from open_in_new_tab string. */\nexport function resolveTarget(target?: 'Yes' | 'No' | null): LinkTarget | undefined {\n if (target === 'Yes') {\n return '_blank';\n }\n return '_self';\n}\n","/**\n * BannerMedia Sub-Component\n * Renders responsive media (image/gif/video) with lazy loading and fallback support\n */\n\nimport React from 'react';\nimport {\n MediaContainer,\n StyledImage,\n StyledVideo,\n FallbackMessage,\n PictureElement,\n SourceElement\n} from './Media.styled';\nimport { MediaProps } from './types';\n\nexport function Media(props: Readonly<MediaProps>): React.ReactElement {\n const {\n mediaUrl,\n fallbackMediaUrl,\n mediaType = 'image',\n mediaAlt = '',\n onError,\n testId,\n $,\n isResponsive,\n desktopUrl,\n mobileUrl\n } = props;\n\n const [currentUrl, setCurrentUrl] = React.useState(mediaUrl);\n const [hasError, setHasError] = React.useState(false);\n\n React.useEffect(() => {\n setCurrentUrl(mediaUrl);\n setHasError(false);\n }, [mediaUrl]);\n\n const handleMediaError = () => {\n if (fallbackMediaUrl && currentUrl !== fallbackMediaUrl) {\n setCurrentUrl(fallbackMediaUrl);\n } else {\n setHasError(true);\n }\n onError?.();\n };\n\n const renderMedia = () => {\n if (hasError && !fallbackMediaUrl) {\n return <FallbackMessage></FallbackMessage>;\n }\n\n if (mediaType === 'video') {\n return (\n <StyledVideo\n src={currentUrl}\n onError={handleMediaError}\n autoPlay\n muted\n loop\n playsInline\n data-testid={`${testId}-video`}\n {...($?.media ?? {})}\n ></StyledVideo>\n );\n }\n\n if (isResponsive && mobileUrl && desktopUrl) {\n return (\n <PictureElement>\n <SourceElement media=\"(max-width: 768px)\" srcSet={mobileUrl} />\n <SourceElement media=\"(min-width: 769px)\" srcSet={desktopUrl} />\n <StyledImage\n src={desktopUrl}\n alt={mediaAlt}\n onError={handleMediaError}\n loading=\"lazy\"\n data-testid={`${testId}-image`}\n {...($?.media ?? {})}\n />\n </PictureElement>\n );\n }\n\n return (\n <StyledImage\n src={currentUrl}\n alt={mediaAlt}\n onError={handleMediaError}\n loading=\"lazy\"\n data-testid={`${testId}-image`}\n {...($?.media ?? {})}\n />\n );\n };\n\n return (\n <MediaContainer data-testid={testId} {...($?.media ?? {})}>\n {renderMedia()}\n </MediaContainer>\n );\n}\n","import styled from '@emotion/styled';\n\nexport const MediaContainer = styled.div`\n position: relative;\n width: 100%;\n height: 100%;\n overflow: hidden;\n`;\n\nexport const StyledImage = styled.img`\n width: 100%;\n height: 100%;\n object-fit: cover;\n display: block;\n`;\n\nexport const StyledVideo = styled.video`\n width: 100%;\n height: 100%;\n object-fit: cover;\n display: block;\n`;\n\nexport const FallbackMessage = styled.div`\n display: flex;\n align-items: center;\n justify-content: center;\n width: 100%;\n height: 100%;\n background-color: #f0f0f0;\n color: #666;\n font-size: 14px;\n`;\n\nexport const PictureElement = styled.picture`\n width: 100%;\n height: 100%;\n display: block;\n`;\n\nexport const SourceElement = styled.source`\n display: block;\n`;\n","import React from 'react';\nimport { NsTypography } from '@nuskin/foundation-ui-components';\n\ninterface TypographyProps {\n value?: string;\n placeholder: string;\n isEditing: boolean;\n typographyProps: React.ComponentProps<typeof NsTypography>;\n}\n\nexport const Typography = ({\n value,\n placeholder,\n isEditing,\n typographyProps\n}: TypographyProps) => {\n\n let displayValue = value;\n\n if (!isEditing && value !== placeholder) {\n displayValue = value;\n } else if (value === '') {\n displayValue = placeholder;\n }\n\n return (\n <NsTypography {...typographyProps}>\n {displayValue}\n </NsTypography>\n );\n};\n","// Placeholder text constants\nexport const PLACEHOLDER_BRAND_CAPTION = 'Enter Brand Caption';\nexport const PLACEHOLDER_TITLE = 'Enter Title';\nexport const PLACEHOLDER_SUBTITLE = 'Enter Subtitle';\nexport const PLACEHOLDER_BODY = 'Enter Body';\n\n// Aria labels\nexport const ARIA_LABEL_HERO_BANNER = 'Hero banner';\n\n// Media loading attribute\nexport const IMAGE_LOADING_LAZY = 'lazy';\n","import React from 'react';\nimport { Typography } from './Typography';\nimport {\n PLACEHOLDER_BRAND_CAPTION,\n PLACEHOLDER_TITLE,\n PLACEHOLDER_SUBTITLE,\n PLACEHOLDER_BODY\n} from '../constants';\n\ninterface TypographyFieldConfig {\n value?: string;\n placeholder: string;\n variant: 'body-s' | 'h2' | 'h5' | 'h6';\n className: string;\n noSpacing?: boolean;\n weight?: 'bold';\n editTagKey: 'brandcaption' | 'title' | 'subtitle' | 'body';\n}\n\ninterface TypographyFieldsProps {\n brandcaption?: string;\n title?: string;\n subtitle?: string;\n body?: string;\n isEditing: boolean;\n editTags?: Record<string, unknown>;\n}\n\nconst getTypographyFields = (\n brandcaption?: string,\n title?: string,\n subtitle?: string,\n body?: string\n): TypographyFieldConfig[] => [\n {\n value: brandcaption,\n placeholder: PLACEHOLDER_BRAND_CAPTION,\n variant: 'body-s',\n className: 'brand-caption',\n noSpacing: true,\n editTagKey: 'brandcaption'\n },\n {\n value: title,\n placeholder: PLACEHOLDER_TITLE,\n variant: 'h2',\n className: 'title',\n weight: 'bold',\n editTagKey: 'title'\n },\n {\n value: subtitle,\n placeholder: PLACEHOLDER_SUBTITLE,\n variant: 'h5',\n className: 'subtitle',\n editTagKey: 'subtitle'\n },\n {\n value: body,\n placeholder: PLACEHOLDER_BODY,\n variant: 'h6',\n className: 'body',\n editTagKey: 'body'\n }\n];\n\nexport const TypographyFields: React.FC<TypographyFieldsProps> = ({\n brandcaption,\n title,\n subtitle,\n body,\n isEditing,\n editTags = {}\n}) => {\n const fields = getTypographyFields(brandcaption, title, subtitle, body);\n\n return (\n <>\n {fields.map((field) => {\n const typographyProps: React.ComponentProps<typeof Typography>['typographyProps'] = {\n variant: field.variant,\n className: field.className,\n ...(field.noSpacing && { noSpacing: true }),\n ...(field.weight && { weight: field.weight }),\n additionalProps: { ...(editTags?.[field.editTagKey] ?? {}) }\n };\n return (\n <Typography\n key={field.editTagKey}\n value={field.value}\n placeholder={field.placeholder}\n isEditing={isEditing}\n typographyProps={typographyProps}\n />\n );\n })}\n </>\n );\n};\n","import React from 'react';\nimport { NsImage } from '@nuskin/foundation-ui-components';\nimport { PictureElement, SourceElement } from '../HeroBanner.styled';\nimport {\n ParsedMedia,\n FULL_SIZE_PERCENT,\n MOBILE_BREAKPOINT,\n DESKTOP_BREAKPOINT\n} from '../helpers';\nimport { IMAGE_LOADING_LAZY } from '../constants';\n\ninterface MediaProps {\n parsedMedia: ParsedMedia | null;\n mediaAttributes?: Record<string, unknown>;\n}\n\nexport const Media = React.forwardRef<HTMLDivElement, MediaProps>(({\n parsedMedia,\n mediaAttributes = {}\n}, ref) => {\n if (!parsedMedia) return null;\n\n const renderImage = () => {\n const commonImageProps = {\n variant: 'fill' as const,\n className: 'media-fill',\n loading: IMAGE_LOADING_LAZY,\n ...mediaAttributes\n };\n\n if (parsedMedia.isResponsive && parsedMedia.desktopUrl && parsedMedia.mobileUrl) {\n return (\n <PictureElement>\n <SourceElement media={MOBILE_BREAKPOINT} srcSet={parsedMedia.mobileUrl} />\n <SourceElement media={DESKTOP_BREAKPOINT} srcSet={parsedMedia.desktopUrl} />\n <NsImage src={parsedMedia.desktopUrl} alt={parsedMedia.alt ?? ''} {...commonImageProps} />\n </PictureElement>\n );\n }\n\n return (\n <NsImage\n src={parsedMedia.url ?? ''}\n alt={parsedMedia.alt ?? ''}\n {...commonImageProps}\n />\n );\n };\n\n const mediaContent = (() => {\n if (parsedMedia.type === 'image' || parsedMedia.type === 'gif') {\n return renderImage();\n }\n\n if (parsedMedia.type === 'video') {\n return (\n <video\n src={parsedMedia.url}\n autoPlay\n muted\n loop\n playsInline\n preload=\"auto\"\n width={FULL_SIZE_PERCENT}\n height={FULL_SIZE_PERCENT}\n style={{ objectFit: 'cover' }}\n {...mediaAttributes}\n />\n );\n }\n\n return null;\n })();\n\n if (!mediaContent) return null;\n\n return (\n <div ref={ref} className=\"media-layer\">\n {mediaContent}\n </div>\n );\n});\nMedia.displayName = 'Media';\n","import { styled } from '@nuskin/foundation-theme';\nimport { GradientDepth } from './helpers';\nimport { MOBILE_BREAKPOINT } from './helpers';\n\n// Container\n\nexport const Container = styled('section') <{ textColor?: string }>`\n width: 100%;\n position: relative;\n min-height: 600px;\n overflow: hidden;\n\n .media-layer {\n position: absolute;\n inset: 0;\n width: 100%;\n height: 100%;\n z-index: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n }\n\n .media-layer .media-fill {\n width: 100%;\n height: 100%;\n object-fit: cover;\n display: block;\n }\n\n .title {\n font-size: clamp(22px, 3.5vw, 48px);\n line-height: 1.05;\n margin-bottom: 8px;\n font-family: 'Lora', serif;\n color: ${({ textColor }) => textColor ?? 'inherit'};\n }\n\n .subtitle {\n margin-bottom: 8px;\n font-size: clamp(16px, 2.2vw, 24px);\n line-height: 1.2;\n font-family: 'Lora', serif;\n color: ${({ textColor }) => textColor ?? 'inherit'};\n }\n\n .brand-caption {\n margin-bottom: 8px;\n font-size: clamp(12px, 1.5vw, 16px);\n line-height: 1.2;\n font-family: 'Lora', serif;\n color: ${({ textColor }) => textColor ?? 'inherit'};\n }\n\n .body {\n margin-bottom: 8px;\n font-size: clamp(14px, 1.6vw, 18px);\n line-height: 1.4;\n font-family: 'Lora', serif;\n color: ${({ textColor }) => textColor ?? 'inherit'};\n }\n`;\n\n// Gradient Overlay\n\nconst GRADIENT_OPACITIES = {\n sm: { start: 0.3, end: 0 },\n md: { start: 0.6, end: 0 },\n lg: { start: 0.9, end: 0 }\n} as const;\n\nconst getGradientBackground = (\n direction: string,\n depth: GradientDepth,\n color: 'black' | 'white'\n): string => {\n const { start, end } = GRADIENT_OPACITIES[depth];\n const baseColor = color === 'black' ? '0, 0, 0' : '255, 255, 255';\n\n if (direction === 'leftToRight') {\n return `background: linear-gradient(to right, rgba(${baseColor}, ${start}), rgba(${baseColor}, ${end}));`;\n }\n\n if (direction === 'rightToLeft') {\n return `background: linear-gradient(to left, rgba(${baseColor}, ${start}), rgba(${baseColor}, ${end}));`;\n }\n\n return `background: radial-gradient(circle, rgba(${baseColor}, ${start}), rgba(${baseColor}, ${end}));`;\n};\n\nexport const GradientOverlay = styled.div<{\n direction: string;\n depth: GradientDepth;\n color: 'black' | 'white';\n}>`\n position: absolute;\n inset: 0;\n z-index: 1;\n pointer-events: none;\n\n ${({ direction, depth, color }) => getGradientBackground(direction, depth, color)}\n\n /* Force radial gradient on small screens */\n @media (max-width: 768px) {\n ${({ depth, color }) => {\n const { start, end } = GRADIENT_OPACITIES[depth];\n const baseColor = color === 'black' ? '0, 0, 0' : '255, 255, 255';\n return `background: radial-gradient(circle, rgba(${baseColor}, ${start}), rgba(${baseColor}, ${end}));`;\n }}\n }\n`;\n\n// Responsive picture \nexport const PictureElement = styled.picture`\n width: 100%;\n height: 100%;\n display: block;\n`;\n\nexport const SourceElement = styled.source`\n display: block;\n`;\n\n// Overlay\n\nexport const Overlay = styled.div<{ justifyContent?: string }>`\n position: absolute;\n inset: 0;\n z-index: 2;\n display: flex;\n align-items: center;\n padding: clamp(16px, 4vw, 48px);\n pointer-events: none;\n justify-content: ${({ justifyContent }) => justifyContent ?? 'flex-start'};\n\n // Force center alignment on mobile\n @media ${MOBILE_BREAKPOINT} {\n justify-content: center;\n }\n`;\n\n// Content\n\nexport const Content = styled.div<{ textAlign?: string }>`\n max-width: min(520px, 90vw);\n z-index: 3;\n word-break: break-word;\n pointer-events: auto;\n text-align: ${({ textAlign }) => textAlign ?? 'left'};\n\n // Force center alignment on mobile\n @media ${MOBILE_BREAKPOINT} {\n text-align: center;\n }\n`;\n\n// Button to be Centered on Mobile\nexport const HERO_CTA_WRAPPER_CLASS = 'hero-banner-button-wrapper';\n\nexport const ButtonWrapper = styled.div`\n @media ${MOBILE_BREAKPOINT} {\n &.${HERO_CTA_WRAPPER_CLASS} > div {\n justify-content: center;\n }\n }\n`;\n\n// Helpers\n\nexport const getJustifyContent = (\n alignment: 'left' | 'center' | 'right'\n) => {\n if (alignment === 'center') return 'center';\n if (alignment === 'right') return 'flex-end';\n return 'flex-start';\n};\n","import { extractBynderMedia } from '../bynder-media/utils';\n\nexport type GradientDepth = 'sm' | 'md' | 'lg';\nexport type ContentAlignment = 'left' | 'center' | 'right';\nexport type TextColor = 'black' | 'white';\n\n// Constants\nexport const FULL_SIZE_PERCENT = '100%';\nexport const MOBILE_BREAKPOINT = '(max-width: 768px)';\nexport const DESKTOP_BREAKPOINT = '(min-width: 769px)';\n\nexport interface ParsedMedia {\n type: 'image' | 'gif' | 'video';\n url: string;\n alt: string;\n width?: number;\n height?: number;\n isResponsive?: boolean;\n desktopUrl?: string;\n mobileUrl?: string;\n}\n\ninterface MediaObject {\n type?: string;\n src?: string;\n alt?: string;\n width?: number;\n height?: number;\n}\n\nfunction isMediaObject(media: unknown): media is MediaObject {\n return typeof media === 'object' && media !== null && 'type' in media && 'src' in media;\n}\n\nexport function parseMedia(media: unknown): ParsedMedia | null {\n if (!media) return null;\n\n // Storybook / direct Media object\n if (isMediaObject(media)) {\n return {\n type: media.type as 'image' | 'gif' | 'video',\n url: media.src ?? '',\n alt: media.alt ?? '',\n width: media.width,\n height: media.height,\n isResponsive: false\n };\n }\n\n // Contentstack JSON string – use bynder-utils\n if (typeof media === 'string') {\n const extracted = extractBynderMedia(media);\n if (extracted) {\n return {\n type: extracted.type,\n url: extracted.url,\n alt: extracted.alt,\n isResponsive: extracted.isResponsive ?? false,\n desktopUrl: extracted.desktopUrl,\n mobileUrl: extracted.mobileUrl\n };\n }\n }\n\n return null;\n}\n\nexport function resolveContentAlignment(contentAlignment?: ContentAlignment): ContentAlignment {\n return contentAlignment ?? 'left';\n}\n\nexport function resolveGradientDepth(gradientDepth?: GradientDepth): GradientDepth {\n return gradientDepth ?? 'md';\n}\n\nexport function resolveTextColor(textColor?: string): TextColor {\n return (textColor === 'white' ? 'white' : 'black') as TextColor;\n}\n\n\nexport function getGradientColor(textColor: TextColor): 'white' | 'black' {\n return textColor === 'black' ? 'white' : 'black';\n}\n\nexport type GradientDirection = 'leftToRight' | 'radial' | 'rightToLeft';\n\nconst gradientDirectionMap: Record<ContentAlignment, GradientDirection> = {\n left: 'leftToRight',\n center: 'radial',\n right: 'rightToLeft'\n} as const;\n\nexport function getGradientDirection(contentAlignment: ContentAlignment): GradientDirection {\n return gradientDirectionMap[contentAlignment];\n}\n\n","import React from 'react';\nimport { Button } from '../button';\nimport { TypographyFields } from './components/TypographyFields';\nimport { Media } from './components/Media';\nimport { HeroBannerProps } from './types';\nimport { Container, GradientOverlay, Overlay, Content, getJustifyContent, ButtonWrapper, HERO_CTA_WRAPPER_CLASS } from './HeroBanner.styled';\nimport {\n parseMedia,\n resolveContentAlignment,\n resolveGradientDepth,\n resolveTextColor,\n getGradientColor,\n getGradientDirection\n} from './helpers';\nimport { ARIA_LABEL_HERO_BANNER } from './constants';\n\nconst HeroBanner: React.FC<HeroBannerProps> = (props) => {\n const {\n title,\n subtitle,\n body,\n brandcaption,\n button,\n media,\n class_name: className,\n content_alignment: contentAlignment,\n gradient_enabled: gradientEnabled = false,\n gradient_depth: gradientDepth,\n text_color: textColor,\n $ = {},\n parent$ = {},\n isEditing = false\n } = props;\n const resolvedContentAlignment = resolveContentAlignment(contentAlignment);\n const resolvedGradientDepth = resolveGradientDepth(gradientDepth);\n const resolvedTextColor = resolveTextColor(textColor);\n\n const parsedMedia = parseMedia(media);\n\n const justifyContent = getJustifyContent(resolvedContentAlignment);\n const gradientColor = getGradientColor(resolvedTextColor);\n const gradientDirection = getGradientDirection(resolvedContentAlignment);\n const shouldRenderButton = button && (button.label?.title || isEditing);\n\n return (\n <Container\n className={className}\n textColor={resolvedTextColor}\n aria-label={ARIA_LABEL_HERO_BANNER}\n {...(parent$ ?? {})}\n >\n {parsedMedia && (\n <Media\n parsedMedia={parsedMedia}\n mediaAttributes={$?.media ?? {}}\n />\n )}\n\n {gradientEnabled && (\n <GradientOverlay\n direction={gradientDirection}\n depth={resolvedGradientDepth}\n color={gradientColor}\n aria-hidden=\"true\"\n />\n )}\n\n <Overlay justifyContent={justifyContent}>\n <Content textAlign={resolvedContentAlignment}>\n <TypographyFields\n brandcaption={brandcaption}\n title={title}\n subtitle={subtitle}\n body={body}\n isEditing={isEditing}\n editTags={$}\n />\n\n {shouldRenderButton && (\n <ButtonWrapper className={HERO_CTA_WRAPPER_CLASS}>\n <Button\n {...button}\n alignment={resolvedContentAlignment}\n parent$={$?.button}\n isEditing={isEditing}\n />\n </ButtonWrapper>\n )}\n </Content>\n </Overlay>\n </Container>\n );\n};\n\nexport default HeroBanner;\n","import { ReactElement, useMemo } from 'react';\nimport DOMPurify from 'dompurify';\nimport CsText from '../text/CsText';\nimport type { ComponentProps } from 'react';\n\ntype CsTextProps = ComponentProps<typeof CsText>;\n\ninterface RichTextProps extends Omit<CsTextProps, 'text_editor' | 'font_color'> {\n text_editor: string;\n font_color?: 'Light' | 'Dark';\n}\n\n/**\n * Sanitization configuration for allowed tags and attributes\n * Following Contentstack Rich Text Editor restricted toolbar guidelines\n */\nconst SANITIZATION_CONFIG = {\n ALLOWED_TAGS: [\n 'p',\n 'div',\n 'span',\n 'a',\n 'br',\n 'strong',\n 'b',\n 'em',\n 'i',\n 'u',\n 'h1',\n 'h2',\n 'h3',\n 'ul',\n 'ol',\n 'li'\n ],\n ALLOWED_ATTR: [\n 'href',\n 'target',\n 'rel',\n 'title',\n 'class',\n 'style',\n 'data-testid',\n 'data-cs-id',\n 'data-cs-type',\n 'data-cslp'\n ]\n};\n\n/**\n * Sanitize HTML using DOMPurify\n * Removes dangerous content while preserving allowed tags and attributes\n *\n * @param html - Raw HTML content from editor\n * @returns Sanitized HTML safe for rendering\n */\nconst sanitizeHtml = (html: string): string => {\n if (!html || typeof html !== 'string') {\n return '';\n }\n\n return DOMPurify.sanitize(html, {\n ALLOWED_TAGS: SANITIZATION_CONFIG.ALLOWED_TAGS,\n ALLOWED_ATTR: SANITIZATION_CONFIG.ALLOWED_ATTR,\n KEEP_CONTENT: true,\n RETURN_DOM: false,\n RETURN_DOM_FRAGMENT: false,\n FORCE_BODY: false,\n SANITIZE_DOM: true,\n IN_PLACE: false\n });\n};\n\n/**\n * RichText Component\n *\n * Wrapper component that sanitizes Rich Text Editor content before passing to CsText.\n * Uses DOMPurify to remove dangerous markup (scripts, styles, event handlers, etc.)\n * while preserving allowed formatting tags and attributes.\n *\n * SECURITY FEATURES:\n * - Removes script tags and event handlers\n * - Strips dangerous attributes and tags\n * - Allows only specified tags: p, div, span, a, br, strong, em, i, u, h1, h2, h3, ul, ol, li\n * - Allows only specified attributes: href, target, rel, title, class, style, data-cslp\n * - Sanitization is applied before rendering in CsText\n *\n * @param props - CsText component props with sanitizable text_editor content\n * @returns Rendered component with sanitized content\n */\nconst RichText = ({ text_editor, font_color, ...restProps }: RichTextProps): ReactElement | null => {\n // Memoize sanitized HTML to avoid recalculation on every render\n const sanitizedHtml = useMemo(() => {\n if (!text_editor || typeof text_editor !== 'string' || !text_editor.trim()) {\n return '';\n }\n return sanitizeHtml(text_editor);\n }, [text_editor]);\n\n // Convert string font_color value to boolean (light = true, dark = false)\n const fontColorBoolean = font_color === 'Light';\n\n // Don't render if no content\n if (!sanitizedHtml) {\n return null;\n }\n\n // Pass sanitized HTML to CsText component with all other props\n return <CsText {...restProps} text_editor={sanitizedHtml} font_color={fontColorBoolean} />;\n};\n\nexport default RichText;\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/text/CsText.tsx","../src/hooks/useRouteReplacer.tsx","../src/utils/route-utils.ts","../src/hooks/use-toggle-font-color/useMainContrast.tsx","../src/hooks/use-toggle-font-color/useToggleFontColor.ts","../src/image/CsImage.tsx","../src/image/CsImage.styled.tsx","../src/marketing-banner/constants.ts","../src/marketing-banner/components/BannerText.styled.tsx","../src/marketing-banner/styles/theme.ts","../src/marketing-banner/styles/mixins.ts","../src/marketing-banner/components/BannerText.tsx","../src/bynder-media/BynderMedia.tsx","../src/bynder-media/utils.ts","../src/bynder-media/BynderMedia.styled.tsx","../src/marketing-banner/hooks/useCarousel.ts","../src/marketing-banner/hooks/useReducedMotion.ts","../src/marketing-banner/utils/utils.ts","../src/button/Button.tsx","../src/button/Button.styled.tsx","../src/button/helpers.ts","../src/marketing-banner/MarketingBanner.styled.tsx","../src/marketing-banner/MarketingBanner.tsx","../src/spacing-divider/SpacingDivider.styled.tsx","../src/spacing-divider/types.ts","../src/spacing-divider/utils/utils.ts","../src/spacing-divider/SpacingDivider.tsx","../src/column-control/ColumnControl.tsx","../src/column-control/shared.tsx","../src/column-control/ColumnControl.styled.tsx","../src/column-control/types.ts","../src/column-control/utils.ts","../src/column-control/hooks/useColumnControl.ts","../src/column-control/hooks/useColumnControlResize.ts","../src/column-control/Carousel.tsx","../src/content-card/ContentCard.tsx","../src/content-card/ContentCard.styled.ts","../src/content-card/Media.tsx","../src/content-card/Media.styled.tsx","../src/content-card/utils/helpers.ts","../src/hero-banner/components/Typography.tsx","../src/hero-banner/constants.ts","../src/hero-banner/components/TypographyFields.tsx","../src/hero-banner/components/Media.tsx","../src/hero-banner/HeroBanner.styled.tsx","../src/hero-banner/helpers.ts","../src/hero-banner/HeroBanner.tsx","../src/rich-text/RichText.tsx"],"names":["useMemo","styled","languageReplaceExpression","languageReplaceExpressionUppercase","regionReplaceExpression","regionReplaceExpressionUppercase","replaceRegionAndLanguage","text","replacer","region","replace","toUpperCase","language","DEFAULT_REGION","DEFAULT_LANGUAGE","getRegionAndLanguageFromSearch","search","startsWith","params","URLSearchParams","get","getRegionAndLanguageFromPath","pathname","parts","split","filter","Boolean","length","getRegionAndLanguageFromLocation","window","location","useTheme","ColorUtils","getGenomeColor","useToggleFontColor","toggleValue","theme","useToggleFontColor_default","jsx","useRegionLanguage","rewriteUrl","url","rewriteLinks","html","doc","DOMParser","parseFromString","querySelectorAll","forEach","link","href","getAttribute","setAttribute","body","innerHTML","Container","div","fullWidth","bgColor","alignment","color","extractColorFromObject","obj","brandColor","colorObj","light","trim","parseJsonColor","jsonString","JSON","parse","resolveBackgroundColor","value","trimmed","CsText","full_width","container_background_color","text_editor","font_color","$","fontColor","regionLang","backgroundColor","updatedHtml","children","dangerouslySetInnerHTML","__html","CsText_default","NsImage","StyledCsImageWrapper","image_alignment","width","height","display","justifyContent","left","right","center","maxWidth","objectFit","objectPosition","PLACEHOLDER_IMAGE_SRC","encodeURIComponent","allowedImageProps","CsImage","props","align","image","parent$","isEditing","rest","selectedImage","fileMeta","contentstackAsset","parsed","entry","selected","files","err","console","warn","resolvedSrc","resolvedAlt","resolvedWidth","resolvedHeight","imageType","fileSource","altText","title","filename","imageProps","src","alt","key","containerClassForNSImage","className","CsImage_default","DEFAULT_BANNER_CONFIG","position","textColor","showGradient","gradientDepth","mediaType","ctaVariant","DEFAULT_CAROUSEL_CONFIG","rotationInterval","DEFAULT_ROTATION_INTERVAL","PLACEHOLDER_VALUES","header","subtitle","BREAKPOINTS","mobile","tablet","desktop","wide","FONT_STACKS","lora","inter","FONT_SIZES","cta","SPACING","headerMargin","titleMargin","subtitleMargin","bodyMargin","textGap","desktopPadding","mobilePadding","carouselGap","ctaPaddingDesktop","ctaPaddingTablet","ctaPaddingWide","DIMENSIONS","bannerHeightDesktop","bannerHeightMobile","textMaxWidth","indicatorSize","indicatorBorder","COLORS","textWhite","textDark","textGray","ctaDark","ctaBorder","fallbackBg","indicatorActive","indicatorInactive","TEXT_COLOR_MAP","white","dark","TRANSITIONS","fast","default","slow","Z_INDEX","background","media","gradient","content","controls","MEDIA_QUERIES","mobileAndBelow","desktopAndUp","css","responsiveFontSize","sizes","centerOnMobile","smoothTransition","properties","map","prop","join","absoluteFill","absoluteFullSize","centerHorizontal","flexCenter","resetSpacing","gradientOverlay","direction","startOpacity","endOpacity","baseColor","radialGradientOverlay","TextContainer","textAlignment","HeaderText","p","Title","h2","Subtitle","h3","BodyText","jsxs","getDisplayText","placeholderValue","BannerText","headerText","bodyText","testId","titleDisplay","subtitleDisplay","header_text","body_text","React","getMediaUrl","isPublic","previewUrls","fileType","type","generateResponsiveUrl","baseUrl","aspectRatio","URL","ioParam","searchParams","updatedIo","push","origin","error","addDefaultTransform","has","extractBynderMedia","mediaJson","firstImage","mediaUrl","toLowerCase","endsWith","isResponsive","result","desktopUrl","mobileUrl","MediaContainer","StyledImage","img","StyledVideo","video","PictureElement","picture","SourceElement","source","BynderMedia","bynder_media","useState","mediaInfo","setMediaInfo","hasError","setHasError","useEffect","extracted","handleMediaError","mediaAlt","onError","autoPlay","muted","loop","playsInline","srcSet","loading","useCallback","useReducedMotion","prefersReducedMotion","setPrefersReducedMotion","matchMedia","mediaQuery","matches","handleChange","event","addEventListener","removeEventListener","useCarousel","options","totalSlides","autoRotate","pauseOnHover","initialIndex","validInitialIndex","Math","min","currentIndex","setCurrentIndex","isPaused","setIsPaused","goToNext","prev","goToPrevious","goToSlide","index","pause","resume","handleKeyDown","preventDefault","intervalId","setInterval","clearInterval","hasCTA","banner","cta_button","label","isCarouselMode","Array","isArray","banners","hasMedia","NsIcon","NsIconVariants","NsButton","ROUNDED_BORDER_RADIUS","REL_NOOPENER_NOREFERRER","PROTOCOL_HTTP","PROTOCOL_HTTPS","DISABLED_STATE_STRING","DEFAULT_VARIANT","DEFAULT_SIZE","DEFAULT_ALIGNMENT","DEFAULT_ICON_POSITION","DEFAULT_BUTTON_TYPE","DEFAULT_PLACEHOLDER_TEXT","DEFAULT_TARGET","BUTTON_TYPE_ROUNDED","BUTTON_TYPE_SQUARE","BORDER_COLOR_TRANSPARENT","isValidDestination","dest","protocol","resolveTarget","target","resolveDisabled","disabled","iconAliasMap","arrow","resolveIconName","iconName","variantDefaults","primary","bg","hover","pressed","disabledBg","disabledText","focusRing","secondary","border","widthBySize","large","medium","small","DEFAULT_BUTTON_WIDTH","getButtonWidth","size","iconSizeByButtonSize","DEFAULT_ICON_SIZE","getIconSize","BUTTON_GAP","BUTTON_MIN_WIDTH","BUTTON_MIN_HEIGHT","DESKTOP_BREAKPOINT","TABLET_BREAKPOINT","MOBILE_BREAKPOINT","DESKTOP_FONT_SIZE","TABLET_FONT_SIZE","MOBILE_FONT_SIZE","DESKTOP_PADDING","TABLET_PADDING","MOBILE_PADDING","DESKTOP_FONT_WEIGHT","TABLET_MOBILE_FONT_WEIGHT","FOCUS_OUTLINE_WIDTH","FONT_FAMILY_LORA","JUSTIFY_CONTENT_CENTER","JUSTIFY_CONTENT_FLEX_END","JUSTIFY_CONTENT_FLEX_START","getJustifyContent","ButtonContainer","StyledButton","$bg","$hover","$pressed","$text","$border","$disabledBg","$disabledText","$focusRing","$buttonWidth","$buttonType","StyledLabelText","span","ICON_MARGIN_PX","StyledIconWrapper","Button","open_in_new_tab","variant","button_size","buttonType","buttontype","icon","iconposition","iconPosition","button_state","placeholderText","placeholder_text","resolvedVariant","resolvedSize","resolvedAlignment","resolvedIconPosition","resolvedButtonType","resolvedUrl","hrefProp","variantDefault","buttonWidth","resolvedTarget","resolvedDisabled","buttonBorder","IconName","isValidNsIcon","iconSize","renderIcon","iconColor","name","colorOverride","getLabelText","labelTitle","$variant","rel","Button_default","BannerContainer","CarouselWrapper","CarouselTrack","BannerSlide","BannerContent","MediaWrapper","TextContentWrapper","GradientOverlay","depth","opacities","sm","start","end","md","lg","ButtonWrapper","CarouselControls","Indicator","button","active","renderBanner","showMedia","showCTA","baseTestId","resolvedTextColor","text_color","show_gradient","content_position","gradientColor","gradientDirection","gradient_depth","MarketingBannerComponent","rotation_interval","isCarousel","carousel","onKeyDown","onMouseEnter","onMouseLeave","onClick","THICKNESS_PX","thin","thick","ultra","StyledSpacingContainer","vertical_padding","divider_alignment","v","none","flexDirection","alignItems","paddingTop","paddingBottom","StyledDividerLine","divider_style","divider_thickness_px","divider_color","divider_gradient","divider_width_percent","base","max","backgroundImage","backgroundSize","dashLength","gapLength","maskImage","WebkitMaskImage","dotSize","spacing","radius","maskSize","WebkitMaskSize","maskRepeat","WebkitMaskRepeat","maskPosition","WebkitMaskPosition","borderBottomStyle","borderBottomWidth","borderBottomColor","isValidHex","test","hexToRgb","hex","r","parseInt","slice","g","b","gradientPresetCss","preset","baseHex","rgb","DEFAULT_HEX","SpacingDivider","divider_thickness","divider_gradient_preset","finalDividerColor","SpacingDivider_default","SliderImport","GAP_PRESET_VALUES","getGapPx","gap","DEVICE_SIZES","ULTRA_SMALL","EXTRA_SMALL","SMALL","MEDIUM","LARGE","EXTRA_LARGE","ULTRA_LARGE","SUPER_LARGE","MIN_SLIDE_WIDTH_PX","MIN_SLIDE_HEIGHT_PX","MAX_SLIDE_HEIGHT_PX","MIN_EMPTY_PLACEHOLDER_HEIGHT_PX","MAX_ALLOWED_COLUMN_CONTROL_ITEMS","getArrowButtonPosition","fullVal","nonFullVal","ColumnControlContainer","columnHeight","maxColumnHeight","dotsInside","textAlign","padding","boxSizing","overflow","minHeight","margin","maxHeight","bottom","listStyle","li","borderRadius","textIndent","cursor","transition","TabletGridContainer","flexWrap","SlideSection","useFlexLayout","stackedVerticalGap","stackedItemHeight","stackedItemMaxHeight","slideWidth","flexBasis","isVariableWidth","flex","minWidth","SlideInner","SlideContentInner","ArrowButton","top","transform","zIndex","fontSize","lineHeight","verticalAlign","outline","outlineOffset","opacity","InnerWrapper","EmptyPlaceholderWrapper","getViewportLayoutState","isGridLayout","windowWidth","gapPx","isStackedViewport","isTabletGridViewport","containerHeight","getSlidesMeta","slides","presetColumns","presetSlidesToShow","effectiveShowPagination","gridSlides","slidesToShow","shouldShowDots","unwrapComponent","mod","EmptyPlaceholder","emptyBlockParentClass","createElement","getPresetColumns","isVariableWidthPreset","getVariableSlideWidth","pos","getSlidesToShowByViewport","EMPTY_SLIDE_SENTINEL","__emptyPlaceholder","isEmptySlide","slide","isRealSlide","padSlidesToPreset","targetCount","padCount","fill","getSlidesForRender","buildResponsiveSettings","effectiveSlidesCount","slideCount","hasPlaceholders","gridSlidesToShow","maxCols","carouselSlidesToShow","breakpoint","settings","slidesToScroll","swipeToSlide","arrows","dots","variableWidth","Slider","CONTAINER_CLASS","getSlideKey","isPlaceholder","id","String","getSlideContent","renderSlide","emptyPlaceholderText","renderSlidesContent","slidesForRender","getSlideWidth","addSlideEditTags","slides__parent","renderContentOrEmpty","hasSlides","useRef","useColumnControlResize","innerWidth","setWindowWidth","Date","now","carouselKey","setCarouselKey","timeoutId","handleResize","clearTimeout","setTimeout","useColumnControl","layout","autoplayEnabled","autoplayDuration","showPagination","onSlideChange","slickSettings","emptyPlaceholderTextProp","effectiveFullWidth","effectiveAutoplayEnabled","showArrowsOnDesktop","viewportLayout","effectiveShouldShowDots","sliderRef","current","slickPrev","slickNext","containerClassName","slidesForRenderPadded","effectivePresetColumns","effectiveSlidesToShow","responsiveSettings","sliderSettings","infinite","speed","autoplay","autoplaySpeed","swipe","draggable","beforeChange","_","next","responsive","renderSlides","slidesLength","GridLayoutContent","ref","ColumnControl","gridProps","ColumnControl_default","Fragment","Carousel","dotsPosition","carouselProps","Card","article","$maxHeight","Content","Body","CtaWrapper","$height","ContentInner","$mediaStyle","$mediaHeight","isNaturalSize","FallbackMessage","Media","fallbackMediaUrl","media_style","mediaHeight","currentUrl","setCurrentUrl","renderMedia","getTitle","normalizeContentAlignment","MEDIA_STYLE_VALUES","normalizeMediaStyle","includes","normalizeCtaStyle","ctaStyle","normalizeContentCardMedia","bynder","ContentCard","cardMediaStyle","cta_style","content_alignment","max_height","background_color","border_radius","ctaStyleNormalized","normalizedMedia","mediaStyle","hasCtaHref","hasCtaLabel","isCardLink","showButton","ctaHeight","cardTarget","contentTitle","as","ContentCard_default","NsTypography","Typography","placeholder","typographyProps","displayValue","PLACEHOLDER_BRAND_CAPTION","PLACEHOLDER_TITLE","PLACEHOLDER_SUBTITLE","PLACEHOLDER_BODY","ARIA_LABEL_HERO_BANNER","IMAGE_LOADING_LAZY","getTypographyFields","brandcaption","noSpacing","editTagKey","weight","TypographyFields","editTags","fields","field","additionalProps","FULL_SIZE_PERCENT","isMediaObject","parseMedia","resolveContentAlignment","contentAlignment","resolveGradientDepth","resolveTextColor","getGradientColor","gradientDirectionMap","getGradientDirection","GRADIENT_OPACITIES","getGradientBackground","Overlay","HERO_CTA_WRAPPER_CLASS","forwardRef","parsedMedia","mediaAttributes","renderImage","commonImageProps","mediaContent","preload","style","displayName","HeroBanner","class_name","gradientEnabled","gradient_enabled","resolvedContentAlignment","resolvedGradientDepth","shouldRenderButton","HeroBanner_default","DOMPurify","SANITIZATION_CONFIG","ALLOWED_TAGS","ALLOWED_ATTR","sanitizeHtml","sanitize","KEEP_CONTENT","RETURN_DOM","RETURN_DOM_FRAGMENT","FORCE_BODY","SANITIZE_DOM","IN_PLACE","RichText","restProps","sanitizedHtml","fontColorBoolean","RichText_default"],"mappings":"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","sourcesContent":["import { ReactElement, useMemo } from 'react';\nimport styled from '@emotion/styled';\nimport { useToggleFontColor } from '../hooks';\nimport { getRegionAndLanguageFromLocation, RegionLanguageQuery, replaceRegionAndLanguage } from '../utils/route-utils';\n\ninterface CsTextProps {\n full_width?: boolean;\n container_background_color?: unknown;\n alignment?: 'left' | 'center' | 'right';\n text_editor: string;\n font_color?: boolean;\n $?: {\n text_editor?: Record<string, unknown>;\n };\n}\n\n// Get region + language once\nconst useRegionLanguage = () => {\n return useMemo(() => getRegionAndLanguageFromLocation(), []);\n};\n\n// Replace region and language in a single URL\nconst rewriteUrl = (url: string, replacer?: RegionLanguageQuery): string => {\n if (!replacer || !url) return url;\n return replaceRegionAndLanguage(url, replacer);\n};\n\n// Rewrite all <a> links inside CMS HTML\nexport const rewriteLinks = (html: string, replacer?: RegionLanguageQuery): string => {\n if (typeof window === 'undefined' || !html || !replacer) return html;\n\n const parser = new DOMParser();\n const doc = parser.parseFromString(html, 'text/html');\n\n doc.querySelectorAll('a').forEach((link) => {\n const href = link.getAttribute('href');\n if (!href) return;\n link.setAttribute('href', rewriteUrl(href, replacer));\n });\n\n return doc.body.innerHTML;\n};\n\n// Styled container for CMS text\nconst Container = styled.div<{\n fullWidth: boolean;\n bgColor: string;\n alignment: string;\n color: string;\n}>`\n width: ${({ fullWidth }) => (fullWidth ? '100%' : 'auto')};\n background-color: ${({ bgColor }) => bgColor};\n text-align: ${({ alignment }) => alignment};\n color: ${({ color }) => color};\n padding: 16px 32px;\n\n h1,\n h2,\n h3,\n h4,\n h5,\n h6 {\n font-family: 'Lora', serif;\n }\n\n h1 {\n font-size: 42px;\n line-height: 48px;\n }\n h2 {\n font-size: 36px;\n line-height: 42px;\n }\n h3 {\n font-size: 32px;\n line-height: 38px;\n }\n h4 {\n font-size: 26px;\n line-height: 34px;\n }\n h5 {\n font-size: 22px;\n line-height: 28px;\n }\n h6 {\n font-size: 18px;\n line-height: 24px;\n }\n\n p {\n margin: 0;\n padding: 0;\n }\n`;\n\n// Safely resolve CMS background color\nconst extractColorFromObject = (obj: any): string | null => {\n const color = obj?.brandColor?.colorObj?.light ?? obj?.color;\n return typeof color === 'string' && color.trim() ? color : null;\n};\n\nconst parseJsonColor = (jsonString: string): string | null => {\n try {\n const parsed = JSON.parse(jsonString);\n const color = parsed?.brandColor?.colorObj?.light;\n return typeof color === 'string' && color.trim() ? color : null;\n } catch {\n return null;\n }\n};\n\nconst resolveBackgroundColor = (value: unknown): string => {\n // null, undefined, false, 0, '' → transparent\n if (!value) return 'transparent';\n\n // CMS object\n if (typeof value === 'object') {\n const color = extractColorFromObject(value);\n return color ?? 'transparent';\n }\n\n // CMS string\n if (typeof value === 'string') {\n const trimmed = value.trim();\n if (!trimmed) return 'transparent';\n\n // JSON string\n if (trimmed.startsWith('{')) {\n const color = parseJsonColor(trimmed);\n return color ?? 'transparent';\n }\n\n // Normal CSS color\n return trimmed;\n }\n\n // numbers, booleans, etc\n return 'transparent';\n};\n\nconst CsText = ({\n full_width = false,\n container_background_color,\n alignment = 'left',\n text_editor,\n font_color = false,\n $\n}: CsTextProps): ReactElement | null => {\n const fontColor = useToggleFontColor(font_color);\n const regionLang = useRegionLanguage();\n\n const backgroundColor = useMemo(\n () => resolveBackgroundColor(container_background_color),\n [container_background_color],\n );\n\n const updatedHtml = useMemo(() => rewriteLinks(text_editor, regionLang), [text_editor, regionLang]);\n\n if (!text_editor) return null;\n\n return (\n <Container fullWidth={full_width} bgColor={backgroundColor} alignment={alignment} color={fontColor}>\n <div dangerouslySetInnerHTML={{ __html: updatedHtml }} {...$?.text_editor} />\n </Container>\n );\n};\n\nexport default CsText;\n","import { useMemo } from 'react';\nimport { getRegionAndLanguageFromLocation, replaceRegionAndLanguage, RegionLanguageQuery } from '../utils/route-utils';\n\n/**\n * Simply use this hook to update the region and language in the url\n * Note: urlToParse should have {%region} or {%language} or {%rREGION} or {%LANGUAGE}\n * @param urlToParse url to be parsed\n * @returns urlToParse after conditionally replacing the region and language\n */\nconst useRouteReplacer = (urlToParse?: string): { url?: string } => {\n const replacer: RegionLanguageQuery | undefined = useMemo(() => getRegionAndLanguageFromLocation(), []);\n\n const url = useMemo(() => {\n if (!urlToParse || !replacer) return undefined;\n return replaceRegionAndLanguage(urlToParse, replacer);\n }, [urlToParse, replacer]);\n\n return { url };\n};\n\nexport default useRouteReplacer;\n","const languageReplaceExpression = '{%language}';\nconst languageReplaceExpressionUppercase = '{%LANGUAGE}';\nconst regionReplaceExpression = '{%region}';\nconst regionReplaceExpressionUppercase = '{%REGION}';\n\nexport type RegionLanguageQuery = {\n region?: string;\n language?: string;\n slug?: string;\n};\n\n/**\n * Replace {%region}, {%language} placeholders in text\n */\nexport const replaceRegionAndLanguage = (text: string, replacer: RegionLanguageQuery = {}): string => {\n if (typeof text !== 'string') {\n return '';\n }\n\n if (replacer.region) {\n text = text.replace(regionReplaceExpression, replacer.region);\n text = text.replace(regionReplaceExpressionUppercase, replacer.region.toUpperCase());\n }\n\n if (replacer.language) {\n text = text.replace(languageReplaceExpression, replacer.language);\n text = text.replace(languageReplaceExpressionUppercase, replacer.language.toUpperCase());\n }\n\n return text;\n};\n\n/**\n * Replace dynamic pathname segments like [region], [language]\n */\nexport const replacePathnameWithQueryParams = (pathname: string, queryParams: RegionLanguageQuery): string => {\n if (!pathname || typeof pathname !== 'string') {\n return '';\n }\n\n let formattedUrl = pathname;\n\n if (queryParams.region) {\n formattedUrl = formattedUrl.replace('[region]', queryParams.region);\n }\n\n if (queryParams.language) {\n formattedUrl = formattedUrl.replace('[language]', queryParams.language);\n }\n\n if (queryParams.slug) {\n formattedUrl = formattedUrl.replace('[[...slug]]', queryParams.slug);\n }\n\n return formattedUrl;\n};\n\n/**\n * Extract region & language from a query object\n */\nexport const getRegionAndLanguageFromQuery = (\n query?: Record<string, string | string[] | undefined>,\n): RegionLanguageQuery | undefined => {\n if (!query) return undefined;\n\n const region = Array.isArray(query.region) ? query.region[0] : query.region;\n\n const language = Array.isArray(query.language) ? query.language[0] : query.language;\n\n if (region || language) {\n return { region, language };\n }\n\n return undefined;\n};\n\n/**\n * ✅ Next.js Router replacement\n * Reads from browser URL safely\n */\nconst DEFAULT_REGION = 'us';\nconst DEFAULT_LANGUAGE = 'en';\n\nfunction getRegionAndLanguageFromSearch(search?: string | null): RegionLanguageQuery | undefined {\n if (!search?.startsWith?.('?')) {\n return undefined;\n }\n\n const params = new URLSearchParams(search);\n const region = params.get('region');\n const language = params.get('language');\n\n if (!region && !language) {\n return undefined;\n }\n\n return {\n region: region ?? DEFAULT_REGION,\n language: language ?? DEFAULT_LANGUAGE\n };\n}\n\nfunction getRegionAndLanguageFromPath(pathname?: string | null): RegionLanguageQuery | undefined {\n if (!pathname) {\n return undefined;\n }\n\n const parts = pathname.split('/').filter(Boolean);\n if (parts.length < 2) {\n return undefined;\n }\n\n const [region, language] = parts;\n if (region?.length === 2 && language?.length === 2) {\n return { region, language };\n }\n\n return undefined;\n}\n\nexport const getRegionAndLanguageFromLocation = (): RegionLanguageQuery => {\n // ---------- SSR ----------\n if (typeof window === 'undefined' || !window.location) {\n return { region: DEFAULT_REGION, language: DEFAULT_LANGUAGE };\n }\n\n const { search, pathname } = window.location;\n\n // Try query params first, then path, then defaults\n return (\n getRegionAndLanguageFromSearch(search) ??\n getRegionAndLanguageFromPath(pathname) ?? {\n region: DEFAULT_REGION,\n language: DEFAULT_LANGUAGE\n }\n );\n};","import { useMemo } from 'react';\n\nimport { useTheme } from '@mui/material';\nimport { ColorUtils } from '@nuskin/foundation-theme';\n\nconst { getGenomeColor } = ColorUtils;\n\n/**\n * @returns {main:#FFFFFF, contrast:#252525} when passed true\n */\nconst useMainContrast = (toggleValue: boolean = false): { main: string; contrast: string } => {\n const theme = useTheme();\n\n return useMemo(() => {\n const main = getGenomeColor(theme, 'N10', toggleValue ? 'light' : 'dark');\n const contrast = getGenomeColor(theme, 'N10', toggleValue ? 'dark' : 'light');\n return { main, contrast };\n }, [toggleValue, theme]);\n};\n\nexport default useMainContrast;\n","import { useTheme } from '@mui/material';\nimport { ColorUtils } from '@nuskin/foundation-theme';\nimport { useMemo } from 'react';\n\nconst { getGenomeColor } = ColorUtils;\n/**\n * Used to fetch the appropriate theme color for primary and contrast.\n * Usually black or similar, and white for contrast.\n * @param toggleValue the CS toggle value between black and white font color.\n * @returns hex value of the color.\n */\nconst useToggleFontColor = (toggleValue: boolean = false): string => {\n const theme = useTheme();\n\n return useMemo(\n () => getGenomeColor(theme, 'N10', toggleValue ? 'light' : 'dark'),\n [toggleValue, theme]\n );\n};\n\nexport default useToggleFontColor;\n","import { NsImage } from '@nuskin/foundation-ui-components';\nimport { StyledCsImageWrapper } from './CsImage.styled';\nimport type { ContentstackAsset, CsImageProps, ImageFile, ImageFileMeta, NsImageProps } from './types';\n\n// Inline SVG data URL used as a safe placeholder when the main image is unavailable\nexport const PLACEHOLDER_IMAGE_SRC =\n 'data:image/svg+xml;utf8,' +\n encodeURIComponent(\n `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 400 300\" role=\"img\" aria-label=\"Image not available\">\n <defs>\n <linearGradient id=\"csImagePlaceholderGradient\" x1=\"0\" y1=\"0\" x2=\"1\" y2=\"1\">\n <stop offset=\"0%\" stop-color=\"#f3f4f6\" />\n <stop offset=\"100%\" stop-color=\"#e5e7eb\" />\n </linearGradient>\n </defs>\n <rect width=\"400\" height=\"300\" fill=\"url(#csImagePlaceholderGradient)\" />\n <g stroke=\"#d1d5db\" stroke-width=\"4\" stroke-linecap=\"round\" stroke-linejoin=\"round\" fill=\"none\">\n <rect x=\"60\" y=\"60\" width=\"280\" height=\"180\" rx=\"12\" />\n <path d=\"M120 200 L180 140 L230 185 L260 160 L320 210\" />\n <circle cx=\"160\" cy=\"120\" r=\"20\" />\n </g>\n </svg>`,\n );\n\nconst allowedImageProps: (keyof NsImageProps)[] = [\n 'alt',\n 'className',\n 'fill',\n 'height',\n 'id',\n 'src',\n 'variant',\n 'width'\n];\n\nconst CsImage = (props: CsImageProps) => {\n const { image_alignment: align = 'center', image, parent$, isEditing, $, ...rest } = props;\n\n let selectedImage: ImageFile | null = null;\n let fileMeta: Record<string, ImageFileMeta> | null = null;\n let contentstackAsset: ContentstackAsset | null = null;\n\n try {\n const parsed = typeof image === 'string' ? JSON.parse(image) : image;\n \n // Try Bynder format first: { image: [{ selected, files }] }\n const entry = parsed?.image?.[0];\n if (entry?.selected || entry?.files) {\n selectedImage = entry?.selected;\n fileMeta = entry?.files;\n } else if (parsed?.url) {\n // Fallback: Contentstack native asset format\n contentstackAsset = parsed;\n }\n } catch (err) {\n console.warn('[CsImage] Failed to parse image prop:', err);\n }\n\n let resolvedSrc = PLACEHOLDER_IMAGE_SRC;\n let resolvedAlt = 'Image not available';\n let resolvedWidth: number | string = '100%';\n let resolvedHeight: number | string = '100%';\n\n // Bynder format\n if (selectedImage || fileMeta) {\n const imageType = selectedImage?.imageType ?? 'transformBaseUrl';\n const fileSource = fileMeta?.[imageType];\n\n \n if (fileSource?.url) {\n resolvedSrc = fileSource.url;\n resolvedAlt = selectedImage?.altText ?? 'Image';\n resolvedWidth = selectedImage?.width ?? '100%';\n resolvedHeight = selectedImage?.height ?? '100%';\n }\n } \n // Contentstack asset fallback\n else if (contentstackAsset?.url) {\n resolvedSrc = contentstackAsset.url;\n resolvedAlt = contentstackAsset.title || contentstackAsset.filename || 'Image';\n // Contentstack assets don't provide width/height in metadata, keep defaults\n }\n\n const imageProps: NsImageProps = {\n src: resolvedSrc,\n alt: resolvedAlt,\n width: resolvedWidth,\n height: resolvedHeight\n };\n\n // Add any other valid props from rest\n allowedImageProps.forEach((key) => {\n if (rest[key] !== undefined) {\n (imageProps as Record<string, unknown>)[key] = rest[key];\n }\n });\n\n const containerClassForNSImage = rest?.full_width ? 'container !p-0' : '';\n\n return (\n <StyledCsImageWrapper\n image_alignment={align}\n width={imageProps.width}\n height={imageProps.height}\n className={containerClassForNSImage}\n >\n <NsImage {...imageProps} {...($?.image || {})} />\n </StyledCsImageWrapper>\n );\n};\n\nexport default CsImage;\n","import { styled } from '@nuskin/foundation-theme';\nimport type { CsImageProps } from './types';\n\nexport const StyledCsImageWrapper = styled('div')<\n Pick<CsImageProps, 'image_alignment'> & { width?: string | number; height?: string | number }\n>(({ image_alignment = 'center', width, height }) => ({\n display: 'flex',\n justifyContent: {\n left: 'flex-start',\n right: 'flex-end',\n center: 'center'\n }[image_alignment],\n '& img': {\n maxWidth: 'fit-content',\n objectFit: 'contain',\n objectPosition: 'center'\n }\n}));\n","/**\n * Default Configurations\n * Marketing Banner Component\n */\n\nexport const DEFAULT_BANNER_CONFIG = {\n position: 'left' as const,\n textColor: 'white' as const,\n showGradient: false,\n gradientDepth: 'md' as const,\n mediaType: 'image' as const,\n ctaVariant: 'dark' as const\n};\n\nexport const DEFAULT_CAROUSEL_CONFIG = {\n rotationInterval: 5000\n};\n\nexport const DEFAULT_ROTATION_INTERVAL = 5000;\n\nexport const PLACEHOLDER_VALUES = {\n header: 'Enter Header',\n title: 'Enter Title',\n subtitle: 'Enter Subtitle',\n body: 'Enter Body Text'\n} as const;\n","import styled from '@emotion/styled';\nimport type { TextAlignment } from '../types';\nimport { FONT_STACKS, FONT_SIZES, SPACING } from '../styles/theme';\nimport { responsiveFontSize, centerOnMobile } from '../styles/mixins';\n\nexport const TextContainer = styled.div<{\n textAlignment: TextAlignment;\n}>`\n text-align: ${({ textAlignment }) => textAlignment};\n max-width: 90vw;\n overflow-wrap: break-word;\n ${centerOnMobile}\n`;\n\nexport const HeaderText = styled.p<{\n fontColor: string;\n}>`\n margin: ${SPACING.headerMargin};\n font-weight: 500;\n font-family: ${FONT_STACKS.inter};\n color: ${({ fontColor }) => fontColor};\n letter-spacing: 0.05em;\n ${responsiveFontSize(FONT_SIZES.header)}\n`;\n\nexport const Title = styled.h2<{\n fontColor: string;\n}>`\n margin: ${SPACING.titleMargin};\n font-weight: 700;\n font-family: ${FONT_STACKS.lora};\n color: ${({ fontColor }) => fontColor};\n ${responsiveFontSize(FONT_SIZES.title)}\n`;\n\nexport const Subtitle = styled.h3<{\n fontColor: string;\n}>`\n margin: ${SPACING.subtitleMargin};\n font-weight: 600;\n font-family: ${FONT_STACKS.inter};\n color: ${({ fontColor }) => fontColor};\n ${responsiveFontSize(FONT_SIZES.subtitle)}\n`;\n\nexport const BodyText = styled.p<{\n fontColor: string;\n}>`\n margin: ${SPACING.bodyMargin};\n line-height: 1.6;\n font-family: ${FONT_STACKS.inter};\n color: ${({ fontColor }) => fontColor};\n ${responsiveFontSize(FONT_SIZES.body)}\n`;\n","/**\n * Marketing Banner Theme Constants\n * Centralized design tokens for all components\n */\n\nexport const BREAKPOINTS = {\n mobile: 0,\n tablet: 768,\n desktop: 1024,\n wide: 1440\n} as const;\n\nexport const FONT_STACKS = {\n lora: \"'Lora', Georgia, 'Times New Roman', serif\",\n inter: \"'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif\"\n} as const;\n\nexport const FONT_SIZES = {\n header: {\n mobile: '12px',\n tablet: '14px',\n desktop: '14px',\n wide: '16px'\n },\n title: {\n mobile: '24px',\n tablet: '32px',\n desktop: '40px',\n wide: '48px'\n },\n subtitle: {\n mobile: '16px',\n tablet: '18px',\n desktop: '20px',\n wide: '22px'\n },\n body: {\n mobile: '14px',\n tablet: '16px',\n desktop: '18px',\n wide: '20px'\n },\n cta: {\n mobile: '18px',\n tablet: '22px',\n wide: '24px'\n }\n} as const;\n\nexport const SPACING = {\n // Text component spacing\n headerMargin: '0 0 0.25rem 0',\n titleMargin: '0 0 0.75rem 0',\n subtitleMargin: '0 0 0.5rem 0',\n bodyMargin: '0',\n\n // Layout spacing\n textGap: '1.5rem',\n desktopPadding: '3rem',\n mobilePadding: '2rem',\n carouselGap: '0.75rem',\n\n // CTA spacing\n ctaPaddingDesktop: '16px 32px',\n ctaPaddingTablet: '12px 28px',\n ctaPaddingWide: '18px 36px'\n} as const;\n\nexport const DIMENSIONS = {\n // Banner height\n bannerHeightDesktop: '600px',\n bannerHeightMobile: '400px',\n\n // Text container\n textMaxWidth: '600px',\n\n // Carousel indicators\n indicatorSize: '12px',\n indicatorBorder: '2px'\n} as const;\n\nexport const COLORS = {\n // Text colors\n textWhite: '#ffffff',\n textDark: '#1D1D1B',\n textGray: '#666',\n\n // CTA colors\n ctaDark: '#888888',\n ctaBorder: '#888888',\n\n // Media fallback\n fallbackBg: '#f0f0f0',\n\n // Indicator colors\n indicatorBorder: 'rgba(255, 255, 255, 0.9)',\n indicatorActive: 'rgba(255, 255, 255, 0.9)',\n indicatorInactive: 'transparent'\n} as const;\n\nexport const TEXT_COLOR_MAP = {\n white: COLORS.textWhite,\n dark: COLORS.textDark\n} as const;\n\nexport const TRANSITIONS = {\n fast: '0.1s ease',\n default: '0.3s ease',\n slow: '0.6s cubic-bezier(0.4, 0, 0.2, 1)'\n} as const;\n\nexport const Z_INDEX = {\n background: 0,\n media: 0,\n gradient: 1,\n content: 2,\n controls: 3\n} as const;\n\nexport const MEDIA_QUERIES = {\n tablet: `@media (min-width: ${BREAKPOINTS.tablet + 1}px) and (max-width: ${BREAKPOINTS.desktop - 1}px)`,\n desktop: `@media (min-width: ${BREAKPOINTS.desktop}px) and (max-width: ${BREAKPOINTS.wide - 1}px)`,\n wide: `@media (min-width: ${BREAKPOINTS.wide}px)`,\n mobileAndBelow: `@media (max-width: ${BREAKPOINTS.tablet}px)`,\n desktopAndUp: `@media (min-width: ${BREAKPOINTS.desktop}px)`\n} as const;\n","/**\n * Marketing Banner Styled Component Mixins\n * Reusable CSS patterns and helper functions\n */\n\nimport { css } from '@emotion/react';\nimport { MEDIA_QUERIES, TRANSITIONS } from './theme';\n\n/**\n * Responsive font sizing\n * Applies font-size at different breakpoints\n */\nexport const responsiveFontSize = (sizes: Record<string, string>) => css`\n font-size: ${sizes.mobile};\n\n ${MEDIA_QUERIES.tablet} {\n font-size: ${sizes.tablet || sizes.mobile};\n }\n ${MEDIA_QUERIES.desktop} {\n font-size: ${sizes.desktop || sizes.tablet || sizes.mobile};\n }\n ${MEDIA_QUERIES.wide} {\n font-size: ${sizes.wide || sizes.desktop || sizes.tablet || sizes.mobile};\n }\n`;\n\n/**\n * Center text on mobile, preserve positioning on desktop\n */\nexport const centerOnMobile = css`\n ${MEDIA_QUERIES.mobileAndBelow} {\n text-align: center;\n }\n`;\n\n/**\n * Smooth transitions for interactive elements\n */\nexport const smoothTransition = (\n properties: string[] = ['background-color', 'color', 'border-color', 'transform', 'text-decoration']\n) => css`\n transition: ${properties.map((prop) => `${prop} ${TRANSITIONS.default}`).join(', ')};\n`;\n\n/**\n * Focus outline styling for accessibility\n */\nexport const focusOutline = (color: string) => css`\n &:focus-visible {\n outline: 2px solid ${color};\n outline-offset: 4px;\n }\n`;\n\n/**\n * Absolute fill (cover parent completely)\n */\nexport const absoluteFill = css`\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n`;\n\n/**\n * Absolute positioning with dimensions\n */\nexport const absoluteFullSize = css`\n ${absoluteFill}\n width: 100%;\n height: 100%;\n`;\n\n/**\n * Center positioning (horizontal only)\n */\nexport const centerHorizontal = css`\n position: absolute;\n left: 50%;\n transform: translateX(-50%);\n`;\n\n/**\n * Flex center alignment\n */\nexport const flexCenter = css`\n display: flex;\n align-items: center;\n justify-content: center;\n`;\n\n/**\n * Removes all margins and padding\n */\nexport const resetSpacing = css`\n margin: 0;\n padding: 0;\n`;\n\n/**\n * CTA hover state with transform\n */\nexport const ctaHoverState = (backgroundColor: string, borderColor: string, textColor: string) => css`\n &:hover {\n background-color: ${backgroundColor};\n color: ${textColor};\n border-color: ${borderColor};\n text-decoration: underline;\n transform: translateY(-2px);\n }\n`;\n\n/**\n * Gradient overlay mixin\n */\nexport const gradientOverlay = (direction: string, startOpacity: number, endOpacity: number, baseColor: string) => css`\n background: linear-gradient(${direction}, rgba(${baseColor}, ${startOpacity}), rgba(${baseColor}, ${endOpacity}));\n`;\n\n/**\n * Radial gradient overlay mixin\n */\nexport const radialGradientOverlay = (startOpacity: number, endOpacity: number, baseColor: string) => css`\n background: radial-gradient(circle, rgba(${baseColor}, ${startOpacity}), rgba(${baseColor}, ${endOpacity}));\n`;\n","/**\n * BannerText Sub-Component\n * Renders text content (title, subtitle, bodyText) with responsive styling\n */\n\nimport React from 'react';\nimport type { BannerTextProps } from '../types';\nimport { PLACEHOLDER_VALUES } from '../constants';\nimport { TextContainer, HeaderText, Title, Subtitle, BodyText } from './BannerText.styled';\n\nfunction getDisplayText(text: string | undefined, placeholderValue: string, isEditing?: boolean): string | undefined {\n if (isEditing === true && (!text || text === placeholderValue)) {\n return placeholderValue;\n }\n if (isEditing === false && text === placeholderValue) {\n return undefined;\n }\n return text;\n}\n\nexport function BannerText({\n headerText,\n title,\n subtitle,\n bodyText,\n textColor = '#ffffff',\n textAlignment = 'left',\n testId,\n $,\n isEditing\n}: Readonly<BannerTextProps>): React.ReactElement | null {\n const header = getDisplayText(headerText, PLACEHOLDER_VALUES.header, isEditing);\n const titleDisplay = getDisplayText(title, PLACEHOLDER_VALUES.title, isEditing);\n const subtitleDisplay = getDisplayText(subtitle, PLACEHOLDER_VALUES.subtitle, isEditing);\n const body = getDisplayText(bodyText, PLACEHOLDER_VALUES.body, isEditing);\n\n if (!header && !titleDisplay && !subtitleDisplay && !body) {\n return null;\n }\n\n return (\n <TextContainer textAlignment={textAlignment} data-testid={testId}>\n {header && (\n <HeaderText fontColor={textColor} aria-label={header} {...($?.header_text ?? {})}>\n {header}\n </HeaderText>\n )}\n {titleDisplay && (\n <Title fontColor={textColor} aria-label={titleDisplay} {...($?.title ?? {})}>\n {titleDisplay}\n </Title>\n )}\n {subtitleDisplay && (\n <Subtitle fontColor={textColor} aria-label={subtitleDisplay} {...($?.subtitle ?? {})}>\n {subtitleDisplay}\n </Subtitle>\n )}\n {body && (\n <BodyText fontColor={textColor} aria-label={body} {...($?.body_text ?? {})}>\n {body}\n </BodyText>\n )}\n </TextContainer>\n );\n}\n","import React from 'react';\nimport { extractBynderMedia } from './utils';\nimport { MediaContainer, StyledImage, StyledVideo, PictureElement, SourceElement } from './BynderMedia.styled';\nimport type { BynderMediaProps } from './types';\n\nexport function BynderMedia({ bynder_media, $ }: Readonly<BynderMediaProps>): React.ReactElement | null {\n const [mediaInfo, setMediaInfo] = React.useState<ReturnType<typeof extractBynderMedia>>(null);\n const [hasError, setHasError] = React.useState(false);\n\n // Extract media data from bynder_media JSON string\n React.useEffect(() => {\n const extracted = extractBynderMedia(bynder_media);\n setMediaInfo(extracted);\n setHasError(!extracted);\n }, [bynder_media]);\n\n const handleMediaError = () => {\n setHasError(true);\n };\n\n if (!mediaInfo || hasError) {\n return null;\n }\n\n const mediaType = mediaInfo.type;\n const mediaAlt = mediaInfo.alt;\n const isResponsive = mediaInfo.isResponsive ?? false;\n const desktopUrl = mediaInfo.desktopUrl;\n const mobileUrl = mediaInfo.mobileUrl;\n const mediaUrl = mediaInfo.url;\n\n if (mediaType === 'video') {\n return (\n <MediaContainer {...($?.bynder_media ?? {})}>\n <StyledVideo\n src={mediaUrl}\n onError={handleMediaError}\n autoPlay\n muted\n loop\n playsInline\n {...($?.bynder_media ?? {})}\n />\n </MediaContainer>\n );\n }\n\n // Responsive image with picture element\n if (isResponsive && mobileUrl && desktopUrl) {\n return (\n <MediaContainer {...($?.bynder_media ?? {})}>\n <PictureElement>\n <SourceElement media=\"(max-width: 768px)\" srcSet={mobileUrl} />\n <SourceElement media=\"(min-width: 769px)\" srcSet={desktopUrl} />\n <StyledImage\n src={desktopUrl}\n alt={mediaAlt}\n onError={handleMediaError}\n loading=\"lazy\"\n {...($?.bynder_media ?? {})}\n />\n </PictureElement>\n </MediaContainer>\n );\n }\n\n // Standard image\n return (\n <MediaContainer {...($?.bynder_media ?? {})}>\n <StyledImage\n src={mediaUrl}\n alt={mediaAlt}\n onError={handleMediaError}\n loading=\"lazy\"\n {...($?.bynder_media ?? {})}\n />\n </MediaContainer>\n );\n}\n","import { BynderImageDataType, BynderMediaExtracted, BynderMediaType } from './types';\n\nexport function getMediaUrl(\n selected: BynderImageDataType['selected'],\n isPublic: boolean,\n previewUrls: BynderImageDataType['previewUrls']\n): string {\n const { url = '', type: fileType = '' } = selected ?? {};\n if (fileType === 'VIDEO') {\n if (isPublic) {\n return url;\n } else {\n return previewUrls?.[0] ?? '';\n }\n }\n return url;\n}\n\nfunction generateResponsiveUrl(baseUrl: string, aspectRatio: string): string {\n try {\n const url = new URL(baseUrl);\n const ioParam = url.searchParams.get('io');\n\n if (!ioParam) return baseUrl;\n\n const updatedIo = `${ioParam},aspectratio:${aspectRatio}`;\n\n const params: string[] = [];\n params.push(`io=${updatedIo}`);\n params.push('quality=95');\n\n url.searchParams.forEach((value, key) => {\n if (key !== 'io') {\n params.push(`${key}=${value}`);\n }\n });\n\n return `${url.origin}${url.pathname}?${params.join('&')}`;\n } catch (error) {\n console.warn('Failed to generate responsive URL:', error);\n return baseUrl;\n }\n}\n\nfunction addDefaultTransform(baseUrl: string): string {\n try {\n const url = new URL(baseUrl);\n if (!url.searchParams.has('io')) {\n return `${baseUrl}?io=transform:fill&quality=95`;\n }\n return baseUrl;\n } catch (error) {\n return baseUrl;\n }\n}\n\nexport function extractBynderMedia(mediaJson?: string): BynderMediaExtracted | null {\n if (!mediaJson) {\n return null;\n }\n try {\n const parsed = JSON.parse(mediaJson);\n const firstImage = parsed?.image?.[0];\n const selected = firstImage?.selected;\n\n const mediaUrl = getMediaUrl(selected, firstImage?.isPublic, firstImage?.previewUrls);\n\n let mediaType: BynderMediaType = 'image';\n if (selected?.type === 'VIDEO') {\n mediaType = 'video';\n } else if (selected?.type === 'IMAGE' && mediaUrl?.toLowerCase().endsWith('.gif')) {\n mediaType = 'gif';\n }\n\n const isResponsive = selected?.imageType === 'customTransformation';\n const result: BynderMediaExtracted = {\n url: mediaUrl,\n type: mediaType,\n alt: selected?.altText ?? ''\n };\n\n if (isResponsive && mediaType === 'image') {\n result.isResponsive = true;\n result.desktopUrl = generateResponsiveUrl(mediaUrl, '16x9');\n result.mobileUrl = generateResponsiveUrl(mediaUrl, '3x4');\n result.url = result.desktopUrl;\n } else if (mediaType === 'image') {\n result.url = addDefaultTransform(mediaUrl);\n }\n\n return result;\n } catch (error) {\n console.warn('Failed to parse bynder_media JSON:', error);\n return null;\n }\n}\n","import styled from '@emotion/styled';\n\nexport const MediaContainer = styled.div`\n width: 100%;\n height: 100%;\n overflow: hidden;\n display: block;\n`;\n\nexport const StyledImage = styled.img`\n width: 100%;\n height: 100%;\n object-fit: cover;\n display: block;\n`;\n\nexport const StyledVideo = styled.video`\n width: 100%;\n height: 100%;\n object-fit: cover;\n display: block;\n`;\n\nexport const PictureElement = styled.picture`\n width: 100%;\n height: 100%;\n display: block;\n`;\n\nexport const SourceElement = styled.source`\n display: block;\n`;\n","/**\n * useCarousel Hook\n * Manages carousel state and keyboard navigation\n */\n\nimport { useCallback, useEffect, useState, KeyboardEvent } from 'react';\nimport type { UseCarouselReturn } from '../types';\nimport { useReducedMotion } from './useReducedMotion';\n\ninterface UseCarouselOptions {\n totalSlides: number;\n autoRotate?: boolean;\n rotationInterval?: number;\n pauseOnHover?: boolean;\n initialIndex?: number;\n}\n\nexport function useCarousel(options: UseCarouselOptions): UseCarouselReturn {\n const { totalSlides, autoRotate = false, rotationInterval = 5000, pauseOnHover = true, initialIndex = 0 } = options;\n\n const validInitialIndex = totalSlides > 0 ? Math.min(initialIndex, totalSlides - 1) : 0;\n const [currentIndex, setCurrentIndex] = useState(validInitialIndex);\n const [isPaused, setIsPaused] = useState(false);\n const prefersReducedMotion = useReducedMotion();\n\n const goToNext = useCallback(() => {\n if (totalSlides === 0) return;\n setCurrentIndex((prev) => (prev + 1) % totalSlides);\n }, [totalSlides]);\n\n const goToPrevious = useCallback(() => {\n if (totalSlides === 0) return;\n setCurrentIndex((prev) => (prev - 1 + totalSlides) % totalSlides);\n }, [totalSlides]);\n\n const goToSlide = useCallback(\n (index: number) => {\n if (index >= 0 && index < totalSlides) {\n setCurrentIndex(index);\n }\n },\n [totalSlides]\n );\n\n const pause = useCallback(() => {\n setIsPaused(true);\n }, []);\n\n const resume = useCallback(() => {\n setIsPaused(false);\n }, []);\n\n const handleKeyDown = useCallback(\n (event: KeyboardEvent) => {\n switch (event.key) {\n case 'ArrowLeft':\n event.preventDefault();\n goToPrevious();\n break;\n case 'ArrowRight':\n event.preventDefault();\n goToNext();\n break;\n case 'Home':\n event.preventDefault();\n goToSlide(0);\n break;\n case 'End':\n event.preventDefault();\n goToSlide(totalSlides - 1);\n break;\n }\n },\n [goToNext, goToPrevious, goToSlide, totalSlides]\n );\n\n useEffect(() => {\n if (currentIndex >= totalSlides && totalSlides > 0) {\n setCurrentIndex(totalSlides - 1);\n }\n }, [totalSlides, currentIndex]);\n\n // Auto-rotation effect\n useEffect(() => {\n if (!autoRotate || isPaused || prefersReducedMotion || totalSlides === 0) return;\n\n const intervalId = setInterval(goToNext, rotationInterval);\n return () => clearInterval(intervalId);\n }, [autoRotate, isPaused, prefersReducedMotion, rotationInterval, goToNext, totalSlides]);\n\n return {\n currentIndex,\n isPaused,\n totalSlides,\n goToNext,\n goToPrevious,\n goToSlide,\n pause,\n resume,\n handleKeyDown\n };\n}\n","/**\n * useReducedMotion Hook\n * Detects user's prefers-reduced-motion preference\n */\n\nimport { useEffect, useState } from 'react';\n\nexport function useReducedMotion(): boolean {\n const [prefersReducedMotion, setPrefersReducedMotion] = useState(false);\n\n useEffect(() => {\n // SSR-safe: Check if window is available\n if (typeof window === 'undefined' || !window.matchMedia) {\n return;\n }\n\n const mediaQuery = window.matchMedia('(prefers-reduced-motion: reduce)');\n setPrefersReducedMotion(mediaQuery.matches);\n\n const handleChange = (event: MediaQueryListEvent) => {\n setPrefersReducedMotion(event.matches);\n };\n\n mediaQuery.addEventListener('change', handleChange);\n return () => mediaQuery.removeEventListener('change', handleChange);\n }, []);\n\n return prefersReducedMotion;\n}\n","import { MarketingBannerProps, BannerData } from '../types';\n\nexport function hasCTA(banner: BannerData): boolean {\n return Boolean(banner?.cta_button?.label?.href);\n}\n\nexport function isCarouselMode(props: MarketingBannerProps): boolean {\n return Array.isArray(props?.banners) && props?.banners?.length > 1;\n}\n\nexport function hasMedia(banner: BannerData): boolean {\n return Boolean(banner?.bynder_media);\n}\n","import React from 'react';\nimport { NsIcon, NsIconVariants } from '@nuskin/foundation-ui-components';\nimport { ButtonContainer, StyledButton, StyledLabelText, StyledIconWrapper } from './Button.styled';\nimport {\n getButtonWidth,\n getIconSize,\n isValidDestination,\n resolveDisabled,\n resolveIconName,\n resolveTarget,\n variantDefaults,\n REL_NOOPENER_NOREFERRER,\n DEFAULT_VARIANT,\n DEFAULT_SIZE,\n DEFAULT_ALIGNMENT,\n DEFAULT_ICON_POSITION,\n DEFAULT_BUTTON_TYPE,\n DEFAULT_PLACEHOLDER_TEXT,\n DEFAULT_TARGET,\n BUTTON_TYPE_ROUNDED,\n BUTTON_TYPE_SQUARE,\n BORDER_COLOR_TRANSPARENT\n} from './helpers';\nimport { ButtonProps, ButtonType } from './types';\n\nconst Button: React.FC<ButtonProps> = ({\n label,\n open_in_new_tab: target = DEFAULT_TARGET,\n variant,\n button_size: size,\n alignment,\n buttontype: buttonType = DEFAULT_BUTTON_TYPE,\n icon,\n iconposition: iconPosition,\n button_state: disabled,\n placeholder_text: placeholderText = DEFAULT_PLACEHOLDER_TEXT,\n isEditing,\n $,\n parent$\n}) => {\n const resolvedVariant = variant ?? DEFAULT_VARIANT;\n const resolvedSize = size ?? DEFAULT_SIZE;\n const resolvedAlignment = alignment ?? DEFAULT_ALIGNMENT;\n const resolvedIconPosition = iconPosition ?? DEFAULT_ICON_POSITION;\n\n const resolvedButtonType: ButtonType =\n buttonType === BUTTON_TYPE_ROUNDED ? BUTTON_TYPE_ROUNDED : BUTTON_TYPE_SQUARE;\n\n const resolvedUrl = label?.href?.trim() ?? undefined;\n const hrefProp = isValidDestination(resolvedUrl) ? resolvedUrl : undefined;\n\n const variantDefault =\n variantDefaults[resolvedVariant as keyof typeof variantDefaults] ?? variantDefaults[DEFAULT_VARIANT];\n const buttonWidth = getButtonWidth(resolvedSize);\n const resolvedTarget = resolveTarget(target);\n const resolvedDisabled = resolveDisabled(disabled);\n const buttonBorder = ('border' in variantDefault ? variantDefault.border : undefined) ?? BORDER_COLOR_TRANSPARENT;\n\n const IconName = resolveIconName(icon);\n const isValidNsIcon = typeof IconName === 'string' && IconName in NsIconVariants;\n const iconSize = getIconSize(resolvedSize);\n\n const renderIcon = (position: 'left' | 'right') => {\n if (!IconName || !isValidNsIcon || resolvedIconPosition !== position) return null;\n\n const iconColor = resolvedDisabled ? variantDefault.disabledText : variantDefault.text;\n\n return (\n <StyledIconWrapper position={position}>\n <NsIcon name={IconName} size={iconSize} colorOverride={iconColor} {...($?.icon ?? {})} />\n </StyledIconWrapper>\n );\n };\n\n const getLabelText = () => {\n let labelTitle = label?.title;\n\n if (labelTitle === '') {\n return placeholderText;\n }\n if (!isEditing && labelTitle !== placeholderText) {\n return labelTitle;\n }\n return labelTitle;\n };\n\n return (\n <ButtonContainer alignment={resolvedAlignment}>\n <StyledButton\n $variant={resolvedVariant}\n $buttonWidth={buttonWidth}\n $buttonType={resolvedButtonType}\n $bg={variantDefault.bg}\n $hover={variantDefault.hover}\n $pressed={variantDefault.pressed}\n $text={variantDefault.text}\n $border={buttonBorder}\n $disabledBg={variantDefault.disabledBg}\n $disabledText={variantDefault.disabledText}\n $focusRing={variantDefault.focusRing}\n href={hrefProp}\n data-variant={resolvedVariant}\n {...(resolvedTarget === '_blank' ? { target: '_blank', rel: REL_NOOPENER_NOREFERRER } : {})}\n aria-disabled={resolvedDisabled}\n disabled={resolvedDisabled}\n {...(parent$ ?? {})}\n >\n {renderIcon('left')}\n <StyledLabelText {...(label?.$?.title ?? {})}>{getLabelText()}</StyledLabelText>\n {renderIcon('right')}\n </StyledButton>\n </ButtonContainer>\n );\n};\n\nexport default Button;\n","import React from 'react';\nimport { NsButton } from '@nuskin/foundation-ui-components';\nimport { styled } from '@nuskin/foundation-theme';\nimport type { ButtonAlignment, ButtonVariant } from './types';\nimport { ROUNDED_BORDER_RADIUS, ICON_MARGIN, BUTTON_TYPE_ROUNDED } from './helpers';\n\nconst BUTTON_GAP = '2px';\nconst BUTTON_MIN_WIDTH = '70px';\nconst BUTTON_MIN_HEIGHT = '30px';\nconst DESKTOP_BREAKPOINT = '769px';\nconst TABLET_BREAKPOINT = '768px';\nconst MOBILE_BREAKPOINT = '425px';\nconst DESKTOP_FONT_SIZE = '13px';\nconst TABLET_FONT_SIZE = '12px';\nconst MOBILE_FONT_SIZE = '10px';\nconst DESKTOP_PADDING = '10px 6px';\nconst TABLET_PADDING = '8px 6px';\nconst MOBILE_PADDING = '4px 8px';\nconst DESKTOP_FONT_WEIGHT = 500;\nconst TABLET_MOBILE_FONT_WEIGHT = 400;\nconst FOCUS_OUTLINE_WIDTH = '2px';\nconst FONT_FAMILY_LORA = 'Lora, sans-serif';\nconst BORDER_COLOR_TRANSPARENT = 'transparent';\nconst JUSTIFY_CONTENT_CENTER = 'center';\nconst JUSTIFY_CONTENT_FLEX_END = 'flex-end';\nconst JUSTIFY_CONTENT_FLEX_START = 'flex-start';\n\nconst getJustifyContent = (alignment: ButtonAlignment): string => {\n if (alignment === 'center') return JUSTIFY_CONTENT_CENTER;\n if (alignment === 'right') return JUSTIFY_CONTENT_FLEX_END;\n return JUSTIFY_CONTENT_FLEX_START;\n};\n\nexport const ButtonContainer = styled('div')<{ alignment: ButtonAlignment }>`\n display: flex;\n justify-content: ${props => getJustifyContent(props.alignment)};\n width: 100%;\n`;\n\ninterface StyledButtonProps {\n $variant: ButtonVariant;\n $buttonWidth: string;\n $buttonType: 'square' | 'rounded';\n $bg: string;\n $hover: string;\n $pressed: string;\n $text: string;\n $border: string;\n $disabledBg: string;\n $disabledText: string;\n $focusRing: string;\n href?: string;\n}\n\nexport const StyledButton = styled(NsButton)<StyledButtonProps>`\n --btn-bg: ${props => props.$bg};\n --btn-hover: ${props => props.$hover};\n --btn-pressed: ${props => props.$pressed};\n --btn-color: ${props => props.$text};\n --btn-border: ${props => props.$border};\n --btn-disabled-bg: ${props => props.$disabledBg};\n --btn-disabled-color: ${props => props.$disabledText};\n --btn-focus: ${props => props.$focusRing};\n \n &&&:link:not(:disabled):not([aria-disabled='true']),\n &&&:visited:not(:disabled):not([aria-disabled='true']) {\n color: var(--btn-color);\n text-decoration: none;\n }\n\n && {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: ${BUTTON_GAP};\n text-decoration: none;\n background: var(--btn-bg);\n color: var(--btn-color);\n border: 1px solid var(--btn-border);\n font-family: ${FONT_FAMILY_LORA};\n min-width: ${BUTTON_MIN_WIDTH};\n min-height: ${BUTTON_MIN_HEIGHT};\n white-space: normal;\n overflow: hidden;\n box-sizing: border-box;\n width: ${props => props.$buttonWidth};\n ${props => props.$buttonType === BUTTON_TYPE_ROUNDED && `border-radius: ${ROUNDED_BORDER_RADIUS};`}\n }\n\n @media (min-width: ${DESKTOP_BREAKPOINT}) {\n && {\n font-size: ${DESKTOP_FONT_SIZE};\n padding: ${DESKTOP_PADDING};\n font-weight: ${DESKTOP_FONT_WEIGHT};\n }\n }\n \n @media (max-width: ${TABLET_BREAKPOINT}) {\n && {\n font-size: ${TABLET_FONT_SIZE};\n padding: ${TABLET_PADDING};\n font-weight: ${TABLET_MOBILE_FONT_WEIGHT};\n }\n }\n\n @media (max-width: ${MOBILE_BREAKPOINT}) {\n && {\n font-size: ${MOBILE_FONT_SIZE};\n padding: ${MOBILE_PADDING};\n font-weight: ${TABLET_MOBILE_FONT_WEIGHT};\n }\n }\n \n &&:hover {\n background: var(--btn-hover);\n }\n \n &&:active {\n background: var(--btn-pressed);\n }\n\n &&:focus {\n border: 1px solid var(--btn-border);\n }\n\n &&:not(:disabled):hover {\n background: var(--btn-hover);\n border-color: var(--btn-border);\n }\n\n &&:not(:disabled):active {\n background: var(--btn-pressed);\n border-color: var(--btn-border);\n }\n \n &&:focus-visible {\n outline: ${FOCUS_OUTLINE_WIDTH} solid var(--btn-focus);\n background: var(--btn-pressed);\n border: 1px solid ${BORDER_COLOR_TRANSPARENT};\n }\n \n &&:disabled:focus-visible {\n box-shadow: none;\n }\n\n &&[aria-disabled='true'],\n &&:disabled {\n pointer-events: none;\n cursor: not-allowed;\n background: var(--btn-disabled-bg);\n color: var(--btn-disabled-color);\n border-color: var(--btn-border);\n box-shadow: none;\n }\n\n &&&&:link[aria-disabled='true'],\n &&&&:link:disabled,\n &&&&:visited[aria-disabled='true'],\n &&&&:visited:disabled {\n color: var(--btn-disabled-color);\n text-decoration: none;\n }\n \n &&[data-variant='secondary'][aria-disabled='true'],\n &&[data-variant='secondary']:disabled {\n border-color: var(--btn-border);\n }\n`;\n\nexport const StyledLabelText = styled.span`\n word-wrap: break-word;\n overflow-wrap: break-word;\n min-width: 0;\n`;\n\ninterface StyledIconWrapperProps {\n position: 'left' | 'right';\n}\n\nconst ICON_MARGIN_PX = `${ICON_MARGIN}px`;\n\nexport const StyledIconWrapper = styled.span<StyledIconWrapperProps>`\n flex-shrink: 0;\n ${props => props.position === 'left' && `margin-right: ${ICON_MARGIN_PX};`}\n ${props => props.position === 'right' && `margin-left: ${ICON_MARGIN_PX};`}\n`;\n","import type { ButtonSize, LinkTarget } from './types';\n\nexport const ROUNDED_BORDER_RADIUS = '25px';\nexport const ICON_MARGIN = 2;\nexport const FLEX_SHRINK_ZERO = 0;\nexport const REL_NOOPENER_NOREFERRER = 'noopener noreferrer';\nexport const CSS_WORD_BREAK = 'break-word';\nexport const PROTOCOL_HTTP = 'http:';\nexport const PROTOCOL_HTTPS = 'https:';\nexport const DISABLED_STATE_STRING = 'disabled';\nexport const DEFAULT_VARIANT = 'primary';\nexport const DEFAULT_SIZE = 'small';\nexport const DEFAULT_ALIGNMENT = 'left';\nexport const DEFAULT_ICON_POSITION = 'left';\nexport const DEFAULT_BUTTON_TYPE = 'square';\nexport const DEFAULT_PLACEHOLDER_TEXT = 'Enter Label';\nexport const DEFAULT_TARGET = 'No';\nexport const BUTTON_TYPE_ROUNDED = 'rounded';\nexport const BUTTON_TYPE_SQUARE = 'square';\nexport const BORDER_COLOR_TRANSPARENT = 'transparent';\n\nexport function isValidDestination(dest?: string): boolean {\n if (!dest || dest.trim() === '') return false;\n \n const trimmed = dest.trim();\n \n if (trimmed.startsWith('#')) return true;\n if (trimmed.startsWith('/')) return true;\n if (trimmed.startsWith('//')) return true;\n \n try {\n const url = new URL(trimmed);\n return url.protocol === PROTOCOL_HTTP || url.protocol === PROTOCOL_HTTPS;\n } catch {\n return false;\n }\n}\n\nexport function resolveTarget(target?: 'Yes' | 'No' | null): LinkTarget | undefined {\n if (target === 'Yes') {\n return '_blank';\n }\n return '_self';\n}\n\nexport function resolveDisabled(disabled?: boolean | string | null): boolean {\n if (disabled == null) {\n return false;\n }\n if (typeof disabled === 'string') {\n return disabled === DISABLED_STATE_STRING;\n }\n return disabled;\n}\n\nconst iconAliasMap: Record<string, string> = {\n arrow: 'arrowRight'\n};\n\nexport function resolveIconName(iconName?: string): string | undefined {\n if (!iconName) return undefined;\n return iconAliasMap[iconName] ?? iconName;\n}\n\nexport const variantDefaults = {\n primary: {\n bg: '#1f1f1f',\n hover: '#3a3530',\n pressed: '#000000',\n text: '#ffffff',\n disabledBg: '#e6e6e6',\n disabledText: '#9e9e9e',\n focusRing: '#4f84b4'\n },\n secondary: {\n bg: '#ffffff',\n hover: '#f2f2f2',\n pressed: '#e6e6e6',\n text: '#000000',\n border: '#626262',\n disabledBg: '#f2f2f2',\n disabledText: '#b0b0b0',\n focusRing: '#4f84b4'\n }\n} as const;\n\nconst widthBySize: Record<ButtonSize, string> = {\n large: '400px',\n medium: '250px',\n small: '130px'\n};\n\nconst DEFAULT_BUTTON_WIDTH = '130px';\n\nexport function getButtonWidth(size: string): string {\n return widthBySize[size] ?? DEFAULT_BUTTON_WIDTH;\n}\n\nconst iconSizeByButtonSize: Record<ButtonSize, ButtonSize> = {\n small: 'small',\n medium: 'medium',\n large: 'medium'\n};\n\nconst DEFAULT_ICON_SIZE: ButtonSize = 'medium';\n\nexport function getIconSize(size: string): ButtonSize {\n return iconSizeByButtonSize[size] ?? DEFAULT_ICON_SIZE;\n}\n","/**\n * MarketingBanner Styled Components\n * All styling for the Marketing Banner component\n */\n\nimport styled from '@emotion/styled';\nimport type { GradientDirection, GradientDepth } from './types';\nimport { DIMENSIONS, SPACING, COLORS, Z_INDEX, TRANSITIONS, MEDIA_QUERIES } from './styles/theme';\nimport {\n absoluteFill,\n centerHorizontal,\n gradientOverlay,\n radialGradientOverlay,\n smoothTransition\n} from './styles/mixins';\n\nexport const BannerContainer = styled.div`\n position: relative;\n width: 100%;\n overflow: hidden;\n`;\n\nexport const CarouselWrapper = styled.div`\n position: relative;\n width: 100%;\n`;\n\nexport const CarouselTrack = styled.div<{ currentIndex: number; totalSlides: number }>`\n display: flex;\n transition: transform ${TRANSITIONS.slow};\n transform: translateX(-${({ currentIndex }) => currentIndex * 100}%);\n`;\n\nexport const BannerSlide = styled.div`\n min-width: 100%;\n position: relative;\n`;\n\nexport const BannerContent = styled.div<{ hasMedia: boolean }>`\n position: relative;\n min-height: ${({ hasMedia }) => (hasMedia ? DIMENSIONS.bannerHeightDesktop : 'auto')};\n display: flex;\n align-items: center;\n justify-content: flex-start;\n\n ${MEDIA_QUERIES.mobileAndBelow} {\n min-height: ${({ hasMedia }) => (hasMedia ? DIMENSIONS.bannerHeightMobile : 'auto')};\n }\n`;\n\nexport const MediaWrapper = styled.div`\n ${absoluteFill}\n z-index: ${Z_INDEX.media};\n`;\n\nexport const TextContentWrapper = styled.div<{\n position?: 'left' | 'center' | 'right';\n}>`\n position: relative;\n z-index: ${Z_INDEX.content};\n display: flex;\n flex-direction: column;\n gap: ${SPACING.textGap};\n justify-content: center;\n padding: ${SPACING.desktopPadding};\n max-width: ${DIMENSIONS.textMaxWidth};\n width: auto;\n\n /* Base positioning from props (applies to desktop/tablet) */\n ${({ position = 'left' }) => {\n if (position === 'center') {\n return `\n margin: 0 auto;\n align-items: center;\n text-align: center;\n `;\n }\n if (position === 'right') {\n return `\n margin-left: auto;\n margin-right: 0;\n align-items: flex-end;\n text-align: right;\n `;\n }\n return `\n margin-right: auto;\n align-items: flex-start;\n text-align: left;\n `;\n }}\n\n /* Mobile: Override to always center content */\n ${MEDIA_QUERIES.mobileAndBelow} {\n padding: ${SPACING.mobilePadding};\n max-width: 100%;\n margin: 0 auto;\n align-items: center;\n text-align: center;\n }\n`;\n\nexport const GradientOverlay = styled.div<{\n direction: GradientDirection;\n depth: GradientDepth;\n color: 'black' | 'white';\n}>`\n ${absoluteFill}\n z-index: ${Z_INDEX.gradient};\n pointer-events: none;\n\n /* Base gradient from props (applies to desktop/tablet) */\n ${({ direction, depth, color }) => {\n const opacities = {\n sm: { start: 0.3, end: 0 },\n md: { start: 0.6, end: 0 },\n lg: { start: 0.9, end: 0 }\n };\n const { start, end } = opacities[depth];\n const baseColor = color === 'black' ? '0, 0, 0' : '255, 255, 255';\n\n if (direction === 'leftToRight') {\n return gradientOverlay('to right', start, end, baseColor);\n }\n if (direction === 'rightToLeft') {\n return gradientOverlay('to left', start, end, baseColor);\n }\n if (direction === 'radial') {\n return radialGradientOverlay(start, end, baseColor);\n }\n return '';\n }}\n\n /* Mobile: Override to always use radial gradient */\n ${MEDIA_QUERIES.mobileAndBelow} {\n ${({ depth, color }) => {\n const opacities = {\n sm: { start: 0.3, end: 0 },\n md: { start: 0.6, end: 0 },\n lg: { start: 0.9, end: 0 }\n };\n const { start, end } = opacities[depth];\n const baseColor = color === 'black' ? '0, 0, 0' : '255, 255, 255';\n return radialGradientOverlay(start, end, baseColor);\n }}\n }\n`;\n\nexport const ButtonWrapper = styled.div`\n /* Mobile: Always center the button */\n display: flex;\n justify-content: center;\n\n /* Desktop: Follow parent alignment from TextContentWrapper */\n ${MEDIA_QUERIES.tablet} {\n justify-content: inherit;\n }\n\n ${MEDIA_QUERIES.desktop} {\n justify-content: inherit;\n }\n`;\n\nexport const CarouselControls = styled.div`\n position: absolute;\n bottom: ${SPACING.carouselGap};\n ${centerHorizontal}\n z-index: ${Z_INDEX.controls};\n display: flex;\n gap: ${SPACING.carouselGap};\n align-items: center;\n\n ${MEDIA_QUERIES.mobileAndBelow} {\n bottom: 1.5rem;\n }\n`;\n\nexport const Indicator = styled.button<{ active: boolean }>`\n width: ${DIMENSIONS.indicatorSize};\n height: ${DIMENSIONS.indicatorSize};\n border-radius: 50%;\n border: ${DIMENSIONS.indicatorBorder} solid ${COLORS.indicatorBorder};\n background-color: ${({ active }) => (active ? COLORS.indicatorActive : COLORS.indicatorInactive)};\n cursor: pointer;\n padding: 0;\n ${smoothTransition(['all'])}\n\n &:hover {\n background-color: ${COLORS.indicatorActive};\n transform: scale(1.15);\n }\n`;\n","/**\n * MarketingBanner Component\n * Main component with single banner and automatic carousel mode\n */\n\nimport React from 'react';\nimport { BannerText } from './components';\nimport { BynderMedia } from '../bynder-media';\nimport { useCarousel } from './hooks';\nimport { hasCTA, hasMedia, isCarouselMode } from './utils/utils';\nimport type { MarketingBannerProps, BannerData } from './types';\nimport { TEXT_COLOR_MAP } from './styles/theme';\nimport { Button } from '../button';\nimport {\n BannerContainer,\n CarouselWrapper,\n CarouselTrack,\n BannerSlide,\n BannerContent,\n MediaWrapper,\n TextContentWrapper,\n GradientOverlay,\n ButtonWrapper,\n CarouselControls,\n Indicator\n} from './MarketingBanner.styled';\n\nconst renderBanner = (banner: BannerData, isEditing: boolean, index: number) => {\n const showMedia = hasMedia(banner);\n const showCTA = hasCTA(banner);\n\n const baseTestId = 'marketing-banner';\n const resolvedTextColor = TEXT_COLOR_MAP[banner.text_color ?? 'white'];\n\n const showGradient = banner.gradient?.show_gradient === true;\n const position = banner.content_position ?? banner.position ?? 'left';\n\n // Derive gradient color from text color (inverse)\n const gradientColor = banner.text_color === 'dark' ? 'white' : 'black';\n\n // Derive gradient direction from position\n let gradientDirection: 'leftToRight' | 'rightToLeft' | 'radial';\n if (position === 'left') {\n gradientDirection = 'leftToRight';\n } else if (position === 'right') {\n gradientDirection = 'rightToLeft';\n } else {\n gradientDirection = 'radial';\n }\n\n // Determine text alignment based on position\n let textAlignment: 'left' | 'center' | 'right';\n if (position === 'center') {\n textAlignment = 'center';\n } else if (position === 'right') {\n textAlignment = 'right';\n } else {\n textAlignment = 'left';\n }\n\n const gradientDepth = banner.gradient?.gradient_depth ?? 'md';\n\n return (\n <BannerSlide key={`${baseTestId}-${index}`}>\n <BannerContent hasMedia={showMedia}>\n {showMedia && (\n <MediaWrapper>\n <BynderMedia {...banner} />\n </MediaWrapper>\n )}\n\n {showGradient && (\n <GradientOverlay direction={gradientDirection} depth={gradientDepth} color={gradientColor} />\n )}\n\n <TextContentWrapper position={position}>\n <BannerText\n headerText={banner.header_text}\n title={banner.title}\n subtitle={banner.subtitle}\n bodyText={banner.body_text}\n textColor={resolvedTextColor}\n textAlignment={textAlignment}\n testId={`${baseTestId}-${index}-text`}\n $={banner.$}\n isEditing={isEditing}\n />\n\n {showCTA && banner?.cta_button && (\n <ButtonWrapper>\n <Button\n {...banner?.cta_button}\n alignment={textAlignment}\n parent$={banner?.$?.cta_button}\n isEditing={isEditing}\n />\n </ButtonWrapper>\n )}\n </TextContentWrapper>\n </BannerContent>\n </BannerSlide>\n );\n};\n\nexport default function MarketingBannerComponent(props: Readonly<MarketingBannerProps>): React.ReactElement {\n const { banners, rotation_interval, isEditing = false } = props;\n\n const isCarousel = isCarouselMode(props);\n\n const carousel = useCarousel({\n totalSlides: banners.length,\n autoRotate: isCarousel,\n rotationInterval: rotation_interval ?? 5000,\n pauseOnHover: true,\n initialIndex: 0\n });\n\n return (\n <BannerContainer\n data-testid={'marketing-banner'}\n onKeyDown={isCarousel ? carousel.handleKeyDown : undefined}\n onMouseEnter={isCarousel ? carousel.pause : undefined}\n onMouseLeave={isCarousel ? carousel.resume : undefined}\n >\n <CarouselWrapper>\n <CarouselTrack currentIndex={carousel.currentIndex} totalSlides={banners.length}>\n {banners.map((banner, index) => renderBanner(banner, isEditing, index))}\n </CarouselTrack>\n </CarouselWrapper>\n\n {isCarousel && (\n <CarouselControls>\n {banners.map((banner, index) => (\n <Indicator\n key={`${'banner'}-indicator-${index}-${banner.title ?? ''}`}\n active={index === carousel.currentIndex}\n onClick={() => carousel.goToSlide(index)}\n aria-label={`Go to slide ${index + 1}`}\n />\n ))}\n </CarouselControls>\n )}\n </BannerContainer>\n );\n}\n","import { styled } from '@nuskin/foundation-theme';\nimport type { StyledSpacingProps, StyledDividerProps } from './types';\nimport { BREAKPOINTS } from './types';\n\nexport const StyledSpacingContainer = styled('div')<StyledSpacingProps>(\n ({ vertical_padding, divider_alignment }) => {\n const verticalScaleMap = {\n none: { mobile: 0, tablet: 0, desktop: 0, ultra: 0 },\n small: { mobile: 8, tablet: 8, desktop: 8, ultra: 12 },\n medium: { mobile: 12, tablet: 12, desktop: 16, ultra: 20 },\n large: { mobile: 16, tablet: 16, desktop: 24, ultra: 32 }\n } as const;\n\n\n const v = verticalScaleMap[vertical_padding];\n\n return {\n display: 'flex',\n flexDirection: 'column',\n alignItems: divider_alignment === 'center' ? 'center' : divider_alignment === 'right' ? 'flex-end' : 'flex-start',\n\n paddingTop: `${v.mobile}px`,\n paddingBottom: `${v.mobile}px`,\n\n [`@media ${BREAKPOINTS.tablet}`]: {\n paddingTop: `${v.tablet}px`,\n paddingBottom: `${v.tablet}px`\n },\n\n [`@media ${BREAKPOINTS.desktop}`]: {\n paddingTop: `${v.desktop}px`,\n paddingBottom: `${v.desktop}px`\n },\n\n [`@media ${BREAKPOINTS.ultra}`]: {\n paddingTop: `${v.ultra}px`,\n paddingBottom: `${v.ultra}px`\n }\n };\n }\n);\n\nexport const StyledDividerLine = styled('div')<StyledDividerProps>(\n ({ divider_style, divider_thickness_px, divider_color, divider_gradient, divider_width_percent }) => {\n const base: Record<string, any> = {\n width: `${Math.max(0, Math.min(100, divider_width_percent))}%`\n };\n \n if (divider_gradient && divider_style !== 'none') {\n base.height = `${divider_thickness_px}px`;\n base.backgroundImage = divider_gradient;\n base.backgroundSize = '100% 100%';\n \n if (divider_style === 'dashed') {\n const dashLength = Math.max(12, divider_thickness_px * 4);\n const gapLength = Math.max(6, divider_thickness_px * 2);\n base.maskImage = `repeating-linear-gradient(90deg, black 0px, black ${dashLength}px, ` +\n `transparent ${dashLength}px, transparent ${dashLength + gapLength}px)`;\n base.WebkitMaskImage = `repeating-linear-gradient(90deg, black 0px, black ${dashLength}px, ` +\n `transparent ${dashLength}px, transparent ${dashLength + gapLength}px)`;\n } else if (divider_style === 'dotted') {\n const dotSize = Math.max(2, divider_thickness_px);\n const spacing = Math.max(8, dotSize * 3);\n const radius = dotSize / 2;\n \n base.maskImage = `radial-gradient(circle ${radius}px at 50% 50%, ` +\n `black 99%, transparent 100%)`;\n base.WebkitMaskImage = `radial-gradient(circle ${radius}px at 50% 50%, ` +\n `black 99%, transparent 100%)`;\n base.maskSize = `${spacing}px ${divider_thickness_px}px`;\n base.WebkitMaskSize = `${spacing}px ${divider_thickness_px}px`;\n base.maskRepeat = 'repeat-x';\n base.WebkitMaskRepeat = 'repeat-x';\n base.maskPosition = '0 center';\n base.WebkitMaskPosition = '0 center';\n }\n } else if (divider_style === 'none') {\n base.height = `${divider_thickness_px}px`;\n base.backgroundImage = divider_gradient;\n } else {\n base.borderBottomStyle = divider_style;\n base.borderBottomWidth = `${divider_thickness_px}px`;\n base.borderBottomColor = divider_color;\n base.height = 0;\n }\n \n return base;\n }\n)\n","export type PaddingScale = 'none' | 'small' | 'medium' | 'large';\nexport type DividerStyle = 'solid' | 'dashed' | 'dotted' | 'none';\nexport type DividerThickness = 'thin' | 'medium' | 'thick';\nexport type BreakpointName = 'mobile' | 'tablet' | 'desktop' | 'ultra';\n\nexport interface SpacingDividerProps {\n vertical_padding?: PaddingScale;\n divider_style?: DividerStyle;\n divider_thickness?: DividerThickness;\n divider_color?: string;\n divider_gradient_preset?: 'none' | 'soft' | 'bold' | 'faint';\n divider_width_percent?: number;\n divider_alignment?: 'left' | 'center' | 'right';\n}\n\nexport interface StyledSpacingProps {\n vertical_padding: PaddingScale;\n divider_alignment: 'left' | 'center' | 'right';\n}\n\nexport interface StyledDividerProps {\n divider_style: DividerStyle;\n divider_thickness_px: number;\n divider_color: string;\n divider_gradient?: string;\n divider_width_percent: number;\n}\n\nexport const THICKNESS_PX: Record<DividerThickness, number> = {\n thin: 1,\n medium: 2,\n thick: 4\n};\n\nexport const BREAKPOINTS: Record<BreakpointName, string> = {\n mobile: '(max-width: 768px)',\n tablet: '(min-width: 769px) and (max-width: 1024px)',\n desktop: '(min-width: 1025px) and (max-width: 1439px)',\n ultra: '(min-width: 1440px)'\n};\n","/**\n * Validates if a string is a valid hex color\n * @param value - The string to validate\n * @returns true if valid hex color, false otherwise\n */\nexport const isValidHex = (value?: string): boolean => {\n if (!value) return false;\n return /^#([A-Fa-f0-9]{6})$/.test(value);\n};\n\n/**\n * Converts hex color to RGB object\n * @param hex - The hex color string (e.g., '#FF0000')\n * @returns RGB object or undefined if invalid hex\n */\nconst hexToRgb = (hex?: string): { r: number; g: number; b: number } | undefined => {\n if (!hex || !/^#([A-Fa-f0-9]{6})$/.test(hex)) return undefined;\n const r = parseInt(hex.slice(1, 3), 16);\n const g = parseInt(hex.slice(3, 5), 16);\n const b = parseInt(hex.slice(5, 7), 16);\n return { r, g, b };\n};\n\n/**\n * Generates CSS gradient string based on preset and base color\n * @param preset - The gradient preset type\n * @param baseHex - The base hex color for the gradient\n * @returns CSS gradient string or undefined\n */\nexport const gradientPresetCss = (\n preset?: 'none' | 'soft' | 'bold' | 'faint',\n baseHex?: string\n): string | undefined => {\n if (!preset || preset === 'none') return undefined;\n const rgb = hexToRgb(baseHex) ?? { r: 0, g: 0, b: 0 };\n switch (preset) {\n case 'soft':\n return `linear-gradient(90deg, rgba(${rgb.r},${rgb.g},${rgb.b},0.3), rgba(${rgb.r},${rgb.g},${rgb.b},0.8))`;\n case 'bold':\n return `linear-gradient(90deg, rgba(${rgb.r},${rgb.g},${rgb.b},0.6), rgba(${rgb.r},${rgb.g},${rgb.b},1.0))`;\n case 'faint':\n return `linear-gradient(90deg, rgba(${rgb.r},${rgb.g},${rgb.b},0.4), rgba(${rgb.r},${rgb.g},${rgb.b},0.4))`;\n default:\n return undefined;\n }\n};","import React from 'react';\nimport { StyledSpacingContainer, StyledDividerLine } from './SpacingDivider.styled';\nimport type { SpacingDividerProps } from './types';\nimport { THICKNESS_PX } from './types';\nimport { isValidHex, gradientPresetCss } from './utils/utils';\n\nconst DEFAULT_HEX = '#000000';\n\nconst SpacingDivider = (props: SpacingDividerProps): React.ReactElement | null => {\n const {\n vertical_padding = 'small',\n divider_style = 'solid',\n divider_thickness = 'thin',\n divider_color,\n divider_gradient_preset = 'none',\n divider_width_percent = 100,\n divider_alignment = 'left'\n } = props;\n\n const divider_thickness_px = THICKNESS_PX[divider_thickness];\n const finalDividerColor = isValidHex(divider_color) ? divider_color! : DEFAULT_HEX;\n const divider_gradient = gradientPresetCss(divider_gradient_preset, finalDividerColor);\n\n return (\n <StyledSpacingContainer vertical_padding={vertical_padding} divider_alignment={divider_alignment}>\n {divider_style !== 'none' && (\n <StyledDividerLine\n divider_style={divider_style}\n divider_thickness_px={divider_thickness_px}\n divider_color={finalDividerColor}\n divider_gradient={divider_gradient}\n divider_width_percent={divider_width_percent ?? 100}\n aria-hidden=\"true\"\n />\n )}\n </StyledSpacingContainer>\n );\n};\n\nexport default SpacingDivider;\n","import React, { useMemo } from 'react';\n\nimport {\n CONTAINER_CLASS,\n Slider,\n ColumnControlContainer,\n InnerWrapper,\n TabletGridContainer,\n renderContentOrEmpty\n} from './shared';\nimport { useColumnControl } from './hooks/useColumnControl';\n\nimport type { ColumnControlProps } from './types';\n\ninterface GridLayoutContentProps {\n addSlideEditTags?: Record<string, unknown>;\n $?: Record<string, unknown>;\n emptyBlockParentClass?: string;\n emptyPlaceholderText?: string;\n slidesForRender: unknown[];\n hasSlides: boolean;\n isStackedViewport: boolean;\n isTabletGridViewport: boolean;\n renderSlides: (useFlexLayout?: boolean) => React.ReactNode;\n sliderRef: React.RefObject<{ slickPrev: () => void; slickNext: () => void } | null>;\n sliderSettings: object;\n carouselKey: string;\n preset: string;\n gap: number;\n}\n\nfunction GridLayoutContent(props: Readonly<GridLayoutContentProps>) {\n const {\n emptyBlockParentClass,\n emptyPlaceholderText,\n hasSlides,\n isStackedViewport,\n isTabletGridViewport,\n slidesForRender,\n renderSlides,\n sliderRef,\n sliderSettings,\n carouselKey,\n preset,\n gap,\n $ = {},\n addSlideEditTags\n } = props;\n\n if (isStackedViewport) {\n return (\n <div className={CONTAINER_CLASS} {...(slidesForRender.length > 0 ? addSlideEditTags : {})}>\n {renderContentOrEmpty(hasSlides, renderSlides(), emptyBlockParentClass, emptyPlaceholderText, $)}\n </div>\n );\n }\n if (isTabletGridViewport) {\n return (\n <TabletGridContainer\n className={CONTAINER_CLASS}\n gap={gap}\n {...(slidesForRender.length > 0 ? addSlideEditTags : {})}\n >\n {renderContentOrEmpty(hasSlides, renderSlides(true), emptyBlockParentClass, emptyPlaceholderText, $)}\n </TabletGridContainer>\n );\n }\n return renderContentOrEmpty(\n hasSlides,\n <Slider ref={sliderRef} {...sliderSettings} key={`${carouselKey}-${preset}`}>\n {renderSlides(true)}\n </Slider>,\n emptyBlockParentClass,\n emptyPlaceholderText,\n $\n );\n}\n\n/** Column control (grid layout only). Use Carousel component for carousel. */\nfunction ColumnControl<T = unknown>(props: ColumnControlProps<T>) {\n const gridProps = { ...props, layout: 'grid' as const };\n const {\n gapPx,\n containerHeight,\n stackedItemHeight,\n stackedItemMaxHeight,\n isVariableWidth,\n containerClassName,\n effectiveFullWidth,\n parent$,\n $,\n emptyBlockParentClass,\n emptyPlaceholderText,\n sliderRef,\n sliderSettings,\n carouselKey,\n renderSlides,\n slidesForRender,\n hasSlides,\n isStackedViewport,\n isTabletGridViewport,\n preset\n } = useColumnControl(gridProps);\n\n const addSlideEditTags = useMemo(() => {\n return {\n ...($?.['slides'] ?? {}),\n ...($?.['slides__parent'] ?? {}),\n ...{ 'data-add-direction': 'horizontal' }\n };\n }, [$]);\n\n return (\n <ColumnControlContainer\n gap={gapPx}\n height={containerHeight}\n columnHeight={stackedItemHeight}\n maxColumnHeight={stackedItemMaxHeight}\n isVariableWidth={isVariableWidth}\n className={containerClassName}\n aria-label=\"Column Control\"\n fullWidth={effectiveFullWidth}\n {...(parent$ ?? {})}\n >\n <InnerWrapper>\n <div\n {...addSlideEditTags}\n >\n <GridLayoutContent\n emptyBlockParentClass={emptyBlockParentClass}\n emptyPlaceholderText={emptyPlaceholderText}\n slidesForRender={slidesForRender}\n hasSlides={hasSlides}\n isStackedViewport={isStackedViewport}\n isTabletGridViewport={isTabletGridViewport}\n renderSlides={renderSlides}\n sliderRef={sliderRef}\n sliderSettings={sliderSettings}\n carouselKey={carouselKey}\n preset={preset}\n gap={gapPx}\n $={$}\n addSlideEditTags={addSlideEditTags}\n />\n </div>\n </InnerWrapper>\n </ColumnControlContainer>\n );\n}\n\nexport default ColumnControl as React.FC<ColumnControlProps>;\n","import React from 'react';\n\nimport SliderImport from 'react-slick';\nimport * as Styled from './ColumnControl.styled';\n\nimport {\n unwrapComponent,\n EmptyPlaceholder,\n isEmptySlide,\n isRealSlide\n} from './utils';\n\nconst Slider = unwrapComponent(SliderImport);\nconst ColumnControlContainer = unwrapComponent(Styled.ColumnControlContainer);\nconst ArrowButton = unwrapComponent(Styled.ArrowButton);\nconst InnerWrapper = unwrapComponent(Styled.InnerWrapper);\nconst TabletGridContainer = unwrapComponent(Styled.TabletGridContainer);\nconst SlideSection = unwrapComponent(Styled.SlideSection);\nconst SlideInner = unwrapComponent(Styled.SlideInner);\nconst SlideContentInner = unwrapComponent(Styled.SlideContentInner);\n\nexport const CONTAINER_CLASS = 'column-control-container';\n\nexport {\n Slider,\n ColumnControlContainer,\n ArrowButton,\n InnerWrapper,\n TabletGridContainer,\n SlideSection,\n SlideInner,\n SlideContentInner\n};\n\nexport interface SliderRefInstance {\n slickPrev: () => void;\n slickNext: () => void;\n}\n\nexport function getSlideKey(slide: unknown, index: number, isPlaceholder: boolean): string {\n if (isPlaceholder) return `placeholder-${index}`;\n const id = (slide as { id?: string | number } | null)?.id;\n return id !== undefined && id !== null ? String(id) : `slide-${index}`;\n}\n\nexport function getSlideContent<T>(\n slide: T | { __emptyPlaceholder: true },\n index: number,\n isPlaceholder: boolean,\n emptyBlockParentClass: string | undefined,\n renderSlide: (slide: T, index: number) => React.ReactNode,\n emptyPlaceholderText?: string\n): React.ReactNode {\n if (isPlaceholder)\n return (\n <EmptyPlaceholder\n emptyBlockParentClass={emptyBlockParentClass}\n text={emptyPlaceholderText}\n />\n );\n if (isRealSlide(slide)) return renderSlide(slide as T, index);\n return null;\n}\n\nexport function renderSlidesContent<T>(params: {\n slidesForRender: (T | { __emptyPlaceholder: true })[];\n renderSlide: (slide: T, index: number) => React.ReactNode;\n presetColumns: number;\n gap: number;\n isVariableWidth: boolean;\n getSlideWidth: (index: number) => string;\n stackedVerticalGap: number;\n stackedItemHeight: string;\n stackedItemMaxHeight?: number;\n useFlexLayout?: boolean;\n emptyBlockParentClass?: string;\n emptyPlaceholderText?: string;\n $?: Record<string, unknown>;\n}) {\n const {\n slidesForRender,\n renderSlide,\n presetColumns,\n gap,\n isVariableWidth,\n getSlideWidth,\n stackedVerticalGap,\n stackedItemHeight,\n stackedItemMaxHeight,\n useFlexLayout = false,\n emptyBlockParentClass,\n emptyPlaceholderText,\n $ = {}\n } = params;\n\n const addSlideEditTags = {\n ...($?.['slides'] ?? {}),\n ...($?.['slides__parent'] ?? {}),\n ...{ 'data-add-direction': 'horizontal' }\n };\n\n const flexBasis =\n presetColumns === 1\n ? '100%'\n : `calc((100% - ${(presetColumns - 1) * gap}px) / ${presetColumns})`;\n\n return slidesForRender.map((slide, index) => {\n const isPlaceholder = isEmptySlide(slide);\n const slideWidth = !useFlexLayout && isVariableWidth ? getSlideWidth(index) : undefined;\n\n return (\n <SlideSection\n key={getSlideKey(slide, index, isPlaceholder)}\n aria-roledescription=\"slide\"\n aria-label={`Slide ${index + 1} of ${slidesForRender.length}`}\n useFlexLayout={useFlexLayout}\n stackedVerticalGap={stackedVerticalGap}\n stackedItemHeight={stackedItemHeight}\n stackedItemMaxHeight={stackedItemMaxHeight}\n slideWidth={slideWidth}\n flexBasis={flexBasis}\n isVariableWidth={isVariableWidth}\n {...addSlideEditTags}\n {...($?.[`slides__${index}`] ?? {})}\n >\n <SlideInner stackedItemHeight={stackedItemHeight} stackedItemMaxHeight={stackedItemMaxHeight}>\n <SlideContentInner>\n {getSlideContent(\n slide,\n index,\n isPlaceholder,\n emptyBlockParentClass,\n renderSlide,\n emptyPlaceholderText\n )}\n </SlideContentInner>\n </SlideInner>\n </SlideSection>\n );\n });\n}\n\nexport function renderContentOrEmpty(\n hasSlides: boolean,\n content: React.ReactNode,\n emptyBlockParentClass: string | undefined,\n emptyPlaceholderText?: string,\n $?: Record<string, unknown>\n): React.ReactNode {\n return hasSlides ? (\n content\n ) : (\n <EmptyPlaceholder\n emptyBlockParentClass={emptyBlockParentClass}\n text={emptyPlaceholderText}\n />\n );\n}\n","import { styled } from '@nuskin/foundation-theme';\nimport { DEVICE_SIZES, MIN_EMPTY_PLACEHOLDER_HEIGHT_PX, MIN_SLIDE_WIDTH_PX } from './types';\n\nfunction getArrowButtonPosition(\n fullWidth: boolean | undefined,\n direction: 'prev' | 'next',\n fullVal: number,\n nonFullVal: number\n): { left?: number; right?: number } {\n if (fullWidth && direction === 'prev') return { left: fullVal };\n if (fullWidth && direction !== 'prev') return { right: fullVal };\n if (!fullWidth && direction === 'prev') return { left: nonFullVal };\n return { right: nonFullVal };\n}\n\nexport const ColumnControlContainer = styled('section')<{\n gap: number;\n height: string;\n columnHeight: string;\n maxColumnHeight?: number;\n isVariableWidth: boolean;\n fullWidth?: boolean;\n dotsInside?: boolean;\n}>(({ gap, height, columnHeight, maxColumnHeight, fullWidth, dotsInside = true }) => ({\n position: 'relative',\n width: '100%',\n textAlign: 'center',\n padding: '0 80px 50px',\n height,\n boxSizing: 'border-box',\n\n ...(fullWidth && {\n padding: '0'\n }),\n\n [`@media (max-width: ${DEVICE_SIZES.MEDIUM}px)`]: {\n padding: '0 40px 50px',\n ...(fullWidth && {\n padding: '0'\n })\n },\n\n [`@media (max-width: ${DEVICE_SIZES.SMALL}px)`]: {\n padding: '0 20px 40px',\n ...(fullWidth && {\n padding: '0'\n })\n },\n\n '.slick-slider': {\n position: 'relative',\n display: 'block',\n height: '100%'\n },\n\n '.slick-list': {\n position: 'relative',\n overflow: 'hidden',\n height: '100%',\n ...(columnHeight === 'auto' && { minHeight: 280 }),\n margin: `0 -${gap / 2}px`,\n // Add a subtle buffer so slides don't touch the container edges\n padding: '1px 0'\n },\n\n '.slick-track': {\n display: 'flex',\n height: '100%'\n },\n\n '.slick-slide': {\n padding: `0 ${gap / 2}px`,\n // When auto, fill track height so slide content can occupy full height; otherwise use fixed columnHeight\n height: columnHeight === 'auto' ? '100%' : columnHeight,\n minHeight: 0,\n ...(maxColumnHeight != null && { maxHeight: `${maxColumnHeight}px` }),\n\n '& > div': {\n height: '100%',\n width: '100%',\n\n '& > div': {\n height: '100%',\n width: '100%'\n }\n }\n },\n\n '.slick-dots': {\n position: dotsInside ? 'absolute' : 'static',\n // When inside, overlay within the slider; when outside, place below as part of layout\n bottom: dotsInside ? 12 : 'auto',\n display: 'flex',\n justifyContent: 'center',\n gap: 8,\n listStyle: 'none',\n padding: 0,\n margin: dotsInside ? 0 : '16px 0 0',\n width: '100%',\n left: 0,\n\n li: {\n margin: 0,\n width: 12,\n height: 12,\n\n button: {\n width: 12,\n height: 12,\n padding: 0,\n borderRadius: '50%',\n border: 'none',\n background: '#ccc',\n textIndent: -9999,\n cursor: 'pointer',\n transition: 'background 0.2s ease, transform 0.2s ease',\n\n '&:before': {\n display: 'none'\n }\n },\n\n '&.slick-active button': {\n background: '#4A90E2'\n }\n }\n },\n\n [`@media (max-width: ${DEVICE_SIZES.SMALL}px)`]: {\n '.slick-dots': {\n bottom: dotsInside ? 8 : 'auto',\n gap: 6,\n\n li: {\n width: 10,\n height: 10,\n\n button: {\n width: 10,\n height: 10\n }\n }\n }\n }\n}));\n\nexport const TabletGridContainer = styled('div')<{ gap: number }>(({ gap }) => ({\n display: 'flex',\n flexWrap: 'wrap',\n gap: `${gap}px`,\n width: '100%'\n}));\n\nexport const SlideSection = styled('section')<{\n useFlexLayout: boolean;\n stackedVerticalGap: number;\n stackedItemHeight: string;\n stackedItemMaxHeight?: number;\n slideWidth?: string;\n flexBasis?: string;\n isVariableWidth: boolean;\n}>(\n ({\n useFlexLayout,\n stackedVerticalGap,\n stackedItemHeight,\n stackedItemMaxHeight,\n slideWidth,\n flexBasis,\n isVariableWidth\n }) => ({\n maxWidth: 'none',\n margin: useFlexLayout ? 0 : `0 0 ${stackedVerticalGap}px`,\n // Fill parent height so renderSlide content can occupy full slide height\n height: stackedItemHeight === 'auto' ? '100%' : stackedItemHeight,\n minHeight: 0,\n ...(stackedItemMaxHeight != null && { maxHeight: stackedItemMaxHeight }),\n width: slideWidth,\n flex: useFlexLayout && flexBasis ? `0 0 ${flexBasis}` : undefined,\n boxSizing: useFlexLayout ? 'border-box' : undefined,\n // Prevent slides from shrinking too small for readability (non-variable presets)\n minWidth: isVariableWidth ? 0 : MIN_SLIDE_WIDTH_PX,\n position: 'relative'\n })\n);\n\nexport const SlideInner = styled('div')<{\n stackedItemHeight: string;\n stackedItemMaxHeight?: number;\n}>(({ stackedItemHeight }) => ({\n width: '100%',\n // Fill slide section so content wrapper can stretch to full height\n height: stackedItemHeight === 'auto' ? '100%' : stackedItemHeight,\n minHeight: 0,\n boxSizing: 'border-box',\n display: 'flex',\n flexDirection: 'column',\n // Remove justifyContent: center so SlideContentInner can fill full height\n alignItems: 'stretch',\n textAlign: 'left',\n overflow: 'hidden',\n minWidth: 0,\n position: 'relative'\n}));\n\nexport const SlideContentInner = styled('div')({\n maxWidth: '100%',\n width: '100%',\n flex: 1,\n minHeight: 0,\n overflow: 'hidden',\n display: 'flex',\n flexDirection: 'column'\n});\n\nexport const ArrowButton = styled('button')<{\n direction: 'prev' | 'next';\n fullWidth?: boolean;\n}>(({ direction, fullWidth }) => ({\n position: 'absolute',\n top: '50%',\n transform: 'translateY(-50%)',\n background: 'rgba(0, 0, 0, 0.5)',\n color: '#fff',\n border: 'none',\n borderRadius: '50%',\n width: 48,\n height: 48,\n padding: 0,\n margin: 0,\n cursor: 'pointer',\n zIndex: 10,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n transition: 'background 0.2s ease',\n fontSize: 24,\n lineHeight: 1,\n verticalAlign: 'middle',\n ...getArrowButtonPosition(fullWidth, direction, 8, -60),\n\n '&:hover': {\n background: 'rgba(0, 0, 0, 0.7)'\n },\n\n '&:focus': {\n outline: '2px solid #4A90E2',\n outlineOffset: 2\n },\n\n '&:disabled': {\n opacity: 0.3,\n cursor: 'not-allowed'\n },\n\n [`@media (max-width: ${DEVICE_SIZES.MEDIUM}px)`]: {\n width: 40,\n height: 40,\n ...getArrowButtonPosition(fullWidth, direction, 4, -45)\n },\n\n [`@media (max-width: ${DEVICE_SIZES.SMALL}px)`]: {\n width: 32,\n height: 32,\n fontSize: 20,\n ...getArrowButtonPosition(fullWidth, direction, 2, -35)\n }\n}));\n\nexport const InnerWrapper = styled('div')({\n position: 'relative',\n height: '100%'\n});\n\n\nexport const EmptyPlaceholderWrapper = styled('div')({\n padding: '10px',\n display: 'flex',\n justifyContent: 'center',\n alignItems: 'center',\n minHeight: `${MIN_EMPTY_PLACEHOLDER_HEIGHT_PX}px`,\n border: '1px dashed #ccc',\n boxSizing: 'border-box'\n});","import React from 'react';\n\n/** Gap between columns/slides: preset name → px (none: 0, small: 8, medium: 12, large: 16) */\nexport type GapPreset = 'none' | 'small' | 'medium' | 'large';\n\nexport const GAP_PRESET_VALUES: Record<GapPreset, number> = {\n none: 0,\n small: 8,\n medium: 12,\n large: 16\n};\n\n/** Resolve gap to pixels. Accepts preset name or legacy number (for backward compatibility). */\nexport function getGapPx(gap?: GapPreset | number): number {\n if (gap === undefined) return GAP_PRESET_VALUES.large;\n if (typeof gap === 'number') return gap;\n return GAP_PRESET_VALUES[gap];\n}\n\nexport type SlidePreset =\n | 'single-full'\n | 'two-equal'\n | 'two-small-large'\n | 'three-equal'\n | 'three-small-medium-large'\n | 'four-equal';\n\nexport type Alignment = 'left' | 'center' | 'right';\n\n/** Render callback: consumer renders each slide from their data. */\nexport type RenderSlideCallback<T = unknown> = (slide: T, index: number) => React.ReactNode;\n\nexport type ColumnControlProps<T = unknown> = Readonly<{\n /** Slide data (CMS/consumer shape). Rendered via renderSlide. */\n slides: T[];\n /** Called to render each slide. Receives slide data and index. */\n renderSlide: RenderSlideCallback<T>;\n preset?: SlidePreset;\n /** Layout mode: grid behaves like stacked list on small/tablet; carousel uses full slider behavior */\n layout?: 'grid' | 'carousel';\n /** Convenience props that override autoplay.enabled */\n autoplayEnabled?: boolean;\n /** Autoplay interval in seconds (e.g. 3 = 3s). Passed to slider as ms internally. */\n autoplayDuration?: number;\n /** Convenience props that override navigation.showArrows */\n showArrows?: boolean;\n /** Convenience props that override navigation.showPagination */\n showPagination?: boolean;\n onSlideChange?: (index: number) => void;\n className?: string;\n slickSettings?: any;\n /** Spacing between columns/slides: 'none'|'small'|'medium'|'large' (0,8,12,16px) or legacy number */\n gap?: GapPreset | number;\n height?: string;\n fullWidth?: boolean;\n emptyBlockParentClass?: string;\n /** Override empty placeholder label. Defaults: \"Add items to the column control\" (grid) or \"Add items to the carousel\" (carousel). */\n emptyPlaceholderText?: string;\n /** Position of slider dots: 'inside' overlays within the slider; 'outside' places them below as part of the height. Defaults to 'inside'. */\n dotsPosition?: 'inside' | 'outside';\n isEditing?: boolean;\n parent$?: Record<string, unknown>;\n $?: Record<string, unknown>;\n}>;\n\nexport interface ColumnControlSlideProps {\n children: React.ReactNode;\n isActive: boolean;\n preset: SlidePreset;\n alignment: Alignment;\n index: number;\n slideCount: number;\n}\n\nexport const DEVICE_SIZES = {\n ULTRA_SMALL: 320,\n EXTRA_SMALL: 480,\n SMALL: 600,\n MEDIUM: 768,\n LARGE: 1024,\n EXTRA_LARGE: 1200,\n ULTRA_LARGE: 1440,\n SUPER_LARGE: 1920\n} as const;\n\nexport type DeviceSize = keyof typeof DEVICE_SIZES;\n\n// Minimum slide width (in px) for non-variable width presets (CMS-friendly default)\nexport const MIN_SLIDE_WIDTH_PX = 280;\n\nexport const MIN_SLIDE_HEIGHT_PX = 320;\n\n/** Max height of a slide/card when height is content-driven. Authoring guide recommends designing for 400px. */\nexport const MAX_SLIDE_HEIGHT_PX = 650;\n\n/** Minimum height (px) for empty placeholder slots in column control/carousel. */\nexport const MIN_EMPTY_PLACEHOLDER_HEIGHT_PX = 220;\n\n// Max number of items allowed when using grid/column-control style layout\nexport const MAX_ALLOWED_COLUMN_CONTROL_ITEMS = 4;\n","import React from 'react';\n\nimport { EmptyPlaceholderWrapper } from './ColumnControl.styled';\nimport type { ColumnControlProps } from './types';\nimport { DEVICE_SIZES, MAX_ALLOWED_COLUMN_CONTROL_ITEMS, MAX_SLIDE_HEIGHT_PX } from './types';\n\nexport interface ViewportLayoutState {\n isStackedViewport: boolean;\n isTabletGridViewport: boolean;\n stackedItemHeight: string;\n stackedItemMaxHeight: number;\n stackedVerticalGap: number;\n containerHeight: string;\n}\n\nexport function getViewportLayoutState(\n isGridLayout: boolean,\n windowWidth: number,\n gapPx: number,\n height: string = 'auto'\n): ViewportLayoutState {\n const isStackedViewport = windowWidth <= DEVICE_SIZES.SMALL;\n const isTabletGridViewport =\n isGridLayout && windowWidth > DEVICE_SIZES.SMALL && windowWidth <= DEVICE_SIZES.LARGE;\n const stackedItemHeight = '100%';\n const stackedItemMaxHeight = MAX_SLIDE_HEIGHT_PX;\n const stackedVerticalGap = isGridLayout && isStackedViewport ? gapPx : 0;\n return {\n isStackedViewport,\n isTabletGridViewport,\n stackedItemHeight,\n stackedItemMaxHeight,\n stackedVerticalGap,\n containerHeight: height\n };\n}\n\nexport interface SlidesMeta<T> {\n gridSlides: T[];\n slidesToShow: number;\n shouldShowDots: boolean;\n}\n\nexport function getSlidesMeta<T>(\n slides: T[],\n isGridLayout: boolean,\n presetColumns: number,\n presetSlidesToShow: number,\n effectiveShowPagination: boolean\n): SlidesMeta<T> {\n const gridSlides = isGridLayout ? slides.slice(0, MAX_ALLOWED_COLUMN_CONTROL_ITEMS) : slides;\n const slidesToShow = isGridLayout\n ? Math.min(gridSlides.length, presetColumns, MAX_ALLOWED_COLUMN_CONTROL_ITEMS)\n : presetSlidesToShow;\n const shouldShowDots = isGridLayout\n ? effectiveShowPagination && gridSlides.length > 1\n : gridSlides.length > 1;\n return { gridSlides, slidesToShow, shouldShowDots };\n}\n\nexport function unwrapComponent<T>(mod: T): any {\n if (!mod) return mod;\n\n // already a component/function\n if (typeof mod === 'function') return mod;\n\n // default export wrapped\n if (typeof mod === 'object' && (mod as any).default) {\n return (mod as any).default;\n }\n\n return mod;\n}\n\nexport const EmptyPlaceholder: React.FC<Readonly<{ emptyBlockParentClass?: string; text?: string }>> = ({\n emptyBlockParentClass,\n text = 'Add items'\n}) =>\n React.createElement(\n EmptyPlaceholderWrapper as React.ComponentType<any>,\n { className: emptyBlockParentClass },\n text\n );\n\nexport function getPresetColumns(preset: ColumnControlProps['preset']): number {\n switch (preset) {\n case 'single-full':\n return 1;\n case 'two-equal':\n case 'two-small-large':\n return 2;\n case 'three-equal':\n case 'three-small-medium-large':\n return 3;\n case 'four-equal':\n return 4;\n default:\n return 1;\n }\n}\n\nexport function isVariableWidthPreset(preset: ColumnControlProps['preset'], windowWidth: number): boolean {\n if (windowWidth <= DEVICE_SIZES.MEDIUM) return false;\n return preset === 'two-small-large' || preset === 'three-small-medium-large';\n}\n\nexport function getVariableSlideWidth(\n preset: ColumnControlProps['preset'],\n index: number,\n windowWidth: number\n): string {\n if (windowWidth <= DEVICE_SIZES.MEDIUM) return 'auto';\n\n if (preset === 'two-small-large') {\n return index % 2 === 0 ? '33.33%' : '66.67%';\n }\n\n if (preset === 'three-small-medium-large') {\n const pos = index % 3;\n if (pos === 0 || pos === 2) return '25%';\n return '50%';\n }\n\n return 'auto';\n}\n\nexport function getSlidesToShowByViewport(windowWidth: number, presetColumns: number): number {\n if (windowWidth >= DEVICE_SIZES.EXTRA_LARGE) return Math.min(presetColumns, 4);\n if (windowWidth >= DEVICE_SIZES.LARGE) return Math.min(presetColumns, 3);\n if (windowWidth >= DEVICE_SIZES.SMALL) return Math.min(presetColumns, 2);\n return 1;\n}\n\n/** Sentinel used in the slides array to represent an empty slot when slides.length < preset. */\nexport const EMPTY_SLIDE_SENTINEL = { __emptyPlaceholder: true } as const;\n\nexport function isEmptySlide(slide: unknown): slide is typeof EMPTY_SLIDE_SENTINEL {\n return (\n typeof slide === 'object' &&\n slide !== null &&\n '__emptyPlaceholder' in slide &&\n (slide as { __emptyPlaceholder?: boolean }).__emptyPlaceholder === true\n );\n}\n\n/** Type guard: true when slide is a real slide (not the empty placeholder sentinel). */\nexport function isRealSlide<T>(slide: T | typeof EMPTY_SLIDE_SENTINEL): slide is T {\n return !isEmptySlide(slide);\n}\n\n/** Pads the slides array with EMPTY_SLIDE_SENTINEL so length equals targetCount when slides.length < targetCount. */\nexport function padSlidesToPreset<T>(\n slides: T[],\n targetCount: number\n): (T | typeof EMPTY_SLIDE_SENTINEL)[] {\n if (slides.length >= targetCount) return slides;\n const padCount = targetCount - slides.length;\n return [...slides, ...new Array(padCount).fill(EMPTY_SLIDE_SENTINEL)];\n}\n\nexport function getSlidesForRender<T>(params: {\n isGridLayout: boolean;\n isStackedViewport: boolean;\n isTabletGridViewport: boolean;\n gridSlides: T[];\n presetColumns: number;\n slidesToShow: number;\n}): T[] {\n const { isGridLayout, isStackedViewport, isTabletGridViewport, gridSlides, presetColumns, slidesToShow } = params;\n if (isGridLayout && (isStackedViewport || isTabletGridViewport)) {\n return gridSlides.slice(0, Math.min(presetColumns, gridSlides.length));\n }\n if (isGridLayout) return gridSlides.slice(0, slidesToShow);\n return gridSlides;\n}\n\nexport function buildResponsiveSettings(params: {\n isGridLayout: boolean;\n presetSlidesToShow: number;\n gridSlides: unknown[];\n presetColumns: number;\n shouldShowDots: boolean;\n /** When set (e.g. after padding to preset), use this as the slide count cap so placeholders are visible. */\n effectiveSlidesCount?: number;\n}) {\n const {\n isGridLayout,\n presetSlidesToShow,\n gridSlides,\n presetColumns,\n shouldShowDots,\n effectiveSlidesCount\n } = params;\n const slideCount = effectiveSlidesCount ?? gridSlides.length;\n const hasPlaceholders = effectiveSlidesCount != null && effectiveSlidesCount > gridSlides.length;\n const gridSlidesToShow = (maxCols: number) =>\n hasPlaceholders\n ? Math.min(slideCount, presetColumns)\n : Math.min(slideCount, presetColumns, maxCols);\n const carouselSlidesToShow = (maxCols: number) =>\n Math.min(presetSlidesToShow, slideCount, maxCols);\n return [\n {\n breakpoint: DEVICE_SIZES.SMALL,\n settings: {\n slidesToShow: isGridLayout\n ? gridSlidesToShow(1)\n : Math.min(presetSlidesToShow, 1),\n slidesToScroll: 1,\n swipeToSlide: !isGridLayout,\n arrows: false,\n dots: shouldShowDots,\n variableWidth: false\n }\n },\n {\n breakpoint: DEVICE_SIZES.MEDIUM,\n settings: {\n slidesToShow: isGridLayout ? gridSlidesToShow(2) : carouselSlidesToShow(2),\n slidesToScroll: 1,\n swipeToSlide: !isGridLayout,\n arrows: false,\n dots: shouldShowDots,\n variableWidth: false\n }\n },\n {\n breakpoint: DEVICE_SIZES.LARGE,\n settings: {\n slidesToShow: isGridLayout\n ? gridSlidesToShow(MAX_ALLOWED_COLUMN_CONTROL_ITEMS)\n : carouselSlidesToShow(3),\n slidesToScroll: 1,\n swipeToSlide: !isGridLayout,\n arrows: false,\n dots: shouldShowDots,\n variableWidth: false\n }\n }\n ];\n}\n","import React, { useRef, useMemo } from 'react';\n\nimport {\n getViewportLayoutState,\n getSlidesMeta,\n buildResponsiveSettings,\n getSlidesForRender,\n padSlidesToPreset,\n getPresetColumns,\n getSlidesToShowByViewport,\n isVariableWidthPreset,\n getVariableSlideWidth\n} from '../utils';\nimport { renderSlidesContent, CONTAINER_CLASS } from '../shared';\nimport { useColumnControlResize } from './useColumnControlResize';\n\nimport type { ColumnControlProps } from '../types';\nimport { DEVICE_SIZES, getGapPx } from '../types';\nimport type { SliderRefInstance } from '../shared';\n\n/** Shared hook for column control (grid) and carousel. Layout drives grid vs carousel behavior. */\nexport function useColumnControl<T>(props: ColumnControlProps<T>) {\n const {\n slides,\n renderSlide,\n preset = 'single-full',\n layout = 'grid',\n autoplayEnabled = false,\n autoplayDuration = 3,\n showPagination = true,\n onSlideChange,\n className,\n slickSettings,\n gap = 'medium',\n height,\n fullWidth,\n emptyBlockParentClass,\n emptyPlaceholderText: emptyPlaceholderTextProp,\n parent$,\n $\n } = props;\n\n const gapPx = getGapPx(gap);\n const isGridLayout = layout === 'grid';\n const emptyPlaceholderText =\n emptyPlaceholderTextProp ??\n (isGridLayout ? 'Add items to the column control' : 'Add items to the carousel');\n const effectiveFullWidth = fullWidth ?? isGridLayout;\n\n const { windowWidth, carouselKey } = useColumnControlResize(preset, slides.length);\n\n const presetColumns = useMemo(() => getPresetColumns(preset), [preset]);\n const presetSlidesToShow = getSlidesToShowByViewport(windowWidth, presetColumns);\n const isVariableWidth = isVariableWidthPreset(preset, windowWidth);\n const getSlideWidth = useMemo(\n () => (index: number) => getVariableSlideWidth(preset, index, windowWidth),\n [preset, windowWidth]\n );\n\n const effectiveAutoplayEnabled = isGridLayout ? false : autoplayEnabled;\n const effectiveShowPagination = isGridLayout ? false : showPagination;\n const showArrowsOnDesktop = !isGridLayout && windowWidth > DEVICE_SIZES.LARGE;\n\n const viewportLayout = getViewportLayoutState(isGridLayout, windowWidth, gapPx, height);\n const {\n isStackedViewport,\n isTabletGridViewport,\n stackedItemHeight,\n stackedItemMaxHeight,\n stackedVerticalGap,\n containerHeight\n } = viewportLayout;\n\n const { gridSlides, slidesToShow, shouldShowDots } = getSlidesMeta(\n slides,\n isGridLayout,\n presetColumns,\n presetSlidesToShow,\n effectiveShowPagination\n );\n const effectiveShouldShowDots =\n isGridLayout\n ? false\n : (effectiveShowPagination && shouldShowDots && windowWidth <= DEVICE_SIZES.LARGE);\n\n const sliderRef = useRef<SliderRefInstance | null>(null);\n const goToPrevious = () => sliderRef.current?.slickPrev();\n const goToNext = () => sliderRef.current?.slickNext();\n\n const containerClassName = [className, isGridLayout ? CONTAINER_CLASS : undefined].filter(Boolean).join(' ');\n\n const slidesForRender = getSlidesForRender({\n isGridLayout,\n isStackedViewport,\n isTabletGridViewport,\n gridSlides,\n presetColumns,\n slidesToShow\n });\n\n const slidesForRenderPadded =\n slidesForRender.length < presetColumns\n ? padSlidesToPreset(slidesForRender, presetColumns)\n : slidesForRender;\n const effectivePresetColumns = presetColumns;\n const effectiveSlidesToShow = isGridLayout\n ? Math.min(presetColumns, slidesForRenderPadded.length)\n : Math.min(presetSlidesToShow, slidesForRenderPadded.length);\n\n const responsiveSettings = useMemo(\n () =>\n buildResponsiveSettings({\n isGridLayout,\n presetSlidesToShow,\n gridSlides,\n presetColumns,\n shouldShowDots,\n effectiveSlidesCount: slidesForRenderPadded.length\n }),\n [\n isGridLayout,\n presetSlidesToShow,\n gridSlides,\n presetColumns,\n shouldShowDots,\n slidesForRenderPadded.length\n ]\n );\n\n const sliderSettings = {\n dots: effectiveShouldShowDots,\n infinite: !isGridLayout && slidesForRenderPadded.length > effectiveSlidesToShow,\n speed: 500,\n slidesToShow: effectiveSlidesToShow,\n slidesToScroll: 1,\n autoplay: effectiveAutoplayEnabled,\n autoplaySpeed: autoplayDuration * 1000,\n pauseOnHover: true,\n arrows: false,\n variableWidth: isVariableWidth,\n swipe: !isGridLayout,\n draggable: !isGridLayout,\n beforeChange: (_: number, next: number) => onSlideChange?.(next),\n responsive: responsiveSettings,\n ...slickSettings\n };\n\n const renderSlides = (useFlexLayout = false) =>\n renderSlidesContent({\n slidesForRender: slidesForRenderPadded,\n renderSlide,\n presetColumns: effectivePresetColumns,\n gap: gapPx,\n isVariableWidth,\n getSlideWidth,\n stackedVerticalGap,\n stackedItemHeight,\n stackedItemMaxHeight,\n useFlexLayout,\n emptyBlockParentClass,\n emptyPlaceholderText,\n $\n });\n\n return {\n gapPx,\n containerHeight,\n stackedItemHeight,\n stackedItemMaxHeight,\n isVariableWidth,\n containerClassName,\n layout,\n effectiveFullWidth,\n parent$,\n $,\n emptyBlockParentClass,\n emptyPlaceholderText,\n sliderRef,\n sliderSettings,\n carouselKey,\n renderSlides,\n slidesForRender,\n hasSlides: slidesForRenderPadded.length > 0,\n isStackedViewport,\n isTabletGridViewport,\n preset,\n showArrowsOnDesktop,\n slidesToShow,\n slidesLength: slides.length,\n goToPrevious,\n goToNext\n };\n}\n","import { useEffect, useState } from 'react';\n\nimport type { ColumnControlProps } from '../types';\n\nexport interface UseColumnControlResizeResult {\n windowWidth: number;\n carouselKey: string;\n}\n\nexport function useColumnControlResize(\n preset: ColumnControlProps['preset'],\n slideCount: number\n): UseColumnControlResizeResult {\n const [windowWidth, setWindowWidth] = useState(\n typeof window !== 'undefined' ? window.innerWidth : 0\n );\n\n const [carouselKey, setCarouselKey] = useState(\n `carousel-${preset}-${slideCount}-${Date.now()}`\n );\n\n useEffect(() => {\n if (typeof window === 'undefined') {\n return;\n }\n\n let timeoutId: NodeJS.Timeout;\n\n const handleResize = () => {\n clearTimeout(timeoutId);\n timeoutId = setTimeout(() => {\n setWindowWidth(window.innerWidth);\n setCarouselKey(`carousel-${preset}-${slideCount}-${Date.now()}`);\n }, 150);\n };\n\n window.addEventListener('resize', handleResize);\n\n return () => {\n clearTimeout(timeoutId);\n window.removeEventListener('resize', handleResize);\n };\n }, [preset, slideCount]);\n\n return { windowWidth, carouselKey };\n}\n\n","import React from 'react';\n\nimport {\n ColumnControlContainer,\n InnerWrapper,\n Slider,\n ArrowButton,\n renderContentOrEmpty\n} from './shared';\nimport { useColumnControl } from './hooks/useColumnControl';\n\nimport type { ColumnControlProps } from './types';\n\nimport 'slick-carousel/slick/slick.css';\nimport 'slick-carousel/slick/slick-theme.css';\n\n/** Carousel layout: slider with arrows and dots. Uses shared hook and UI with ColumnControl. */\nexport function Carousel<T = unknown>(props: Readonly<Omit<ColumnControlProps<T>, 'layout'>>) {\n const { dotsPosition } = props;\n const carouselProps = { ...props, layout: 'carousel' as const };\n const {\n gapPx,\n containerHeight,\n stackedItemHeight,\n stackedItemMaxHeight,\n isVariableWidth,\n containerClassName,\n effectiveFullWidth,\n parent$,\n $,\n emptyBlockParentClass,\n emptyPlaceholderText,\n sliderRef,\n sliderSettings,\n carouselKey,\n renderSlides,\n hasSlides,\n showArrowsOnDesktop,\n slidesToShow,\n slidesLength,\n goToPrevious,\n goToNext\n } = useColumnControl(carouselProps);\n\n return (\n <ColumnControlContainer\n gap={gapPx}\n height={containerHeight}\n columnHeight={stackedItemHeight}\n maxColumnHeight={stackedItemMaxHeight}\n isVariableWidth={isVariableWidth}\n className={containerClassName}\n aria-label=\"Carousel Control\"\n fullWidth={effectiveFullWidth}\n dotsInside={dotsPosition !== 'outside'}\n {...(parent$ ?? {})}\n >\n <InnerWrapper>\n <div\n {...($?.['slides'] ?? {})}\n {...($?.['slides__parent'] ?? {})}\n {...{ 'data-add-direction': 'horizontal' }}\n >\n <Slider ref={sliderRef} {...sliderSettings} key={carouselKey}>\n {renderContentOrEmpty(\n hasSlides,\n renderSlides(),\n emptyBlockParentClass,\n emptyPlaceholderText,\n $\n )}\n </Slider>\n </div>\n\n {showArrowsOnDesktop && slidesLength > slidesToShow && (\n <>\n <ArrowButton\n direction=\"prev\"\n onClick={goToPrevious}\n aria-label=\"Previous slide\"\n fullWidth={effectiveFullWidth}\n >\n ‹\n </ArrowButton>\n <ArrowButton\n direction=\"next\"\n onClick={goToNext}\n aria-label=\"Next slide\"\n fullWidth={effectiveFullWidth}\n >\n ›\n </ArrowButton>\n </>\n )}\n </InnerWrapper>\n </ColumnControlContainer>\n );\n}\n\nexport default Carousel;\n","import React, { useMemo } from 'react';\nimport { ContentCardProps, MediaProps } from './types';\nimport { \n Card, \n MediaWrapper, \n Content, \n Title, \n Subtitle, \n Body, \n CtaWrapper, \n ContentInner \n} from './ContentCard.styled';\nimport Button from '../button/Button';\nimport { Media } from './Media';\nimport {\n resolveTarget,\n getTitle,\n normalizeContentAlignment,\n normalizeContentCardMedia,\n normalizeCtaStyle,\n normalizeMediaStyle\n} from './utils/helpers';\nimport { CTA_BUTTON_HEIGHT, DEFAULT_MAX_HEIGHT } from './constants';\n\nconst ContentCard: React.FC<ContentCardProps> = (props) => {\n const {\n title,\n subtitle = '',\n body = '',\n media,\n cta,\n cta_style = 'none',\n content_alignment = 'left',\n max_height = DEFAULT_MAX_HEIGHT,\n media_style: cardMediaStyle,\n background_color = '#ffffff',\n text_color = '#000000',\n border_radius = '0px',\n parent$ = {},\n isEditing = false,\n $ = {}\n } = props;\n\n const alignment = normalizeContentAlignment(content_alignment);\n const ctaStyleNormalized = normalizeCtaStyle(cta_style);\n\n const normalizedMedia: MediaProps | undefined = useMemo(\n () => normalizeContentCardMedia(media, $),\n [media, $]\n );\n const mediaStyle = normalizeMediaStyle(\n cardMediaStyle ?? normalizedMedia?.media_style ?? 'cover'\n );\n const hasCtaHref = Boolean(cta?.label?.href);\n const hasCtaLabel = Boolean(cta?.label?.title);\n\n const isCardLink = ctaStyleNormalized === 'card' && hasCtaHref;\n const showButton = ctaStyleNormalized === 'button' && hasCtaLabel;\n const ctaHeight = showButton ? CTA_BUTTON_HEIGHT : 0;\n const cardTarget = resolveTarget(cta?.open_in_new_tab);\n\n const contentTitle = getTitle(title ?? '', isEditing);\n\n return (\n <Card\n align={alignment}\n borderRadius={border_radius}\n backgroundColor={background_color}\n textColor={text_color}\n as={isCardLink ? 'a' : 'article'}\n {...(isCardLink\n ? { href: cta?.label?.href, target: cardTarget }\n : {})}\n data-cta-style={ctaStyleNormalized}\n {...parent$}\n >\n <MediaWrapper data-testid=\"card-media\"> \n <Media {...normalizedMedia} mediaUrl={normalizedMedia?.mediaUrl ?? ''} media_style={mediaStyle} />\n </MediaWrapper>\n\n <Content data-testid=\"card-content\">\n <ContentInner data-testid=\"card-content-inner\">\n {title && <Title {...($?.title ?? {})}>{contentTitle}</Title>}\n {subtitle && <Subtitle {...($?.subtitle ?? {})}>{subtitle}</Subtitle>}\n {body && <Body {...($?.body ?? {})}>{body}</Body>}\n </ContentInner>\n\n {showButton && (\n <CtaWrapper $height={ctaHeight}>\n <Button {...cta} alignment={alignment} />\n </CtaWrapper>\n )}\n </Content>\n </Card>\n );\n};\n\nexport default ContentCard;\n","import styled from '@emotion/styled';\n\n/* ===================== CARD ===================== */\nexport const Card = styled.article<{\n align?: 'left' | 'center' | 'right';\n borderRadius?: string;\n backgroundColor?: string;\n textColor?: string;\n $maxHeight?: number;\n}>`\n display: flex;\n flex-direction: column;\n width: 100%;\n height: 100%;\n min-height: 0;\n max-height: ${({ $maxHeight }) => ($maxHeight ? `${$maxHeight}px` : 'none')};\n flex: 1 1 0%;\n overflow: hidden;\n text-align: ${({ align }) => align || 'left'};\n border-radius: ${({ borderRadius }) => borderRadius || '12px'};\n background-color: inherit;\n color: inherit;\n text-decoration: none;\n\n &[data-cta-style='card'] {\n cursor: pointer;\n }\n\n &[data-cta-style='card'],\n &[data-cta-style='card'] * {\n color: ${({ textColor }) => textColor || 'inherit'};\n text-decoration: none;\n }\n`;\n\n/* ===================== MEDIA ===================== */\nexport const MediaWrapper = styled.div`\n position: relative;\n width: 100%;\n flex-shrink: 0;\n overflow: hidden;\n border-top-left-radius: inherit;\n border-top-right-radius: inherit;\n height: auto;\n`;\n\n/* ===================== CONTENT ===================== */\nexport const Content = styled.div`\n display: flex;\n flex-direction: column;\n flex: 1 1 auto;\n min-height: 0;\n min-width: 0;\n padding: 16px 0;\n gap: 8px;\n justify-content: flex-start;\n align-items: stretch;\n`;\n\n/* ===================== TEXT ===================== */\nexport const Title = styled.h3`\n font-size: 18px;\n font-weight: 600;\n line-height: 1.3;\n margin: 0;\n word-break: break-word;\n color: inherit;\n`;\n\nexport const Subtitle = styled.p`\n font-size: 14px;\n margin: 0;\n color: inherit;\n opacity: 1;\n word-break: break-word;\n`;\n\nexport const Body = styled.p`\n font-size: 14px;\n line-height: 1.5;\n margin: 0;\n flex: 1 1 auto;\n min-height: 0;\n display: -webkit-box;\n -webkit-line-clamp: 4;\n -webkit-box-orient: vertical;\n`;\n\n/* ===================== CTA WRAPPER ===================== */\nexport const CtaWrapper = styled.div<{ $height?: number }>`\n margin-top: auto;\n height: ${({ $height }) => ($height == null ? 'auto' : `${$height}px`)};\n`;\n\n/* ===================== CONTENT INNER ===================== */\nexport const ContentInner = styled.div`\n display: flex;\n flex-direction: column;\n flex: 1 1 auto;\n min-height: 0;\n gap: 8px;\n overflow-y: auto;\n`;\n","/** Renders responsive media (image/gif/video) with lazy loading and fallback support. */\n\nimport React from 'react';\nimport {\n MediaContainer,\n StyledImage,\n StyledVideo,\n FallbackMessage,\n PictureElement,\n SourceElement\n} from './Media.styled';\nimport { MediaProps } from './types';\n\nexport function Media(props: Readonly<MediaProps>): React.ReactElement {\n const {\n mediaUrl,\n fallbackMediaUrl,\n mediaType = 'image',\n mediaAlt = '',\n onError,\n testId,\n $,\n isResponsive,\n desktopUrl,\n mobileUrl,\n media_style = 'cover',\n mediaHeight\n } = props;\n\n const [currentUrl, setCurrentUrl] = React.useState(mediaUrl);\n const [hasError, setHasError] = React.useState(false);\n\n React.useEffect(() => {\n setCurrentUrl(mediaUrl);\n setHasError(false);\n }, [mediaUrl]);\n\n const handleMediaError = () => {\n if (fallbackMediaUrl && currentUrl !== fallbackMediaUrl) {\n setCurrentUrl(fallbackMediaUrl);\n } else {\n setHasError(true);\n }\n onError?.();\n };\n\n const renderMedia = () => {\n if (hasError && !fallbackMediaUrl) {\n return <FallbackMessage />;\n }\n\n if (mediaType === 'video') {\n return (\n <StyledVideo\n src={currentUrl}\n onError={handleMediaError}\n autoPlay\n muted\n loop\n playsInline\n data-testid={`${testId}-video`}\n $mediaHeight={mediaHeight}\n $mediaStyle={media_style ?? 'cover'}\n {...($?.media ?? {})}\n ></StyledVideo>\n );\n }\n\n if (isResponsive && mobileUrl && desktopUrl) {\n return (\n <PictureElement>\n <SourceElement media=\"(max-width: 768px)\" srcSet={mobileUrl} />\n <SourceElement media=\"(min-width: 769px)\" srcSet={desktopUrl} />\n <StyledImage\n src={desktopUrl}\n alt={mediaAlt}\n onError={handleMediaError}\n loading=\"lazy\"\n data-testid={`${testId}-image`}\n $mediaStyle={media_style ?? 'cover'}\n $mediaHeight={mediaHeight}\n {...($?.media ?? {})}\n />\n </PictureElement>\n );\n }\n\n return (\n <StyledImage\n src={currentUrl}\n alt={mediaAlt}\n onError={handleMediaError}\n loading=\"lazy\"\n data-testid={`${testId}-image`}\n $mediaStyle={media_style ?? 'cover'}\n $mediaHeight={mediaHeight}\n {...($?.media ?? {})}\n />\n );\n };\n\n return (\n <MediaContainer data-testid={testId} {...($?.media ?? {})}>\n {renderMedia()}\n </MediaContainer>\n );\n}\n","import styled from '@emotion/styled';\nimport { MAX_MEDIA_HEIGHT_PX } from './constants';\n\nexport const MediaContainer = styled.div`\n position: relative;\n width: 100%;\n height: auto;\n overflow: hidden;\n`;\n\nexport const StyledImage = styled.img<{\n $mediaStyle?: string;\n $mediaHeight?: number;\n}>`\n display: block;\n ${({ $mediaStyle, $mediaHeight }) => {\n const isNaturalSize = $mediaStyle === 'none';\n const objectFit = $mediaStyle ?? 'cover';\n if (isNaturalSize) {\n return `\n width: auto;\n height: auto;\n object-fit: none;\n display: inline !important;\n `;\n }\n return `\n width: 100%;\n height: ${$mediaHeight != null ? `${$mediaHeight}px` : `${MAX_MEDIA_HEIGHT_PX}px`};\n max-height: ${$mediaHeight != null ? `${$mediaHeight}px` : `${MAX_MEDIA_HEIGHT_PX}px`};\n object-fit: ${objectFit};\n object-position: center center;\n `;\n }}\n`;\n\nexport const StyledVideo = styled.video<{\n $mediaHeight?: number;\n $mediaStyle?: string;\n}>`\n display: block;\n width: 100%;\n height: ${({ $mediaHeight }) =>\n $mediaHeight != null ? `${$mediaHeight}px` : `${MAX_MEDIA_HEIGHT_PX}px`};\n max-height: ${({ $mediaHeight }) =>\n $mediaHeight != null ? `${$mediaHeight}px` : `${MAX_MEDIA_HEIGHT_PX}px`};\n object-fit: ${({ $mediaStyle }) => $mediaStyle ?? 'contain'};\n object-position: center center;\n`;\n\nexport const FallbackMessage = styled.div`\n display: flex;\n align-items: center;\n justify-content: center;\n width: 100%;\n height: 100%;\n background-color: #f0f0f0;\n color: #666;\n font-size: 14px;\n`;\n\nexport const PictureElement = styled.picture`\n width: 100%;\n height: 100%;\n display: block;\n`;\n\nexport const SourceElement = styled.source`\n display: block;\n`;\n","import { extractBynderMedia } from '../../bynder-media/utils';\nimport type { ContentAlignment, CtaStyle, LinkTarget, MediaProps, MediaStyle } from '../types';\n\nexport const getMaxHeight = (maxHeight: number) => {\n return typeof maxHeight === 'number' ? maxHeight : 450;\n};\n\nexport const getTitle = (title: string, isEditing: boolean) => {\n if (title) return title;\n if (isEditing) return 'Enter Title';\n return '';\n};\n\n/** Normalize content alignment string to 'left' | 'center' | 'right'. */\nexport function normalizeContentAlignment(\n alignment?: string | null\n): ContentAlignment {\n if (alignment === 'centre' || alignment === 'center') return 'center';\n if (alignment === 'right') return 'right';\n return 'left';\n}\n\nconst MEDIA_STYLE_VALUES: MediaStyle[] = ['cover', 'contain', 'fill', 'none'];\n\n/** Normalize media style string to object-fit value: cover | contain | fill | none. */\nexport function normalizeMediaStyle(value?: string | null): MediaStyle {\n const v = typeof value === 'string' ? value.toLowerCase().trim() : '';\n return MEDIA_STYLE_VALUES.includes(v as MediaStyle) ? (v as MediaStyle) : 'cover';\n}\n\n/** Normalize CTA style string to 'card' | 'button' | 'none'. */\nexport function normalizeCtaStyle(\n value?: string | null\n): CtaStyle {\n const ctaStyle = typeof value === 'string' ? value.toLowerCase().trim() : '';\n if (['card', 'button', 'none'].includes(ctaStyle)) {\n return ctaStyle as CtaStyle;\n }\n return 'button';\n}\n\nexport function normalizeContentCardMedia(\n media: MediaProps | string | undefined,\n $: Record<string, unknown>\n): MediaProps | undefined {\n if (!media) return undefined;\n if (typeof media === 'string') {\n const bynder = extractBynderMedia(media);\n if (!bynder) return undefined;\n return {\n mediaUrl: bynder.url,\n mediaType: bynder.type,\n mediaAlt: bynder.alt,\n isResponsive: bynder.isResponsive,\n desktopUrl: bynder.desktopUrl,\n mobileUrl: bynder.mobileUrl,\n $\n };\n }\n if (\n typeof media === 'object' &&\n media !== null &&\n 'mediaUrl' in media &&\n typeof media.mediaUrl === 'string'\n ) {\n return media;\n }\n return media as MediaProps | undefined;\n}\n\n/** Resolve target from open_in_new_tab string. */\nexport function resolveTarget(target?: 'Yes' | 'No' | null): LinkTarget | undefined {\n if (target === 'Yes') {\n return '_blank';\n }\n return '_self';\n}\n","import React from 'react';\nimport { NsTypography } from '@nuskin/foundation-ui-components';\n\ninterface TypographyProps {\n value?: string;\n placeholder: string;\n isEditing: boolean;\n typographyProps: React.ComponentProps<typeof NsTypography>;\n}\n\nexport const Typography = ({\n value,\n placeholder,\n isEditing,\n typographyProps\n}: TypographyProps) => {\n\n let displayValue = value;\n\n if (!isEditing && value !== placeholder) {\n displayValue = value;\n } else if (value === '') {\n displayValue = placeholder;\n }\n\n return (\n <NsTypography {...typographyProps}>\n {displayValue}\n </NsTypography>\n );\n};\n","// Placeholder text constants\nexport const PLACEHOLDER_BRAND_CAPTION = 'Enter Brand Caption';\nexport const PLACEHOLDER_TITLE = 'Enter Title';\nexport const PLACEHOLDER_SUBTITLE = 'Enter Subtitle';\nexport const PLACEHOLDER_BODY = 'Enter Body';\n\n// Aria labels\nexport const ARIA_LABEL_HERO_BANNER = 'Hero banner';\n\n// Media loading attribute\nexport const IMAGE_LOADING_LAZY = 'lazy';\n","import React from 'react';\nimport { Typography } from './Typography';\nimport {\n PLACEHOLDER_BRAND_CAPTION,\n PLACEHOLDER_TITLE,\n PLACEHOLDER_SUBTITLE,\n PLACEHOLDER_BODY\n} from '../constants';\n\ninterface TypographyFieldConfig {\n value?: string;\n placeholder: string;\n variant: 'body-s' | 'h2' | 'h5' | 'h6';\n className: string;\n noSpacing?: boolean;\n weight?: 'bold';\n editTagKey: 'brandcaption' | 'title' | 'subtitle' | 'body';\n}\n\ninterface TypographyFieldsProps {\n brandcaption?: string;\n title?: string;\n subtitle?: string;\n body?: string;\n isEditing: boolean;\n editTags?: Record<string, unknown>;\n}\n\nconst getTypographyFields = (\n brandcaption?: string,\n title?: string,\n subtitle?: string,\n body?: string\n): TypographyFieldConfig[] => [\n {\n value: brandcaption,\n placeholder: PLACEHOLDER_BRAND_CAPTION,\n variant: 'body-s',\n className: 'brand-caption',\n noSpacing: true,\n editTagKey: 'brandcaption'\n },\n {\n value: title,\n placeholder: PLACEHOLDER_TITLE,\n variant: 'h2',\n className: 'title',\n weight: 'bold',\n editTagKey: 'title'\n },\n {\n value: subtitle,\n placeholder: PLACEHOLDER_SUBTITLE,\n variant: 'h5',\n className: 'subtitle',\n editTagKey: 'subtitle'\n },\n {\n value: body,\n placeholder: PLACEHOLDER_BODY,\n variant: 'h6',\n className: 'body',\n editTagKey: 'body'\n }\n];\n\nexport const TypographyFields: React.FC<TypographyFieldsProps> = ({\n brandcaption,\n title,\n subtitle,\n body,\n isEditing,\n editTags = {}\n}) => {\n const fields = getTypographyFields(brandcaption, title, subtitle, body);\n\n return (\n <>\n {fields.map((field) => {\n const typographyProps: React.ComponentProps<typeof Typography>['typographyProps'] = {\n variant: field.variant,\n className: field.className,\n ...(field.noSpacing && { noSpacing: true }),\n ...(field.weight && { weight: field.weight }),\n additionalProps: { ...(editTags?.[field.editTagKey] ?? {}) }\n };\n return (\n <Typography\n key={field.editTagKey}\n value={field.value}\n placeholder={field.placeholder}\n isEditing={isEditing}\n typographyProps={typographyProps}\n />\n );\n })}\n </>\n );\n};\n","import React from 'react';\nimport { NsImage } from '@nuskin/foundation-ui-components';\nimport { PictureElement, SourceElement } from '../HeroBanner.styled';\nimport {\n ParsedMedia,\n FULL_SIZE_PERCENT,\n MOBILE_BREAKPOINT,\n DESKTOP_BREAKPOINT\n} from '../helpers';\nimport { IMAGE_LOADING_LAZY } from '../constants';\n\ninterface MediaProps {\n parsedMedia: ParsedMedia | null;\n mediaAttributes?: Record<string, unknown>;\n}\n\nexport const Media = React.forwardRef<HTMLDivElement, MediaProps>(({\n parsedMedia,\n mediaAttributes = {}\n}, ref) => {\n if (!parsedMedia) return null;\n\n const renderImage = () => {\n const commonImageProps = {\n variant: 'fill' as const,\n className: 'media-fill',\n loading: IMAGE_LOADING_LAZY,\n ...mediaAttributes\n };\n\n if (parsedMedia.isResponsive && parsedMedia.desktopUrl && parsedMedia.mobileUrl) {\n return (\n <PictureElement>\n <SourceElement media={MOBILE_BREAKPOINT} srcSet={parsedMedia.mobileUrl} />\n <SourceElement media={DESKTOP_BREAKPOINT} srcSet={parsedMedia.desktopUrl} />\n <NsImage src={parsedMedia.desktopUrl} alt={parsedMedia.alt ?? ''} {...commonImageProps} />\n </PictureElement>\n );\n }\n\n return (\n <NsImage\n src={parsedMedia.url ?? ''}\n alt={parsedMedia.alt ?? ''}\n {...commonImageProps}\n />\n );\n };\n\n const mediaContent = (() => {\n if (parsedMedia.type === 'image' || parsedMedia.type === 'gif') {\n return renderImage();\n }\n\n if (parsedMedia.type === 'video') {\n return (\n <video\n src={parsedMedia.url}\n autoPlay\n muted\n loop\n playsInline\n preload=\"auto\"\n width={FULL_SIZE_PERCENT}\n height={FULL_SIZE_PERCENT}\n style={{ objectFit: 'cover' }}\n {...mediaAttributes}\n />\n );\n }\n\n return null;\n })();\n\n if (!mediaContent) return null;\n\n return (\n <div ref={ref} className=\"media-layer\">\n {mediaContent}\n </div>\n );\n});\nMedia.displayName = 'Media';\n","import { styled } from '@nuskin/foundation-theme';\nimport { GradientDepth } from './helpers';\nimport { MOBILE_BREAKPOINT } from './helpers';\n\n// Container\n\nexport const Container = styled('section') <{ textColor?: string }>`\n width: 100%;\n position: relative;\n min-height: 600px;\n overflow: hidden;\n\n .media-layer {\n position: absolute;\n inset: 0;\n width: 100%;\n height: 100%;\n z-index: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n }\n\n .media-layer .media-fill {\n width: 100%;\n height: 100%;\n object-fit: cover;\n display: block;\n }\n\n .title {\n font-size: clamp(22px, 3.5vw, 48px);\n line-height: 1.05;\n margin-bottom: 8px;\n font-family: 'Lora', serif;\n color: ${({ textColor }) => textColor ?? 'inherit'};\n }\n\n .subtitle {\n margin-bottom: 8px;\n font-size: clamp(16px, 2.2vw, 24px);\n line-height: 1.2;\n font-family: 'Lora', serif;\n color: ${({ textColor }) => textColor ?? 'inherit'};\n }\n\n .brand-caption {\n margin-bottom: 8px;\n font-size: clamp(12px, 1.5vw, 16px);\n line-height: 1.2;\n font-family: 'Lora', serif;\n color: ${({ textColor }) => textColor ?? 'inherit'};\n }\n\n .body {\n margin-bottom: 8px;\n font-size: clamp(14px, 1.6vw, 18px);\n line-height: 1.4;\n font-family: 'Lora', serif;\n color: ${({ textColor }) => textColor ?? 'inherit'};\n }\n`;\n\n// Gradient Overlay\n\nconst GRADIENT_OPACITIES = {\n sm: { start: 0.3, end: 0 },\n md: { start: 0.6, end: 0 },\n lg: { start: 0.9, end: 0 }\n} as const;\n\nconst getGradientBackground = (\n direction: string,\n depth: GradientDepth,\n color: 'black' | 'white'\n): string => {\n const { start, end } = GRADIENT_OPACITIES[depth];\n const baseColor = color === 'black' ? '0, 0, 0' : '255, 255, 255';\n\n if (direction === 'leftToRight') {\n return `background: linear-gradient(to right, rgba(${baseColor}, ${start}), rgba(${baseColor}, ${end}));`;\n }\n\n if (direction === 'rightToLeft') {\n return `background: linear-gradient(to left, rgba(${baseColor}, ${start}), rgba(${baseColor}, ${end}));`;\n }\n\n return `background: radial-gradient(circle, rgba(${baseColor}, ${start}), rgba(${baseColor}, ${end}));`;\n};\n\nexport const GradientOverlay = styled.div<{\n direction: string;\n depth: GradientDepth;\n color: 'black' | 'white';\n}>`\n position: absolute;\n inset: 0;\n z-index: 1;\n pointer-events: none;\n\n ${({ direction, depth, color }) => getGradientBackground(direction, depth, color)}\n\n /* Force radial gradient on small screens */\n @media (max-width: 768px) {\n ${({ depth, color }) => {\n const { start, end } = GRADIENT_OPACITIES[depth];\n const baseColor = color === 'black' ? '0, 0, 0' : '255, 255, 255';\n return `background: radial-gradient(circle, rgba(${baseColor}, ${start}), rgba(${baseColor}, ${end}));`;\n }}\n }\n`;\n\n// Responsive picture \nexport const PictureElement = styled.picture`\n width: 100%;\n height: 100%;\n display: block;\n`;\n\nexport const SourceElement = styled.source`\n display: block;\n`;\n\n// Overlay\n\nexport const Overlay = styled.div<{ justifyContent?: string }>`\n position: absolute;\n inset: 0;\n z-index: 2;\n display: flex;\n align-items: center;\n padding: clamp(16px, 4vw, 48px);\n pointer-events: none;\n justify-content: ${({ justifyContent }) => justifyContent ?? 'flex-start'};\n\n // Force center alignment on mobile\n @media ${MOBILE_BREAKPOINT} {\n justify-content: center;\n }\n`;\n\n// Content\n\nexport const Content = styled.div<{ textAlign?: string }>`\n max-width: min(520px, 90vw);\n z-index: 3;\n word-break: break-word;\n pointer-events: auto;\n text-align: ${({ textAlign }) => textAlign ?? 'left'};\n\n // Force center alignment on mobile\n @media ${MOBILE_BREAKPOINT} {\n text-align: center;\n }\n`;\n\n// Button to be Centered on Mobile\nexport const HERO_CTA_WRAPPER_CLASS = 'hero-banner-button-wrapper';\n\nexport const ButtonWrapper = styled.div`\n @media ${MOBILE_BREAKPOINT} {\n &.${HERO_CTA_WRAPPER_CLASS} > div {\n justify-content: center;\n }\n }\n`;\n\n// Helpers\n\nexport const getJustifyContent = (\n alignment: 'left' | 'center' | 'right'\n) => {\n if (alignment === 'center') return 'center';\n if (alignment === 'right') return 'flex-end';\n return 'flex-start';\n};\n","import { extractBynderMedia } from '../bynder-media/utils';\n\nexport type GradientDepth = 'sm' | 'md' | 'lg';\nexport type ContentAlignment = 'left' | 'center' | 'right';\nexport type TextColor = 'black' | 'white';\n\n// Constants\nexport const FULL_SIZE_PERCENT = '100%';\nexport const MOBILE_BREAKPOINT = '(max-width: 768px)';\nexport const DESKTOP_BREAKPOINT = '(min-width: 769px)';\n\nexport interface ParsedMedia {\n type: 'image' | 'gif' | 'video';\n url: string;\n alt: string;\n width?: number;\n height?: number;\n isResponsive?: boolean;\n desktopUrl?: string;\n mobileUrl?: string;\n}\n\ninterface MediaObject {\n type?: string;\n src?: string;\n alt?: string;\n width?: number;\n height?: number;\n}\n\nfunction isMediaObject(media: unknown): media is MediaObject {\n return typeof media === 'object' && media !== null && 'type' in media && 'src' in media;\n}\n\nexport function parseMedia(media: unknown): ParsedMedia | null {\n if (!media) return null;\n\n // Storybook / direct Media object\n if (isMediaObject(media)) {\n return {\n type: media.type as 'image' | 'gif' | 'video',\n url: media.src ?? '',\n alt: media.alt ?? '',\n width: media.width,\n height: media.height,\n isResponsive: false\n };\n }\n\n // Contentstack JSON string – use bynder-utils\n if (typeof media === 'string') {\n const extracted = extractBynderMedia(media);\n if (extracted) {\n return {\n type: extracted.type,\n url: extracted.url,\n alt: extracted.alt,\n isResponsive: extracted.isResponsive ?? false,\n desktopUrl: extracted.desktopUrl,\n mobileUrl: extracted.mobileUrl\n };\n }\n }\n\n return null;\n}\n\nexport function resolveContentAlignment(contentAlignment?: ContentAlignment): ContentAlignment {\n return contentAlignment ?? 'left';\n}\n\nexport function resolveGradientDepth(gradientDepth?: GradientDepth): GradientDepth {\n return gradientDepth ?? 'md';\n}\n\nexport function resolveTextColor(textColor?: string): TextColor {\n return (textColor === 'white' ? 'white' : 'black') as TextColor;\n}\n\n\nexport function getGradientColor(textColor: TextColor): 'white' | 'black' {\n return textColor === 'black' ? 'white' : 'black';\n}\n\nexport type GradientDirection = 'leftToRight' | 'radial' | 'rightToLeft';\n\nconst gradientDirectionMap: Record<ContentAlignment, GradientDirection> = {\n left: 'leftToRight',\n center: 'radial',\n right: 'rightToLeft'\n} as const;\n\nexport function getGradientDirection(contentAlignment: ContentAlignment): GradientDirection {\n return gradientDirectionMap[contentAlignment];\n}\n\n","import React from 'react';\nimport { Button } from '../button';\nimport { TypographyFields } from './components/TypographyFields';\nimport { Media } from './components/Media';\nimport { HeroBannerProps } from './types';\nimport { Container, GradientOverlay, Overlay, Content, getJustifyContent, ButtonWrapper, HERO_CTA_WRAPPER_CLASS } from './HeroBanner.styled';\nimport {\n parseMedia,\n resolveContentAlignment,\n resolveGradientDepth,\n resolveTextColor,\n getGradientColor,\n getGradientDirection\n} from './helpers';\nimport { ARIA_LABEL_HERO_BANNER } from './constants';\n\nconst HeroBanner: React.FC<HeroBannerProps> = (props) => {\n const {\n title,\n subtitle,\n body,\n brandcaption,\n button,\n media,\n class_name: className,\n content_alignment: contentAlignment,\n gradient_enabled: gradientEnabled = false,\n gradient_depth: gradientDepth,\n text_color: textColor,\n $ = {},\n parent$ = {},\n isEditing = false\n } = props;\n const resolvedContentAlignment = resolveContentAlignment(contentAlignment);\n const resolvedGradientDepth = resolveGradientDepth(gradientDepth);\n const resolvedTextColor = resolveTextColor(textColor);\n\n const parsedMedia = parseMedia(media);\n\n const justifyContent = getJustifyContent(resolvedContentAlignment);\n const gradientColor = getGradientColor(resolvedTextColor);\n const gradientDirection = getGradientDirection(resolvedContentAlignment);\n const shouldRenderButton = button && (button.label?.title || isEditing);\n\n return (\n <Container\n className={className}\n textColor={resolvedTextColor}\n aria-label={ARIA_LABEL_HERO_BANNER}\n {...(parent$ ?? {})}\n >\n {parsedMedia && (\n <Media\n parsedMedia={parsedMedia}\n mediaAttributes={$?.media ?? {}}\n />\n )}\n\n {gradientEnabled && (\n <GradientOverlay\n direction={gradientDirection}\n depth={resolvedGradientDepth}\n color={gradientColor}\n aria-hidden=\"true\"\n />\n )}\n\n <Overlay justifyContent={justifyContent}>\n <Content textAlign={resolvedContentAlignment}>\n <TypographyFields\n brandcaption={brandcaption}\n title={title}\n subtitle={subtitle}\n body={body}\n isEditing={isEditing}\n editTags={$}\n />\n\n {shouldRenderButton && (\n <ButtonWrapper className={HERO_CTA_WRAPPER_CLASS}>\n <Button\n {...button}\n alignment={resolvedContentAlignment}\n parent$={$?.button}\n isEditing={isEditing}\n />\n </ButtonWrapper>\n )}\n </Content>\n </Overlay>\n </Container>\n );\n};\n\nexport default HeroBanner;\n","import { ReactElement, useMemo } from 'react';\nimport DOMPurify from 'dompurify';\nimport CsText from '../text/CsText';\nimport type { ComponentProps } from 'react';\n\ntype CsTextProps = ComponentProps<typeof CsText>;\n\ninterface RichTextProps extends Omit<CsTextProps, 'text_editor' | 'font_color'> {\n text_editor: string;\n font_color?: 'Light' | 'Dark';\n}\n\n/**\n * Sanitization configuration for allowed tags and attributes\n * Following Contentstack Rich Text Editor restricted toolbar guidelines\n */\nconst SANITIZATION_CONFIG = {\n ALLOWED_TAGS: [\n 'p',\n 'div',\n 'span',\n 'a',\n 'br',\n 'strong',\n 'b',\n 'em',\n 'i',\n 'u',\n 'h1',\n 'h2',\n 'h3',\n 'ul',\n 'ol',\n 'li'\n ],\n ALLOWED_ATTR: [\n 'href',\n 'target',\n 'rel',\n 'title',\n 'class',\n 'style',\n 'data-testid',\n 'data-cs-id',\n 'data-cs-type',\n 'data-cslp'\n ]\n};\n\n/**\n * Sanitize HTML using DOMPurify\n * Removes dangerous content while preserving allowed tags and attributes\n *\n * @param html - Raw HTML content from editor\n * @returns Sanitized HTML safe for rendering\n */\nconst sanitizeHtml = (html: string): string => {\n if (!html || typeof html !== 'string') {\n return '';\n }\n\n return DOMPurify.sanitize(html, {\n ALLOWED_TAGS: SANITIZATION_CONFIG.ALLOWED_TAGS,\n ALLOWED_ATTR: SANITIZATION_CONFIG.ALLOWED_ATTR,\n KEEP_CONTENT: true,\n RETURN_DOM: false,\n RETURN_DOM_FRAGMENT: false,\n FORCE_BODY: false,\n SANITIZE_DOM: true,\n IN_PLACE: false\n });\n};\n\n/**\n * RichText Component\n *\n * Wrapper component that sanitizes Rich Text Editor content before passing to CsText.\n * Uses DOMPurify to remove dangerous markup (scripts, styles, event handlers, etc.)\n * while preserving allowed formatting tags and attributes.\n *\n * SECURITY FEATURES:\n * - Removes script tags and event handlers\n * - Strips dangerous attributes and tags\n * - Allows only specified tags: p, div, span, a, br, strong, em, i, u, h1, h2, h3, ul, ol, li\n * - Allows only specified attributes: href, target, rel, title, class, style, data-cslp\n * - Sanitization is applied before rendering in CsText\n *\n * @param props - CsText component props with sanitizable text_editor content\n * @returns Rendered component with sanitized content\n */\nconst RichText = ({ text_editor, font_color, ...restProps }: RichTextProps): ReactElement | null => {\n // Memoize sanitized HTML to avoid recalculation on every render\n const sanitizedHtml = useMemo(() => {\n if (!text_editor || typeof text_editor !== 'string' || !text_editor.trim()) {\n return '';\n }\n return sanitizeHtml(text_editor);\n }, [text_editor]);\n\n // Convert string font_color value to boolean (light = true, dark = false)\n const fontColorBoolean = font_color === 'Light';\n\n // Don't render if no content\n if (!sanitizedHtml) {\n return null;\n }\n\n // Pass sanitized HTML to CsText component with all other props\n return <CsText {...restProps} text_editor={sanitizedHtml} font_color={fontColorBoolean} />;\n};\n\nexport default RichText;\n"]}
|