xertica-ui 2.7.0 → 2.9.6
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/CHANGELOG.md +114 -0
- package/README.md +20 -12
- package/bin/cli.ts +327 -87
- package/bin/generate-tokens.ts +25 -9
- package/bin/language-config.ts +58 -18
- package/components/assistant/xertica-assistant/xertica-assistant.tsx +1 -1
- package/components/blocks/auth/AuthPageShell.tsx +63 -18
- package/components/blocks/auth/SocialLoginButtons.tsx +3 -3
- package/components/blocks/index.ts +1 -0
- package/components/blocks/marketing/CTASection.tsx +73 -0
- package/components/blocks/marketing/ComplianceBadgeRow.tsx +49 -0
- package/components/blocks/marketing/EvidenceTimeline.tsx +91 -0
- package/components/blocks/marketing/FeatureRow.tsx +78 -0
- package/components/blocks/marketing/Hero.tsx +125 -0
- package/components/blocks/marketing/HowItWorksSteps.tsx +90 -0
- package/components/blocks/marketing/LogoCloud.tsx +47 -0
- package/components/blocks/marketing/MarketingFooter.tsx +109 -0
- package/components/blocks/marketing/MarketingNavbar.tsx +192 -0
- package/components/blocks/marketing/PillBadge.tsx +96 -0
- package/components/blocks/marketing/SectionHeading.tsx +82 -0
- package/components/blocks/marketing/ServiceCardGrid.tsx +238 -0
- package/components/blocks/marketing/StatBand.tsx +99 -0
- package/components/blocks/marketing/TopAccentCards.tsx +91 -0
- package/components/blocks/marketing/index.ts +41 -0
- package/components/brand/index.ts +1 -0
- package/components/brand/isotype/Isotype.tsx +64 -0
- package/components/brand/isotype/IsotypeDiagonal.tsx +51 -0
- package/components/brand/isotype/IsotypeFrames.tsx +82 -0
- package/components/brand/isotype/IsotypeMini.tsx +65 -0
- package/components/brand/isotype/IsotypeTwist.tsx +68 -0
- package/components/brand/isotype/frame-variants.ts +20 -0
- package/components/brand/isotype/index.ts +9 -0
- package/components/brand/isotype/isotype-diagonal.mdx +52 -0
- package/components/brand/isotype/isotype-diagonal.stories.tsx +44 -0
- package/components/brand/isotype/isotype-diagonal.test.tsx +180 -0
- package/components/brand/isotype/isotype-frames.mdx +50 -0
- package/components/brand/isotype/isotype-frames.stories.tsx +63 -0
- package/components/brand/isotype/isotype-frames.test.tsx +92 -0
- package/components/brand/isotype/isotype-mini.mdx +61 -0
- package/components/brand/isotype/isotype-mini.stories.tsx +75 -0
- package/components/brand/isotype/isotype-mini.test.tsx +45 -0
- package/components/brand/isotype/isotype-twist.test.tsx +71 -0
- package/components/brand/isotype/isotype.mdx +61 -0
- package/components/brand/isotype/isotype.stories.tsx +74 -0
- package/components/brand/isotype/isotype.test.tsx +41 -0
- package/components/brand/isotype/mini-patterns.ts +50 -0
- package/components/brand/isotype/patterns.ts +83 -0
- package/components/brand/isotype/twist-variants.ts +20 -0
- package/components/pages/forgot-password-page/ForgotPasswordPage.tsx +3 -6
- package/components/pages/index.ts +1 -0
- package/components/pages/landing-page/LandingPage.tsx +360 -0
- package/components/pages/landing-page/index.ts +1 -0
- package/components/pages/login-page/LoginPage.tsx +3 -6
- package/components/pages/reset-password-page/ResetPasswordPage.tsx +1 -4
- package/components/pages/verify-email-page/VerifyEmailPage.tsx +2 -5
- package/components/ui/button/button.test.tsx +3 -3
- package/components/ui/button/button.tsx +5 -4
- package/components/ui/card/card.test.tsx +12 -0
- package/components/ui/card/card.tsx +16 -2
- package/components/ui/input/input.tsx +1 -1
- package/components/ui/input-otp/input-otp.tsx +1 -1
- package/components/ui/search/search.tsx +1 -1
- package/components/ui/select/select.tsx +2 -2
- package/components/ui/switch/switch.tsx +1 -1
- package/components/ui/textarea/textarea.tsx +1 -1
- package/contexts/BrandColorsContext.tsx +59 -7
- package/contexts/theme-data.ts +127 -3
- package/dist/AssistantChart-BFBJXVcm.js +3383 -0
- package/dist/AssistantChart-BTnE94FR.cjs +3551 -0
- package/dist/AssistantChart-BU48lxL2.js +3383 -0
- package/dist/AssistantChart-BvccsQMx.cjs +3551 -0
- package/dist/AssistantChart-CkskcBVD.js +3383 -0
- package/dist/AssistantChart-CoN6ga6Z.js +3383 -0
- package/dist/AssistantChart-CrPkO9ip.js +3383 -0
- package/dist/AssistantChart-DIRYJ7WY.js +3383 -0
- package/dist/AssistantChart-DKz2O1R8.cjs +3551 -0
- package/dist/AssistantChart-DOnY1ZlD.cjs +3551 -0
- package/dist/AssistantChart-DYL6UEvo.cjs +3551 -0
- package/dist/AssistantChart-DjM3qnp5.cjs +3551 -0
- package/dist/AssistantChart-hxPyE1S9.cjs +3551 -0
- package/dist/AssistantChart-keo-ogKi.js +3383 -0
- package/dist/AudioPlayer-AoU5MTiM.cjs +1282 -0
- package/dist/AudioPlayer-Bx1vrblm.js +1278 -0
- package/dist/AudioPlayer-CpihsbaD.js +1278 -0
- package/dist/AudioPlayer-CvGajzMC.cjs +1282 -0
- package/dist/AudioPlayer-CvHpFqDG.cjs +1282 -0
- package/dist/AudioPlayer-D0-I6J3J.cjs +1282 -0
- package/dist/AudioPlayer-D4S7GQou.js +1278 -0
- package/dist/AudioPlayer-DIWX_Yg7.cjs +1282 -0
- package/dist/AudioPlayer-DrWJnS7c.js +1278 -0
- package/dist/AudioPlayer-_P-Z7pAK.js +1278 -0
- package/dist/BrandColorsContext-B25Bpr3b.cjs +819 -0
- package/dist/BrandColorsContext-BCieATdW.js +812 -0
- package/dist/BrandColorsContext-BNKLUVcU.js +829 -0
- package/dist/BrandColorsContext-DNZGHItQ.cjs +836 -0
- package/dist/BrandColorsContext-DP0DXAXS.js +824 -0
- package/dist/BrandColorsContext-DjpC9wR_.cjs +798 -0
- package/dist/BrandColorsContext-MpXFhte7.cjs +831 -0
- package/dist/BrandColorsContext-Ug_TZ8yn.cjs +846 -0
- package/dist/BrandColorsContext-V3tOc-Zw.js +791 -0
- package/dist/BrandColorsContext-z0O2LlZz.js +839 -0
- package/dist/CodeBlock-BkaZf-R8.cjs +223 -0
- package/dist/CodeBlock-CK4rO6lM.js +221 -0
- package/dist/CodeBlock-CKXamfVd.cjs +223 -0
- package/dist/CodeBlock-CKu8LgbP.cjs +223 -0
- package/dist/CodeBlock-CVmE7isS.cjs +223 -0
- package/dist/CodeBlock-D7i5-cMv.js +221 -0
- package/dist/CodeBlock-Dg56j2ut.cjs +223 -0
- package/dist/CodeBlock-DiLS5LLI.js +221 -0
- package/dist/CodeBlock-Dt6nUQoo.js +221 -0
- package/dist/CodeBlock-zdylBGdZ.js +221 -0
- package/dist/CustomTooltipContent-BAR5qCQg.js +33 -0
- package/dist/CustomTooltipContent-Bxynuq7T.js +33 -0
- package/dist/CustomTooltipContent-BzjOSA0P.cjs +54 -0
- package/dist/CustomTooltipContent-C-ZeCNsf.js +33 -0
- package/dist/CustomTooltipContent-CBLHBxX8.cjs +54 -0
- package/dist/CustomTooltipContent-CON_QrXm.cjs +54 -0
- package/dist/CustomTooltipContent-CjWm3jjV.js +33 -0
- package/dist/CustomTooltipContent-DTV9MN9E.cjs +54 -0
- package/dist/CustomTooltipContent-UR_n2QfW.js +33 -0
- package/dist/CustomTooltipContent-v1SXjoFn.cjs +54 -0
- package/dist/EvidenceTimeline-DrRk4yqb.cjs +560 -0
- package/dist/EvidenceTimeline-l4MaV4C7.js +546 -0
- package/dist/FeatureCard-4n_8a63v.cjs +497 -0
- package/dist/FeatureCard-BLiAWT3w.js +485 -0
- package/dist/FeatureCard-BXRW97Ef.cjs +497 -0
- package/dist/FeatureCard-CDgLlWE2.js +485 -0
- package/dist/FeatureCard-CIbBHqeY.cjs +497 -0
- package/dist/FeatureCard-CgQ8lq-I.cjs +497 -0
- package/dist/FeatureCard-Cp8cVC6T.cjs +497 -0
- package/dist/FeatureCard-D0MwrTRP.js +485 -0
- package/dist/FeatureCard-DtoKPSfW.cjs +497 -0
- package/dist/FeatureCard-P4iEpBmB.js +485 -0
- package/dist/FeatureCard-e3f8bnF0.js +485 -0
- package/dist/FeatureCard-uE5i0in_.js +485 -0
- package/dist/ImageWithFallback-BOh1FM3I.js +98 -0
- package/dist/ImageWithFallback-BQO7952C.js +98 -0
- package/dist/ImageWithFallback-BkMXHCvV.cjs +122 -0
- package/dist/ImageWithFallback-C1ww9Hg3.cjs +122 -0
- package/dist/ImageWithFallback-C72nwszA.cjs +122 -0
- package/dist/ImageWithFallback-CBrkAEo3.cjs +122 -0
- package/dist/ImageWithFallback-CCUMDuEC.cjs +122 -0
- package/dist/ImageWithFallback-CGk5zPH-.js +98 -0
- package/dist/ImageWithFallback-CfnoFFSP.js +98 -0
- package/dist/ImageWithFallback-DQD5TTlY.js +98 -0
- package/dist/Isotype--fRZWwS6.js +85 -0
- package/dist/Isotype-0dpLqetB.js +85 -0
- package/dist/Isotype-B8XLEXSB.cjs +92 -0
- package/dist/Isotype-ChKwN7e-.cjs +91 -0
- package/dist/IsotypeDiagonal-CuPYPP4f.js +84 -0
- package/dist/IsotypeDiagonal-eNcOXRAc.cjs +91 -0
- package/dist/IsotypeDiagonal-oiwpXZhE.js +104 -0
- package/dist/IsotypeDiagonal-xMFoFXkb.cjs +109 -0
- package/dist/IsotypeFrames-BcWtyAWp.cjs +83 -0
- package/dist/IsotypeFrames-BnvSJKiH.cjs +73 -0
- package/dist/IsotypeFrames-iDRTRuIu.js +79 -0
- package/dist/IsotypeFrames-qoXOvOJt.js +69 -0
- package/dist/IsotypeMini-CQtWVo3h.js +126 -0
- package/dist/IsotypeMini-Cu_sW5yN.cjs +134 -0
- package/dist/IsotypeTwist-BTdNL4iV.js +106 -0
- package/dist/IsotypeTwist-DvsUgZs_.cjs +115 -0
- package/dist/LanguageContext-B1aOXO-K.js +1987 -0
- package/dist/LanguageContext-BP0k7AzI.js +1993 -0
- package/dist/LanguageContext-CChcIHIG.cjs +1998 -0
- package/dist/LanguageContext-ubC7TSs_.cjs +1992 -0
- package/dist/LanguageSelector-1XhM7R1i.cjs +48 -0
- package/dist/LanguageSelector-B3ZVNc55.js +46 -0
- package/dist/LanguageSelector-BLFPXGo8.cjs +48 -0
- package/dist/LanguageSelector-CYRzWkRZ.cjs +48 -0
- package/dist/LanguageSelector-Cj6zl0CM.js +46 -0
- package/dist/LanguageSelector-CyHjZgC4.cjs +48 -0
- package/dist/LanguageSelector-DE8lIySO.js +46 -0
- package/dist/LanguageSelector-DK1zD4VH.cjs +48 -0
- package/dist/LanguageSelector-DUr1hjBW.js +46 -0
- package/dist/LanguageSelector-DjbWIKWC.js +46 -0
- package/dist/LanguageSelector-DseCAa0p.cjs +48 -0
- package/dist/LanguageSelector-Du09anfM.js +46 -0
- package/dist/LanguageSelector-PZHlFfEs.cjs +48 -0
- package/dist/LanguageSelector-SB-NJSmx.js +46 -0
- package/dist/LogoCloud-C_uMKVNg.cjs +513 -0
- package/dist/LogoCloud-DJsMPNPh.js +500 -0
- package/dist/MarketingFooter-B_ycEdTJ.cjs +727 -0
- package/dist/MarketingFooter-Bhx-2Vlr.cjs +727 -0
- package/dist/MarketingFooter-Br1MGK9e.js +699 -0
- package/dist/MarketingFooter-BwE1vmeX.cjs +700 -0
- package/dist/MarketingFooter-CsZ1_xL9.js +709 -0
- package/dist/MarketingFooter-DCwf78Q4.cjs +716 -0
- package/dist/MarketingFooter-KH2r-OOL.js +709 -0
- package/dist/MarketingFooter-nB7G7gQ5.js +682 -0
- package/dist/PasswordStrengthMeter-B3S6i_k4.cjs +179 -0
- package/dist/PasswordStrengthMeter-B8ky1nJI.js +173 -0
- package/dist/PasswordStrengthMeter-C5VEopH-.cjs +179 -0
- package/dist/PasswordStrengthMeter-CIm7_jNT.js +173 -0
- package/dist/PasswordStrengthMeter-DKSAbQzu.js +173 -0
- package/dist/PasswordStrengthMeter-DxLu54p-.cjs +179 -0
- package/dist/PasswordStrengthMeter-k-e9Pole.cjs +179 -0
- package/dist/PasswordStrengthMeter-pAi2viq5.js +173 -0
- package/dist/SectionHeading-DEeOKcAd.cjs +857 -0
- package/dist/SectionHeading-DMNObcwm.js +838 -0
- package/dist/ThemeToggle--CGJjQJv.cjs +219 -0
- package/dist/ThemeToggle-4pQbVkpK.js +215 -0
- package/dist/ThemeToggle-B6rIVLvC.cjs +219 -0
- package/dist/ThemeToggle-BUOTps5l.cjs +219 -0
- package/dist/ThemeToggle-Bn_7Pmfe.js +215 -0
- package/dist/ThemeToggle-CO5mPl6e.js +215 -0
- package/dist/ThemeToggle-CoL8Ady7.js +215 -0
- package/dist/ThemeToggle-D2Wzm5bn.cjs +219 -0
- package/dist/ThemeToggle-DbZQ0JSV.cjs +219 -0
- package/dist/ThemeToggle-vLXEq2TS.js +215 -0
- package/dist/VerifyEmailPage-90lK6pP4.js +3258 -0
- package/dist/VerifyEmailPage-BJX1Rter.cjs +3320 -0
- package/dist/VerifyEmailPage-BSWvOgry.js +3310 -0
- package/dist/VerifyEmailPage-BTjI2c9n.js +2954 -0
- package/dist/VerifyEmailPage-CDqIkhx-.js +3224 -0
- package/dist/VerifyEmailPage-CJGfDSOx.js +2954 -0
- package/dist/VerifyEmailPage-Crxje3ZB.js +3323 -0
- package/dist/VerifyEmailPage-D2ShbuEN.cjs +3333 -0
- package/dist/VerifyEmailPage-DEBZXQ7c.cjs +3310 -0
- package/dist/VerifyEmailPage-DGaX-jZv.cjs +3268 -0
- package/dist/VerifyEmailPage-DOlZUNc0.cjs +2963 -0
- package/dist/VerifyEmailPage-DQPRl_RJ.js +2954 -0
- package/dist/VerifyEmailPage-DrdqMbLC.cjs +2963 -0
- package/dist/VerifyEmailPage-ZtOPkgOA.cjs +3234 -0
- package/dist/VerifyEmailPage-hyDfeCRa.cjs +2963 -0
- package/dist/VerifyEmailPage-kKSXl8vu.cjs +2963 -0
- package/dist/VerifyEmailPage-s927GSiR.js +3300 -0
- package/dist/VerifyEmailPage-w4N-bDhU.js +2954 -0
- package/dist/XerticaOrbe-B9tegV1n.js +1925 -0
- package/dist/XerticaOrbe-BHex09xs.js +1925 -0
- package/dist/XerticaOrbe-BKW3LJEz.js +1925 -0
- package/dist/XerticaOrbe-BQ_NjwPS.cjs +1927 -0
- package/dist/XerticaOrbe-BdUX171Q.cjs +1927 -0
- package/dist/XerticaOrbe-BdlKXRHU.cjs +1927 -0
- package/dist/XerticaOrbe-Br2i99U_.cjs +1927 -0
- package/dist/XerticaOrbe-CByPAFE5.js +1925 -0
- package/dist/XerticaOrbe-Ccu9eFMu.js +1925 -0
- package/dist/XerticaOrbe-kjFmuyx-.cjs +1927 -0
- package/dist/XerticaProvider-BVid1oqn.cjs +46 -0
- package/dist/XerticaProvider-Bi5lKC9N.js +44 -0
- package/dist/XerticaProvider-BrPMVhiv.js +44 -0
- package/dist/XerticaProvider-Bz_YfNY4.js +44 -0
- package/dist/XerticaProvider-CnX5kt5W.cjs +46 -0
- package/dist/XerticaProvider-CtvYfRbZ.cjs +46 -0
- package/dist/XerticaProvider-DEKNJTlN.js +44 -0
- package/dist/XerticaProvider-DMiyExQS.js +44 -0
- package/dist/XerticaProvider-DP2lzKip.cjs +46 -0
- package/dist/XerticaProvider-De79hhgp.js +44 -0
- package/dist/XerticaProvider-Dkk1Vbsy.js +44 -0
- package/dist/XerticaProvider-EdzH9Nrw.cjs +46 -0
- package/dist/XerticaProvider-X_wavDYA.cjs +46 -0
- package/dist/XerticaProvider-b3n_oL8w.cjs +46 -0
- package/dist/alert-dialog--qdlmB5i.cjs +872 -0
- package/dist/alert-dialog-9XYAn5z5.js +819 -0
- package/dist/alert-dialog-B281hud0.cjs +872 -0
- package/dist/alert-dialog-BVWbrcrw.cjs +872 -0
- package/dist/alert-dialog-B_Ko1xpu.js +819 -0
- package/dist/alert-dialog-C48TOdYU.cjs +872 -0
- package/dist/alert-dialog-CEPpnpXt.js +819 -0
- package/dist/alert-dialog-CIxE8T-J.cjs +872 -0
- package/dist/alert-dialog-DW-_iPuf.js +819 -0
- package/dist/alert-dialog-NjflitDa.js +819 -0
- package/dist/assistant.cjs.js +2 -2
- package/dist/assistant.es.js +2 -2
- package/dist/avatar-BJwIMbZ_.js +54 -0
- package/dist/avatar-C4Zh5fAJ.cjs +77 -0
- package/dist/avatar-CTEUKZUT.js +54 -0
- package/dist/avatar-CtEKgg7s.cjs +77 -0
- package/dist/avatar-D03MNQxs.js +54 -0
- package/dist/avatar-D1bZhlhL.cjs +77 -0
- package/dist/avatar-DKIxHeKG.cjs +77 -0
- package/dist/avatar-Df7KgSvs.js +54 -0
- package/dist/avatar-Gy0_Xu9i.cjs +77 -0
- package/dist/avatar-v16eZC8p.js +54 -0
- package/dist/blocks.cjs.js +33 -18
- package/dist/blocks.es.js +2 -2
- package/dist/brand.cjs.js +110 -4
- package/dist/brand.es.js +98 -4
- package/dist/breadcrumb-B1mUiaWB.cjs +98 -0
- package/dist/breadcrumb-BGO5PZPG.js +90 -0
- package/dist/breadcrumb-BIRgmem-.js +90 -0
- package/dist/breadcrumb-BSng-oUf.cjs +98 -0
- package/dist/breadcrumb-BvGAY4ne.cjs +98 -0
- package/dist/breadcrumb-CES7furU.js +90 -0
- package/dist/breadcrumb-CP275kbF.cjs +98 -0
- package/dist/breadcrumb-CU-punra.js +90 -0
- package/dist/breadcrumb-D7hr1EvJ.js +90 -0
- package/dist/breadcrumb-DjV9wfX1.cjs +98 -0
- package/dist/button-B05czY_8.js +62 -0
- package/dist/button-B3SE1liJ.js +62 -0
- package/dist/button-BMDlWZR8.cjs +85 -0
- package/dist/button-BYtQygX5.cjs +85 -0
- package/dist/button-BnAW-a_w.js +62 -0
- package/dist/button-CUPDQews.js +62 -0
- package/dist/button-DFa-rtPy.js +62 -0
- package/dist/button-DV1G6XrI.cjs +85 -0
- package/dist/button-DVhloDtr.cjs +85 -0
- package/dist/button-Kd9Fj53S.cjs +85 -0
- package/dist/cli.js +367 -65
- package/dist/components/blocks/auth/AuthPageShell.d.ts +21 -5
- package/dist/components/blocks/index.d.ts +1 -0
- package/dist/components/blocks/marketing/CTASection.d.ts +28 -0
- package/dist/components/blocks/marketing/ComplianceBadgeRow.d.ts +23 -0
- package/dist/components/blocks/marketing/EvidenceTimeline.d.ts +26 -0
- package/dist/components/blocks/marketing/FeatureRow.d.ts +25 -0
- package/dist/components/blocks/marketing/Hero.d.ts +35 -0
- package/dist/components/blocks/marketing/HowItWorksSteps.d.ts +29 -0
- package/dist/components/blocks/marketing/LogoCloud.d.ts +22 -0
- package/dist/components/blocks/marketing/MarketingFooter.d.ts +42 -0
- package/dist/components/blocks/marketing/MarketingNavbar.d.ts +47 -0
- package/dist/components/blocks/marketing/PillBadge.d.ts +21 -0
- package/dist/components/blocks/marketing/SectionHeading.d.ts +23 -0
- package/dist/components/blocks/marketing/ServiceCardGrid.d.ts +65 -0
- package/dist/components/blocks/marketing/StatBand.d.ts +25 -0
- package/dist/components/blocks/marketing/TopAccentCards.d.ts +29 -0
- package/dist/components/blocks/marketing/index.d.ts +28 -0
- package/dist/components/brand/index.d.ts +1 -0
- package/dist/components/brand/isotype/Isotype.d.ts +27 -0
- package/dist/components/brand/isotype/IsotypeDiagonal.d.ts +19 -0
- package/dist/components/brand/isotype/IsotypeFrames.d.ts +21 -0
- package/dist/components/brand/isotype/IsotypeMini.d.ts +26 -0
- package/dist/components/brand/isotype/IsotypeTwist.d.ts +22 -0
- package/dist/components/brand/isotype/frame-variants.d.ts +11 -0
- package/dist/components/brand/isotype/index.d.ts +9 -0
- package/dist/components/brand/isotype/mini-patterns.d.ts +25 -0
- package/dist/components/brand/isotype/patterns.d.ts +42 -0
- package/dist/components/brand/isotype/twist-variants.d.ts +11 -0
- package/dist/components/pages/forgot-password-page/ForgotPasswordPage.d.ts +2 -2
- package/dist/components/pages/index.d.ts +1 -0
- package/dist/components/pages/landing-page/LandingPage.d.ts +18 -0
- package/dist/components/pages/landing-page/index.d.ts +1 -0
- package/dist/components/pages/login-page/LoginPage.d.ts +2 -2
- package/dist/components/pages/verify-email-page/VerifyEmailPage.d.ts +1 -1
- package/dist/components/ui/card/card.d.ts +13 -1
- package/dist/contexts/theme-data.d.ts +21 -1
- package/dist/dropdown-menu-B9wTZ0uX.cjs +225 -0
- package/dist/dropdown-menu-BeBtZOrs.cjs +225 -0
- package/dist/dropdown-menu-ChQa9zW3.cjs +225 -0
- package/dist/dropdown-menu-D7mRDGis.js +190 -0
- package/dist/dropdown-menu-D8ZmqHB7.js +190 -0
- package/dist/dropdown-menu-DRvnsQAt.cjs +225 -0
- package/dist/dropdown-menu-DUk81i5Y.js +190 -0
- package/dist/dropdown-menu-NlUHhVmK.js +190 -0
- package/dist/dropdown-menu-_AWBeOts.cjs +225 -0
- package/dist/dropdown-menu-qGzLO_HO.js +190 -0
- package/dist/hooks.cjs.js +2 -2
- package/dist/hooks.es.js +2 -2
- package/dist/index.cjs.js +57 -41
- package/dist/index.es.js +25 -25
- package/dist/input-B53E6K8G.js +65 -0
- package/dist/input-B7Q7vcoG.cjs +91 -0
- package/dist/input-BysqLMK1.js +65 -0
- package/dist/input-CStdFsaH.cjs +91 -0
- package/dist/input-CXYth6nW.cjs +91 -0
- package/dist/input-CX_fWE2D.cjs +91 -0
- package/dist/input-CitUVnEn.js +65 -0
- package/dist/input-Csp_Metb.cjs +91 -0
- package/dist/input-DVRwGVLx.js +65 -0
- package/dist/input-Dqyj7Hdw.cjs +91 -0
- package/dist/input-dOgrFQ-3.js +65 -0
- package/dist/input-wkBYTp-B.js +65 -0
- package/dist/layout.cjs.js +1 -1
- package/dist/layout.es.js +1 -1
- package/dist/media.cjs.js +1 -1
- package/dist/media.es.js +1 -1
- package/dist/pages.cjs.js +2 -1
- package/dist/pages.es.js +1 -1
- package/dist/rich-text-editor-7K7UjLJN.cjs +2968 -0
- package/dist/rich-text-editor-B3jLP2bm.cjs +2968 -0
- package/dist/rich-text-editor-BHiRUzWZ.js +2894 -0
- package/dist/rich-text-editor-BWMRUMJ2.js +2894 -0
- package/dist/rich-text-editor-BntMVQsB.js +2894 -0
- package/dist/rich-text-editor-BoE6Ks5x.cjs +2968 -0
- package/dist/rich-text-editor-BzuEwR_X.js +2894 -0
- package/dist/rich-text-editor-CcopGbQ-.js +2894 -0
- package/dist/rich-text-editor-CmxSRJIi.cjs +2968 -0
- package/dist/rich-text-editor-Diz_onyB.js +2894 -0
- package/dist/rich-text-editor-DyYAu28v.cjs +2968 -0
- package/dist/rich-text-editor-JS_eMQCC.cjs +2968 -0
- package/dist/rich-text-editor-RWvK4hd3.cjs +2968 -0
- package/dist/rich-text-editor-gauEkzPM.js +2894 -0
- package/dist/select-B6PygS38.cjs +161 -0
- package/dist/select-BD763J5Y.cjs +161 -0
- package/dist/select-BNfFJwYp.js +130 -0
- package/dist/select-CN8IDjGB.js +130 -0
- package/dist/select-CwRzQHA7.cjs +161 -0
- package/dist/select-CwgD3nMD.js +130 -0
- package/dist/select-DEHUm_AC.cjs +161 -0
- package/dist/select-DJDgpVm3.cjs +161 -0
- package/dist/select-DSLWQLmo.cjs +161 -0
- package/dist/select-QJDKZITN.js +130 -0
- package/dist/select-YFx0wCYT.js +130 -0
- package/dist/select-q7aDfuPn.js +130 -0
- package/dist/sidebar-BF7JEL7U.js +1151 -0
- package/dist/sidebar-Bjr2doX5.cjs +1154 -0
- package/dist/sidebar-Bkk1YAsD.cjs +1154 -0
- package/dist/sidebar-CMrNCmhb.cjs +1154 -0
- package/dist/sidebar-CO9x8AVn.cjs +1154 -0
- package/dist/sidebar-Cn_KB4c6.js +1151 -0
- package/dist/sidebar-CuzYeOSz.cjs +1154 -0
- package/dist/sidebar-CwlW3LXE.js +1151 -0
- package/dist/sidebar-DNkf-Ug6.js +1151 -0
- package/dist/sidebar-DaS3fplw.cjs +1154 -0
- package/dist/sidebar-Db_C30ph.cjs +1154 -0
- package/dist/sidebar-FDCY42oP.js +1151 -0
- package/dist/sidebar-miPHsRz4.js +1151 -0
- package/dist/sidebar-pZF8mLLu.js +1151 -0
- package/dist/skeleton-BX2XTjMO.cjs +87 -0
- package/dist/skeleton-BoLK0iV7.js +78 -0
- package/dist/skeleton-BtBwJ39W.js +79 -0
- package/dist/skeleton-Bysq8yeB.js +79 -0
- package/dist/skeleton-C7nspYnC.cjs +87 -0
- package/dist/skeleton-CJyg0eJ1.cjs +88 -0
- package/dist/skeleton-D8WaauK0.cjs +88 -0
- package/dist/skeleton-DBYtjaZW.cjs +88 -0
- package/dist/skeleton-DL4V5Vub.cjs +87 -0
- package/dist/skeleton-DSMhdqp1.js +78 -0
- package/dist/skeleton-DY_lSFWf.js +79 -0
- package/dist/skeleton-Df65Ox10.js +79 -0
- package/dist/skeleton-DhJswvTW.cjs +88 -0
- package/dist/skeleton-DicUfozA.js +78 -0
- package/dist/slider-77T_Eqw4.js +56 -0
- package/dist/slider-B6puMLXS.cjs +78 -0
- package/dist/slider-B785N7lZ.js +56 -0
- package/dist/slider-BKV_vvsh.cjs +78 -0
- package/dist/slider-B_lUjFNa.cjs +78 -0
- package/dist/slider-C6yssKyZ.cjs +78 -0
- package/dist/slider-CKZO9gVh.cjs +78 -0
- package/dist/slider-Cn-ImSze.js +56 -0
- package/dist/slider-CtBpIaU4.js +56 -0
- package/dist/slider-KgWmSJbx.js +56 -0
- package/dist/tooltip-BPttuPxU.js +48 -0
- package/dist/tooltip-BiJVGob3.cjs +72 -0
- package/dist/tooltip-CIKRzQqE.cjs +72 -0
- package/dist/tooltip-CoDByjE_.cjs +72 -0
- package/dist/tooltip-D2OPn-1v.cjs +72 -0
- package/dist/tooltip-DlCHQuh1.js +48 -0
- package/dist/tooltip-_MAwsiOL.js +48 -0
- package/dist/tooltip-fQ2Va0G8.cjs +72 -0
- package/dist/tooltip-oAw00FX2.js +48 -0
- package/dist/tooltip-u147L0wD.js +48 -0
- package/dist/ui.cjs.js +13 -13
- package/dist/ui.es.js +13 -13
- package/dist/xertica-assistant-B1xAl2Vn.js +2173 -0
- package/dist/xertica-assistant-BBUMaUXw.js +2173 -0
- package/dist/xertica-assistant-C2A0R94j.js +2173 -0
- package/dist/xertica-assistant-CSUprvTR.js +2173 -0
- package/dist/xertica-assistant-CWuBwfzt.cjs +2180 -0
- package/dist/xertica-assistant-Caubm0HR.js +2173 -0
- package/dist/xertica-assistant-D2hlwiEP.js +2173 -0
- package/dist/xertica-assistant-DEexPM2u.cjs +2180 -0
- package/dist/xertica-assistant-DN2J_sQQ.cjs +2180 -0
- package/dist/xertica-assistant-DdYS6WXT.cjs +2180 -0
- package/dist/xertica-assistant-Dh1dmEx3.cjs +2180 -0
- package/dist/xertica-assistant-GGcyHEZG.cjs +2180 -0
- package/dist/xertica-assistant-USefPe2L.js +2173 -0
- package/dist/xertica-assistant-cwSHFwfv.cjs +2180 -0
- package/dist/xertica-ui.css +1 -1
- package/llms-compact.txt +1 -1
- package/llms.txt +1 -1
- package/package.json +3 -2
- package/styles/xertica/base.css +46 -0
- package/styles/xertica/tokens.css +10 -0
- package/templates/package.json +1 -1
- package/templates/src/app/App.tsx +5 -1
- package/templates/src/app/components/AuthGuard.tsx +6 -0
- package/templates/src/features/auth/ui/ForgotPasswordContent.tsx +1 -4
- package/templates/src/features/auth/ui/LoginContent.tsx +1 -4
- package/templates/src/features/auth/ui/ResetPasswordContent.tsx +1 -4
- package/templates/src/features/auth/ui/VerifyEmailContent.tsx +1 -4
- package/templates/src/features/home/ui/HomeContent.tsx +12 -13
- package/templates/src/features/template/ui/TemplateContent.tsx +569 -26
- package/templates/src/locales/en/pages/landing.json +175 -0
- package/templates/src/locales/en/pages/templates.json +112 -4
- package/templates/src/locales/es/pages/landing.json +175 -0
- package/templates/src/locales/es/pages/templates.json +112 -4
- package/templates/src/locales/pt-BR/pages/landing.json +175 -0
- package/templates/src/locales/pt-BR/pages/templates.json +112 -4
- package/templates/src/pages/LandingPage.tsx +3 -0
- package/templates/src/styles/xertica/tokens.css +10 -0
- package/templates/vite.config.ts +25 -0
|
@@ -441,7 +441,7 @@ export function XerticaAssistant({
|
|
|
441
441
|
{/* Main Assistant Container */}
|
|
442
442
|
<div
|
|
443
443
|
className={cn(
|
|
444
|
-
`${containerHeight} flex flex-col bg-
|
|
444
|
+
`${containerHeight} flex flex-col bg-card relative`,
|
|
445
445
|
!isFullPage && 'border-l border-border shadow-sm',
|
|
446
446
|
isMobile && isExpanded && 'fixed inset-0 z-[100] h-[100dvh] w-full border-l-0 shadow-2xl',
|
|
447
447
|
className
|
|
@@ -1,35 +1,80 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { ImageWithFallback } from '../../figma/ImageWithFallback';
|
|
3
3
|
import { LanguageSelector } from '../../brand/language-selector';
|
|
4
|
+
import { IsotypeTwist } from '../../brand/isotype';
|
|
5
|
+
import { cn } from '../../shared/utils';
|
|
4
6
|
|
|
5
|
-
export
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
7
|
+
export type AuthPageShellProps =
|
|
8
|
+
| {
|
|
9
|
+
/** Hero photo on the left (default). Requires `imageSrc`/`imageAlt`. */
|
|
10
|
+
leftPanel?: 'image';
|
|
11
|
+
imageSrc: string;
|
|
12
|
+
imageAlt: string;
|
|
13
|
+
/**
|
|
14
|
+
* Background classes for the hero image overlay gradient. Defaults to the
|
|
15
|
+
* shared `--gradient-diagonal` theme token; pass a Tailwind gradient to
|
|
16
|
+
* override it for a specific auth page without affecting the others.
|
|
17
|
+
*/
|
|
18
|
+
gradientClassName?: string;
|
|
19
|
+
children: React.ReactNode;
|
|
20
|
+
}
|
|
21
|
+
| {
|
|
22
|
+
/**
|
|
23
|
+
* Brand isotype mark on a solid `bg-muted` panel — no photo, no
|
|
24
|
+
* gradient. Pairs with a lighter `bg-card` form panel on the right,
|
|
25
|
+
* the inverse of the `image` variant's `bg-muted` form panel.
|
|
26
|
+
*/
|
|
27
|
+
leftPanel: 'isotype';
|
|
28
|
+
children: React.ReactNode;
|
|
29
|
+
};
|
|
10
30
|
|
|
11
31
|
/**
|
|
12
32
|
* Shared two-column shell used by every auth page (Login, ForgotPassword,
|
|
13
|
-
* ResetPassword, VerifyEmail): hero image
|
|
14
|
-
* with a language selector on the right.
|
|
33
|
+
* ResetPassword, VerifyEmail): a left panel (hero image or brand isotype) and
|
|
34
|
+
* a centered form panel with a language selector on the right.
|
|
15
35
|
*/
|
|
16
|
-
export function AuthPageShell(
|
|
36
|
+
export function AuthPageShell(props: AuthPageShellProps) {
|
|
37
|
+
const { children } = props;
|
|
38
|
+
|
|
17
39
|
return (
|
|
18
40
|
<div className="h-screen w-full flex overflow-y-auto">
|
|
19
|
-
|
|
20
|
-
<
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
41
|
+
{props.leftPanel === 'isotype' ? (
|
|
42
|
+
<div className="hidden lg:flex lg:flex-1 items-center justify-center bg-muted">
|
|
43
|
+
<IsotypeTwist variant="magenta-blue" className="w-full max-w-sm" />
|
|
44
|
+
</div>
|
|
45
|
+
) : (
|
|
46
|
+
<div className="hidden lg:flex lg:flex-1 relative overflow-hidden">
|
|
47
|
+
<ImageWithFallback
|
|
48
|
+
src={props.imageSrc}
|
|
49
|
+
alt={props.imageAlt}
|
|
50
|
+
className="absolute inset-0 w-full h-full object-cover"
|
|
51
|
+
/>
|
|
52
|
+
<div
|
|
53
|
+
className={cn(
|
|
54
|
+
'absolute inset-0 opacity-80',
|
|
55
|
+
props.gradientClassName ?? 'bg-[image:var(--gradient-diagonal)]'
|
|
56
|
+
)}
|
|
57
|
+
/>
|
|
58
|
+
</div>
|
|
59
|
+
)}
|
|
27
60
|
|
|
28
|
-
<div
|
|
61
|
+
<div
|
|
62
|
+
className={cn(
|
|
63
|
+
'flex-1 flex items-center justify-center px-4 sm:px-6 lg:px-8 lg:flex-none lg:w-1/2 relative',
|
|
64
|
+
props.leftPanel === 'isotype' ? 'bg-card' : 'bg-muted'
|
|
65
|
+
)}
|
|
66
|
+
>
|
|
29
67
|
<div className="absolute top-4 right-4 z-20">
|
|
30
68
|
<LanguageSelector variant="minimal" showIcon={false} />
|
|
31
69
|
</div>
|
|
32
|
-
|
|
70
|
+
{props.leftPanel !== 'isotype' && (
|
|
71
|
+
<div
|
|
72
|
+
className={cn(
|
|
73
|
+
'absolute inset-0 lg:hidden opacity-10 dark:opacity-5',
|
|
74
|
+
props.gradientClassName ?? 'bg-[image:var(--gradient-diagonal)]'
|
|
75
|
+
)}
|
|
76
|
+
/>
|
|
77
|
+
)}
|
|
33
78
|
<div className="w-full max-w-sm space-y-6 relative z-10">{children}</div>
|
|
34
79
|
</div>
|
|
35
80
|
</div>
|
|
@@ -37,7 +37,7 @@ export function SocialLoginButtons({
|
|
|
37
37
|
<Button
|
|
38
38
|
type="button"
|
|
39
39
|
variant="outline"
|
|
40
|
-
className="w-full justify-center"
|
|
40
|
+
className="w-full justify-center shadow-xs"
|
|
41
41
|
onClick={() => onSocialLogin('Google')}
|
|
42
42
|
>
|
|
43
43
|
<svg className="w-5 h-5 mr-2" viewBox="0 0 48 48" xmlns="http://www.w3.org/2000/svg">
|
|
@@ -67,7 +67,7 @@ export function SocialLoginButtons({
|
|
|
67
67
|
<Button
|
|
68
68
|
type="button"
|
|
69
69
|
variant="outline"
|
|
70
|
-
className="w-full justify-center"
|
|
70
|
+
className="w-full justify-center shadow-xs"
|
|
71
71
|
onClick={() => onSocialLogin('MT Login')}
|
|
72
72
|
>
|
|
73
73
|
<Lock className="w-5 h-5 mr-2 text-[var(--chart-4)]" />
|
|
@@ -79,7 +79,7 @@ export function SocialLoginButtons({
|
|
|
79
79
|
<Button
|
|
80
80
|
type="button"
|
|
81
81
|
variant="outline"
|
|
82
|
-
className="w-full justify-center font-normal"
|
|
82
|
+
className="w-full justify-center font-normal shadow-xs"
|
|
83
83
|
onClick={() => onSocialLogin('gov.br')}
|
|
84
84
|
>
|
|
85
85
|
<span>
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { Button } from '../../ui/button';
|
|
3
|
+
import { cn } from '../../shared/utils';
|
|
4
|
+
|
|
5
|
+
export interface CTASectionAction {
|
|
6
|
+
label: string;
|
|
7
|
+
href?: string;
|
|
8
|
+
onClick?: () => void;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export interface CTASectionProps extends React.HTMLAttributes<HTMLElement> {
|
|
12
|
+
title: string;
|
|
13
|
+
description?: string;
|
|
14
|
+
cta: CTASectionAction;
|
|
15
|
+
secondaryCta?: CTASectionAction;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Full-width dark band prompting a primary conversion action.
|
|
20
|
+
*
|
|
21
|
+
* @description
|
|
22
|
+
* A high-impact closing section for marketing pages: a bold left-aligned
|
|
23
|
+
* headline, optional supporting copy, and up to two CTA buttons on a flat
|
|
24
|
+
* `bg-sidebar` surface — the same token-driven dark surface used elsewhere
|
|
25
|
+
* on this page (e.g. the methodology section) — so it stays legible across
|
|
26
|
+
* all Xertica-ui themes without per-theme contrast tuning or a gradient.
|
|
27
|
+
*
|
|
28
|
+
* @ai-rules
|
|
29
|
+
* 1. The background is a flat `bg-sidebar` surface with a `border-sidebar-border` hairline — never reintroduce a gradient or hardcode colors here.
|
|
30
|
+
* 2. Both buttons use their natural variants (`default` for `cta`, `outline` for `secondaryCta`) with no color overrides — they already contrast correctly against `bg-sidebar`; do not force-style them with one-off colors.
|
|
31
|
+
* 3. Each `cta`/`secondaryCta` needs either `href` (renders an `<a>`) or `onClick`.
|
|
32
|
+
*/
|
|
33
|
+
export function CTASection({
|
|
34
|
+
title,
|
|
35
|
+
description,
|
|
36
|
+
cta,
|
|
37
|
+
secondaryCta,
|
|
38
|
+
className,
|
|
39
|
+
...props
|
|
40
|
+
}: CTASectionProps) {
|
|
41
|
+
return (
|
|
42
|
+
<section
|
|
43
|
+
className={cn(
|
|
44
|
+
'w-full rounded-[var(--radius-card)] border border-sidebar-border bg-sidebar px-6 py-16 md:py-20',
|
|
45
|
+
className
|
|
46
|
+
)}
|
|
47
|
+
{...props}
|
|
48
|
+
>
|
|
49
|
+
<div className="flex flex-col gap-8 md:flex-row md:items-center md:justify-between">
|
|
50
|
+
<div className="max-w-xl">
|
|
51
|
+
<h2 className="text-2xl font-bold text-sidebar-foreground md:text-4xl">{title}</h2>
|
|
52
|
+
{description && <p className="mt-6 text-sidebar-foreground/70">{description}</p>}
|
|
53
|
+
</div>
|
|
54
|
+
|
|
55
|
+
<div className="flex flex-col gap-3 sm:flex-row md:shrink-0">
|
|
56
|
+
<Button asChild={!!cta.href} onClick={cta.onClick}>
|
|
57
|
+
{cta.href ? <a href={cta.href}>{cta.label}</a> : cta.label}
|
|
58
|
+
</Button>
|
|
59
|
+
|
|
60
|
+
{secondaryCta && (
|
|
61
|
+
<Button variant="outline" asChild={!!secondaryCta.href} onClick={secondaryCta.onClick}>
|
|
62
|
+
{secondaryCta.href ? (
|
|
63
|
+
<a href={secondaryCta.href}>{secondaryCta.label}</a>
|
|
64
|
+
) : (
|
|
65
|
+
secondaryCta.label
|
|
66
|
+
)}
|
|
67
|
+
</Button>
|
|
68
|
+
)}
|
|
69
|
+
</div>
|
|
70
|
+
</div>
|
|
71
|
+
</section>
|
|
72
|
+
);
|
|
73
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { cn } from '../../shared/utils';
|
|
3
|
+
|
|
4
|
+
export interface ComplianceBadge {
|
|
5
|
+
icon: React.ReactNode;
|
|
6
|
+
label: string;
|
|
7
|
+
description?: string;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export interface ComplianceBadgeRowProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
11
|
+
badges: ComplianceBadge[];
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* A row of certification/compliance badges (e.g. SOC 2, GDPR, WCAG 2.1 AA).
|
|
16
|
+
*
|
|
17
|
+
* @description
|
|
18
|
+
* Renders a left-aligned grid where each badge pairs a token-radius outlined
|
|
19
|
+
* icon chip with a label and an optional short description, built entirely
|
|
20
|
+
* from theme tokens so it reskins across all Xertica-ui themes and dark mode.
|
|
21
|
+
*
|
|
22
|
+
* @ai-rules
|
|
23
|
+
* 1. Provide `badges` as `{ icon, label, description? }` — `icon` should be a small lucide-react element.
|
|
24
|
+
* 2. Keep `label` and `description` short — badges sit in a `grid-cols-2 sm:grid-cols-4` layout, so each column has limited width.
|
|
25
|
+
* 3. Do not hand-roll badge styling elsewhere — this component owns the icon-chip/label/description layout.
|
|
26
|
+
*/
|
|
27
|
+
export function ComplianceBadgeRow({ badges, className, ...props }: ComplianceBadgeRowProps) {
|
|
28
|
+
return (
|
|
29
|
+
<div
|
|
30
|
+
className={cn('grid grid-cols-2 gap-x-8 gap-y-10 sm:grid-cols-4', className)}
|
|
31
|
+
{...props}
|
|
32
|
+
>
|
|
33
|
+
{badges.map((badge, index) => (
|
|
34
|
+
<div
|
|
35
|
+
key={`${badge.label}-${index}`}
|
|
36
|
+
className="flex flex-col items-start gap-3 text-left"
|
|
37
|
+
>
|
|
38
|
+
<div className="flex items-center justify-center rounded-[var(--radius)] border border-border bg-background p-3 [&>svg]:size-6">
|
|
39
|
+
{badge.icon}
|
|
40
|
+
</div>
|
|
41
|
+
<p className="text-sm font-medium text-foreground">{badge.label}</p>
|
|
42
|
+
{badge.description && (
|
|
43
|
+
<p className="text-xs text-muted-foreground">{badge.description}</p>
|
|
44
|
+
)}
|
|
45
|
+
</div>
|
|
46
|
+
))}
|
|
47
|
+
</div>
|
|
48
|
+
);
|
|
49
|
+
}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { cn } from '../../shared/utils';
|
|
3
|
+
|
|
4
|
+
export type BlockColor =
|
|
5
|
+
| 'primary'
|
|
6
|
+
| 'chart-1'
|
|
7
|
+
| 'chart-2'
|
|
8
|
+
| 'chart-3'
|
|
9
|
+
| 'chart-4'
|
|
10
|
+
| 'chart-5'
|
|
11
|
+
| 'success'
|
|
12
|
+
| 'info'
|
|
13
|
+
| 'warning'
|
|
14
|
+
| 'destructive';
|
|
15
|
+
|
|
16
|
+
const colorTokens: Record<BlockColor, { bg: string; icon: string }> = {
|
|
17
|
+
primary: { bg: 'bg-primary/10', icon: 'text-primary' },
|
|
18
|
+
'chart-1': { bg: 'bg-[var(--chart-1)]/15', icon: 'text-[var(--chart-1)]' },
|
|
19
|
+
'chart-2': { bg: 'bg-[var(--chart-2)]/15', icon: 'text-[var(--chart-2)]' },
|
|
20
|
+
'chart-3': { bg: 'bg-[var(--chart-3)]/15', icon: 'text-[var(--chart-3)]' },
|
|
21
|
+
'chart-4': { bg: 'bg-[var(--chart-4)]/15', icon: 'text-[var(--chart-4)]' },
|
|
22
|
+
'chart-5': { bg: 'bg-[var(--chart-5)]/15', icon: 'text-[var(--chart-5)]' },
|
|
23
|
+
success: { bg: 'bg-success/10', icon: 'text-success' },
|
|
24
|
+
info: { bg: 'bg-info/10', icon: 'text-info' },
|
|
25
|
+
warning: { bg: 'bg-warning/10', icon: 'text-warning' },
|
|
26
|
+
destructive: { bg: 'bg-destructive/10', icon: 'text-destructive' },
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
export interface EvidenceTimelineItem {
|
|
30
|
+
number?: string | number;
|
|
31
|
+
icon?: React.ReactNode;
|
|
32
|
+
title: string;
|
|
33
|
+
description: string;
|
|
34
|
+
color?: BlockColor;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export interface EvidenceTimelineProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
38
|
+
items: EvidenceTimelineItem[];
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Vertical numbered timeline with a connecting line and colored step dots.
|
|
43
|
+
*
|
|
44
|
+
* @description
|
|
45
|
+
* Renders a "how our methodology works" style list: each item gets a
|
|
46
|
+
* colored dot (icon or step number) on a shared vertical line, with a
|
|
47
|
+
* title and description to its right.
|
|
48
|
+
*
|
|
49
|
+
* @ai-rules
|
|
50
|
+
* 1. Provide `icon` for a lucide-react icon in the dot, or `number` for a step label; if neither is set the 1-based index is used.
|
|
51
|
+
* 2. Each item's `color` maps to `colorTokens` — never hardcode colors.
|
|
52
|
+
* 3. This block has no outer card chrome; wrap it in a `<Card>` or section if chrome is needed.
|
|
53
|
+
*/
|
|
54
|
+
export function EvidenceTimeline({ items, className, ...props }: EvidenceTimelineProps) {
|
|
55
|
+
return (
|
|
56
|
+
<div className={cn('relative pl-12', className)} {...props}>
|
|
57
|
+
<div aria-hidden="true" className="absolute left-4 top-4 bottom-4 w-px bg-border" />
|
|
58
|
+
|
|
59
|
+
<ol className="relative">
|
|
60
|
+
{items.map((item, index) => {
|
|
61
|
+
const { bg, icon: iconColor } = colorTokens[item.color ?? 'primary'];
|
|
62
|
+
|
|
63
|
+
return (
|
|
64
|
+
<li key={index} className="relative flex items-start gap-4 pb-10 last:pb-0">
|
|
65
|
+
<div
|
|
66
|
+
className={cn(
|
|
67
|
+
'absolute -left-12 top-0 flex size-8 shrink-0 items-center justify-center rounded-[var(--radius)] z-10 border border-current/20',
|
|
68
|
+
bg
|
|
69
|
+
)}
|
|
70
|
+
>
|
|
71
|
+
<span
|
|
72
|
+
className={cn(
|
|
73
|
+
'flex items-center justify-center text-sm font-semibold [&>svg]:size-4',
|
|
74
|
+
iconColor
|
|
75
|
+
)}
|
|
76
|
+
>
|
|
77
|
+
{item.icon ?? (item.number ?? index + 1)}
|
|
78
|
+
</span>
|
|
79
|
+
</div>
|
|
80
|
+
|
|
81
|
+
<div className="min-w-0">
|
|
82
|
+
<p className="font-semibold">{item.title}</p>
|
|
83
|
+
<p className="mt-2 text-sm opacity-70">{item.description}</p>
|
|
84
|
+
</div>
|
|
85
|
+
</li>
|
|
86
|
+
);
|
|
87
|
+
})}
|
|
88
|
+
</ol>
|
|
89
|
+
</div>
|
|
90
|
+
);
|
|
91
|
+
}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { CheckCircle2 } from 'lucide-react';
|
|
3
|
+
import { cn } from '../../shared/utils';
|
|
4
|
+
|
|
5
|
+
export interface FeatureRowProps extends React.HTMLAttributes<HTMLElement> {
|
|
6
|
+
eyebrow?: string;
|
|
7
|
+
title: string;
|
|
8
|
+
description?: string;
|
|
9
|
+
bullets?: string[];
|
|
10
|
+
visual: React.ReactNode;
|
|
11
|
+
reverse?: boolean;
|
|
12
|
+
tone?: 'default' | 'muted' | 'card';
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Alternating text + visual marketing section.
|
|
17
|
+
*
|
|
18
|
+
* @description
|
|
19
|
+
* A two-column "how it works" / definition row: a text block (eyebrow,
|
|
20
|
+
* title, description, optional checklist) paired with a consumer-supplied
|
|
21
|
+
* visual (image, illustration, or custom node). Stacks on mobile and
|
|
22
|
+
* alternates sides on desktop via `reverse`.
|
|
23
|
+
*
|
|
24
|
+
* @ai-rules
|
|
25
|
+
* 1. Chain multiple `FeatureRow`s and alternate `reverse` to build a "how it works" narrative.
|
|
26
|
+
* 2. Pass the visual as `<ImageWithFallback />` or any custom `ReactNode`; this component never renders an image itself.
|
|
27
|
+
* 3. Use `tone="muted"` on every other row to create a subtle section break instead of adding manual dividers; use `tone="card"` when a theme needs a stronger, genuinely lighter break (some themes set `--muted` equal to `--background`).
|
|
28
|
+
*/
|
|
29
|
+
export function FeatureRow({
|
|
30
|
+
eyebrow,
|
|
31
|
+
title,
|
|
32
|
+
description,
|
|
33
|
+
bullets,
|
|
34
|
+
visual,
|
|
35
|
+
reverse = false,
|
|
36
|
+
tone = 'default',
|
|
37
|
+
className,
|
|
38
|
+
...props
|
|
39
|
+
}: FeatureRowProps) {
|
|
40
|
+
return (
|
|
41
|
+
<section
|
|
42
|
+
className={cn(
|
|
43
|
+
'py-16 md:py-24',
|
|
44
|
+
tone === 'muted' ? 'bg-muted' : tone === 'card' ? 'bg-card' : 'bg-background',
|
|
45
|
+
className
|
|
46
|
+
)}
|
|
47
|
+
{...props}
|
|
48
|
+
>
|
|
49
|
+
<div className="mx-auto grid max-w-6xl gap-12 px-4 sm:px-6 lg:grid-cols-2 lg:items-center lg:px-8">
|
|
50
|
+
<div className={cn(reverse ? 'lg:order-last' : 'lg:order-first')}>
|
|
51
|
+
{eyebrow && (
|
|
52
|
+
<p className="text-sm font-semibold uppercase tracking-wide text-primary">
|
|
53
|
+
{eyebrow}
|
|
54
|
+
</p>
|
|
55
|
+
)}
|
|
56
|
+
<h2 className={cn('text-2xl font-bold text-foreground md:text-3xl', eyebrow && 'mt-2')}>
|
|
57
|
+
{title}
|
|
58
|
+
</h2>
|
|
59
|
+
{description && (
|
|
60
|
+
<p className="mt-6 text-muted-foreground leading-relaxed">{description}</p>
|
|
61
|
+
)}
|
|
62
|
+
{bullets && bullets.length > 0 && (
|
|
63
|
+
<ul className="mt-4 space-y-2">
|
|
64
|
+
{bullets.map(bullet => (
|
|
65
|
+
<li key={bullet} className="flex items-start gap-2">
|
|
66
|
+
<CheckCircle2 className="size-5 shrink-0 text-primary" />
|
|
67
|
+
<span className="text-foreground">{bullet}</span>
|
|
68
|
+
</li>
|
|
69
|
+
))}
|
|
70
|
+
</ul>
|
|
71
|
+
)}
|
|
72
|
+
</div>
|
|
73
|
+
|
|
74
|
+
<div className={cn(reverse ? 'lg:order-first' : 'lg:order-last')}>{visual}</div>
|
|
75
|
+
</div>
|
|
76
|
+
</section>
|
|
77
|
+
);
|
|
78
|
+
}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { Button } from '../../ui/button';
|
|
3
|
+
import { PillBadge } from './PillBadge';
|
|
4
|
+
import { cn } from '../../shared/utils';
|
|
5
|
+
|
|
6
|
+
export interface HeroCta {
|
|
7
|
+
label: string;
|
|
8
|
+
href?: string;
|
|
9
|
+
onClick?: () => void;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export interface HeroProps extends Omit<React.HTMLAttributes<HTMLElement>, 'title'> {
|
|
13
|
+
eyebrow?: { label: string; icon?: React.ReactNode };
|
|
14
|
+
title: React.ReactNode;
|
|
15
|
+
description?: React.ReactNode;
|
|
16
|
+
primaryCta?: HeroCta;
|
|
17
|
+
secondaryCta?: HeroCta;
|
|
18
|
+
visual?: React.ReactNode;
|
|
19
|
+
align?: 'left' | 'center';
|
|
20
|
+
decorative?: boolean;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function HeroCtaButton({
|
|
24
|
+
cta,
|
|
25
|
+
variant,
|
|
26
|
+
}: {
|
|
27
|
+
cta: HeroCta;
|
|
28
|
+
variant: React.ComponentProps<typeof Button>['variant'];
|
|
29
|
+
}) {
|
|
30
|
+
if (cta.href) {
|
|
31
|
+
return (
|
|
32
|
+
<Button asChild variant={variant} size="lg">
|
|
33
|
+
<a href={cta.href} onClick={cta.onClick}>
|
|
34
|
+
{cta.label}
|
|
35
|
+
</a>
|
|
36
|
+
</Button>
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
return (
|
|
41
|
+
<Button variant={variant} size="lg" onClick={cta.onClick}>
|
|
42
|
+
{cta.label}
|
|
43
|
+
</Button>
|
|
44
|
+
);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Full-width, above-the-fold marketing hero section.
|
|
49
|
+
*
|
|
50
|
+
* @description
|
|
51
|
+
* The lead block for landing and marketing pages: an optional `PillBadge`
|
|
52
|
+
* eyebrow, a very large headline, supporting copy, and up to two `<Button>`
|
|
53
|
+
* CTAs. Automatically switches from a single column to a two-column layout
|
|
54
|
+
* once a `visual` (screenshot, illustration, collage) is supplied.
|
|
55
|
+
*
|
|
56
|
+
* @ai-rules
|
|
57
|
+
* 1. Pass `visual` for the two-column desktop layout; omit it for a single-column hero.
|
|
58
|
+
* 2. `primaryCta` renders as `default` (primary/brand) and `secondaryCta` as `secondary`, both via `<Button>` (`size="lg"`) — never hand-roll buttons.
|
|
59
|
+
* 3. Set `decorative` to add a token-based gradient blob backdrop; it is purely visual and never shifts layout.
|
|
60
|
+
* 4. `align="center"` centers the eyebrow/heading/copy/CTAs — pair it with omitting `visual` for a classic centered hero.
|
|
61
|
+
*/
|
|
62
|
+
export function Hero({
|
|
63
|
+
eyebrow,
|
|
64
|
+
title,
|
|
65
|
+
description,
|
|
66
|
+
primaryCta,
|
|
67
|
+
secondaryCta,
|
|
68
|
+
visual,
|
|
69
|
+
align = 'left',
|
|
70
|
+
decorative = false,
|
|
71
|
+
className,
|
|
72
|
+
...props
|
|
73
|
+
}: HeroProps) {
|
|
74
|
+
const isCentered = align === 'center';
|
|
75
|
+
|
|
76
|
+
return (
|
|
77
|
+
<section className={cn('relative overflow-hidden py-16 md:py-24', className)} {...props}>
|
|
78
|
+
{decorative && (
|
|
79
|
+
<div
|
|
80
|
+
className="pointer-events-none absolute inset-0 z-0 overflow-hidden"
|
|
81
|
+
aria-hidden="true"
|
|
82
|
+
>
|
|
83
|
+
<div className="absolute left-1/2 top-1/2 h-72 w-72 -translate-x-1/2 -translate-y-1/2 rounded-full bg-[linear-gradient(135deg,var(--gradient-start),var(--gradient-end))] opacity-20 blur-3xl md:h-[28rem] md:w-[28rem] lg:h-[36rem] lg:w-[36rem]" />
|
|
84
|
+
</div>
|
|
85
|
+
)}
|
|
86
|
+
|
|
87
|
+
<div className="relative z-10 mx-auto max-w-7xl px-4 sm:px-6 lg:px-8">
|
|
88
|
+
<div
|
|
89
|
+
className={cn('grid items-center gap-12', visual ? 'lg:grid-cols-2' : 'mx-auto max-w-3xl')}
|
|
90
|
+
>
|
|
91
|
+
<div
|
|
92
|
+
className={cn(
|
|
93
|
+
'flex flex-col gap-6',
|
|
94
|
+
isCentered ? 'items-center text-center' : 'items-start text-left'
|
|
95
|
+
)}
|
|
96
|
+
>
|
|
97
|
+
{eyebrow && <PillBadge icon={eyebrow.icon}>{eyebrow.label}</PillBadge>}
|
|
98
|
+
|
|
99
|
+
<h1 className="text-4xl font-bold tracking-tight text-foreground md:text-5xl lg:text-6xl">
|
|
100
|
+
{title}
|
|
101
|
+
</h1>
|
|
102
|
+
|
|
103
|
+
{description && (
|
|
104
|
+
<p className="max-w-2xl text-lg text-muted-foreground">{description}</p>
|
|
105
|
+
)}
|
|
106
|
+
|
|
107
|
+
{(primaryCta || secondaryCta) && (
|
|
108
|
+
<div
|
|
109
|
+
className={cn(
|
|
110
|
+
'flex flex-col gap-3 pt-2 sm:flex-row',
|
|
111
|
+
isCentered && 'sm:justify-center'
|
|
112
|
+
)}
|
|
113
|
+
>
|
|
114
|
+
{primaryCta && <HeroCtaButton cta={primaryCta} variant="default" />}
|
|
115
|
+
{secondaryCta && <HeroCtaButton cta={secondaryCta} variant="secondary" />}
|
|
116
|
+
</div>
|
|
117
|
+
)}
|
|
118
|
+
</div>
|
|
119
|
+
|
|
120
|
+
{visual && <div className="relative">{visual}</div>}
|
|
121
|
+
</div>
|
|
122
|
+
</div>
|
|
123
|
+
</section>
|
|
124
|
+
);
|
|
125
|
+
}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { cn } from '../../shared/utils';
|
|
3
|
+
|
|
4
|
+
export type BlockColor =
|
|
5
|
+
| 'primary'
|
|
6
|
+
| 'chart-1'
|
|
7
|
+
| 'chart-2'
|
|
8
|
+
| 'chart-3'
|
|
9
|
+
| 'chart-4'
|
|
10
|
+
| 'chart-5'
|
|
11
|
+
| 'success'
|
|
12
|
+
| 'info'
|
|
13
|
+
| 'warning'
|
|
14
|
+
| 'destructive';
|
|
15
|
+
|
|
16
|
+
const colorTokens: Record<BlockColor, { bg: string; icon: string }> = {
|
|
17
|
+
primary: { bg: 'bg-primary/10', icon: 'text-primary' },
|
|
18
|
+
'chart-1': { bg: 'bg-[var(--chart-1)]/15', icon: 'text-[var(--chart-1)]' },
|
|
19
|
+
'chart-2': { bg: 'bg-[var(--chart-2)]/15', icon: 'text-[var(--chart-2)]' },
|
|
20
|
+
'chart-3': { bg: 'bg-[var(--chart-3)]/15', icon: 'text-[var(--chart-3)]' },
|
|
21
|
+
'chart-4': { bg: 'bg-[var(--chart-4)]/15', icon: 'text-[var(--chart-4)]' },
|
|
22
|
+
'chart-5': { bg: 'bg-[var(--chart-5)]/15', icon: 'text-[var(--chart-5)]' },
|
|
23
|
+
success: { bg: 'bg-success/10', icon: 'text-success' },
|
|
24
|
+
info: { bg: 'bg-info/10', icon: 'text-info' },
|
|
25
|
+
warning: { bg: 'bg-warning/10', icon: 'text-warning' },
|
|
26
|
+
destructive: { bg: 'bg-destructive/10', icon: 'text-destructive' },
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
export interface HowItWorksStepItem {
|
|
30
|
+
number?: string | number;
|
|
31
|
+
icon?: React.ReactNode;
|
|
32
|
+
title: string;
|
|
33
|
+
description: string;
|
|
34
|
+
color?: BlockColor;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export interface HowItWorksStepsProps {
|
|
38
|
+
items: HowItWorksStepItem[];
|
|
39
|
+
className?: string;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Horizontal numbered process row — the horizontal counterpart to `EvidenceTimeline`.
|
|
44
|
+
*
|
|
45
|
+
* @description
|
|
46
|
+
* Renders a "how it works" style row of steps: each item gets a colored
|
|
47
|
+
* badge (icon or step number) above a title and description, laid out
|
|
48
|
+
* side by side in a responsive grid instead of `EvidenceTimeline`'s
|
|
49
|
+
* vertical connecting line.
|
|
50
|
+
*
|
|
51
|
+
* @ai-rules
|
|
52
|
+
* 1. Provide `icon` for a lucide-react icon in the badge, or `number` for a step label; if neither is set the 1-based index is used.
|
|
53
|
+
* 2. Each item's `color` maps to `colorTokens` — never hardcode colors.
|
|
54
|
+
* 3. There is no connecting line between steps (unlike `EvidenceTimeline`) — this avoids awkward line fragments when steps wrap to a new row on narrow screens.
|
|
55
|
+
* 4. This block has no outer card chrome; wrap it in a `<Card>` or section if chrome is needed.
|
|
56
|
+
*/
|
|
57
|
+
export function HowItWorksSteps({ items, className }: HowItWorksStepsProps) {
|
|
58
|
+
return (
|
|
59
|
+
<ol className={cn('grid grid-cols-1 gap-8 sm:grid-cols-2 lg:grid-cols-4', className)}>
|
|
60
|
+
{items.map((item, index) => {
|
|
61
|
+
const { bg, icon: iconColor } = colorTokens[item.color ?? 'primary'];
|
|
62
|
+
|
|
63
|
+
return (
|
|
64
|
+
<li key={index} className="flex flex-col gap-4">
|
|
65
|
+
<div
|
|
66
|
+
className={cn(
|
|
67
|
+
'flex size-10 shrink-0 items-center justify-center rounded-[var(--radius)] border border-current/20 md:size-12',
|
|
68
|
+
bg
|
|
69
|
+
)}
|
|
70
|
+
>
|
|
71
|
+
<span
|
|
72
|
+
className={cn(
|
|
73
|
+
'flex items-center justify-center text-sm font-semibold [&>svg]:size-5',
|
|
74
|
+
iconColor
|
|
75
|
+
)}
|
|
76
|
+
>
|
|
77
|
+
{item.icon ?? (item.number ?? index + 1)}
|
|
78
|
+
</span>
|
|
79
|
+
</div>
|
|
80
|
+
|
|
81
|
+
<div className="min-w-0">
|
|
82
|
+
<p className="font-semibold">{item.title}</p>
|
|
83
|
+
<p className="mt-2 text-sm opacity-70">{item.description}</p>
|
|
84
|
+
</div>
|
|
85
|
+
</li>
|
|
86
|
+
);
|
|
87
|
+
})}
|
|
88
|
+
</ol>
|
|
89
|
+
);
|
|
90
|
+
}
|