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.
Files changed (480) hide show
  1. package/CHANGELOG.md +114 -0
  2. package/README.md +20 -12
  3. package/bin/cli.ts +327 -87
  4. package/bin/generate-tokens.ts +25 -9
  5. package/bin/language-config.ts +58 -18
  6. package/components/assistant/xertica-assistant/xertica-assistant.tsx +1 -1
  7. package/components/blocks/auth/AuthPageShell.tsx +63 -18
  8. package/components/blocks/auth/SocialLoginButtons.tsx +3 -3
  9. package/components/blocks/index.ts +1 -0
  10. package/components/blocks/marketing/CTASection.tsx +73 -0
  11. package/components/blocks/marketing/ComplianceBadgeRow.tsx +49 -0
  12. package/components/blocks/marketing/EvidenceTimeline.tsx +91 -0
  13. package/components/blocks/marketing/FeatureRow.tsx +78 -0
  14. package/components/blocks/marketing/Hero.tsx +125 -0
  15. package/components/blocks/marketing/HowItWorksSteps.tsx +90 -0
  16. package/components/blocks/marketing/LogoCloud.tsx +47 -0
  17. package/components/blocks/marketing/MarketingFooter.tsx +109 -0
  18. package/components/blocks/marketing/MarketingNavbar.tsx +192 -0
  19. package/components/blocks/marketing/PillBadge.tsx +96 -0
  20. package/components/blocks/marketing/SectionHeading.tsx +82 -0
  21. package/components/blocks/marketing/ServiceCardGrid.tsx +238 -0
  22. package/components/blocks/marketing/StatBand.tsx +99 -0
  23. package/components/blocks/marketing/TopAccentCards.tsx +91 -0
  24. package/components/blocks/marketing/index.ts +41 -0
  25. package/components/brand/index.ts +1 -0
  26. package/components/brand/isotype/Isotype.tsx +64 -0
  27. package/components/brand/isotype/IsotypeDiagonal.tsx +51 -0
  28. package/components/brand/isotype/IsotypeFrames.tsx +82 -0
  29. package/components/brand/isotype/IsotypeMini.tsx +65 -0
  30. package/components/brand/isotype/IsotypeTwist.tsx +68 -0
  31. package/components/brand/isotype/frame-variants.ts +20 -0
  32. package/components/brand/isotype/index.ts +9 -0
  33. package/components/brand/isotype/isotype-diagonal.mdx +52 -0
  34. package/components/brand/isotype/isotype-diagonal.stories.tsx +44 -0
  35. package/components/brand/isotype/isotype-diagonal.test.tsx +180 -0
  36. package/components/brand/isotype/isotype-frames.mdx +50 -0
  37. package/components/brand/isotype/isotype-frames.stories.tsx +63 -0
  38. package/components/brand/isotype/isotype-frames.test.tsx +92 -0
  39. package/components/brand/isotype/isotype-mini.mdx +61 -0
  40. package/components/brand/isotype/isotype-mini.stories.tsx +75 -0
  41. package/components/brand/isotype/isotype-mini.test.tsx +45 -0
  42. package/components/brand/isotype/isotype-twist.test.tsx +71 -0
  43. package/components/brand/isotype/isotype.mdx +61 -0
  44. package/components/brand/isotype/isotype.stories.tsx +74 -0
  45. package/components/brand/isotype/isotype.test.tsx +41 -0
  46. package/components/brand/isotype/mini-patterns.ts +50 -0
  47. package/components/brand/isotype/patterns.ts +83 -0
  48. package/components/brand/isotype/twist-variants.ts +20 -0
  49. package/components/pages/forgot-password-page/ForgotPasswordPage.tsx +3 -6
  50. package/components/pages/index.ts +1 -0
  51. package/components/pages/landing-page/LandingPage.tsx +360 -0
  52. package/components/pages/landing-page/index.ts +1 -0
  53. package/components/pages/login-page/LoginPage.tsx +3 -6
  54. package/components/pages/reset-password-page/ResetPasswordPage.tsx +1 -4
  55. package/components/pages/verify-email-page/VerifyEmailPage.tsx +2 -5
  56. package/components/ui/button/button.test.tsx +3 -3
  57. package/components/ui/button/button.tsx +5 -4
  58. package/components/ui/card/card.test.tsx +12 -0
  59. package/components/ui/card/card.tsx +16 -2
  60. package/components/ui/input/input.tsx +1 -1
  61. package/components/ui/input-otp/input-otp.tsx +1 -1
  62. package/components/ui/search/search.tsx +1 -1
  63. package/components/ui/select/select.tsx +2 -2
  64. package/components/ui/switch/switch.tsx +1 -1
  65. package/components/ui/textarea/textarea.tsx +1 -1
  66. package/contexts/BrandColorsContext.tsx +59 -7
  67. package/contexts/theme-data.ts +127 -3
  68. package/dist/AssistantChart-BFBJXVcm.js +3383 -0
  69. package/dist/AssistantChart-BTnE94FR.cjs +3551 -0
  70. package/dist/AssistantChart-BU48lxL2.js +3383 -0
  71. package/dist/AssistantChart-BvccsQMx.cjs +3551 -0
  72. package/dist/AssistantChart-CkskcBVD.js +3383 -0
  73. package/dist/AssistantChart-CoN6ga6Z.js +3383 -0
  74. package/dist/AssistantChart-CrPkO9ip.js +3383 -0
  75. package/dist/AssistantChart-DIRYJ7WY.js +3383 -0
  76. package/dist/AssistantChart-DKz2O1R8.cjs +3551 -0
  77. package/dist/AssistantChart-DOnY1ZlD.cjs +3551 -0
  78. package/dist/AssistantChart-DYL6UEvo.cjs +3551 -0
  79. package/dist/AssistantChart-DjM3qnp5.cjs +3551 -0
  80. package/dist/AssistantChart-hxPyE1S9.cjs +3551 -0
  81. package/dist/AssistantChart-keo-ogKi.js +3383 -0
  82. package/dist/AudioPlayer-AoU5MTiM.cjs +1282 -0
  83. package/dist/AudioPlayer-Bx1vrblm.js +1278 -0
  84. package/dist/AudioPlayer-CpihsbaD.js +1278 -0
  85. package/dist/AudioPlayer-CvGajzMC.cjs +1282 -0
  86. package/dist/AudioPlayer-CvHpFqDG.cjs +1282 -0
  87. package/dist/AudioPlayer-D0-I6J3J.cjs +1282 -0
  88. package/dist/AudioPlayer-D4S7GQou.js +1278 -0
  89. package/dist/AudioPlayer-DIWX_Yg7.cjs +1282 -0
  90. package/dist/AudioPlayer-DrWJnS7c.js +1278 -0
  91. package/dist/AudioPlayer-_P-Z7pAK.js +1278 -0
  92. package/dist/BrandColorsContext-B25Bpr3b.cjs +819 -0
  93. package/dist/BrandColorsContext-BCieATdW.js +812 -0
  94. package/dist/BrandColorsContext-BNKLUVcU.js +829 -0
  95. package/dist/BrandColorsContext-DNZGHItQ.cjs +836 -0
  96. package/dist/BrandColorsContext-DP0DXAXS.js +824 -0
  97. package/dist/BrandColorsContext-DjpC9wR_.cjs +798 -0
  98. package/dist/BrandColorsContext-MpXFhte7.cjs +831 -0
  99. package/dist/BrandColorsContext-Ug_TZ8yn.cjs +846 -0
  100. package/dist/BrandColorsContext-V3tOc-Zw.js +791 -0
  101. package/dist/BrandColorsContext-z0O2LlZz.js +839 -0
  102. package/dist/CodeBlock-BkaZf-R8.cjs +223 -0
  103. package/dist/CodeBlock-CK4rO6lM.js +221 -0
  104. package/dist/CodeBlock-CKXamfVd.cjs +223 -0
  105. package/dist/CodeBlock-CKu8LgbP.cjs +223 -0
  106. package/dist/CodeBlock-CVmE7isS.cjs +223 -0
  107. package/dist/CodeBlock-D7i5-cMv.js +221 -0
  108. package/dist/CodeBlock-Dg56j2ut.cjs +223 -0
  109. package/dist/CodeBlock-DiLS5LLI.js +221 -0
  110. package/dist/CodeBlock-Dt6nUQoo.js +221 -0
  111. package/dist/CodeBlock-zdylBGdZ.js +221 -0
  112. package/dist/CustomTooltipContent-BAR5qCQg.js +33 -0
  113. package/dist/CustomTooltipContent-Bxynuq7T.js +33 -0
  114. package/dist/CustomTooltipContent-BzjOSA0P.cjs +54 -0
  115. package/dist/CustomTooltipContent-C-ZeCNsf.js +33 -0
  116. package/dist/CustomTooltipContent-CBLHBxX8.cjs +54 -0
  117. package/dist/CustomTooltipContent-CON_QrXm.cjs +54 -0
  118. package/dist/CustomTooltipContent-CjWm3jjV.js +33 -0
  119. package/dist/CustomTooltipContent-DTV9MN9E.cjs +54 -0
  120. package/dist/CustomTooltipContent-UR_n2QfW.js +33 -0
  121. package/dist/CustomTooltipContent-v1SXjoFn.cjs +54 -0
  122. package/dist/EvidenceTimeline-DrRk4yqb.cjs +560 -0
  123. package/dist/EvidenceTimeline-l4MaV4C7.js +546 -0
  124. package/dist/FeatureCard-4n_8a63v.cjs +497 -0
  125. package/dist/FeatureCard-BLiAWT3w.js +485 -0
  126. package/dist/FeatureCard-BXRW97Ef.cjs +497 -0
  127. package/dist/FeatureCard-CDgLlWE2.js +485 -0
  128. package/dist/FeatureCard-CIbBHqeY.cjs +497 -0
  129. package/dist/FeatureCard-CgQ8lq-I.cjs +497 -0
  130. package/dist/FeatureCard-Cp8cVC6T.cjs +497 -0
  131. package/dist/FeatureCard-D0MwrTRP.js +485 -0
  132. package/dist/FeatureCard-DtoKPSfW.cjs +497 -0
  133. package/dist/FeatureCard-P4iEpBmB.js +485 -0
  134. package/dist/FeatureCard-e3f8bnF0.js +485 -0
  135. package/dist/FeatureCard-uE5i0in_.js +485 -0
  136. package/dist/ImageWithFallback-BOh1FM3I.js +98 -0
  137. package/dist/ImageWithFallback-BQO7952C.js +98 -0
  138. package/dist/ImageWithFallback-BkMXHCvV.cjs +122 -0
  139. package/dist/ImageWithFallback-C1ww9Hg3.cjs +122 -0
  140. package/dist/ImageWithFallback-C72nwszA.cjs +122 -0
  141. package/dist/ImageWithFallback-CBrkAEo3.cjs +122 -0
  142. package/dist/ImageWithFallback-CCUMDuEC.cjs +122 -0
  143. package/dist/ImageWithFallback-CGk5zPH-.js +98 -0
  144. package/dist/ImageWithFallback-CfnoFFSP.js +98 -0
  145. package/dist/ImageWithFallback-DQD5TTlY.js +98 -0
  146. package/dist/Isotype--fRZWwS6.js +85 -0
  147. package/dist/Isotype-0dpLqetB.js +85 -0
  148. package/dist/Isotype-B8XLEXSB.cjs +92 -0
  149. package/dist/Isotype-ChKwN7e-.cjs +91 -0
  150. package/dist/IsotypeDiagonal-CuPYPP4f.js +84 -0
  151. package/dist/IsotypeDiagonal-eNcOXRAc.cjs +91 -0
  152. package/dist/IsotypeDiagonal-oiwpXZhE.js +104 -0
  153. package/dist/IsotypeDiagonal-xMFoFXkb.cjs +109 -0
  154. package/dist/IsotypeFrames-BcWtyAWp.cjs +83 -0
  155. package/dist/IsotypeFrames-BnvSJKiH.cjs +73 -0
  156. package/dist/IsotypeFrames-iDRTRuIu.js +79 -0
  157. package/dist/IsotypeFrames-qoXOvOJt.js +69 -0
  158. package/dist/IsotypeMini-CQtWVo3h.js +126 -0
  159. package/dist/IsotypeMini-Cu_sW5yN.cjs +134 -0
  160. package/dist/IsotypeTwist-BTdNL4iV.js +106 -0
  161. package/dist/IsotypeTwist-DvsUgZs_.cjs +115 -0
  162. package/dist/LanguageContext-B1aOXO-K.js +1987 -0
  163. package/dist/LanguageContext-BP0k7AzI.js +1993 -0
  164. package/dist/LanguageContext-CChcIHIG.cjs +1998 -0
  165. package/dist/LanguageContext-ubC7TSs_.cjs +1992 -0
  166. package/dist/LanguageSelector-1XhM7R1i.cjs +48 -0
  167. package/dist/LanguageSelector-B3ZVNc55.js +46 -0
  168. package/dist/LanguageSelector-BLFPXGo8.cjs +48 -0
  169. package/dist/LanguageSelector-CYRzWkRZ.cjs +48 -0
  170. package/dist/LanguageSelector-Cj6zl0CM.js +46 -0
  171. package/dist/LanguageSelector-CyHjZgC4.cjs +48 -0
  172. package/dist/LanguageSelector-DE8lIySO.js +46 -0
  173. package/dist/LanguageSelector-DK1zD4VH.cjs +48 -0
  174. package/dist/LanguageSelector-DUr1hjBW.js +46 -0
  175. package/dist/LanguageSelector-DjbWIKWC.js +46 -0
  176. package/dist/LanguageSelector-DseCAa0p.cjs +48 -0
  177. package/dist/LanguageSelector-Du09anfM.js +46 -0
  178. package/dist/LanguageSelector-PZHlFfEs.cjs +48 -0
  179. package/dist/LanguageSelector-SB-NJSmx.js +46 -0
  180. package/dist/LogoCloud-C_uMKVNg.cjs +513 -0
  181. package/dist/LogoCloud-DJsMPNPh.js +500 -0
  182. package/dist/MarketingFooter-B_ycEdTJ.cjs +727 -0
  183. package/dist/MarketingFooter-Bhx-2Vlr.cjs +727 -0
  184. package/dist/MarketingFooter-Br1MGK9e.js +699 -0
  185. package/dist/MarketingFooter-BwE1vmeX.cjs +700 -0
  186. package/dist/MarketingFooter-CsZ1_xL9.js +709 -0
  187. package/dist/MarketingFooter-DCwf78Q4.cjs +716 -0
  188. package/dist/MarketingFooter-KH2r-OOL.js +709 -0
  189. package/dist/MarketingFooter-nB7G7gQ5.js +682 -0
  190. package/dist/PasswordStrengthMeter-B3S6i_k4.cjs +179 -0
  191. package/dist/PasswordStrengthMeter-B8ky1nJI.js +173 -0
  192. package/dist/PasswordStrengthMeter-C5VEopH-.cjs +179 -0
  193. package/dist/PasswordStrengthMeter-CIm7_jNT.js +173 -0
  194. package/dist/PasswordStrengthMeter-DKSAbQzu.js +173 -0
  195. package/dist/PasswordStrengthMeter-DxLu54p-.cjs +179 -0
  196. package/dist/PasswordStrengthMeter-k-e9Pole.cjs +179 -0
  197. package/dist/PasswordStrengthMeter-pAi2viq5.js +173 -0
  198. package/dist/SectionHeading-DEeOKcAd.cjs +857 -0
  199. package/dist/SectionHeading-DMNObcwm.js +838 -0
  200. package/dist/ThemeToggle--CGJjQJv.cjs +219 -0
  201. package/dist/ThemeToggle-4pQbVkpK.js +215 -0
  202. package/dist/ThemeToggle-B6rIVLvC.cjs +219 -0
  203. package/dist/ThemeToggle-BUOTps5l.cjs +219 -0
  204. package/dist/ThemeToggle-Bn_7Pmfe.js +215 -0
  205. package/dist/ThemeToggle-CO5mPl6e.js +215 -0
  206. package/dist/ThemeToggle-CoL8Ady7.js +215 -0
  207. package/dist/ThemeToggle-D2Wzm5bn.cjs +219 -0
  208. package/dist/ThemeToggle-DbZQ0JSV.cjs +219 -0
  209. package/dist/ThemeToggle-vLXEq2TS.js +215 -0
  210. package/dist/VerifyEmailPage-90lK6pP4.js +3258 -0
  211. package/dist/VerifyEmailPage-BJX1Rter.cjs +3320 -0
  212. package/dist/VerifyEmailPage-BSWvOgry.js +3310 -0
  213. package/dist/VerifyEmailPage-BTjI2c9n.js +2954 -0
  214. package/dist/VerifyEmailPage-CDqIkhx-.js +3224 -0
  215. package/dist/VerifyEmailPage-CJGfDSOx.js +2954 -0
  216. package/dist/VerifyEmailPage-Crxje3ZB.js +3323 -0
  217. package/dist/VerifyEmailPage-D2ShbuEN.cjs +3333 -0
  218. package/dist/VerifyEmailPage-DEBZXQ7c.cjs +3310 -0
  219. package/dist/VerifyEmailPage-DGaX-jZv.cjs +3268 -0
  220. package/dist/VerifyEmailPage-DOlZUNc0.cjs +2963 -0
  221. package/dist/VerifyEmailPage-DQPRl_RJ.js +2954 -0
  222. package/dist/VerifyEmailPage-DrdqMbLC.cjs +2963 -0
  223. package/dist/VerifyEmailPage-ZtOPkgOA.cjs +3234 -0
  224. package/dist/VerifyEmailPage-hyDfeCRa.cjs +2963 -0
  225. package/dist/VerifyEmailPage-kKSXl8vu.cjs +2963 -0
  226. package/dist/VerifyEmailPage-s927GSiR.js +3300 -0
  227. package/dist/VerifyEmailPage-w4N-bDhU.js +2954 -0
  228. package/dist/XerticaOrbe-B9tegV1n.js +1925 -0
  229. package/dist/XerticaOrbe-BHex09xs.js +1925 -0
  230. package/dist/XerticaOrbe-BKW3LJEz.js +1925 -0
  231. package/dist/XerticaOrbe-BQ_NjwPS.cjs +1927 -0
  232. package/dist/XerticaOrbe-BdUX171Q.cjs +1927 -0
  233. package/dist/XerticaOrbe-BdlKXRHU.cjs +1927 -0
  234. package/dist/XerticaOrbe-Br2i99U_.cjs +1927 -0
  235. package/dist/XerticaOrbe-CByPAFE5.js +1925 -0
  236. package/dist/XerticaOrbe-Ccu9eFMu.js +1925 -0
  237. package/dist/XerticaOrbe-kjFmuyx-.cjs +1927 -0
  238. package/dist/XerticaProvider-BVid1oqn.cjs +46 -0
  239. package/dist/XerticaProvider-Bi5lKC9N.js +44 -0
  240. package/dist/XerticaProvider-BrPMVhiv.js +44 -0
  241. package/dist/XerticaProvider-Bz_YfNY4.js +44 -0
  242. package/dist/XerticaProvider-CnX5kt5W.cjs +46 -0
  243. package/dist/XerticaProvider-CtvYfRbZ.cjs +46 -0
  244. package/dist/XerticaProvider-DEKNJTlN.js +44 -0
  245. package/dist/XerticaProvider-DMiyExQS.js +44 -0
  246. package/dist/XerticaProvider-DP2lzKip.cjs +46 -0
  247. package/dist/XerticaProvider-De79hhgp.js +44 -0
  248. package/dist/XerticaProvider-Dkk1Vbsy.js +44 -0
  249. package/dist/XerticaProvider-EdzH9Nrw.cjs +46 -0
  250. package/dist/XerticaProvider-X_wavDYA.cjs +46 -0
  251. package/dist/XerticaProvider-b3n_oL8w.cjs +46 -0
  252. package/dist/alert-dialog--qdlmB5i.cjs +872 -0
  253. package/dist/alert-dialog-9XYAn5z5.js +819 -0
  254. package/dist/alert-dialog-B281hud0.cjs +872 -0
  255. package/dist/alert-dialog-BVWbrcrw.cjs +872 -0
  256. package/dist/alert-dialog-B_Ko1xpu.js +819 -0
  257. package/dist/alert-dialog-C48TOdYU.cjs +872 -0
  258. package/dist/alert-dialog-CEPpnpXt.js +819 -0
  259. package/dist/alert-dialog-CIxE8T-J.cjs +872 -0
  260. package/dist/alert-dialog-DW-_iPuf.js +819 -0
  261. package/dist/alert-dialog-NjflitDa.js +819 -0
  262. package/dist/assistant.cjs.js +2 -2
  263. package/dist/assistant.es.js +2 -2
  264. package/dist/avatar-BJwIMbZ_.js +54 -0
  265. package/dist/avatar-C4Zh5fAJ.cjs +77 -0
  266. package/dist/avatar-CTEUKZUT.js +54 -0
  267. package/dist/avatar-CtEKgg7s.cjs +77 -0
  268. package/dist/avatar-D03MNQxs.js +54 -0
  269. package/dist/avatar-D1bZhlhL.cjs +77 -0
  270. package/dist/avatar-DKIxHeKG.cjs +77 -0
  271. package/dist/avatar-Df7KgSvs.js +54 -0
  272. package/dist/avatar-Gy0_Xu9i.cjs +77 -0
  273. package/dist/avatar-v16eZC8p.js +54 -0
  274. package/dist/blocks.cjs.js +33 -18
  275. package/dist/blocks.es.js +2 -2
  276. package/dist/brand.cjs.js +110 -4
  277. package/dist/brand.es.js +98 -4
  278. package/dist/breadcrumb-B1mUiaWB.cjs +98 -0
  279. package/dist/breadcrumb-BGO5PZPG.js +90 -0
  280. package/dist/breadcrumb-BIRgmem-.js +90 -0
  281. package/dist/breadcrumb-BSng-oUf.cjs +98 -0
  282. package/dist/breadcrumb-BvGAY4ne.cjs +98 -0
  283. package/dist/breadcrumb-CES7furU.js +90 -0
  284. package/dist/breadcrumb-CP275kbF.cjs +98 -0
  285. package/dist/breadcrumb-CU-punra.js +90 -0
  286. package/dist/breadcrumb-D7hr1EvJ.js +90 -0
  287. package/dist/breadcrumb-DjV9wfX1.cjs +98 -0
  288. package/dist/button-B05czY_8.js +62 -0
  289. package/dist/button-B3SE1liJ.js +62 -0
  290. package/dist/button-BMDlWZR8.cjs +85 -0
  291. package/dist/button-BYtQygX5.cjs +85 -0
  292. package/dist/button-BnAW-a_w.js +62 -0
  293. package/dist/button-CUPDQews.js +62 -0
  294. package/dist/button-DFa-rtPy.js +62 -0
  295. package/dist/button-DV1G6XrI.cjs +85 -0
  296. package/dist/button-DVhloDtr.cjs +85 -0
  297. package/dist/button-Kd9Fj53S.cjs +85 -0
  298. package/dist/cli.js +367 -65
  299. package/dist/components/blocks/auth/AuthPageShell.d.ts +21 -5
  300. package/dist/components/blocks/index.d.ts +1 -0
  301. package/dist/components/blocks/marketing/CTASection.d.ts +28 -0
  302. package/dist/components/blocks/marketing/ComplianceBadgeRow.d.ts +23 -0
  303. package/dist/components/blocks/marketing/EvidenceTimeline.d.ts +26 -0
  304. package/dist/components/blocks/marketing/FeatureRow.d.ts +25 -0
  305. package/dist/components/blocks/marketing/Hero.d.ts +35 -0
  306. package/dist/components/blocks/marketing/HowItWorksSteps.d.ts +29 -0
  307. package/dist/components/blocks/marketing/LogoCloud.d.ts +22 -0
  308. package/dist/components/blocks/marketing/MarketingFooter.d.ts +42 -0
  309. package/dist/components/blocks/marketing/MarketingNavbar.d.ts +47 -0
  310. package/dist/components/blocks/marketing/PillBadge.d.ts +21 -0
  311. package/dist/components/blocks/marketing/SectionHeading.d.ts +23 -0
  312. package/dist/components/blocks/marketing/ServiceCardGrid.d.ts +65 -0
  313. package/dist/components/blocks/marketing/StatBand.d.ts +25 -0
  314. package/dist/components/blocks/marketing/TopAccentCards.d.ts +29 -0
  315. package/dist/components/blocks/marketing/index.d.ts +28 -0
  316. package/dist/components/brand/index.d.ts +1 -0
  317. package/dist/components/brand/isotype/Isotype.d.ts +27 -0
  318. package/dist/components/brand/isotype/IsotypeDiagonal.d.ts +19 -0
  319. package/dist/components/brand/isotype/IsotypeFrames.d.ts +21 -0
  320. package/dist/components/brand/isotype/IsotypeMini.d.ts +26 -0
  321. package/dist/components/brand/isotype/IsotypeTwist.d.ts +22 -0
  322. package/dist/components/brand/isotype/frame-variants.d.ts +11 -0
  323. package/dist/components/brand/isotype/index.d.ts +9 -0
  324. package/dist/components/brand/isotype/mini-patterns.d.ts +25 -0
  325. package/dist/components/brand/isotype/patterns.d.ts +42 -0
  326. package/dist/components/brand/isotype/twist-variants.d.ts +11 -0
  327. package/dist/components/pages/forgot-password-page/ForgotPasswordPage.d.ts +2 -2
  328. package/dist/components/pages/index.d.ts +1 -0
  329. package/dist/components/pages/landing-page/LandingPage.d.ts +18 -0
  330. package/dist/components/pages/landing-page/index.d.ts +1 -0
  331. package/dist/components/pages/login-page/LoginPage.d.ts +2 -2
  332. package/dist/components/pages/verify-email-page/VerifyEmailPage.d.ts +1 -1
  333. package/dist/components/ui/card/card.d.ts +13 -1
  334. package/dist/contexts/theme-data.d.ts +21 -1
  335. package/dist/dropdown-menu-B9wTZ0uX.cjs +225 -0
  336. package/dist/dropdown-menu-BeBtZOrs.cjs +225 -0
  337. package/dist/dropdown-menu-ChQa9zW3.cjs +225 -0
  338. package/dist/dropdown-menu-D7mRDGis.js +190 -0
  339. package/dist/dropdown-menu-D8ZmqHB7.js +190 -0
  340. package/dist/dropdown-menu-DRvnsQAt.cjs +225 -0
  341. package/dist/dropdown-menu-DUk81i5Y.js +190 -0
  342. package/dist/dropdown-menu-NlUHhVmK.js +190 -0
  343. package/dist/dropdown-menu-_AWBeOts.cjs +225 -0
  344. package/dist/dropdown-menu-qGzLO_HO.js +190 -0
  345. package/dist/hooks.cjs.js +2 -2
  346. package/dist/hooks.es.js +2 -2
  347. package/dist/index.cjs.js +57 -41
  348. package/dist/index.es.js +25 -25
  349. package/dist/input-B53E6K8G.js +65 -0
  350. package/dist/input-B7Q7vcoG.cjs +91 -0
  351. package/dist/input-BysqLMK1.js +65 -0
  352. package/dist/input-CStdFsaH.cjs +91 -0
  353. package/dist/input-CXYth6nW.cjs +91 -0
  354. package/dist/input-CX_fWE2D.cjs +91 -0
  355. package/dist/input-CitUVnEn.js +65 -0
  356. package/dist/input-Csp_Metb.cjs +91 -0
  357. package/dist/input-DVRwGVLx.js +65 -0
  358. package/dist/input-Dqyj7Hdw.cjs +91 -0
  359. package/dist/input-dOgrFQ-3.js +65 -0
  360. package/dist/input-wkBYTp-B.js +65 -0
  361. package/dist/layout.cjs.js +1 -1
  362. package/dist/layout.es.js +1 -1
  363. package/dist/media.cjs.js +1 -1
  364. package/dist/media.es.js +1 -1
  365. package/dist/pages.cjs.js +2 -1
  366. package/dist/pages.es.js +1 -1
  367. package/dist/rich-text-editor-7K7UjLJN.cjs +2968 -0
  368. package/dist/rich-text-editor-B3jLP2bm.cjs +2968 -0
  369. package/dist/rich-text-editor-BHiRUzWZ.js +2894 -0
  370. package/dist/rich-text-editor-BWMRUMJ2.js +2894 -0
  371. package/dist/rich-text-editor-BntMVQsB.js +2894 -0
  372. package/dist/rich-text-editor-BoE6Ks5x.cjs +2968 -0
  373. package/dist/rich-text-editor-BzuEwR_X.js +2894 -0
  374. package/dist/rich-text-editor-CcopGbQ-.js +2894 -0
  375. package/dist/rich-text-editor-CmxSRJIi.cjs +2968 -0
  376. package/dist/rich-text-editor-Diz_onyB.js +2894 -0
  377. package/dist/rich-text-editor-DyYAu28v.cjs +2968 -0
  378. package/dist/rich-text-editor-JS_eMQCC.cjs +2968 -0
  379. package/dist/rich-text-editor-RWvK4hd3.cjs +2968 -0
  380. package/dist/rich-text-editor-gauEkzPM.js +2894 -0
  381. package/dist/select-B6PygS38.cjs +161 -0
  382. package/dist/select-BD763J5Y.cjs +161 -0
  383. package/dist/select-BNfFJwYp.js +130 -0
  384. package/dist/select-CN8IDjGB.js +130 -0
  385. package/dist/select-CwRzQHA7.cjs +161 -0
  386. package/dist/select-CwgD3nMD.js +130 -0
  387. package/dist/select-DEHUm_AC.cjs +161 -0
  388. package/dist/select-DJDgpVm3.cjs +161 -0
  389. package/dist/select-DSLWQLmo.cjs +161 -0
  390. package/dist/select-QJDKZITN.js +130 -0
  391. package/dist/select-YFx0wCYT.js +130 -0
  392. package/dist/select-q7aDfuPn.js +130 -0
  393. package/dist/sidebar-BF7JEL7U.js +1151 -0
  394. package/dist/sidebar-Bjr2doX5.cjs +1154 -0
  395. package/dist/sidebar-Bkk1YAsD.cjs +1154 -0
  396. package/dist/sidebar-CMrNCmhb.cjs +1154 -0
  397. package/dist/sidebar-CO9x8AVn.cjs +1154 -0
  398. package/dist/sidebar-Cn_KB4c6.js +1151 -0
  399. package/dist/sidebar-CuzYeOSz.cjs +1154 -0
  400. package/dist/sidebar-CwlW3LXE.js +1151 -0
  401. package/dist/sidebar-DNkf-Ug6.js +1151 -0
  402. package/dist/sidebar-DaS3fplw.cjs +1154 -0
  403. package/dist/sidebar-Db_C30ph.cjs +1154 -0
  404. package/dist/sidebar-FDCY42oP.js +1151 -0
  405. package/dist/sidebar-miPHsRz4.js +1151 -0
  406. package/dist/sidebar-pZF8mLLu.js +1151 -0
  407. package/dist/skeleton-BX2XTjMO.cjs +87 -0
  408. package/dist/skeleton-BoLK0iV7.js +78 -0
  409. package/dist/skeleton-BtBwJ39W.js +79 -0
  410. package/dist/skeleton-Bysq8yeB.js +79 -0
  411. package/dist/skeleton-C7nspYnC.cjs +87 -0
  412. package/dist/skeleton-CJyg0eJ1.cjs +88 -0
  413. package/dist/skeleton-D8WaauK0.cjs +88 -0
  414. package/dist/skeleton-DBYtjaZW.cjs +88 -0
  415. package/dist/skeleton-DL4V5Vub.cjs +87 -0
  416. package/dist/skeleton-DSMhdqp1.js +78 -0
  417. package/dist/skeleton-DY_lSFWf.js +79 -0
  418. package/dist/skeleton-Df65Ox10.js +79 -0
  419. package/dist/skeleton-DhJswvTW.cjs +88 -0
  420. package/dist/skeleton-DicUfozA.js +78 -0
  421. package/dist/slider-77T_Eqw4.js +56 -0
  422. package/dist/slider-B6puMLXS.cjs +78 -0
  423. package/dist/slider-B785N7lZ.js +56 -0
  424. package/dist/slider-BKV_vvsh.cjs +78 -0
  425. package/dist/slider-B_lUjFNa.cjs +78 -0
  426. package/dist/slider-C6yssKyZ.cjs +78 -0
  427. package/dist/slider-CKZO9gVh.cjs +78 -0
  428. package/dist/slider-Cn-ImSze.js +56 -0
  429. package/dist/slider-CtBpIaU4.js +56 -0
  430. package/dist/slider-KgWmSJbx.js +56 -0
  431. package/dist/tooltip-BPttuPxU.js +48 -0
  432. package/dist/tooltip-BiJVGob3.cjs +72 -0
  433. package/dist/tooltip-CIKRzQqE.cjs +72 -0
  434. package/dist/tooltip-CoDByjE_.cjs +72 -0
  435. package/dist/tooltip-D2OPn-1v.cjs +72 -0
  436. package/dist/tooltip-DlCHQuh1.js +48 -0
  437. package/dist/tooltip-_MAwsiOL.js +48 -0
  438. package/dist/tooltip-fQ2Va0G8.cjs +72 -0
  439. package/dist/tooltip-oAw00FX2.js +48 -0
  440. package/dist/tooltip-u147L0wD.js +48 -0
  441. package/dist/ui.cjs.js +13 -13
  442. package/dist/ui.es.js +13 -13
  443. package/dist/xertica-assistant-B1xAl2Vn.js +2173 -0
  444. package/dist/xertica-assistant-BBUMaUXw.js +2173 -0
  445. package/dist/xertica-assistant-C2A0R94j.js +2173 -0
  446. package/dist/xertica-assistant-CSUprvTR.js +2173 -0
  447. package/dist/xertica-assistant-CWuBwfzt.cjs +2180 -0
  448. package/dist/xertica-assistant-Caubm0HR.js +2173 -0
  449. package/dist/xertica-assistant-D2hlwiEP.js +2173 -0
  450. package/dist/xertica-assistant-DEexPM2u.cjs +2180 -0
  451. package/dist/xertica-assistant-DN2J_sQQ.cjs +2180 -0
  452. package/dist/xertica-assistant-DdYS6WXT.cjs +2180 -0
  453. package/dist/xertica-assistant-Dh1dmEx3.cjs +2180 -0
  454. package/dist/xertica-assistant-GGcyHEZG.cjs +2180 -0
  455. package/dist/xertica-assistant-USefPe2L.js +2173 -0
  456. package/dist/xertica-assistant-cwSHFwfv.cjs +2180 -0
  457. package/dist/xertica-ui.css +1 -1
  458. package/llms-compact.txt +1 -1
  459. package/llms.txt +1 -1
  460. package/package.json +3 -2
  461. package/styles/xertica/base.css +46 -0
  462. package/styles/xertica/tokens.css +10 -0
  463. package/templates/package.json +1 -1
  464. package/templates/src/app/App.tsx +5 -1
  465. package/templates/src/app/components/AuthGuard.tsx +6 -0
  466. package/templates/src/features/auth/ui/ForgotPasswordContent.tsx +1 -4
  467. package/templates/src/features/auth/ui/LoginContent.tsx +1 -4
  468. package/templates/src/features/auth/ui/ResetPasswordContent.tsx +1 -4
  469. package/templates/src/features/auth/ui/VerifyEmailContent.tsx +1 -4
  470. package/templates/src/features/home/ui/HomeContent.tsx +12 -13
  471. package/templates/src/features/template/ui/TemplateContent.tsx +569 -26
  472. package/templates/src/locales/en/pages/landing.json +175 -0
  473. package/templates/src/locales/en/pages/templates.json +112 -4
  474. package/templates/src/locales/es/pages/landing.json +175 -0
  475. package/templates/src/locales/es/pages/templates.json +112 -4
  476. package/templates/src/locales/pt-BR/pages/landing.json +175 -0
  477. package/templates/src/locales/pt-BR/pages/templates.json +112 -4
  478. package/templates/src/pages/LandingPage.tsx +3 -0
  479. package/templates/src/styles/xertica/tokens.css +10 -0
  480. package/templates/vite.config.ts +25 -0
@@ -0,0 +1,360 @@
1
+ import * as React from 'react';
2
+ import {
3
+ BookOpen,
4
+ Braces,
5
+ Code2,
6
+ Component,
7
+ Figma,
8
+ FileCode2,
9
+ Github,
10
+ Layers,
11
+ Package,
12
+ ShieldCheck,
13
+ Sparkles,
14
+ SquareTerminal,
15
+ SwatchBook,
16
+ } from 'lucide-react';
17
+ import { useTranslation } from 'react-i18next';
18
+ import { IsotypeDiagonal, IsotypeFrames } from '../../brand/isotype';
19
+ import { XerticaLogo } from '../../brand/xertica-logo';
20
+ import {
21
+ ComplianceBadgeRow,
22
+ CTASection,
23
+ FeatureRow,
24
+ Hero,
25
+ HowItWorksSteps,
26
+ MarketingFooter,
27
+ MarketingNavbar,
28
+ SectionHeading,
29
+ ServiceCardGrid,
30
+ StatBand,
31
+ TopAccentCards,
32
+ } from '../../blocks/marketing';
33
+
34
+ /**
35
+ * Public marketing landing page for the Xertica-ui design system.
36
+ *
37
+ * @description
38
+ * A full composition of the `blocks/marketing` primitives — navbar, hero,
39
+ * framing cards, service grids, alternating feature rows, a "how it works"
40
+ * steps block, compliance badges, a closing CTA, and a footer.
41
+ * Renders in its own scrollable root, independent of the authenticated
42
+ * app shell's fixed-height layout.
43
+ *
44
+ * @ai-rules
45
+ * 1. This page is presentational only — all CTAs use placeholder `href="#"` links; wire real routes/handlers when integrating.
46
+ * 2. All visuals are token-driven placeholders (brand isotypes, inline SVG logos) to avoid any network/image dependency.
47
+ * 3. Keep composing exclusively from `components/blocks/marketing` — do not hand-roll sections that a block already covers.
48
+ * 4. All copy comes from the `landing` i18n namespace (`locales/<lang>/pages/landing.json`) via `useTranslation()` — never hardcode user-facing text here.
49
+ */
50
+ export function LandingPage() {
51
+ const { t } = useTranslation();
52
+
53
+ return (
54
+ <div className="h-full w-full overflow-y-auto bg-background">
55
+ <MarketingNavbar
56
+ logo={<XerticaLogo className="h-8 w-auto text-primary dark:text-foreground" variant="theme" />}
57
+ links={[
58
+ { label: t('landing.nav.product'), href: '#' },
59
+ { label: t('landing.nav.resources'), href: '#' },
60
+ { label: t('landing.nav.pricing'), href: '#' },
61
+ { label: t('landing.nav.contact'), href: '#' },
62
+ ]}
63
+ cta={{ label: t('landing.nav.login'), href: '#' }}
64
+ openMenuLabel={t('landing.nav.openMenu')}
65
+ closeMenuLabel={t('landing.nav.closeMenu')}
66
+ />
67
+
68
+ <Hero
69
+ eyebrow={{ label: t('landing.hero.eyebrow'), icon: <Sparkles /> }}
70
+ title={t('landing.hero.title')}
71
+ description={t('landing.hero.description')}
72
+ primaryCta={{ label: t('landing.hero.primaryCta'), href: '#' }}
73
+ secondaryCta={{ label: t('landing.hero.secondaryCta'), href: '#' }}
74
+ // Isotype (plain grid mark) is out of rotation for now — only Diagonal + Frames are in active use.
75
+ // visual={<Isotype className="mx-auto w-full max-w-md" />}
76
+ visual={<IsotypeDiagonal className="mx-auto w-full max-w-md" />}
77
+ />
78
+
79
+ <section className="mx-auto max-w-7xl px-4 py-16 sm:px-6 lg:px-8 md:py-24">
80
+ <TopAccentCards
81
+ items={[
82
+ {
83
+ title: t('landing.framing.purpose.title'),
84
+ body: t('landing.framing.purpose.body'),
85
+ color: 'chart-4',
86
+ },
87
+ {
88
+ title: t('landing.framing.problem.title'),
89
+ body: t('landing.framing.problem.body'),
90
+ bullets: [
91
+ t('landing.framing.problem.bullet1'),
92
+ t('landing.framing.problem.bullet2'),
93
+ t('landing.framing.problem.bullet3'),
94
+ ],
95
+ color: 'chart-5',
96
+ },
97
+ ]}
98
+ />
99
+ </section>
100
+
101
+ <section className="bg-card">
102
+ <div className="mx-auto max-w-7xl px-4 py-16 sm:px-6 lg:px-8 md:py-24">
103
+ <SectionHeading
104
+ title={t('landing.ecosystem.title')}
105
+ accentColor="chart-1"
106
+ className="mb-12"
107
+ />
108
+
109
+ <ServiceCardGrid
110
+ variant="card"
111
+ columns={4}
112
+ items={[
113
+ {
114
+ icon: <Figma />,
115
+ color: 'primary',
116
+ title: t('landing.ecosystem.figma.title'),
117
+ description: t('landing.ecosystem.figma.description'),
118
+ bullets: [
119
+ t('landing.ecosystem.figma.bullet1'),
120
+ t('landing.ecosystem.figma.bullet2'),
121
+ ],
122
+ },
123
+ {
124
+ icon: <FileCode2 />,
125
+ color: 'chart-1',
126
+ title: t('landing.ecosystem.vscode.title'),
127
+ description: t('landing.ecosystem.vscode.description'),
128
+ bullets: [
129
+ t('landing.ecosystem.vscode.bullet1'),
130
+ t('landing.ecosystem.vscode.bullet2'),
131
+ ],
132
+ },
133
+ {
134
+ icon: <Component />,
135
+ color: 'chart-5',
136
+ title: t('landing.ecosystem.storybook.title'),
137
+ description: t('landing.ecosystem.storybook.description'),
138
+ bullets: [
139
+ t('landing.ecosystem.storybook.bullet1'),
140
+ t('landing.ecosystem.storybook.bullet2'),
141
+ ],
142
+ },
143
+ {
144
+ icon: <Github />,
145
+ color: 'chart-2',
146
+ title: t('landing.ecosystem.github.title'),
147
+ description: t('landing.ecosystem.github.description'),
148
+ bullets: [
149
+ t('landing.ecosystem.github.bullet1'),
150
+ t('landing.ecosystem.github.bullet2'),
151
+ ],
152
+ },
153
+ ]}
154
+ />
155
+ </div>
156
+ </section>
157
+
158
+ <FeatureRow
159
+ eyebrow={t('landing.features.theming.eyebrow')}
160
+ title={t('landing.features.theming.title')}
161
+ description={t('landing.features.theming.description')}
162
+ bullets={[
163
+ t('landing.features.theming.bullet1'),
164
+ t('landing.features.theming.bullet2'),
165
+ t('landing.features.theming.bullet3'),
166
+ ]}
167
+ visual={<IsotypeFrames variant="blue-magenta" className="mx-auto w-full max-w-md" />}
168
+ />
169
+
170
+ <FeatureRow
171
+ tone="card"
172
+ reverse
173
+ eyebrow={t('landing.features.composition.eyebrow')}
174
+ title={t('landing.features.composition.title')}
175
+ description={t('landing.features.composition.description')}
176
+ bullets={[
177
+ t('landing.features.composition.bullet1'),
178
+ t('landing.features.composition.bullet2'),
179
+ t('landing.features.composition.bullet3'),
180
+ ]}
181
+ visual={<IsotypeDiagonal className="mx-auto w-full max-w-md" />}
182
+ />
183
+
184
+ <FeatureRow
185
+ eyebrow={t('landing.features.onboarding.eyebrow')}
186
+ title={t('landing.features.onboarding.title')}
187
+ description={t('landing.features.onboarding.description')}
188
+ bullets={[
189
+ t('landing.features.onboarding.bullet1'),
190
+ t('landing.features.onboarding.bullet2'),
191
+ t('landing.features.onboarding.bullet3'),
192
+ ]}
193
+ visual={<IsotypeFrames variant="blue-yellow" className="mx-auto w-full max-w-md" />}
194
+ />
195
+
196
+ <section className="mx-auto max-w-7xl px-4 py-16 sm:px-6 lg:px-8 md:py-24">
197
+ <SectionHeading
198
+ title={t('landing.useCases.title')}
199
+ accentColor="chart-4"
200
+ className="mb-12"
201
+ />
202
+
203
+ <ServiceCardGrid
204
+ variant="card"
205
+ columns={3}
206
+ items={[
207
+ {
208
+ color: 'chart-2',
209
+ title: t('landing.useCases.ecommerce.title'),
210
+ description: t('landing.useCases.ecommerce.description'),
211
+ checklist: [
212
+ t('landing.useCases.ecommerce.check1'),
213
+ t('landing.useCases.ecommerce.check2'),
214
+ ],
215
+ className: 'border',
216
+ },
217
+ {
218
+ color: 'primary',
219
+ title: t('landing.useCases.saas.title'),
220
+ description: t('landing.useCases.saas.description'),
221
+ checklist: [t('landing.useCases.saas.check1'), t('landing.useCases.saas.check2')],
222
+ className: 'border',
223
+ },
224
+ {
225
+ color: 'chart-4',
226
+ title: t('landing.useCases.fintech.title'),
227
+ description: t('landing.useCases.fintech.description'),
228
+ checklist: [
229
+ t('landing.useCases.fintech.check1'),
230
+ t('landing.useCases.fintech.check2'),
231
+ ],
232
+ className: 'border',
233
+ },
234
+ ]}
235
+ />
236
+ </section>
237
+
238
+ <section className="bg-sidebar text-sidebar-foreground">
239
+ <div className="mx-auto max-w-5xl px-4 py-16 sm:px-6 lg:px-8 md:py-24">
240
+ <SectionHeading
241
+ title={t('landing.methodology.title')}
242
+ tone="sidebar"
243
+ accentColor="primary"
244
+ className="mb-12"
245
+ />
246
+
247
+ <HowItWorksSteps
248
+ items={[
249
+ {
250
+ icon: <SwatchBook />,
251
+ title: t('landing.methodology.tokensFirst.title'),
252
+ description: t('landing.methodology.tokensFirst.description'),
253
+ color: 'chart-4',
254
+ },
255
+ {
256
+ icon: <Layers />,
257
+ title: t('landing.methodology.primitives.title'),
258
+ description: t('landing.methodology.primitives.description'),
259
+ color: 'chart-2',
260
+ },
261
+ {
262
+ icon: <Braces />,
263
+ title: t('landing.methodology.compositionBlocks.title'),
264
+ description: t('landing.methodology.compositionBlocks.description'),
265
+ color: 'chart-1',
266
+ },
267
+ {
268
+ icon: <SquareTerminal />,
269
+ title: t('landing.methodology.cliTemplates.title'),
270
+ description: t('landing.methodology.cliTemplates.description'),
271
+ color: 'warning',
272
+ },
273
+ ]}
274
+ />
275
+ </div>
276
+ </section>
277
+
278
+ <section className="mx-auto max-w-7xl px-4 py-16 sm:px-6 lg:px-8 md:py-24">
279
+ <div className="rounded-2xl border border-border bg-card p-8 md:p-12">
280
+ <ComplianceBadgeRow
281
+ badges={[
282
+ {
283
+ icon: <ShieldCheck />,
284
+ label: t('landing.compliance.wcag.label'),
285
+ description: t('landing.compliance.wcag.description'),
286
+ },
287
+ {
288
+ icon: <Code2 />,
289
+ label: t('landing.compliance.typescript.label'),
290
+ description: t('landing.compliance.typescript.description'),
291
+ },
292
+ {
293
+ icon: <Package />,
294
+ label: t('landing.compliance.treeShakeable.label'),
295
+ description: t('landing.compliance.treeShakeable.description'),
296
+ },
297
+ {
298
+ icon: <BookOpen />,
299
+ label: t('landing.compliance.themeable.label'),
300
+ description: t('landing.compliance.themeable.description'),
301
+ },
302
+ ]}
303
+ />
304
+
305
+ <div className="my-10 border-t border-border" />
306
+
307
+ <StatBand
308
+ columns={3}
309
+ stats={[
310
+ { value: '99.9%', label: t('landing.stats.docsUptime'), color: 'success' },
311
+ { value: '<24h', label: t('landing.stats.avgResponseTime'), color: 'info' },
312
+ { value: '100%', label: t('landing.stats.typedComponents'), color: 'chart-5' },
313
+ ]}
314
+ />
315
+ </div>
316
+ </section>
317
+
318
+ <section className="mx-auto max-w-7xl px-4 pb-16 sm:px-6 lg:px-8 md:pb-24">
319
+ <CTASection
320
+ title={t('landing.cta.title')}
321
+ description={t('landing.cta.description')}
322
+ cta={{ label: t('landing.cta.primary'), href: '#' }}
323
+ secondaryCta={{ label: t('landing.cta.secondary'), href: '#' }}
324
+ />
325
+ </section>
326
+
327
+ <MarketingFooter
328
+ logo={<XerticaLogo className="h-8 w-auto text-primary dark:text-foreground" variant="theme" />}
329
+ tagline={t('landing.footer.tagline')}
330
+ columns={[
331
+ {
332
+ heading: t('landing.footer.product.heading'),
333
+ links: [
334
+ { label: t('landing.footer.product.components'), href: '#' },
335
+ { label: t('landing.footer.product.blocks'), href: '#' },
336
+ { label: t('landing.footer.product.themes'), href: '#' },
337
+ ],
338
+ },
339
+ {
340
+ heading: t('landing.footer.resources.heading'),
341
+ links: [
342
+ { label: t('landing.footer.resources.docs'), href: '#' },
343
+ { label: t('landing.footer.resources.cli'), href: '#' },
344
+ { label: t('landing.footer.resources.changelog'), href: '#' },
345
+ ],
346
+ },
347
+ {
348
+ heading: t('landing.footer.company.heading'),
349
+ links: [
350
+ { label: t('landing.footer.company.about'), href: '#' },
351
+ { label: t('landing.footer.company.contact'), href: '#' },
352
+ { label: t('landing.footer.company.careers'), href: '#' },
353
+ ],
354
+ },
355
+ ]}
356
+ copyright={t('landing.footer.copyright')}
357
+ />
358
+ </div>
359
+ );
360
+ }
@@ -0,0 +1 @@
1
+ export { LandingPage } from './LandingPage';
@@ -22,13 +22,13 @@ interface LoginPageProps {
22
22
  * Standard Login Page component.
23
23
  *
24
24
  * @description
25
- * A complete, responsive login screen featuring a hero image side-panel (on desktop)
25
+ * A complete, responsive login screen featuring a brand isotype side-panel (on desktop)
26
26
  * and a focused authentication form. Supports email/password login and placeholders
27
27
  * for Social/SSO providers (Google, MT Login, gov.br).
28
28
  *
29
29
  * @ai-rules
30
30
  * 1. State Management: You must provide the `onLogin` callback to handle the actual authentication logic.
31
- * 2. Visuals: Hero images use `ImageWithFallback`. You can customize the `src` if needed.
31
+ * 2. Visuals: Left panel renders `IsotypeTwist` via `AuthPageShell`'s `leftPanel="isotype"` no hero image on this page.
32
32
  * 3. Routing: Uses `react-router` for navigation to the forgot-password flow.
33
33
  */
34
34
  export function LoginPage({ onLogin }: LoginPageProps) {
@@ -62,10 +62,7 @@ export function LoginPage({ onLogin }: LoginPageProps) {
62
62
  };
63
63
 
64
64
  return (
65
- <AuthPageShell
66
- imageSrc="https://images.unsplash.com/photo-1551434678-e076c223a692?w=1200&h=800&fit=crop&auto=format"
67
- imageAlt={t('login.heroImageAlt')}
68
- >
65
+ <AuthPageShell leftPanel="isotype">
69
66
  <div className="text-center">
70
67
  <div className="flex items-center justify-center mb-4">
71
68
  <XerticaLogo className="h-12 w-auto text-primary dark:text-foreground" variant="theme" />
@@ -62,10 +62,7 @@ export function ResetPasswordPage() {
62
62
  };
63
63
 
64
64
  return (
65
- <AuthPageShell
66
- imageSrc="https://images.unsplash.com/photo-1555949963-aa79dcee981c?w=1200&h=800&fit=crop&auto=format"
67
- imageAlt={t('resetPassword.heroImageAlt')}
68
- >
65
+ <AuthPageShell leftPanel="isotype">
69
66
  <button
70
67
  onClick={() => navigate('/login')}
71
68
  className="flex items-center gap-2 text-muted-foreground hover:text-foreground transition-colors"
@@ -12,7 +12,7 @@ import { useTranslation } from 'react-i18next';
12
12
  * @description
13
13
  * An informative screen shown after a password reset request. It instructs
14
14
  * the user to check their email and provides a "Resend email" feature.
15
- * Includes the same consistent layout with a hero image side-panel.
15
+ * Includes the same consistent layout with the shared brand isotype side-panel.
16
16
  *
17
17
  * @ai-rules
18
18
  * 1. Data Source: It retrieves the email from the router's `location.state`.
@@ -46,10 +46,7 @@ export function VerifyEmailPage() {
46
46
  };
47
47
 
48
48
  return (
49
- <AuthPageShell
50
- imageSrc="https://images.unsplash.com/photo-1563986768609-322da13575f3?w=1200&h=800&fit=crop&auto=format"
51
- imageAlt={t('verifyEmail.heroImageAlt')}
52
- >
49
+ <AuthPageShell leftPanel="isotype">
53
50
  <div className="text-center">
54
51
  <div className="flex items-center justify-center mb-4">
55
52
  <XerticaLogo className="h-12 w-auto text-primary dark:text-foreground" variant="theme" />
@@ -8,7 +8,7 @@ describe('Button', () => {
8
8
  render(<Button>Click me</Button>);
9
9
  const button = screen.getByRole('button', { name: /click me/i });
10
10
  expect(button).toBeInTheDocument();
11
- expect(button).toHaveClass('bg-primary');
11
+ expect(button).toHaveClass('bg-button-primary');
12
12
  });
13
13
 
14
14
  it('renders correctly with different variants', () => {
@@ -16,7 +16,7 @@ describe('Button', () => {
16
16
  expect(screen.getByRole('button')).toHaveClass('bg-destructive');
17
17
 
18
18
  rerender(<Button variant="outline">Outline</Button>);
19
- expect(screen.getByRole('button')).toHaveClass('border-border');
19
+ expect(screen.getByRole('button')).toHaveClass('border-outline-stroke');
20
20
 
21
21
  rerender(<Button variant="ghost">Ghost</Button>);
22
22
  expect(screen.getByRole('button')).toHaveClass('hover:bg-accent');
@@ -59,6 +59,6 @@ describe('Button', () => {
59
59
  );
60
60
  const link = screen.getByRole('link', { name: /link button/i });
61
61
  expect(link).toBeInTheDocument();
62
- expect(link).toHaveClass('bg-primary'); // Should still have button styles
62
+ expect(link).toHaveClass('bg-button-primary'); // Should still have button styles
63
63
  });
64
64
  });
@@ -6,15 +6,16 @@ import { Loader2 } from 'lucide-react';
6
6
  import { cn } from '../../shared/utils';
7
7
 
8
8
  const buttonVariants = cva(
9
- "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-[var(--radius-button)] text-sm font-medium transition-colors disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
9
+ "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-[var(--radius-button)] text-sm font-button-weight transition-colors disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
10
10
  {
11
11
  variants: {
12
12
  variant: {
13
- default: 'bg-primary text-primary-foreground hover:bg-primary/90',
13
+ default: 'border-button-stroke bg-button-primary text-button-primary',
14
14
  destructive:
15
15
  'bg-destructive text-destructive-foreground hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40',
16
- outline: 'border border-border bg-background hover:bg-accent hover:text-accent-foreground',
17
- secondary: 'bg-secondary text-secondary-foreground hover:bg-secondary/80',
16
+ outline:
17
+ 'border border-outline-stroke bg-background hover:bg-accent hover:text-accent-foreground',
18
+ secondary: 'border-button-stroke bg-button-secondary text-button-secondary',
18
19
  ghost: 'hover:bg-accent hover:text-accent-foreground',
19
20
  link: 'text-primary underline-offset-4 hover:underline',
20
21
  success:
@@ -52,4 +52,16 @@ describe('Card', () => {
52
52
  const { container } = render(<Card className="custom-card">Content</Card>);
53
53
  expect(container.querySelector('[data-slot="card"]')).toHaveClass('custom-card');
54
54
  });
55
+
56
+ it('defaults to the theme-reactive card background and foreground', () => {
57
+ const { container } = render(<Card>Content</Card>);
58
+ expect(container.querySelector('[data-slot="card"]')).toHaveClass('bg-card', 'text-card-foreground');
59
+ });
60
+
61
+ it('pairs variant="white" with a fixed dark text color, not the theme-reactive one', () => {
62
+ const { container } = render(<Card variant="white">Content</Card>);
63
+ const card = container.querySelector('[data-slot="card"]');
64
+ expect(card).toHaveClass('bg-white', 'text-neutral-900');
65
+ expect(card).not.toHaveClass('text-card-foreground');
66
+ });
55
67
  });
@@ -2,6 +2,18 @@ import * as React from 'react';
2
2
 
3
3
  import { cn } from '../../shared/utils';
4
4
 
5
+ export interface CardProps extends React.ComponentProps<'div'> {
6
+ /**
7
+ * Background variant.
8
+ * - `default`: uses the theme's `--card` token (e.g. Marfim on the Xertica theme).
9
+ * - `white`: forces a solid white background regardless of the active theme,
10
+ * for cards that should stand out from the theme's own card tone. Pairs
11
+ * with a fixed dark text color, since the theme's `--card-foreground` can
12
+ * be near-white in dark mode.
13
+ */
14
+ variant?: 'default' | 'white';
15
+ }
16
+
5
17
  /**
6
18
  * Primary content container surface.
7
19
  *
@@ -13,13 +25,15 @@ import { cn } from '../../shared/utils';
13
25
  * 1. NEVER create raw divs with `bg-white dark:bg-black rounded border shadow` — use `<Card>`.
14
26
  * 2. Compose with the semantic order: `CardHeader > CardTitle + CardDescription > CardContent > CardFooter`.
15
27
  * 3. For inline action buttons in the header, use `<CardAction>` (rendered right-aligned automatically).
28
+ * 4. Use `variant="white"` for cards that need a solid white background instead of the theme's card tone.
16
29
  */
17
- function Card({ className, ...props }: React.ComponentProps<'div'>) {
30
+ function Card({ className, variant = 'default', ...props }: CardProps) {
18
31
  return (
19
32
  <div
20
33
  data-slot="card"
21
34
  className={cn(
22
- 'bg-card text-card-foreground flex flex-col gap-6 rounded-[var(--radius-card)]',
35
+ 'flex flex-col gap-6 rounded-[var(--radius-card)]',
36
+ variant === 'white' ? 'bg-white text-neutral-900' : 'bg-card text-card-foreground',
23
37
  className
24
38
  )}
25
39
  {...props}
@@ -38,7 +38,7 @@ const Input = React.forwardRef<HTMLInputElement, InputProps>(
38
38
  type={type}
39
39
  data-slot="input"
40
40
  className={cn(
41
- 'flex w-full min-w-0 bg-background rounded-[var(--radius)] border border-border transition-colors outline-none text-foreground',
41
+ 'flex w-full min-w-0 bg-background rounded-[var(--radius)] border border-input-stroke transition-colors outline-none text-foreground',
42
42
  'placeholder:text-muted-foreground',
43
43
  'focus:ring-2 focus:ring-primary focus:border-transparent',
44
44
  'disabled:cursor-not-allowed disabled:opacity-50',
@@ -74,7 +74,7 @@ function InputOTPSlot({
74
74
  data-slot="input-otp-slot"
75
75
  data-active={isActive}
76
76
  className={cn(
77
- 'data-[active=true]:border-primary data-[active=true]:ring-primary/20 data-[active=true]:aria-invalid:ring-destructive/20 aria-invalid:border-destructive data-[active=true]:aria-invalid:border-destructive relative flex items-center justify-center border border-border rounded-[var(--radius)] bg-background transition-all outline-none data-[active=true]:z-10 data-[active=true]:ring-2',
77
+ 'data-[active=true]:border-primary data-[active=true]:ring-primary/20 data-[active=true]:aria-invalid:ring-destructive/20 aria-invalid:border-destructive data-[active=true]:aria-invalid:border-destructive relative flex items-center justify-center border border-input-stroke rounded-[var(--radius)] bg-background transition-all outline-none data-[active=true]:z-10 data-[active=true]:ring-2',
78
78
  sizeClasses[size],
79
79
  className
80
80
  )}
@@ -109,7 +109,7 @@ const Search = React.forwardRef<HTMLInputElement, SearchProps>(
109
109
  onChange={handleChange}
110
110
  onKeyDown={handleKeyDown}
111
111
  className={cn(
112
- 'flex w-full rounded-[var(--radius)] border border-border bg-background text-foreground transition-colors outline-none',
112
+ 'flex w-full rounded-[var(--radius)] border border-input-stroke bg-background text-foreground transition-colors outline-none',
113
113
  'placeholder:text-muted-foreground',
114
114
  'focus:ring-2 focus:ring-primary focus:border-transparent',
115
115
  'disabled:cursor-not-allowed disabled:opacity-50',
@@ -48,7 +48,7 @@ const SelectTrigger = React.forwardRef<
48
48
  data-slot="select-trigger"
49
49
  data-size={size}
50
50
  className={cn(
51
- 'flex w-full items-center justify-between gap-2 bg-background rounded-[var(--radius)] border border-border transition-colors outline-none whitespace-nowrap text-foreground',
51
+ 'flex w-full items-center justify-between gap-2 bg-background rounded-[var(--radius)] border border-input-stroke transition-colors outline-none whitespace-nowrap text-foreground',
52
52
  'data-[placeholder]:text-muted-foreground',
53
53
  'focus:ring-2 focus:ring-primary focus:border-transparent',
54
54
  'disabled:cursor-not-allowed disabled:opacity-50',
@@ -107,7 +107,7 @@ const SelectContent = React.forwardRef<
107
107
  ref={ref}
108
108
  data-slot="select-content"
109
109
  className={cn(
110
- 'bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 relative z-50 max-h-(--radix-select-content-available-height) min-w-[8rem] origin-(--radix-select-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-[var(--radius)] border border-border shadow-md',
110
+ 'bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 relative z-50 max-h-(--radix-select-content-available-height) min-w-[8rem] origin-(--radix-select-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-[var(--radius)] border border-input-stroke shadow-md',
111
111
  position === 'popper' &&
112
112
  'data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1',
113
113
  className
@@ -45,7 +45,7 @@ const Switch = React.forwardRef<
45
45
  <SwitchPrimitive.Root
46
46
  className={cn(
47
47
  'peer inline-flex shrink-0 items-center rounded-full border border-transparent transition-all outline-none disabled:cursor-not-allowed disabled:opacity-50',
48
- 'data-[state=checked]:bg-primary',
48
+ 'data-[state=checked]:bg-button-primary',
49
49
  'data-[state=unchecked]:bg-muted',
50
50
  'focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]',
51
51
  trackClasses[size],
@@ -43,7 +43,7 @@ const Textarea = React.forwardRef<HTMLTextAreaElement, TextareaProps>(
43
43
  <textarea
44
44
  data-slot="textarea"
45
45
  className={cn(
46
- 'flex min-h-16 w-full bg-background rounded-[var(--radius)] border border-border transition-colors outline-none resize-none text-foreground',
46
+ 'flex min-h-16 w-full bg-background rounded-[var(--radius)] border border-input-stroke transition-colors outline-none resize-none text-foreground',
47
47
  'placeholder:text-muted-foreground',
48
48
  'focus:ring-2 focus:ring-primary focus:border-transparent',
49
49
  'disabled:cursor-not-allowed disabled:opacity-50',