tempest-react-sdk 0.62.0 → 0.64.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (808) hide show
  1. package/README.md +10 -7
  2. package/dist/br/BrazilMap.module.cjs +1 -0
  3. package/dist/br/BrazilMap.module.cjs.map +1 -1
  4. package/dist/br/BrazilMap.module.js +1 -0
  5. package/dist/br/BrazilMap.module.js.map +1 -1
  6. package/dist/br/MapLegend.module.cjs +1 -0
  7. package/dist/br/MapLegend.module.cjs.map +1 -1
  8. package/dist/br/MapLegend.module.js +1 -0
  9. package/dist/br/MapLegend.module.js.map +1 -1
  10. package/dist/br/MunicipalitySearch.module.cjs +1 -0
  11. package/dist/br/MunicipalitySearch.module.cjs.map +1 -1
  12. package/dist/br/MunicipalitySearch.module.js +1 -0
  13. package/dist/br/MunicipalitySearch.module.js.map +1 -1
  14. package/dist/br/PixQRCode.module.cjs +1 -0
  15. package/dist/br/PixQRCode.module.cjs.map +1 -1
  16. package/dist/br/PixQRCode.module.js +1 -0
  17. package/dist/br/PixQRCode.module.js.map +1 -1
  18. package/dist/components/AIChat/AIChat.module.cjs +1 -0
  19. package/dist/components/AIChat/AIChat.module.cjs.map +1 -1
  20. package/dist/components/AIChat/AIChat.module.js +1 -0
  21. package/dist/components/AIChat/AIChat.module.js.map +1 -1
  22. package/dist/components/Accordion/Accordion.module.cjs +1 -0
  23. package/dist/components/Accordion/Accordion.module.cjs.map +1 -1
  24. package/dist/components/Accordion/Accordion.module.js +1 -0
  25. package/dist/components/Accordion/Accordion.module.js.map +1 -1
  26. package/dist/components/Alert/Alert.module.cjs +1 -0
  27. package/dist/components/Alert/Alert.module.cjs.map +1 -1
  28. package/dist/components/Alert/Alert.module.js +1 -0
  29. package/dist/components/Alert/Alert.module.js.map +1 -1
  30. package/dist/components/AppBar/AppBar.module.cjs +1 -0
  31. package/dist/components/AppBar/AppBar.module.cjs.map +1 -1
  32. package/dist/components/AppBar/AppBar.module.js +1 -0
  33. package/dist/components/AppBar/AppBar.module.js.map +1 -1
  34. package/dist/components/AppShell/AppShell.module.cjs +1 -0
  35. package/dist/components/AppShell/AppShell.module.cjs.map +1 -1
  36. package/dist/components/AppShell/AppShell.module.js +1 -0
  37. package/dist/components/AppShell/AppShell.module.js.map +1 -1
  38. package/dist/components/AspectRatio/AspectRatio.module.cjs +1 -0
  39. package/dist/components/AspectRatio/AspectRatio.module.cjs.map +1 -1
  40. package/dist/components/AspectRatio/AspectRatio.module.js +1 -0
  41. package/dist/components/AspectRatio/AspectRatio.module.js.map +1 -1
  42. package/dist/components/AudioPlayer/AudioPlayer.module.cjs +1 -0
  43. package/dist/components/AudioPlayer/AudioPlayer.module.cjs.map +1 -1
  44. package/dist/components/AudioPlayer/AudioPlayer.module.js +1 -0
  45. package/dist/components/AudioPlayer/AudioPlayer.module.js.map +1 -1
  46. package/dist/components/AudioRecorder/AudioRecorder.module.cjs +1 -0
  47. package/dist/components/AudioRecorder/AudioRecorder.module.cjs.map +1 -1
  48. package/dist/components/AudioRecorder/AudioRecorder.module.js +1 -0
  49. package/dist/components/AudioRecorder/AudioRecorder.module.js.map +1 -1
  50. package/dist/components/Avatar/Avatar.module.cjs +1 -0
  51. package/dist/components/Avatar/Avatar.module.cjs.map +1 -1
  52. package/dist/components/Avatar/Avatar.module.js +1 -0
  53. package/dist/components/Avatar/Avatar.module.js.map +1 -1
  54. package/dist/components/AvatarGroup/AvatarGroup.module.cjs +1 -0
  55. package/dist/components/AvatarGroup/AvatarGroup.module.cjs.map +1 -1
  56. package/dist/components/AvatarGroup/AvatarGroup.module.js +1 -0
  57. package/dist/components/AvatarGroup/AvatarGroup.module.js.map +1 -1
  58. package/dist/components/Badge/Badge.module.cjs +1 -0
  59. package/dist/components/Badge/Badge.module.cjs.map +1 -1
  60. package/dist/components/Badge/Badge.module.js +1 -0
  61. package/dist/components/Badge/Badge.module.js.map +1 -1
  62. package/dist/components/Banner/Banner.module.cjs +1 -0
  63. package/dist/components/Banner/Banner.module.cjs.map +1 -1
  64. package/dist/components/Banner/Banner.module.js +1 -0
  65. package/dist/components/Banner/Banner.module.js.map +1 -1
  66. package/dist/components/BarList/BarList.module.cjs +1 -0
  67. package/dist/components/BarList/BarList.module.cjs.map +1 -1
  68. package/dist/components/BarList/BarList.module.js +1 -0
  69. package/dist/components/BarList/BarList.module.js.map +1 -1
  70. package/dist/components/BarcodeScanner/BarcodeScanner.module.cjs +1 -0
  71. package/dist/components/BarcodeScanner/BarcodeScanner.module.cjs.map +1 -1
  72. package/dist/components/BarcodeScanner/BarcodeScanner.module.js +1 -0
  73. package/dist/components/BarcodeScanner/BarcodeScanner.module.js.map +1 -1
  74. package/dist/components/BottomNavigation/BottomNavigation.module.cjs +1 -0
  75. package/dist/components/BottomNavigation/BottomNavigation.module.cjs.map +1 -1
  76. package/dist/components/BottomNavigation/BottomNavigation.module.js +1 -0
  77. package/dist/components/BottomNavigation/BottomNavigation.module.js.map +1 -1
  78. package/dist/components/BottomSheet/BottomSheet.module.cjs +1 -0
  79. package/dist/components/BottomSheet/BottomSheet.module.cjs.map +1 -1
  80. package/dist/components/BottomSheet/BottomSheet.module.js +1 -0
  81. package/dist/components/BottomSheet/BottomSheet.module.js.map +1 -1
  82. package/dist/components/Breadcrumbs/Breadcrumbs.module.cjs +1 -0
  83. package/dist/components/Breadcrumbs/Breadcrumbs.module.cjs.map +1 -1
  84. package/dist/components/Breadcrumbs/Breadcrumbs.module.js +1 -0
  85. package/dist/components/Breadcrumbs/Breadcrumbs.module.js.map +1 -1
  86. package/dist/components/Button/Button.module.cjs +1 -0
  87. package/dist/components/Button/Button.module.cjs.map +1 -1
  88. package/dist/components/Button/Button.module.js +1 -0
  89. package/dist/components/Button/Button.module.js.map +1 -1
  90. package/dist/components/Calendar/Calendar.module.cjs +1 -0
  91. package/dist/components/Calendar/Calendar.module.cjs.map +1 -1
  92. package/dist/components/Calendar/Calendar.module.js +1 -0
  93. package/dist/components/Calendar/Calendar.module.js.map +1 -1
  94. package/dist/components/Card/Card.module.cjs +1 -0
  95. package/dist/components/Card/Card.module.cjs.map +1 -1
  96. package/dist/components/Card/Card.module.js +1 -0
  97. package/dist/components/Card/Card.module.js.map +1 -1
  98. package/dist/components/Carousel/Carousel.module.cjs +1 -0
  99. package/dist/components/Carousel/Carousel.module.cjs.map +1 -1
  100. package/dist/components/Carousel/Carousel.module.js +1 -0
  101. package/dist/components/Carousel/Carousel.module.js.map +1 -1
  102. package/dist/components/Center/Center.module.cjs +1 -0
  103. package/dist/components/Center/Center.module.cjs.map +1 -1
  104. package/dist/components/Center/Center.module.js +1 -0
  105. package/dist/components/Center/Center.module.js.map +1 -1
  106. package/dist/components/Chat/Chat.cjs +1 -1
  107. package/dist/components/Chat/Chat.cjs.map +1 -1
  108. package/dist/components/Chat/Chat.js +71 -96
  109. package/dist/components/Chat/Chat.js.map +1 -1
  110. package/dist/components/Chat/Chat.module.cjs +2 -1
  111. package/dist/components/Chat/Chat.module.cjs.map +1 -1
  112. package/dist/components/Chat/Chat.module.js +31 -8
  113. package/dist/components/Chat/Chat.module.js.map +1 -1
  114. package/dist/components/Chat/ChatActionsMenu.cjs +2 -0
  115. package/dist/components/Chat/ChatActionsMenu.cjs.map +1 -0
  116. package/dist/components/Chat/ChatActionsMenu.js +14 -0
  117. package/dist/components/Chat/ChatActionsMenu.js.map +1 -0
  118. package/dist/components/Chat/ChatAttachments.cjs +2 -0
  119. package/dist/components/Chat/ChatAttachments.cjs.map +1 -0
  120. package/dist/components/Chat/ChatAttachments.js +80 -0
  121. package/dist/components/Chat/ChatAttachments.js.map +1 -0
  122. package/dist/components/Chat/ChatBubble.cjs +2 -0
  123. package/dist/components/Chat/ChatBubble.cjs.map +1 -0
  124. package/dist/components/Chat/ChatBubble.js +155 -0
  125. package/dist/components/Chat/ChatBubble.js.map +1 -0
  126. package/dist/components/Chat/chat-groups.cjs +1 -1
  127. package/dist/components/Chat/chat-groups.cjs.map +1 -1
  128. package/dist/components/Chat/chat-groups.js +42 -2
  129. package/dist/components/Chat/chat-groups.js.map +1 -1
  130. package/dist/components/Chat/chat-receipt.cjs +2 -0
  131. package/dist/components/Chat/chat-receipt.cjs.map +1 -0
  132. package/dist/components/Chat/chat-receipt.js +14 -0
  133. package/dist/components/Chat/chat-receipt.js.map +1 -0
  134. package/dist/components/Checkbox/Checkbox.module.cjs +1 -0
  135. package/dist/components/Checkbox/Checkbox.module.cjs.map +1 -1
  136. package/dist/components/Checkbox/Checkbox.module.js +1 -0
  137. package/dist/components/Checkbox/Checkbox.module.js.map +1 -1
  138. package/dist/components/ChipInput/ChipInput.module.cjs +1 -0
  139. package/dist/components/ChipInput/ChipInput.module.cjs.map +1 -1
  140. package/dist/components/ChipInput/ChipInput.module.js +1 -0
  141. package/dist/components/ChipInput/ChipInput.module.js.map +1 -1
  142. package/dist/components/CodeBlock/CodeBlock.module.cjs +1 -0
  143. package/dist/components/CodeBlock/CodeBlock.module.cjs.map +1 -1
  144. package/dist/components/CodeBlock/CodeBlock.module.js +1 -0
  145. package/dist/components/CodeBlock/CodeBlock.module.js.map +1 -1
  146. package/dist/components/Collapsible/Collapsible.module.cjs +1 -0
  147. package/dist/components/Collapsible/Collapsible.module.cjs.map +1 -1
  148. package/dist/components/Collapsible/Collapsible.module.js +1 -0
  149. package/dist/components/Collapsible/Collapsible.module.js.map +1 -1
  150. package/dist/components/Combobox/Combobox.module.cjs +1 -0
  151. package/dist/components/Combobox/Combobox.module.cjs.map +1 -1
  152. package/dist/components/Combobox/Combobox.module.js +1 -0
  153. package/dist/components/Combobox/Combobox.module.js.map +1 -1
  154. package/dist/components/Command/Command.module.cjs +1 -0
  155. package/dist/components/Command/Command.module.cjs.map +1 -1
  156. package/dist/components/Command/Command.module.js +1 -0
  157. package/dist/components/Command/Command.module.js.map +1 -1
  158. package/dist/components/ContextMenu/ContextMenu.cjs +1 -1
  159. package/dist/components/ContextMenu/ContextMenu.cjs.map +1 -1
  160. package/dist/components/ContextMenu/ContextMenu.js +100 -48
  161. package/dist/components/ContextMenu/ContextMenu.js.map +1 -1
  162. package/dist/components/ContextMenu/ContextMenu.module.cjs +1 -0
  163. package/dist/components/ContextMenu/ContextMenu.module.cjs.map +1 -1
  164. package/dist/components/ContextMenu/ContextMenu.module.js +1 -0
  165. package/dist/components/ContextMenu/ContextMenu.module.js.map +1 -1
  166. package/dist/components/CopyButton/CopyButton.module.cjs +1 -0
  167. package/dist/components/CopyButton/CopyButton.module.cjs.map +1 -1
  168. package/dist/components/CopyButton/CopyButton.module.js +1 -0
  169. package/dist/components/CopyButton/CopyButton.module.js.map +1 -1
  170. package/dist/components/DataList/DataList.module.cjs +1 -0
  171. package/dist/components/DataList/DataList.module.cjs.map +1 -1
  172. package/dist/components/DataList/DataList.module.js +1 -0
  173. package/dist/components/DataList/DataList.module.js.map +1 -1
  174. package/dist/components/DataTable/DataTable.module.cjs +1 -0
  175. package/dist/components/DataTable/DataTable.module.cjs.map +1 -1
  176. package/dist/components/DataTable/DataTable.module.js +1 -0
  177. package/dist/components/DataTable/DataTable.module.js.map +1 -1
  178. package/dist/components/DateRangePicker/DateRangePicker.module.cjs +1 -0
  179. package/dist/components/DateRangePicker/DateRangePicker.module.cjs.map +1 -1
  180. package/dist/components/DateRangePicker/DateRangePicker.module.js +1 -0
  181. package/dist/components/DateRangePicker/DateRangePicker.module.js.map +1 -1
  182. package/dist/components/DescriptionList/DescriptionList.module.cjs +1 -0
  183. package/dist/components/DescriptionList/DescriptionList.module.cjs.map +1 -1
  184. package/dist/components/DescriptionList/DescriptionList.module.js +1 -0
  185. package/dist/components/DescriptionList/DescriptionList.module.js.map +1 -1
  186. package/dist/components/Divider/Divider.module.cjs +1 -0
  187. package/dist/components/Divider/Divider.module.cjs.map +1 -1
  188. package/dist/components/Divider/Divider.module.js +1 -0
  189. package/dist/components/Divider/Divider.module.js.map +1 -1
  190. package/dist/components/Drawer/Drawer.module.cjs +1 -0
  191. package/dist/components/Drawer/Drawer.module.cjs.map +1 -1
  192. package/dist/components/Drawer/Drawer.module.js +1 -0
  193. package/dist/components/Drawer/Drawer.module.js.map +1 -1
  194. package/dist/components/DropdownMenu/DropdownMenu.module.cjs +1 -0
  195. package/dist/components/DropdownMenu/DropdownMenu.module.cjs.map +1 -1
  196. package/dist/components/DropdownMenu/DropdownMenu.module.js +1 -0
  197. package/dist/components/DropdownMenu/DropdownMenu.module.js.map +1 -1
  198. package/dist/components/Dropzone/Dropzone.module.cjs +1 -0
  199. package/dist/components/Dropzone/Dropzone.module.cjs.map +1 -1
  200. package/dist/components/Dropzone/Dropzone.module.js +1 -0
  201. package/dist/components/Dropzone/Dropzone.module.js.map +1 -1
  202. package/dist/components/EmptyState/EmptyState.module.cjs +1 -0
  203. package/dist/components/EmptyState/EmptyState.module.cjs.map +1 -1
  204. package/dist/components/EmptyState/EmptyState.module.js +1 -0
  205. package/dist/components/EmptyState/EmptyState.module.js.map +1 -1
  206. package/dist/components/ErrorState/ErrorState.module.cjs +1 -0
  207. package/dist/components/ErrorState/ErrorState.module.cjs.map +1 -1
  208. package/dist/components/ErrorState/ErrorState.module.js +1 -0
  209. package/dist/components/ErrorState/ErrorState.module.js.map +1 -1
  210. package/dist/components/ErrorText/ErrorText.module.cjs +1 -0
  211. package/dist/components/ErrorText/ErrorText.module.cjs.map +1 -1
  212. package/dist/components/ErrorText/ErrorText.module.js +1 -0
  213. package/dist/components/ErrorText/ErrorText.module.js.map +1 -1
  214. package/dist/components/FileUpload/FileUpload.module.cjs +1 -0
  215. package/dist/components/FileUpload/FileUpload.module.cjs.map +1 -1
  216. package/dist/components/FileUpload/FileUpload.module.js +1 -0
  217. package/dist/components/FileUpload/FileUpload.module.js.map +1 -1
  218. package/dist/components/FilterBar/FilterBar.module.cjs +1 -0
  219. package/dist/components/FilterBar/FilterBar.module.cjs.map +1 -1
  220. package/dist/components/FilterBar/FilterBar.module.js +1 -0
  221. package/dist/components/FilterBar/FilterBar.module.js.map +1 -1
  222. package/dist/components/FloatingActionButton/FloatingActionButton.module.cjs +1 -0
  223. package/dist/components/FloatingActionButton/FloatingActionButton.module.cjs.map +1 -1
  224. package/dist/components/FloatingActionButton/FloatingActionButton.module.js +1 -0
  225. package/dist/components/FloatingActionButton/FloatingActionButton.module.js.map +1 -1
  226. package/dist/components/Form/Form.module.cjs +1 -0
  227. package/dist/components/Form/Form.module.cjs.map +1 -1
  228. package/dist/components/Form/Form.module.js +1 -0
  229. package/dist/components/Form/Form.module.js.map +1 -1
  230. package/dist/components/HoverCard/HoverCard.module.cjs +1 -0
  231. package/dist/components/HoverCard/HoverCard.module.cjs.map +1 -1
  232. package/dist/components/HoverCard/HoverCard.module.js +1 -0
  233. package/dist/components/HoverCard/HoverCard.module.js.map +1 -1
  234. package/dist/components/Image/Image.module.cjs +1 -0
  235. package/dist/components/Image/Image.module.cjs.map +1 -1
  236. package/dist/components/Image/Image.module.js +1 -0
  237. package/dist/components/Image/Image.module.js.map +1 -1
  238. package/dist/components/ImageCropper/ImageCropper.module.cjs +1 -0
  239. package/dist/components/ImageCropper/ImageCropper.module.cjs.map +1 -1
  240. package/dist/components/ImageCropper/ImageCropper.module.js +1 -0
  241. package/dist/components/ImageCropper/ImageCropper.module.js.map +1 -1
  242. package/dist/components/Input/Input.module.cjs +1 -0
  243. package/dist/components/Input/Input.module.cjs.map +1 -1
  244. package/dist/components/Input/Input.module.js +1 -0
  245. package/dist/components/Input/Input.module.js.map +1 -1
  246. package/dist/components/InstallBanner/InstallBanner.module.cjs +1 -0
  247. package/dist/components/InstallBanner/InstallBanner.module.cjs.map +1 -1
  248. package/dist/components/InstallBanner/InstallBanner.module.js +1 -0
  249. package/dist/components/InstallBanner/InstallBanner.module.js.map +1 -1
  250. package/dist/components/Kanban/Kanban.module.cjs +1 -0
  251. package/dist/components/Kanban/Kanban.module.cjs.map +1 -1
  252. package/dist/components/Kanban/Kanban.module.js +1 -0
  253. package/dist/components/Kanban/Kanban.module.js.map +1 -1
  254. package/dist/components/Kbd/Kbd.module.cjs +1 -0
  255. package/dist/components/Kbd/Kbd.module.cjs.map +1 -1
  256. package/dist/components/Kbd/Kbd.module.js +1 -0
  257. package/dist/components/Kbd/Kbd.module.js.map +1 -1
  258. package/dist/components/Label/Label.module.cjs +1 -0
  259. package/dist/components/Label/Label.module.cjs.map +1 -1
  260. package/dist/components/Label/Label.module.js +1 -0
  261. package/dist/components/Label/Label.module.js.map +1 -1
  262. package/dist/components/Layout/Layout.module.cjs +1 -0
  263. package/dist/components/Layout/Layout.module.cjs.map +1 -1
  264. package/dist/components/Layout/Layout.module.js +1 -0
  265. package/dist/components/Layout/Layout.module.js.map +1 -1
  266. package/dist/components/Lightbox/Lightbox.module.cjs +1 -0
  267. package/dist/components/Lightbox/Lightbox.module.cjs.map +1 -1
  268. package/dist/components/Lightbox/Lightbox.module.js +1 -0
  269. package/dist/components/Lightbox/Lightbox.module.js.map +1 -1
  270. package/dist/components/ListTile/ListTile.module.cjs +1 -0
  271. package/dist/components/ListTile/ListTile.module.cjs.map +1 -1
  272. package/dist/components/ListTile/ListTile.module.js +1 -0
  273. package/dist/components/ListTile/ListTile.module.js.map +1 -1
  274. package/dist/components/Markdown/Markdown.module.cjs +1 -0
  275. package/dist/components/Markdown/Markdown.module.cjs.map +1 -1
  276. package/dist/components/Markdown/Markdown.module.js +1 -0
  277. package/dist/components/Markdown/Markdown.module.js.map +1 -1
  278. package/dist/components/Masonry/Masonry.module.cjs +1 -0
  279. package/dist/components/Masonry/Masonry.module.cjs.map +1 -1
  280. package/dist/components/Masonry/Masonry.module.js +1 -0
  281. package/dist/components/Masonry/Masonry.module.js.map +1 -1
  282. package/dist/components/Menubar/Menubar.module.cjs +1 -0
  283. package/dist/components/Menubar/Menubar.module.cjs.map +1 -1
  284. package/dist/components/Menubar/Menubar.module.js +1 -0
  285. package/dist/components/Menubar/Menubar.module.js.map +1 -1
  286. package/dist/components/Modal/Modal.module.cjs +1 -0
  287. package/dist/components/Modal/Modal.module.cjs.map +1 -1
  288. package/dist/components/Modal/Modal.module.js +1 -0
  289. package/dist/components/Modal/Modal.module.js.map +1 -1
  290. package/dist/components/ModalsManager/ModalsManager.module.cjs +1 -0
  291. package/dist/components/ModalsManager/ModalsManager.module.cjs.map +1 -1
  292. package/dist/components/ModalsManager/ModalsManager.module.js +1 -0
  293. package/dist/components/ModalsManager/ModalsManager.module.js.map +1 -1
  294. package/dist/components/MultiSelect/MultiSelect.module.cjs +1 -0
  295. package/dist/components/MultiSelect/MultiSelect.module.cjs.map +1 -1
  296. package/dist/components/MultiSelect/MultiSelect.module.js +1 -0
  297. package/dist/components/MultiSelect/MultiSelect.module.js.map +1 -1
  298. package/dist/components/NProgress/NProgress.module.cjs +1 -0
  299. package/dist/components/NProgress/NProgress.module.cjs.map +1 -1
  300. package/dist/components/NProgress/NProgress.module.js +1 -0
  301. package/dist/components/NProgress/NProgress.module.js.map +1 -1
  302. package/dist/components/Navbar/Navbar.module.cjs +1 -0
  303. package/dist/components/Navbar/Navbar.module.cjs.map +1 -1
  304. package/dist/components/Navbar/Navbar.module.js +1 -0
  305. package/dist/components/Navbar/Navbar.module.js.map +1 -1
  306. package/dist/components/NavigationMenu/NavigationMenu.module.cjs +1 -0
  307. package/dist/components/NavigationMenu/NavigationMenu.module.cjs.map +1 -1
  308. package/dist/components/NavigationMenu/NavigationMenu.module.js +1 -0
  309. package/dist/components/NavigationMenu/NavigationMenu.module.js.map +1 -1
  310. package/dist/components/NavigationRail/NavigationRail.module.cjs +1 -0
  311. package/dist/components/NavigationRail/NavigationRail.module.cjs.map +1 -1
  312. package/dist/components/NavigationRail/NavigationRail.module.js +1 -0
  313. package/dist/components/NavigationRail/NavigationRail.module.js.map +1 -1
  314. package/dist/components/NotificationCenter/NotificationCenter.module.cjs +1 -0
  315. package/dist/components/NotificationCenter/NotificationCenter.module.cjs.map +1 -1
  316. package/dist/components/NotificationCenter/NotificationCenter.module.js +1 -0
  317. package/dist/components/NotificationCenter/NotificationCenter.module.js.map +1 -1
  318. package/dist/components/OfflineIndicator/OfflineIndicator.module.cjs +1 -0
  319. package/dist/components/OfflineIndicator/OfflineIndicator.module.cjs.map +1 -1
  320. package/dist/components/OfflineIndicator/OfflineIndicator.module.js +1 -0
  321. package/dist/components/OfflineIndicator/OfflineIndicator.module.js.map +1 -1
  322. package/dist/components/Page/Page.module.cjs +1 -0
  323. package/dist/components/Page/Page.module.cjs.map +1 -1
  324. package/dist/components/Page/Page.module.js +1 -0
  325. package/dist/components/Page/Page.module.js.map +1 -1
  326. package/dist/components/Pagination/Pagination.module.cjs +1 -0
  327. package/dist/components/Pagination/Pagination.module.cjs.map +1 -1
  328. package/dist/components/Pagination/Pagination.module.js +1 -0
  329. package/dist/components/Pagination/Pagination.module.js.map +1 -1
  330. package/dist/components/PasswordInput/PasswordInput.module.cjs +1 -0
  331. package/dist/components/PasswordInput/PasswordInput.module.cjs.map +1 -1
  332. package/dist/components/PasswordInput/PasswordInput.module.js +1 -0
  333. package/dist/components/PasswordInput/PasswordInput.module.js.map +1 -1
  334. package/dist/components/PinInput/PinInput.module.cjs +1 -0
  335. package/dist/components/PinInput/PinInput.module.cjs.map +1 -1
  336. package/dist/components/PinInput/PinInput.module.js +1 -0
  337. package/dist/components/PinInput/PinInput.module.js.map +1 -1
  338. package/dist/components/Popover/Popover.module.cjs +1 -0
  339. package/dist/components/Popover/Popover.module.cjs.map +1 -1
  340. package/dist/components/Popover/Popover.module.js +1 -0
  341. package/dist/components/Popover/Popover.module.js.map +1 -1
  342. package/dist/components/Progress/Progress.module.cjs +1 -0
  343. package/dist/components/Progress/Progress.module.cjs.map +1 -1
  344. package/dist/components/Progress/Progress.module.js +1 -0
  345. package/dist/components/Progress/Progress.module.js.map +1 -1
  346. package/dist/components/QRCode/QRCode.module.cjs +1 -0
  347. package/dist/components/QRCode/QRCode.module.cjs.map +1 -1
  348. package/dist/components/QRCode/QRCode.module.js +1 -0
  349. package/dist/components/QRCode/QRCode.module.js.map +1 -1
  350. package/dist/components/Radio/Radio.module.cjs +1 -0
  351. package/dist/components/Radio/Radio.module.cjs.map +1 -1
  352. package/dist/components/Radio/Radio.module.js +1 -0
  353. package/dist/components/Radio/Radio.module.js.map +1 -1
  354. package/dist/components/RangeSlider/RangeSlider.module.cjs +1 -0
  355. package/dist/components/RangeSlider/RangeSlider.module.cjs.map +1 -1
  356. package/dist/components/RangeSlider/RangeSlider.module.js +1 -0
  357. package/dist/components/RangeSlider/RangeSlider.module.js.map +1 -1
  358. package/dist/components/RatingStars/RatingStars.module.cjs +1 -0
  359. package/dist/components/RatingStars/RatingStars.module.cjs.map +1 -1
  360. package/dist/components/RatingStars/RatingStars.module.js +1 -0
  361. package/dist/components/RatingStars/RatingStars.module.js.map +1 -1
  362. package/dist/components/RefreshIndicator/RefreshIndicator.module.cjs +1 -0
  363. package/dist/components/RefreshIndicator/RefreshIndicator.module.cjs.map +1 -1
  364. package/dist/components/RefreshIndicator/RefreshIndicator.module.js +1 -0
  365. package/dist/components/RefreshIndicator/RefreshIndicator.module.js.map +1 -1
  366. package/dist/components/Resizable/Resizable.module.cjs +1 -0
  367. package/dist/components/Resizable/Resizable.module.cjs.map +1 -1
  368. package/dist/components/Resizable/Resizable.module.js +1 -0
  369. package/dist/components/Resizable/Resizable.module.js.map +1 -1
  370. package/dist/components/SafeArea/SafeArea.module.cjs +1 -0
  371. package/dist/components/SafeArea/SafeArea.module.cjs.map +1 -1
  372. package/dist/components/SafeArea/SafeArea.module.js +1 -0
  373. package/dist/components/SafeArea/SafeArea.module.js.map +1 -1
  374. package/dist/components/Scheduler/Scheduler.module.cjs +1 -0
  375. package/dist/components/Scheduler/Scheduler.module.cjs.map +1 -1
  376. package/dist/components/Scheduler/Scheduler.module.js +1 -0
  377. package/dist/components/Scheduler/Scheduler.module.js.map +1 -1
  378. package/dist/components/ScrollArea/ScrollArea.module.cjs +1 -0
  379. package/dist/components/ScrollArea/ScrollArea.module.cjs.map +1 -1
  380. package/dist/components/ScrollArea/ScrollArea.module.js +1 -0
  381. package/dist/components/ScrollArea/ScrollArea.module.js.map +1 -1
  382. package/dist/components/SearchBar/SearchBar.module.cjs +1 -0
  383. package/dist/components/SearchBar/SearchBar.module.cjs.map +1 -1
  384. package/dist/components/SearchBar/SearchBar.module.js +1 -0
  385. package/dist/components/SearchBar/SearchBar.module.js.map +1 -1
  386. package/dist/components/SegmentedControl/SegmentedControl.module.cjs +1 -0
  387. package/dist/components/SegmentedControl/SegmentedControl.module.cjs.map +1 -1
  388. package/dist/components/SegmentedControl/SegmentedControl.module.js +1 -0
  389. package/dist/components/SegmentedControl/SegmentedControl.module.js.map +1 -1
  390. package/dist/components/Select/Select.module.cjs +1 -0
  391. package/dist/components/Select/Select.module.cjs.map +1 -1
  392. package/dist/components/Select/Select.module.js +1 -0
  393. package/dist/components/Select/Select.module.js.map +1 -1
  394. package/dist/components/Sidebar/Sidebar.module.cjs +1 -0
  395. package/dist/components/Sidebar/Sidebar.module.cjs.map +1 -1
  396. package/dist/components/Sidebar/Sidebar.module.js +1 -0
  397. package/dist/components/Sidebar/Sidebar.module.js.map +1 -1
  398. package/dist/components/SignaturePad/SignaturePad.module.cjs +1 -0
  399. package/dist/components/SignaturePad/SignaturePad.module.cjs.map +1 -1
  400. package/dist/components/SignaturePad/SignaturePad.module.js +1 -0
  401. package/dist/components/SignaturePad/SignaturePad.module.js.map +1 -1
  402. package/dist/components/Skeleton/Skeleton.module.cjs +1 -0
  403. package/dist/components/Skeleton/Skeleton.module.cjs.map +1 -1
  404. package/dist/components/Skeleton/Skeleton.module.js +1 -0
  405. package/dist/components/Skeleton/Skeleton.module.js.map +1 -1
  406. package/dist/components/Slider/Slider.module.cjs +1 -0
  407. package/dist/components/Slider/Slider.module.cjs.map +1 -1
  408. package/dist/components/Slider/Slider.module.js +1 -0
  409. package/dist/components/Slider/Slider.module.js.map +1 -1
  410. package/dist/components/Spacer/Spacer.module.cjs +1 -0
  411. package/dist/components/Spacer/Spacer.module.cjs.map +1 -1
  412. package/dist/components/Spacer/Spacer.module.js +1 -0
  413. package/dist/components/Spacer/Spacer.module.js.map +1 -1
  414. package/dist/components/Sparkline/Sparkline.module.cjs +1 -0
  415. package/dist/components/Sparkline/Sparkline.module.cjs.map +1 -1
  416. package/dist/components/Sparkline/Sparkline.module.js +1 -0
  417. package/dist/components/Sparkline/Sparkline.module.js.map +1 -1
  418. package/dist/components/Spinner/Spinner.module.cjs +1 -0
  419. package/dist/components/Spinner/Spinner.module.cjs.map +1 -1
  420. package/dist/components/Spinner/Spinner.module.js +1 -0
  421. package/dist/components/Spinner/Spinner.module.js.map +1 -1
  422. package/dist/components/Stat/Stat.module.cjs +1 -0
  423. package/dist/components/Stat/Stat.module.cjs.map +1 -1
  424. package/dist/components/Stat/Stat.module.js +1 -0
  425. package/dist/components/Stat/Stat.module.js.map +1 -1
  426. package/dist/components/Stepper/Stepper.module.cjs +1 -0
  427. package/dist/components/Stepper/Stepper.module.cjs.map +1 -1
  428. package/dist/components/Stepper/Stepper.module.js +1 -0
  429. package/dist/components/Stepper/Stepper.module.js.map +1 -1
  430. package/dist/components/StepperInput/StepperInput.module.cjs +1 -0
  431. package/dist/components/StepperInput/StepperInput.module.cjs.map +1 -1
  432. package/dist/components/StepperInput/StepperInput.module.js +1 -0
  433. package/dist/components/StepperInput/StepperInput.module.js.map +1 -1
  434. package/dist/components/Switch/Switch.module.cjs +1 -0
  435. package/dist/components/Switch/Switch.module.cjs.map +1 -1
  436. package/dist/components/Switch/Switch.module.js +1 -0
  437. package/dist/components/Switch/Switch.module.js.map +1 -1
  438. package/dist/components/SyncStatusBadge/SyncStatusBadge.module.cjs +1 -0
  439. package/dist/components/SyncStatusBadge/SyncStatusBadge.module.cjs.map +1 -1
  440. package/dist/components/SyncStatusBadge/SyncStatusBadge.module.js +1 -0
  441. package/dist/components/SyncStatusBadge/SyncStatusBadge.module.js.map +1 -1
  442. package/dist/components/Table/Table.module.cjs +1 -0
  443. package/dist/components/Table/Table.module.cjs.map +1 -1
  444. package/dist/components/Table/Table.module.js +1 -0
  445. package/dist/components/Table/Table.module.js.map +1 -1
  446. package/dist/components/Tabs/Tabs.module.cjs +1 -0
  447. package/dist/components/Tabs/Tabs.module.cjs.map +1 -1
  448. package/dist/components/Tabs/Tabs.module.js +1 -0
  449. package/dist/components/Tabs/Tabs.module.js.map +1 -1
  450. package/dist/components/Tag/Tag.module.cjs +1 -0
  451. package/dist/components/Tag/Tag.module.cjs.map +1 -1
  452. package/dist/components/Tag/Tag.module.js +1 -0
  453. package/dist/components/Tag/Tag.module.js.map +1 -1
  454. package/dist/components/Textarea/Textarea.module.cjs +1 -0
  455. package/dist/components/Textarea/Textarea.module.cjs.map +1 -1
  456. package/dist/components/Textarea/Textarea.module.js +1 -0
  457. package/dist/components/Textarea/Textarea.module.js.map +1 -1
  458. package/dist/components/TimePicker/TimePicker.module.cjs +1 -0
  459. package/dist/components/TimePicker/TimePicker.module.cjs.map +1 -1
  460. package/dist/components/TimePicker/TimePicker.module.js +1 -0
  461. package/dist/components/TimePicker/TimePicker.module.js.map +1 -1
  462. package/dist/components/Timeline/Timeline.module.cjs +1 -0
  463. package/dist/components/Timeline/Timeline.module.cjs.map +1 -1
  464. package/dist/components/Timeline/Timeline.module.js +1 -0
  465. package/dist/components/Timeline/Timeline.module.js.map +1 -1
  466. package/dist/components/Toast/Toast.module.cjs +1 -0
  467. package/dist/components/Toast/Toast.module.cjs.map +1 -1
  468. package/dist/components/Toast/Toast.module.js +1 -0
  469. package/dist/components/Toast/Toast.module.js.map +1 -1
  470. package/dist/components/Toggle/Toggle.module.cjs +1 -0
  471. package/dist/components/Toggle/Toggle.module.cjs.map +1 -1
  472. package/dist/components/Toggle/Toggle.module.js +1 -0
  473. package/dist/components/Toggle/Toggle.module.js.map +1 -1
  474. package/dist/components/ToggleGroup/ToggleGroup.module.cjs +1 -0
  475. package/dist/components/ToggleGroup/ToggleGroup.module.cjs.map +1 -1
  476. package/dist/components/ToggleGroup/ToggleGroup.module.js +1 -0
  477. package/dist/components/ToggleGroup/ToggleGroup.module.js.map +1 -1
  478. package/dist/components/Tooltip/Tooltip.module.cjs +1 -0
  479. package/dist/components/Tooltip/Tooltip.module.cjs.map +1 -1
  480. package/dist/components/Tooltip/Tooltip.module.js +1 -0
  481. package/dist/components/Tooltip/Tooltip.module.js.map +1 -1
  482. package/dist/components/Tour/Tour.module.cjs +1 -0
  483. package/dist/components/Tour/Tour.module.cjs.map +1 -1
  484. package/dist/components/Tour/Tour.module.js +1 -0
  485. package/dist/components/Tour/Tour.module.js.map +1 -1
  486. package/dist/components/Transfer/Transfer.module.cjs +1 -0
  487. package/dist/components/Transfer/Transfer.module.cjs.map +1 -1
  488. package/dist/components/Transfer/Transfer.module.js +1 -0
  489. package/dist/components/Transfer/Transfer.module.js.map +1 -1
  490. package/dist/components/TreeView/TreeView.module.cjs +1 -0
  491. package/dist/components/TreeView/TreeView.module.cjs.map +1 -1
  492. package/dist/components/TreeView/TreeView.module.js +1 -0
  493. package/dist/components/TreeView/TreeView.module.js.map +1 -1
  494. package/dist/components/TruncateText/TruncateText.module.cjs +1 -0
  495. package/dist/components/TruncateText/TruncateText.module.cjs.map +1 -1
  496. package/dist/components/TruncateText/TruncateText.module.js +1 -0
  497. package/dist/components/TruncateText/TruncateText.module.js.map +1 -1
  498. package/dist/components/UpdatePrompt/UpdatePrompt.module.cjs +1 -0
  499. package/dist/components/UpdatePrompt/UpdatePrompt.module.cjs.map +1 -1
  500. package/dist/components/UpdatePrompt/UpdatePrompt.module.js +1 -0
  501. package/dist/components/UpdatePrompt/UpdatePrompt.module.js.map +1 -1
  502. package/dist/components/VideoPlayer/VideoPlayer.module.cjs +1 -0
  503. package/dist/components/VideoPlayer/VideoPlayer.module.cjs.map +1 -1
  504. package/dist/components/VideoPlayer/VideoPlayer.module.js +1 -0
  505. package/dist/components/VideoPlayer/VideoPlayer.module.js.map +1 -1
  506. package/dist/components/VirtualList/VirtualList.module.cjs +1 -0
  507. package/dist/components/VirtualList/VirtualList.module.cjs.map +1 -1
  508. package/dist/components/VirtualList/VirtualList.module.js +1 -0
  509. package/dist/components/VirtualList/VirtualList.module.js.map +1 -1
  510. package/dist/components/VirtualTable/VirtualTable.module.cjs +1 -0
  511. package/dist/components/VirtualTable/VirtualTable.module.cjs.map +1 -1
  512. package/dist/components/VirtualTable/VirtualTable.module.js +1 -0
  513. package/dist/components/VirtualTable/VirtualTable.module.js.map +1 -1
  514. package/dist/components/VisuallyHidden/VisuallyHidden.module.cjs +1 -0
  515. package/dist/components/VisuallyHidden/VisuallyHidden.module.cjs.map +1 -1
  516. package/dist/components/VisuallyHidden/VisuallyHidden.module.js +1 -0
  517. package/dist/components/VisuallyHidden/VisuallyHidden.module.js.map +1 -1
  518. package/dist/components/Wizard/Wizard.module.cjs +1 -0
  519. package/dist/components/Wizard/Wizard.module.cjs.map +1 -1
  520. package/dist/components/Wizard/Wizard.module.js +1 -0
  521. package/dist/components/Wizard/Wizard.module.js.map +1 -1
  522. package/dist/editor/RichTextEditor.module.cjs +1 -0
  523. package/dist/editor/RichTextEditor.module.cjs.map +1 -1
  524. package/dist/editor/RichTextEditor.module.js +1 -0
  525. package/dist/editor/RichTextEditor.module.js.map +1 -1
  526. package/dist/geo/TrajectoryMap.module.cjs +1 -0
  527. package/dist/geo/TrajectoryMap.module.cjs.map +1 -1
  528. package/dist/geo/TrajectoryMap.module.js +1 -0
  529. package/dist/geo/TrajectoryMap.module.js.map +1 -1
  530. package/dist/icons/IconPicker.module.cjs +1 -0
  531. package/dist/icons/IconPicker.module.cjs.map +1 -1
  532. package/dist/icons/IconPicker.module.js +1 -0
  533. package/dist/icons/IconPicker.module.js.map +1 -1
  534. package/dist/styles/AIChat.css +1 -78
  535. package/dist/styles/Accordion.css +1 -11
  536. package/dist/styles/Alert.css +1 -31
  537. package/dist/styles/AppBar.css +1 -16
  538. package/dist/styles/AppShell.css +1 -7
  539. package/dist/styles/AspectRatio.css +1 -2
  540. package/dist/styles/AudioPlayer.css +1 -12
  541. package/dist/styles/AudioRecorder.css +1 -19
  542. package/dist/styles/Avatar.css +1 -12
  543. package/dist/styles/AvatarGroup.css +1 -17
  544. package/dist/styles/Badge.css +1 -24
  545. package/dist/styles/Banner.css +1 -12
  546. package/dist/styles/BarList.css +1 -9
  547. package/dist/styles/BarcodeScanner.css +1 -20
  548. package/dist/styles/BottomNavigation.css +1 -9
  549. package/dist/styles/BottomSheet.css +1 -10
  550. package/dist/styles/BrazilMap.css +1 -19
  551. package/dist/styles/Breadcrumbs.css +1 -7
  552. package/dist/styles/Button.css +1 -41
  553. package/dist/styles/Calendar.css +1 -15
  554. package/dist/styles/Card.css +1 -14
  555. package/dist/styles/Carousel.css +1 -16
  556. package/dist/styles/Center.css +1 -4
  557. package/dist/styles/Chat.css +1 -34
  558. package/dist/styles/Checkbox.css +1 -10
  559. package/dist/styles/ChipInput.css +1 -12
  560. package/dist/styles/CodeBlock.css +1 -24
  561. package/dist/styles/Collapsible.css +1 -5
  562. package/dist/styles/Combobox.css +1 -17
  563. package/dist/styles/Command.css +1 -19
  564. package/dist/styles/ContextMenu.css +1 -10
  565. package/dist/styles/CopyButton.css +1 -3
  566. package/dist/styles/DataList.css +1 -2
  567. package/dist/styles/DataTable.css +1 -18
  568. package/dist/styles/DateRangePicker.css +1 -21
  569. package/dist/styles/DescriptionList.css +1 -3
  570. package/dist/styles/Divider.css +1 -10
  571. package/dist/styles/Drawer.css +1 -21
  572. package/dist/styles/DropdownMenu.css +1 -15
  573. package/dist/styles/Dropzone.css +1 -6
  574. package/dist/styles/EmptyState.css +1 -5
  575. package/dist/styles/ErrorState.css +1 -5
  576. package/dist/styles/ErrorText.css +1 -1
  577. package/dist/styles/FileUpload.css +1 -16
  578. package/dist/styles/FilterBar.css +1 -18
  579. package/dist/styles/FloatingActionButton.css +1 -22
  580. package/dist/styles/Form.css +1 -20
  581. package/dist/styles/HoverCard.css +1 -10
  582. package/dist/styles/IconPicker.css +1 -5
  583. package/dist/styles/Image.css +1 -1
  584. package/dist/styles/ImageCropper.css +1 -15
  585. package/dist/styles/Input.css +1 -23
  586. package/dist/styles/InstallBanner.css +1 -7
  587. package/dist/styles/Kanban.css +1 -14
  588. package/dist/styles/Kbd.css +1 -4
  589. package/dist/styles/Label.css +1 -2
  590. package/dist/styles/Layout.css +1 -21
  591. package/dist/styles/Lightbox.css +1 -20
  592. package/dist/styles/ListTile.css +1 -13
  593. package/dist/styles/MapLegend.css +1 -8
  594. package/dist/styles/Markdown.css +1 -23
  595. package/dist/styles/Masonry.css +1 -3
  596. package/dist/styles/Menubar.css +1 -16
  597. package/dist/styles/Modal.css +1 -20
  598. package/dist/styles/ModalsManager.css +1 -1
  599. package/dist/styles/MultiSelect.css +1 -20
  600. package/dist/styles/MunicipalitySearch.css +1 -5
  601. package/dist/styles/NProgress.css +1 -1
  602. package/dist/styles/Navbar.css +1 -9
  603. package/dist/styles/NavigationMenu.css +1 -11
  604. package/dist/styles/NavigationRail.css +1 -13
  605. package/dist/styles/NotificationCenter.css +1 -20
  606. package/dist/styles/OfflineIndicator.css +1 -6
  607. package/dist/styles/Page.css +1 -12
  608. package/dist/styles/Pagination.css +1 -11
  609. package/dist/styles/PasswordInput.css +1 -20
  610. package/dist/styles/PinInput.css +1 -12
  611. package/dist/styles/PixQRCode.css +1 -8
  612. package/dist/styles/Popover.css +1 -9
  613. package/dist/styles/Progress.css +1 -10
  614. package/dist/styles/QRCode.css +1 -2
  615. package/dist/styles/Radio.css +1 -13
  616. package/dist/styles/RangeSlider.css +1 -14
  617. package/dist/styles/RatingStars.css +1 -10
  618. package/dist/styles/RefreshIndicator.css +1 -4
  619. package/dist/styles/Resizable.css +1 -12
  620. package/dist/styles/RichTextEditor.css +1 -18
  621. package/dist/styles/SafeArea.css +1 -6
  622. package/dist/styles/Scheduler.css +1 -23
  623. package/dist/styles/ScrollArea.css +1 -6
  624. package/dist/styles/SearchBar.css +1 -10
  625. package/dist/styles/SegmentedControl.css +1 -11
  626. package/dist/styles/Select.css +1 -13
  627. package/dist/styles/Sidebar.css +1 -18
  628. package/dist/styles/SignaturePad.css +1 -5
  629. package/dist/styles/Skeleton.css +1 -6
  630. package/dist/styles/Slider.css +1 -14
  631. package/dist/styles/Spacer.css +1 -3
  632. package/dist/styles/Sparkline.css +1 -3
  633. package/dist/styles/Spinner.css +1 -11
  634. package/dist/styles/Stat.css +1 -11
  635. package/dist/styles/Stepper.css +1 -16
  636. package/dist/styles/StepperInput.css +1 -14
  637. package/dist/styles/Switch.css +1 -10
  638. package/dist/styles/SyncStatusBadge.css +1 -12
  639. package/dist/styles/Table.css +1 -15
  640. package/dist/styles/Tabs.css +1 -13
  641. package/dist/styles/Tag.css +1 -13
  642. package/dist/styles/Textarea.css +1 -12
  643. package/dist/styles/TimePicker.css +1 -13
  644. package/dist/styles/Timeline.css +1 -16
  645. package/dist/styles/Toast.css +1 -20
  646. package/dist/styles/Toggle.css +1 -11
  647. package/dist/styles/ToggleGroup.css +1 -8
  648. package/dist/styles/Tooltip.css +1 -9
  649. package/dist/styles/Tour.css +1 -19
  650. package/dist/styles/TrajectoryMap.css +1 -15
  651. package/dist/styles/Transfer.css +1 -20
  652. package/dist/styles/TreeView.css +1 -16
  653. package/dist/styles/TruncateText.css +1 -1
  654. package/dist/styles/UpdatePrompt.css +1 -9
  655. package/dist/styles/VideoPlayer.css +1 -22
  656. package/dist/styles/VirtualList.css +1 -4
  657. package/dist/styles/VirtualTable.css +1 -16
  658. package/dist/styles/VisuallyHidden.css +1 -1
  659. package/dist/styles/Wizard.css +1 -3
  660. package/dist/styles/advanced.css +2 -0
  661. package/dist/styles/chat.css +28 -0
  662. package/dist/styles/component/AIChat.css +79 -0
  663. package/dist/styles/component/Accordion.css +12 -0
  664. package/dist/styles/component/Alert.css +32 -0
  665. package/dist/styles/component/AppBar.css +17 -0
  666. package/dist/styles/component/AppShell.css +8 -0
  667. package/dist/styles/component/AspectRatio.css +3 -0
  668. package/dist/styles/component/AudioPlayer.css +13 -0
  669. package/dist/styles/component/AudioRecorder.css +20 -0
  670. package/dist/styles/component/Avatar.css +13 -0
  671. package/dist/styles/component/AvatarGroup.css +18 -0
  672. package/dist/styles/component/Badge.css +25 -0
  673. package/dist/styles/component/Banner.css +13 -0
  674. package/dist/styles/component/BarList.css +10 -0
  675. package/dist/styles/component/BarcodeScanner.css +21 -0
  676. package/dist/styles/component/BottomNavigation.css +10 -0
  677. package/dist/styles/component/BottomSheet.css +11 -0
  678. package/dist/styles/component/BrazilMap.css +20 -0
  679. package/dist/styles/component/Breadcrumbs.css +8 -0
  680. package/dist/styles/component/Button.css +42 -0
  681. package/dist/styles/component/Calendar.css +16 -0
  682. package/dist/styles/component/Card.css +15 -0
  683. package/dist/styles/component/Carousel.css +17 -0
  684. package/dist/styles/component/Center.css +5 -0
  685. package/dist/styles/component/Chat.css +63 -0
  686. package/dist/styles/component/Checkbox.css +11 -0
  687. package/dist/styles/component/ChipInput.css +13 -0
  688. package/dist/styles/component/CodeBlock.css +25 -0
  689. package/dist/styles/component/Collapsible.css +6 -0
  690. package/dist/styles/component/Combobox.css +18 -0
  691. package/dist/styles/component/Command.css +20 -0
  692. package/dist/styles/component/ContextMenu.css +13 -0
  693. package/dist/styles/component/CopyButton.css +4 -0
  694. package/dist/styles/component/DataList.css +3 -0
  695. package/dist/styles/component/DataTable.css +19 -0
  696. package/dist/styles/component/DateRangePicker.css +22 -0
  697. package/dist/styles/component/DescriptionList.css +4 -0
  698. package/dist/styles/component/Divider.css +11 -0
  699. package/dist/styles/component/Drawer.css +22 -0
  700. package/dist/styles/component/DropdownMenu.css +16 -0
  701. package/dist/styles/component/Dropzone.css +7 -0
  702. package/dist/styles/component/EmptyState.css +6 -0
  703. package/dist/styles/component/ErrorState.css +6 -0
  704. package/dist/styles/component/ErrorText.css +2 -0
  705. package/dist/styles/component/FileUpload.css +17 -0
  706. package/dist/styles/component/FilterBar.css +19 -0
  707. package/dist/styles/component/FloatingActionButton.css +23 -0
  708. package/dist/styles/component/Form.css +21 -0
  709. package/dist/styles/component/HoverCard.css +11 -0
  710. package/dist/styles/component/IconPicker.css +6 -0
  711. package/dist/styles/component/Image.css +2 -0
  712. package/dist/styles/component/ImageCropper.css +16 -0
  713. package/dist/styles/component/Input.css +24 -0
  714. package/dist/styles/component/InstallBanner.css +8 -0
  715. package/dist/styles/component/Kanban.css +15 -0
  716. package/dist/styles/component/Kbd.css +5 -0
  717. package/dist/styles/component/Label.css +3 -0
  718. package/dist/styles/component/Layout.css +22 -0
  719. package/dist/styles/component/Lightbox.css +21 -0
  720. package/dist/styles/component/ListTile.css +14 -0
  721. package/dist/styles/component/MapLegend.css +9 -0
  722. package/dist/styles/component/Markdown.css +24 -0
  723. package/dist/styles/component/Masonry.css +4 -0
  724. package/dist/styles/component/Menubar.css +17 -0
  725. package/dist/styles/component/Modal.css +21 -0
  726. package/dist/styles/component/ModalsManager.css +2 -0
  727. package/dist/styles/component/MultiSelect.css +21 -0
  728. package/dist/styles/component/MunicipalitySearch.css +6 -0
  729. package/dist/styles/component/NProgress.css +2 -0
  730. package/dist/styles/component/Navbar.css +10 -0
  731. package/dist/styles/component/NavigationMenu.css +12 -0
  732. package/dist/styles/component/NavigationRail.css +14 -0
  733. package/dist/styles/component/NotificationCenter.css +21 -0
  734. package/dist/styles/component/OfflineIndicator.css +7 -0
  735. package/dist/styles/component/Page.css +13 -0
  736. package/dist/styles/component/Pagination.css +12 -0
  737. package/dist/styles/component/PasswordInput.css +21 -0
  738. package/dist/styles/component/PinInput.css +13 -0
  739. package/dist/styles/component/PixQRCode.css +9 -0
  740. package/dist/styles/component/Popover.css +10 -0
  741. package/dist/styles/component/Progress.css +11 -0
  742. package/dist/styles/component/QRCode.css +3 -0
  743. package/dist/styles/component/Radio.css +14 -0
  744. package/dist/styles/component/RangeSlider.css +15 -0
  745. package/dist/styles/component/RatingStars.css +11 -0
  746. package/dist/styles/component/RefreshIndicator.css +5 -0
  747. package/dist/styles/component/Resizable.css +13 -0
  748. package/dist/styles/component/RichTextEditor.css +19 -0
  749. package/dist/styles/component/SafeArea.css +7 -0
  750. package/dist/styles/component/Scheduler.css +24 -0
  751. package/dist/styles/component/ScrollArea.css +7 -0
  752. package/dist/styles/component/SearchBar.css +11 -0
  753. package/dist/styles/component/SegmentedControl.css +12 -0
  754. package/dist/styles/component/Select.css +14 -0
  755. package/dist/styles/component/Sidebar.css +19 -0
  756. package/dist/styles/component/SignaturePad.css +6 -0
  757. package/dist/styles/component/Skeleton.css +7 -0
  758. package/dist/styles/component/Slider.css +15 -0
  759. package/dist/styles/component/Spacer.css +4 -0
  760. package/dist/styles/component/Sparkline.css +4 -0
  761. package/dist/styles/component/Spinner.css +12 -0
  762. package/dist/styles/component/Stat.css +12 -0
  763. package/dist/styles/component/Stepper.css +17 -0
  764. package/dist/styles/component/StepperInput.css +15 -0
  765. package/dist/styles/component/Switch.css +11 -0
  766. package/dist/styles/component/SyncStatusBadge.css +13 -0
  767. package/dist/styles/component/Table.css +16 -0
  768. package/dist/styles/component/Tabs.css +14 -0
  769. package/dist/styles/component/Tag.css +14 -0
  770. package/dist/styles/component/Textarea.css +13 -0
  771. package/dist/styles/component/TimePicker.css +14 -0
  772. package/dist/styles/component/Timeline.css +17 -0
  773. package/dist/styles/component/Toast.css +21 -0
  774. package/dist/styles/component/Toggle.css +12 -0
  775. package/dist/styles/component/ToggleGroup.css +9 -0
  776. package/dist/styles/component/Tooltip.css +10 -0
  777. package/dist/styles/component/Tour.css +20 -0
  778. package/dist/styles/component/TrajectoryMap.css +16 -0
  779. package/dist/styles/component/Transfer.css +21 -0
  780. package/dist/styles/component/TreeView.css +17 -0
  781. package/dist/styles/component/TruncateText.css +2 -0
  782. package/dist/styles/component/UpdatePrompt.css +10 -0
  783. package/dist/styles/component/VideoPlayer.css +23 -0
  784. package/dist/styles/component/VirtualList.css +5 -0
  785. package/dist/styles/component/VirtualTable.css +17 -0
  786. package/dist/styles/component/VisuallyHidden.css +2 -0
  787. package/dist/styles/component/Wizard.css +4 -0
  788. package/dist/styles/manifest.json +202 -190
  789. package/dist/styles.css +1 -1
  790. package/dist/tempest-react-sdk.cjs +1 -1
  791. package/dist/tempest-react-sdk.d.ts +253 -10
  792. package/dist/tempest-react-sdk.js +169 -167
  793. package/dist/theme/create-theme.cjs +3 -3
  794. package/dist/theme/create-theme.cjs.map +1 -1
  795. package/dist/theme/create-theme.js +109 -57
  796. package/dist/theme/create-theme.js.map +1 -1
  797. package/dist/vite/narrow-tokens.cjs +3 -0
  798. package/dist/vite/narrow-tokens.cjs.map +1 -0
  799. package/dist/vite/narrow-tokens.js +50 -0
  800. package/dist/vite/narrow-tokens.js.map +1 -0
  801. package/dist/vite/tempest-styles.cjs +6 -4
  802. package/dist/vite/tempest-styles.cjs.map +1 -1
  803. package/dist/vite/tempest-styles.js +73 -47
  804. package/dist/vite/tempest-styles.js.map +1 -1
  805. package/dist/vite.d.ts +19 -0
  806. package/loader/css-loader-hooks.mjs +37 -0
  807. package/loader/css-loader.mjs +46 -0
  808. package/package.json +4 -2
@@ -1 +1 @@
1
- {"version":3,"file":"create-theme.cjs","names":[],"sources":["../../src/theme/create-theme.ts"],"sourcesContent":["/**\n * @tempest-limits file-lines — one pass that emits the whole token set — surfaces,\n * text, borders, states, the chart ramps — for both modes, with every value checked\n * against the surface it will sit on. The checks are what make the length: each\n * token is derived and then verified against the same background table.\n */\n/**\n * Theme factory: turns a handful of brand colors into the full set of\n * `--tempest-*` token overrides, for both light and dark.\n *\n * Rebranding used to mean hand-writing ~167 custom properties (and getting the\n * dark ramp inversion right by hand). `createTheme({ primary: \"#7c3aed\" })`\n * emits the same thing, derived in OKLCH so the ramp stays perceptually even.\n */\nimport {\n contrastRatio,\n createColorScale,\n hexToRgbaString,\n readableForeground,\n type ColorScale,\n type ScaleStep,\n} from \"./color\";\nimport { buildDivergingRamp, buildRamp, hueOf } from \"./data-viz-ramps\";\n\n/** Radius presets, applied to the whole `--tempest-radius-*` family at once. */\nexport type ThemeRadius = \"none\" | \"sm\" | \"md\" | \"lg\" | \"xl\" | \"full\";\n\n/** Status token families that {@link createTheme} can regenerate. */\nexport type ThemeStatus = \"success\" | \"warning\" | \"danger\" | \"info\";\n\n/** Input for {@link createTheme}. Every field is optional — omitted families keep the built-in tokens. */\nexport interface CreateThemeOptions {\n /** Brand color, used as the `500` step of the primary scale. */\n primary?: string;\n /** Neutral color, used as the `500` step of the gray scale (surfaces, borders, text). */\n gray?: string;\n /** Success color (`--tempest-success*`). */\n success?: string;\n /** Warning color (`--tempest-warning*`). */\n warning?: string;\n /** Danger color (`--tempest-danger*`). */\n danger?: string;\n /** Info color (`--tempest-info*`). */\n info?: string;\n /**\n * Categorical series colors for `tempest-react-sdk/charts`, in cycle order.\n * Written to `--tempest-chart-1` … `--tempest-chart-N`, so charts follow the\n * theme instead of a hardcoded palette.\n */\n chart?: string[];\n /** Corner radius scale. A preset name, or explicit per-step values. */\n radius?: ThemeRadius | Partial<Record<\"xs\" | \"sm\" | \"md\" | \"lg\" | \"xl\" | \"2xl\", string>>;\n /** Alpha of `--tempest-focus-ring-color`, derived from the brand color. Default `0.35`. */\n focusRingAlpha?: number;\n /** Selector the light tokens are written under. Default `\":root\"`. */\n selector?: string;\n /** Selector the dark tokens are written under. Default `'[data-tempest-theme=\"dark\"]'`. */\n darkSelector?: string;\n}\n\n/** A generated theme: token maps per color scheme, plus the CSS text that carries them. */\nexport interface GeneratedTheme {\n /** Light-scheme custom properties, without the leading `--`-less names (keys include `--`). */\n light: Record<string, string>;\n /** Dark-scheme custom properties. */\n dark: Record<string, string>;\n /** Both blocks rendered as CSS, ready for {@link applyTheme} or a stylesheet. */\n css: string;\n}\n\nconst RADIUS_PRESETS: Record<ThemeRadius, Record<string, string>> = {\n none: { xs: \"0\", sm: \"0\", md: \"0\", lg: \"0\", xl: \"0\", \"2xl\": \"0\" },\n sm: { xs: \"1px\", sm: \"2px\", md: \"4px\", lg: \"6px\", xl: \"8px\", \"2xl\": \"12px\" },\n md: { xs: \"2px\", sm: \"4px\", md: \"8px\", lg: \"12px\", xl: \"16px\", \"2xl\": \"24px\" },\n lg: { xs: \"4px\", sm: \"6px\", md: \"12px\", lg: \"16px\", xl: \"22px\", \"2xl\": \"32px\" },\n xl: { xs: \"6px\", sm: \"10px\", md: \"16px\", lg: \"24px\", xl: \"32px\", \"2xl\": \"44px\" },\n full: { xs: \"4px\", sm: \"8px\", md: \"9999px\", lg: \"9999px\", xl: \"9999px\", \"2xl\": \"9999px\" },\n};\n\nconst SCALE_STEPS: ScaleStep[] = [50, 100, 200, 300, 400, 500, 600, 700, 800, 900];\n\nfunction writeScale(tokens: Record<string, string>, name: string, scale: ColorScale): void {\n for (const step of SCALE_STEPS) {\n tokens[`--tempest-${name}-${step}`] = scale[step];\n }\n}\n\n/** Minimum contrast for body text, WCAG 2.x AA. */\nconst AA_TEXT_CONTRAST = 4.5;\n\n/**\n * Choose the ramp step for text sitting on the soft tint.\n *\n * A fixed step does not survive an arbitrary brand color: the built-in blue only\n * reaches 4.37:1 at `500` over its own `50` tint, and a generated emerald lands\n * at 4.41:1 at `600` — both fail AA for body text by a hair. So the step is\n * picked by measuring, walking away from the tint until it clears AA, and\n * falling back to the most extreme candidate when even that cannot (a very light\n * or very desaturated brand).\n *\n * @param scale - The generated ramp.\n * @param softStep - Step used as `--tempest-primary-soft`.\n * @param candidates - Steps to try, in order of preference.\n * @returns The first candidate clearing {@link AA_TEXT_CONTRAST}, else the last.\n */\nfunction pickOnSoftStep(\n scale: ColorScale,\n softStep: ScaleStep,\n candidates: ScaleStep[],\n): ScaleStep {\n for (const step of candidates) {\n if (contrastRatio(scale[softStep], scale[step]) >= AA_TEXT_CONTRAST) return step;\n }\n return candidates[candidates.length - 1];\n}\n\n/**\n * The dark ink for content sitting on a saturated fill.\n *\n * Near-black tinted toward warm rather than pure black, matching the value\n * `colors.css` uses for the same job: it reads as part of the swatch instead of\n * a hole punched in it.\n */\nconst ON_SOLID_INK = \"#1f0606\";\n\n/**\n * Emit the primary aliases for one scheme.\n *\n * The dark scheme walks the ramp the other way (hover is *lighter*, the soft\n * tint is a dark shade, and readable text on that tint is a light shade) — the\n * same inversion the built-in `colors.css` dark block does by hand.\n */\nfunction writePrimaryAliases(\n tokens: Record<string, string>,\n scale: ColorScale,\n scheme: \"light\" | \"dark\",\n focusRingAlpha: number,\n): void {\n tokens[\"--tempest-primary\"] = \"var(--tempest-primary-500)\";\n if (scheme === \"light\") {\n tokens[\"--tempest-primary-hover\"] = \"var(--tempest-primary-600)\";\n tokens[\"--tempest-primary-active\"] = \"var(--tempest-primary-700)\";\n tokens[\"--tempest-primary-soft\"] = \"var(--tempest-primary-50)\";\n tokens[\"--tempest-primary-soft-hover\"] = \"var(--tempest-primary-100)\";\n tokens[\"--tempest-primary-on-soft\"] =\n `var(--tempest-primary-${pickOnSoftStep(scale, 50, [600, 700, 800, 900])})`;\n } else {\n tokens[\"--tempest-primary-hover\"] = \"var(--tempest-primary-400)\";\n tokens[\"--tempest-primary-active\"] = \"var(--tempest-primary-300)\";\n tokens[\"--tempest-primary-soft\"] = \"var(--tempest-primary-100)\";\n tokens[\"--tempest-primary-soft-hover\"] = \"var(--tempest-primary-200)\";\n tokens[\"--tempest-primary-on-soft\"] =\n `var(--tempest-primary-${pickOnSoftStep(scale, 100, [700, 800, 900])})`;\n }\n\n const foreground = readableForeground(scale[500]);\n tokens[\"--tempest-primary-foreground\"] = foreground;\n tokens[\"--tempest-text-on-primary\"] = foreground;\n tokens[\"--tempest-focus-ring-color\"] = hexToRgbaString(scale[500], focusRingAlpha);\n}\n\n/**\n * Emit the neutral surface/border/text aliases from a generated gray scale.\n *\n * `--tempest-bg` is pushed past the ramp on purpose: pure white in light mode and\n * a shade darker than `gray-50` in dark mode, so a raised surface still reads as\n * raised against the page.\n */\nfunction writeNeutralAliases(\n tokens: Record<string, string>,\n scale: ColorScale,\n scheme: \"light\" | \"dark\",\n): void {\n if (scheme === \"light\") {\n tokens[\"--tempest-bg\"] = \"#ffffff\";\n tokens[\"--tempest-surface\"] = \"var(--tempest-gray-50)\";\n tokens[\"--tempest-surface-2\"] = \"var(--tempest-gray-100)\";\n tokens[\"--tempest-surface-3\"] = \"var(--tempest-gray-200)\";\n tokens[\"--tempest-border\"] = \"var(--tempest-gray-200)\";\n tokens[\"--tempest-border-strong\"] = \"var(--tempest-gray-300)\";\n tokens[\"--tempest-text\"] = \"var(--tempest-gray-900)\";\n tokens[\"--tempest-text-muted\"] = \"var(--tempest-gray-600)\";\n tokens[\"--tempest-text-subtle\"] = \"var(--tempest-gray-500)\";\n } else {\n tokens[\"--tempest-bg\"] = scale[50];\n tokens[\"--tempest-surface\"] = \"var(--tempest-gray-100)\";\n tokens[\"--tempest-surface-2\"] = \"var(--tempest-gray-200)\";\n tokens[\"--tempest-surface-3\"] = \"var(--tempest-gray-300)\";\n tokens[\"--tempest-border\"] = \"var(--tempest-gray-300)\";\n tokens[\"--tempest-border-strong\"] = \"var(--tempest-gray-400)\";\n tokens[\"--tempest-text\"] = \"var(--tempest-gray-900)\";\n tokens[\"--tempest-text-muted\"] = \"var(--tempest-gray-700)\";\n tokens[\"--tempest-text-subtle\"] = \"var(--tempest-gray-600)\";\n }\n tokens[\"--tempest-neutral-on-solid\"] = readableForeground(scale[700], \"#ffffff\", ON_SOLID_INK);\n}\n\n/**\n * Emit one status family (`--tempest-danger`, `-fg`, `-bg`, `-border`, `-solid`).\n *\n * `-fg` is the text shade over `-bg`, so it has to cross the ramp in opposite\n * directions per scheme; `-solid` stays the saturated fill used by badges.\n *\n * `-on-solid` is derived from the `-solid` this call just emitted, rather than\n * left to fall through. Falling through was the bug: the SDK's own\n * `-on-solid` values are measured against the SDK's own fills, so a brand whose\n * `danger-600` lands light kept white ink over it and nothing said so. The\n * generated neutral hit exactly that — white over a generated `gray-700` of\n * `#a8b2c6` measures 2.13:1.\n */\nfunction writeStatus(\n tokens: Record<string, string>,\n name: ThemeStatus,\n scale: ColorScale,\n scheme: \"light\" | \"dark\",\n): void {\n if (scheme === \"light\") {\n tokens[`--tempest-${name}`] = scale[700];\n tokens[`--tempest-${name}-fg`] = scale[800];\n tokens[`--tempest-${name}-bg`] = scale[50];\n tokens[`--tempest-${name}-border`] = scale[200];\n tokens[`--tempest-${name}-solid`] = scale[600];\n tokens[`--tempest-${name}-on-solid`] = readableForeground(\n scale[600],\n \"#ffffff\",\n ON_SOLID_INK,\n );\n } else {\n tokens[`--tempest-${name}`] = scale[700];\n tokens[`--tempest-${name}-fg`] = scale[700];\n tokens[`--tempest-${name}-bg`] = scale[50];\n tokens[`--tempest-${name}-border`] = scale[200];\n tokens[`--tempest-${name}-solid`] = scale[500];\n tokens[`--tempest-${name}-on-solid`] = readableForeground(\n scale[500],\n \"#ffffff\",\n ON_SOLID_INK,\n );\n }\n}\n\nfunction renderBlock(selector: string, tokens: Record<string, string>): string {\n const entries = Object.entries(tokens);\n if (entries.length === 0) return \"\";\n const body = entries.map(([name, value]) => ` ${name}: ${value};`).join(\"\\n\");\n return `${selector} {\\n${body}\\n}`;\n}\n\n/**\n * Generate `--tempest-*` overrides from a small brand description.\n *\n * Only the families you pass are generated; everything else falls through to the\n * SDK's own tokens, so a theme stays a patch and not a fork of `colors.css`.\n *\n * @example\n * ```ts\n * import { applyTheme, createTheme } from \"tempest-react-sdk\";\n *\n * const theme = createTheme({\n * primary: \"#7c3aed\",\n * radius: \"lg\",\n * chart: [\"#7c3aed\", \"#0ea5e9\", \"#22c55e\", \"#f59e0b\"],\n * });\n *\n * applyTheme(theme);\n * ```\n *\n * @param options - Brand colors plus optional radius / chart / focus-ring tuning.\n * @returns The light and dark token maps and the CSS text that carries them.\n */\nexport function createTheme(options: CreateThemeOptions = {}): GeneratedTheme {\n const {\n primary,\n gray,\n chart,\n radius,\n focusRingAlpha = 0.35,\n selector = \":root\",\n darkSelector = '[data-tempest-theme=\"dark\"]',\n } = options;\n\n const light: Record<string, string> = {};\n const dark: Record<string, string> = {};\n\n if (primary) {\n const lightScale = createColorScale(primary, \"light\");\n const darkScale = createColorScale(primary, \"dark\");\n writeScale(light, \"primary\", lightScale);\n writeScale(dark, \"primary\", darkScale);\n writePrimaryAliases(light, lightScale, \"light\", focusRingAlpha);\n writePrimaryAliases(dark, darkScale, \"dark\", focusRingAlpha);\n }\n\n if (gray) {\n // `anchor: false`: a neutral ramp has to keep its tuned lightness curve.\n // Anchoring it at the input compressed both halves and dropped\n // text-muted-on-surface-3 to ~4.2:1 — below AA — which the browser axe\n // sweep caught on the generated themes.\n const lightScale = createColorScale(gray, \"light\", { anchor: false, neutral: true });\n const darkScale = createColorScale(gray, \"dark\", { anchor: false, neutral: true });\n writeScale(light, \"gray\", lightScale);\n writeScale(dark, \"gray\", darkScale);\n writeNeutralAliases(light, lightScale, \"light\");\n writeNeutralAliases(dark, darkScale, \"dark\");\n }\n\n for (const status of [\"success\", \"warning\", \"danger\", \"info\"] as const) {\n const value = options[status];\n if (!value) continue;\n writeStatus(light, status, createColorScale(value, \"light\"), \"light\");\n writeStatus(dark, status, createColorScale(value, \"dark\"), \"dark\");\n }\n\n if (chart?.length) {\n chart.forEach((color, index) => {\n light[`--tempest-chart-${index + 1}`] = color;\n });\n // Declares how many series colors this theme owns. Without it the reader\n // keeps walking into the SDK's built-in `--tempest-chart-7`/`-8`, so a\n // 6-color brand palette silently mixes with two leftover defaults — which\n // is exactly what a 7-series chart would show.\n light[\"--tempest-chart-count\"] = String(chart.length);\n }\n\n /*\n * Continuous scales follow the brand too.\n *\n * Without this a rebranded app gets its categorical slots recoloured and then a\n * heatmap still painted in the SDK's blue — the one chart on the page that\n * silently ignores the brand. Both scales derive from the first series hue (or\n * the primary), stepped by perceptual lightness for each mode separately.\n *\n * Skipped entirely when the theme names no colour to derive from, so the\n * built-in tokens survive instead of being overwritten with a guess.\n */\n const scaleSource = chart?.[0] ?? primary;\n if (scaleSource) {\n const coolHue = hueOf(scaleSource);\n // The opposite pole: the brand's own danger colour when it has one, since a\n // diverging scale's warm arm and \"bad\" should not disagree on screen.\n const warmHue = options.danger ? hueOf(options.danger) : (coolHue + 180) % 360;\n for (const [target, mode] of [\n [light, \"light\"],\n [dark, \"dark\"],\n ] as const) {\n buildRamp(coolHue, mode).forEach((stepColor, index) => {\n target[`--tempest-chart-sequential-${index + 1}`] = stepColor;\n });\n const diverging = buildDivergingRamp({\n coolHue,\n warmHue,\n mid: mode === \"light\" ? \"#e4e7ec\" : \"#262d3f\",\n mode,\n });\n [...diverging.cool, diverging.mid, ...diverging.warm].forEach((stepColor, index) => {\n target[`--tempest-chart-diverging-${index + 1}`] = stepColor;\n });\n }\n }\n\n if (radius) {\n const steps = typeof radius === \"string\" ? RADIUS_PRESETS[radius] : radius;\n for (const [step, value] of Object.entries(steps)) {\n light[`--tempest-radius-${step}`] = value;\n }\n }\n\n const css = [renderBlock(selector, light), renderBlock(darkSelector, dark)]\n .filter(Boolean)\n .join(\"\\n\\n\");\n\n return { light, dark, css };\n}\n\n/**\n * Contrast ratio of `--tempest-primary-foreground` over the brand color.\n *\n * Exposed so an app (or a test) can assert its own brand clears WCAG AA (4.5) for\n * body text or AA-large (3.0) for button labels, instead of trusting the pick.\n *\n * @param options - The same input given to {@link createTheme}.\n * @returns The ratio, or `null` when no `primary` was provided.\n */\nexport function themeContrast(options: CreateThemeOptions): number | null {\n if (!options.primary) return null;\n const scale = createColorScale(options.primary, \"light\");\n return contrastRatio(scale[500], readableForeground(scale[500]));\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"create-theme.cjs","names":[],"sources":["../../src/theme/create-theme.ts"],"sourcesContent":["/**\n * @tempest-limits file-lines — one pass that emits the whole token set — surfaces,\n * text, borders, states, the chart ramps — for both modes, with every value checked\n * against the surface it will sit on. The checks are what make the length: each\n * token is derived and then verified against the same background table.\n */\n/**\n * Theme factory: turns a handful of brand colors into the full set of\n * `--tempest-*` token overrides, for both light and dark.\n *\n * Rebranding used to mean hand-writing ~167 custom properties (and getting the\n * dark ramp inversion right by hand). `createTheme({ primary: \"#7c3aed\" })`\n * emits the same thing, derived in OKLCH so the ramp stays perceptually even.\n */\nimport {\n contrastRatio,\n createColorScale,\n hexToRgbaString,\n readableForeground,\n type ColorScale,\n type ScaleStep,\n} from \"./color\";\nimport { buildDivergingRamp, buildRamp, hueOf } from \"./data-viz-ramps\";\nimport { isDevBuild } from \"../utils/dev-mode\";\n\n/** Radius presets, applied to the whole `--tempest-radius-*` family at once. */\nexport type ThemeRadius = \"none\" | \"sm\" | \"md\" | \"lg\" | \"xl\" | \"full\";\n\n/** Status token families that {@link createTheme} can regenerate. */\nexport type ThemeStatus = \"success\" | \"warning\" | \"danger\" | \"info\";\n\n/** Input for {@link createTheme}. Every field is optional — omitted families keep the built-in tokens. */\nexport interface CreateThemeOptions {\n /** Brand color, used as the `500` step of the primary scale. */\n primary?: string;\n /** Neutral color, used as the `500` step of the gray scale (surfaces, borders, text). */\n gray?: string;\n /** Success color (`--tempest-success*`). */\n success?: string;\n /** Warning color (`--tempest-warning*`). */\n warning?: string;\n /** Danger color (`--tempest-danger*`). */\n danger?: string;\n /** Info color (`--tempest-info*`). */\n info?: string;\n /**\n * Categorical series colors for `tempest-react-sdk/charts`, in cycle order.\n * Written to `--tempest-chart-1` … `--tempest-chart-N`, so charts follow the\n * theme instead of a hardcoded palette.\n */\n chart?: string[];\n /** Corner radius scale. A preset name, or explicit per-step values. */\n radius?: ThemeRadius | Partial<Record<\"xs\" | \"sm\" | \"md\" | \"lg\" | \"xl\" | \"2xl\", string>>;\n /**\n * Opacity of `--tempest-focus-ring-color`. Omit it — the default ring is opaque.\n *\n * A translucent ring has no contrast of its own; it has the contrast of\n * whatever it composites over. Passing a value below `1` reintroduces the\n * failure 0.61.0 fixed in the built-in tokens, and logs a warning in a\n * development build. Kept because a translucent ring over a background you\n * control is a legitimate choice.\n */\n focusRingAlpha?: number;\n /** Selector the light tokens are written under. Default `\":root\"`. */\n selector?: string;\n /** Selector the dark tokens are written under. Default `'[data-tempest-theme=\"dark\"]'`. */\n darkSelector?: string;\n}\n\n/** A generated theme: token maps per color scheme, plus the CSS text that carries them. */\nexport interface GeneratedTheme {\n /** Light-scheme custom properties, without the leading `--`-less names (keys include `--`). */\n light: Record<string, string>;\n /** Dark-scheme custom properties. */\n dark: Record<string, string>;\n /** Both blocks rendered as CSS, ready for {@link applyTheme} or a stylesheet. */\n css: string;\n}\n\nconst RADIUS_PRESETS: Record<ThemeRadius, Record<string, string>> = {\n none: { xs: \"0\", sm: \"0\", md: \"0\", lg: \"0\", xl: \"0\", \"2xl\": \"0\" },\n sm: { xs: \"1px\", sm: \"2px\", md: \"4px\", lg: \"6px\", xl: \"8px\", \"2xl\": \"12px\" },\n md: { xs: \"2px\", sm: \"4px\", md: \"8px\", lg: \"12px\", xl: \"16px\", \"2xl\": \"24px\" },\n lg: { xs: \"4px\", sm: \"6px\", md: \"12px\", lg: \"16px\", xl: \"22px\", \"2xl\": \"32px\" },\n xl: { xs: \"6px\", sm: \"10px\", md: \"16px\", lg: \"24px\", xl: \"32px\", \"2xl\": \"44px\" },\n full: { xs: \"4px\", sm: \"8px\", md: \"9999px\", lg: \"9999px\", xl: \"9999px\", \"2xl\": \"9999px\" },\n};\n\nconst SCALE_STEPS: ScaleStep[] = [50, 100, 200, 300, 400, 500, 600, 700, 800, 900];\n\nfunction writeScale(tokens: Record<string, string>, name: string, scale: ColorScale): void {\n for (const step of SCALE_STEPS) {\n tokens[`--tempest-${name}-${step}`] = scale[step];\n }\n}\n\n/** Minimum contrast for body text, WCAG 2.x AA. */\nconst AA_TEXT_CONTRAST = 4.5;\n\n/**\n * Choose the ramp step for text sitting on the soft tint.\n *\n * A fixed step does not survive an arbitrary brand color: the built-in blue only\n * reaches 4.37:1 at `500` over its own `50` tint, and a generated emerald lands\n * at 4.41:1 at `600` — both fail AA for body text by a hair. So the step is\n * picked by measuring, walking away from the tint until it clears AA, and\n * falling back to the most extreme candidate when even that cannot (a very light\n * or very desaturated brand).\n *\n * @param scale - The generated ramp.\n * @param softStep - Step used as `--tempest-primary-soft`.\n * @param candidates - Steps to try, in order of preference.\n * @returns The first candidate clearing {@link AA_TEXT_CONTRAST}, else the last.\n */\nfunction pickOnSoftStep(\n scale: ColorScale,\n softStep: ScaleStep,\n candidates: ScaleStep[],\n): ScaleStep {\n for (const step of candidates) {\n if (contrastRatio(scale[softStep], scale[step]) >= AA_TEXT_CONTRAST) return step;\n }\n return candidates[candidates.length - 1];\n}\n\n/** Minimum contrast for a non-text indicator, WCAG 2.2 SC 1.4.11. */\nconst INDICATOR_CONTRAST = 3;\n\n/**\n * The four surfaces a focus ring can land on, as the SDK's own `colors.css`\n * paints them.\n *\n * Ported from `src/styles/colors.css` (`--tempest-bg`, `--tempest-surface`,\n * `--tempest-surface-2`, `--tempest-surface-3`, resolved through the gray ramp),\n * and pinned by a test that reads that file — a theme that only names `primary`\n * keeps these, so the ring has to be measured against them and not against a\n * guess. The light values resolve through `--tempest-gray-50/100/200`; the dark\n * ones are literals in the dark block.\n */\nconst SDK_SURFACES: Record<\"light\" | \"dark\", readonly string[]> = {\n light: [\"#ffffff\", \"#f8f9fb\", \"#f1f3f6\", \"#e4e7ec\"],\n dark: [\"#0b0d12\", \"#14171f\", \"#1d2230\", \"#262d3f\"],\n};\n\n/**\n * Ramp steps to try for the focus ring, in order.\n *\n * `500` first, because the ring should read as the brand when it can, then up\n * the ramp — which moves away from the surfaces in **both** schemes, because\n * `createColorScale` inverts the dark ramp: there `50` is the darkest step (it\n * is what `--tempest-bg` is made of) and `900` the lightest. Walking down in\n * dark mode looks like the right inversion and is the wrong direction; measured,\n * it left a near-black brand's ring at 1.04:1 over its own background.\n */\nconst FOCUS_RING_CANDIDATES: readonly ScaleStep[] = [500, 600, 700, 800, 900];\n\n/**\n * Choose the ramp step for the focus ring, by measuring it against the surfaces\n * it will actually be drawn on.\n *\n * A fixed step does not survive an arbitrary brand, and the measurement says so\n * loudly: of twelve brands checked against the four surfaces in both schemes —\n * 96 pairings — `500` opaque clears 3:1 in 58 of them, and `500` at the old\n * default alpha of 0.35 in 3. Picking the step by measurement clears all 96. The\n * brand from the report that opened this\n * (`#8100D7`) passes in light at 7.20:1 and fails in **dark** at 2.70:1 down to\n * 1.91:1 on `surface-3`; a yellow fails in light at 1.43:1. So the step is\n * picked the way {@link pickOnSoftStep} picks text on a tint: walk away from the\n * surfaces until the ring clears the floor against *all* of them.\n *\n * The fallback is the candidate with the best worst case rather than the last\n * one, because \"the most extreme step\" is not always the most contrasting one\n * once a brand is near-neutral.\n *\n * @param scale - The generated ramp.\n * @param surfaces - The four surfaces this theme will paint, opaque hex.\n * @returns The first candidate clearing {@link INDICATOR_CONTRAST} on every\n * surface, else the candidate whose weakest pairing is strongest.\n */\nfunction pickFocusRingStep(scale: ColorScale, surfaces: readonly string[]): ScaleStep {\n const worstCase = (step: ScaleStep): number =>\n Math.min(...surfaces.map((surface) => contrastRatio(scale[step], surface)));\n let best: ScaleStep = FOCUS_RING_CANDIDATES[0] as ScaleStep;\n let bestRatio = -1;\n for (const step of FOCUS_RING_CANDIDATES) {\n const measured = worstCase(step);\n if (measured >= INDICATOR_CONTRAST) return step;\n if (measured > bestRatio) {\n best = step;\n bestRatio = measured;\n }\n }\n return best;\n}\n\n/**\n * The surfaces this theme will actually paint, per scheme.\n *\n * A theme that names `gray` repaints all four, so measuring the ring against the\n * SDK's would be measuring the wrong backdrop — and a theme that does not keeps\n * the SDK's, which is the common case. The order and the ramp steps mirror\n * {@link writeNeutralAliases}, which is what emits them.\n *\n * @param scheme - Which scheme is being emitted.\n * @param grayScales - The generated neutral ramps, when the theme names one.\n * @returns Four opaque hex colors: bg, surface, surface-2, surface-3.\n */\nfunction surfacesOf(\n scheme: \"light\" | \"dark\",\n grayScales: { light: ColorScale; dark: ColorScale } | undefined,\n): readonly string[] {\n if (!grayScales) return SDK_SURFACES[scheme];\n const scale = grayScales[scheme];\n return scheme === \"light\"\n ? [\"#ffffff\", scale[50], scale[100], scale[200]]\n : [scale[50], scale[100], scale[200], scale[300]];\n}\n\n/**\n * Warn, in a development build, that an alpha was asked for the focus ring.\n *\n * A translucent ring has no contrast of its own — it has the contrast of\n * whatever it composites over — and that is the failure this option used to\n * ship by default: measured at alpha `0.35`, twelve brands across four surfaces\n * and both schemes produced 96 pairings, of which 3 cleared the 3:1 of WCAG 2.2\n * SC 1.4.11. It stays available, because a translucent ring over a\n * known background is a legitimate choice, but it is a choice a theme now has to\n * make on purpose.\n *\n * The warning is the difficult part to notice otherwise: a failing focus ring is\n * visible, it just does not separate.\n *\n * @param focusRingAlpha - The opacity the caller asked for, if any.\n */\nfunction warnOnTranslucentFocusRing(focusRingAlpha: number | undefined): void {\n if (focusRingAlpha === undefined || focusRingAlpha >= 1) return;\n if (!isDevBuild()) return;\n console.warn(\n `[tempest-react-sdk] createTheme({ focusRingAlpha: ${focusRingAlpha} }) makes the focus ring ` +\n \"translucent, so its contrast becomes whatever it composites over — measured below the 3:1 \" +\n \"of WCAG 2.2 SC 1.4.11 on every surface the SDK paints. Drop the option to get the opaque \" +\n \"ring, which is derived from your brand ramp and measured against those surfaces.\",\n );\n}\n\n/**\n * The dark ink for content sitting on a saturated fill.\n *\n * Near-black tinted toward warm rather than pure black, matching the value\n * `colors.css` uses for the same job: it reads as part of the swatch instead of\n * a hole punched in it.\n */\nconst ON_SOLID_INK = \"#1f0606\";\n\n/**\n * Emit the primary aliases for one scheme.\n *\n * The dark scheme walks the ramp the other way (hover is *lighter*, the soft\n * tint is a dark shade, and readable text on that tint is a light shade) — the\n * same inversion the built-in `colors.css` dark block does by hand.\n *\n * @param tokens - The token map for this scheme, written in place.\n * @param scale - The generated primary ramp.\n * @param scheme - Which scheme is being emitted.\n * @param surfaces - The surfaces this theme paints, for the focus-ring measurement.\n * @param focusRingAlpha - Opacity asked for the ring, or `undefined` for opaque.\n */\nfunction writePrimaryAliases(\n tokens: Record<string, string>,\n scale: ColorScale,\n scheme: \"light\" | \"dark\",\n surfaces: readonly string[],\n focusRingAlpha: number | undefined,\n): void {\n tokens[\"--tempest-primary\"] = \"var(--tempest-primary-500)\";\n if (scheme === \"light\") {\n tokens[\"--tempest-primary-hover\"] = \"var(--tempest-primary-600)\";\n tokens[\"--tempest-primary-active\"] = \"var(--tempest-primary-700)\";\n tokens[\"--tempest-primary-soft\"] = \"var(--tempest-primary-50)\";\n tokens[\"--tempest-primary-soft-hover\"] = \"var(--tempest-primary-100)\";\n tokens[\"--tempest-primary-on-soft\"] =\n `var(--tempest-primary-${pickOnSoftStep(scale, 50, [600, 700, 800, 900])})`;\n } else {\n tokens[\"--tempest-primary-hover\"] = \"var(--tempest-primary-400)\";\n tokens[\"--tempest-primary-active\"] = \"var(--tempest-primary-300)\";\n tokens[\"--tempest-primary-soft\"] = \"var(--tempest-primary-100)\";\n tokens[\"--tempest-primary-soft-hover\"] = \"var(--tempest-primary-200)\";\n tokens[\"--tempest-primary-on-soft\"] =\n `var(--tempest-primary-${pickOnSoftStep(scale, 100, [700, 800, 900])})`;\n }\n\n const foreground = readableForeground(scale[500]);\n tokens[\"--tempest-primary-foreground\"] = foreground;\n tokens[\"--tempest-text-on-primary\"] = foreground;\n const ring = scale[pickFocusRingStep(scale, surfaces)];\n tokens[\"--tempest-focus-ring-color\"] =\n focusRingAlpha === undefined || focusRingAlpha >= 1\n ? ring\n : hexToRgbaString(ring, focusRingAlpha);\n}\n\n/**\n * Emit the neutral surface/border/text aliases from a generated gray scale.\n *\n * `--tempest-bg` is pushed past the ramp on purpose: pure white in light mode and\n * a shade darker than `gray-50` in dark mode, so a raised surface still reads as\n * raised against the page.\n */\nfunction writeNeutralAliases(\n tokens: Record<string, string>,\n scale: ColorScale,\n scheme: \"light\" | \"dark\",\n): void {\n if (scheme === \"light\") {\n tokens[\"--tempest-bg\"] = \"#ffffff\";\n tokens[\"--tempest-surface\"] = \"var(--tempest-gray-50)\";\n tokens[\"--tempest-surface-2\"] = \"var(--tempest-gray-100)\";\n tokens[\"--tempest-surface-3\"] = \"var(--tempest-gray-200)\";\n tokens[\"--tempest-border\"] = \"var(--tempest-gray-200)\";\n tokens[\"--tempest-border-strong\"] = \"var(--tempest-gray-300)\";\n tokens[\"--tempest-text\"] = \"var(--tempest-gray-900)\";\n tokens[\"--tempest-text-muted\"] = \"var(--tempest-gray-600)\";\n tokens[\"--tempest-text-subtle\"] = \"var(--tempest-gray-500)\";\n } else {\n tokens[\"--tempest-bg\"] = scale[50];\n tokens[\"--tempest-surface\"] = \"var(--tempest-gray-100)\";\n tokens[\"--tempest-surface-2\"] = \"var(--tempest-gray-200)\";\n tokens[\"--tempest-surface-3\"] = \"var(--tempest-gray-300)\";\n tokens[\"--tempest-border\"] = \"var(--tempest-gray-300)\";\n tokens[\"--tempest-border-strong\"] = \"var(--tempest-gray-400)\";\n tokens[\"--tempest-text\"] = \"var(--tempest-gray-900)\";\n tokens[\"--tempest-text-muted\"] = \"var(--tempest-gray-700)\";\n tokens[\"--tempest-text-subtle\"] = \"var(--tempest-gray-600)\";\n }\n tokens[\"--tempest-neutral-on-solid\"] = readableForeground(scale[700], \"#ffffff\", ON_SOLID_INK);\n}\n\n/**\n * Emit one status family (`--tempest-danger`, `-fg`, `-bg`, `-border`, `-solid`).\n *\n * `-fg` is the text shade over `-bg`, so it has to cross the ramp in opposite\n * directions per scheme; `-solid` stays the saturated fill used by badges.\n *\n * `-on-solid` is derived from the `-solid` this call just emitted, rather than\n * left to fall through. Falling through was the bug: the SDK's own\n * `-on-solid` values are measured against the SDK's own fills, so a brand whose\n * `danger-600` lands light kept white ink over it and nothing said so. The\n * generated neutral hit exactly that — white over a generated `gray-700` of\n * `#a8b2c6` measures 2.13:1.\n */\nfunction writeStatus(\n tokens: Record<string, string>,\n name: ThemeStatus,\n scale: ColorScale,\n scheme: \"light\" | \"dark\",\n): void {\n if (scheme === \"light\") {\n tokens[`--tempest-${name}`] = scale[700];\n tokens[`--tempest-${name}-fg`] = scale[800];\n tokens[`--tempest-${name}-bg`] = scale[50];\n tokens[`--tempest-${name}-border`] = scale[200];\n tokens[`--tempest-${name}-solid`] = scale[600];\n tokens[`--tempest-${name}-on-solid`] = readableForeground(\n scale[600],\n \"#ffffff\",\n ON_SOLID_INK,\n );\n } else {\n tokens[`--tempest-${name}`] = scale[700];\n tokens[`--tempest-${name}-fg`] = scale[700];\n tokens[`--tempest-${name}-bg`] = scale[50];\n tokens[`--tempest-${name}-border`] = scale[200];\n tokens[`--tempest-${name}-solid`] = scale[500];\n tokens[`--tempest-${name}-on-solid`] = readableForeground(\n scale[500],\n \"#ffffff\",\n ON_SOLID_INK,\n );\n }\n}\n\nfunction renderBlock(selector: string, tokens: Record<string, string>): string {\n const entries = Object.entries(tokens);\n if (entries.length === 0) return \"\";\n const body = entries.map(([name, value]) => ` ${name}: ${value};`).join(\"\\n\");\n return `${selector} {\\n${body}\\n}`;\n}\n\n/**\n * Generate `--tempest-*` overrides from a small brand description.\n *\n * Only the families you pass are generated; everything else falls through to the\n * SDK's own tokens, so a theme stays a patch and not a fork of `colors.css`.\n *\n * @example\n * ```ts\n * import { applyTheme, createTheme } from \"tempest-react-sdk\";\n *\n * const theme = createTheme({\n * primary: \"#7c3aed\",\n * radius: \"lg\",\n * chart: [\"#7c3aed\", \"#0ea5e9\", \"#22c55e\", \"#f59e0b\"],\n * });\n *\n * applyTheme(theme);\n * ```\n *\n * @param options - Brand colors plus optional radius / chart / focus-ring tuning.\n * @returns The light and dark token maps and the CSS text that carries them.\n */\nexport function createTheme(options: CreateThemeOptions = {}): GeneratedTheme {\n const {\n primary,\n gray,\n chart,\n radius,\n focusRingAlpha,\n selector = \":root\",\n darkSelector = '[data-tempest-theme=\"dark\"]',\n } = options;\n\n warnOnTranslucentFocusRing(focusRingAlpha);\n\n const light: Record<string, string> = {};\n const dark: Record<string, string> = {};\n\n // `anchor: false`: a neutral ramp has to keep its tuned lightness curve.\n // Anchoring it at the input compressed both halves and dropped\n // text-muted-on-surface-3 to ~4.2:1 — below AA — which the browser axe\n // sweep caught on the generated themes.\n const grayScales = gray\n ? {\n light: createColorScale(gray, \"light\", { anchor: false, neutral: true }),\n dark: createColorScale(gray, \"dark\", { anchor: false, neutral: true }),\n }\n : undefined;\n\n if (primary) {\n const lightScale = createColorScale(primary, \"light\");\n const darkScale = createColorScale(primary, \"dark\");\n writeScale(light, \"primary\", lightScale);\n writeScale(dark, \"primary\", darkScale);\n writePrimaryAliases(\n light,\n lightScale,\n \"light\",\n surfacesOf(\"light\", grayScales),\n focusRingAlpha,\n );\n writePrimaryAliases(\n dark,\n darkScale,\n \"dark\",\n surfacesOf(\"dark\", grayScales),\n focusRingAlpha,\n );\n }\n\n if (grayScales) {\n writeScale(light, \"gray\", grayScales.light);\n writeScale(dark, \"gray\", grayScales.dark);\n writeNeutralAliases(light, grayScales.light, \"light\");\n writeNeutralAliases(dark, grayScales.dark, \"dark\");\n }\n\n for (const status of [\"success\", \"warning\", \"danger\", \"info\"] as const) {\n const value = options[status];\n if (!value) continue;\n writeStatus(light, status, createColorScale(value, \"light\"), \"light\");\n writeStatus(dark, status, createColorScale(value, \"dark\"), \"dark\");\n }\n\n if (chart?.length) {\n chart.forEach((color, index) => {\n light[`--tempest-chart-${index + 1}`] = color;\n });\n // Declares how many series colors this theme owns. Without it the reader\n // keeps walking into the SDK's built-in `--tempest-chart-7`/`-8`, so a\n // 6-color brand palette silently mixes with two leftover defaults — which\n // is exactly what a 7-series chart would show.\n light[\"--tempest-chart-count\"] = String(chart.length);\n }\n\n /*\n * Continuous scales follow the brand too.\n *\n * Without this a rebranded app gets its categorical slots recoloured and then a\n * heatmap still painted in the SDK's blue — the one chart on the page that\n * silently ignores the brand. Both scales derive from the first series hue (or\n * the primary), stepped by perceptual lightness for each mode separately.\n *\n * Skipped entirely when the theme names no colour to derive from, so the\n * built-in tokens survive instead of being overwritten with a guess.\n */\n const scaleSource = chart?.[0] ?? primary;\n if (scaleSource) {\n const coolHue = hueOf(scaleSource);\n // The opposite pole: the brand's own danger colour when it has one, since a\n // diverging scale's warm arm and \"bad\" should not disagree on screen.\n const warmHue = options.danger ? hueOf(options.danger) : (coolHue + 180) % 360;\n for (const [target, mode] of [\n [light, \"light\"],\n [dark, \"dark\"],\n ] as const) {\n buildRamp(coolHue, mode).forEach((stepColor, index) => {\n target[`--tempest-chart-sequential-${index + 1}`] = stepColor;\n });\n const diverging = buildDivergingRamp({\n coolHue,\n warmHue,\n mid: mode === \"light\" ? \"#e4e7ec\" : \"#262d3f\",\n mode,\n });\n [...diverging.cool, diverging.mid, ...diverging.warm].forEach((stepColor, index) => {\n target[`--tempest-chart-diverging-${index + 1}`] = stepColor;\n });\n }\n }\n\n if (radius) {\n const steps = typeof radius === \"string\" ? RADIUS_PRESETS[radius] : radius;\n for (const [step, value] of Object.entries(steps)) {\n light[`--tempest-radius-${step}`] = value;\n }\n }\n\n const css = [renderBlock(selector, light), renderBlock(darkSelector, dark)]\n .filter(Boolean)\n .join(\"\\n\\n\");\n\n return { light, dark, css };\n}\n\n/**\n * Contrast ratio of `--tempest-primary-foreground` over the brand color.\n *\n * Exposed so an app (or a test) can assert its own brand clears WCAG AA (4.5) for\n * body text or AA-large (3.0) for button labels, instead of trusting the pick.\n *\n * @param options - The same input given to {@link createTheme}.\n * @returns The ratio, or `null` when no `primary` was provided.\n */\nexport function themeContrast(options: CreateThemeOptions): number | null {\n if (!options.primary) return null;\n const scale = createColorScale(options.primary, \"light\");\n return contrastRatio(scale[500], readableForeground(scale[500]));\n}\n"],"mappings":"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"}
@@ -1,7 +1,8 @@
1
- import { contrastRatio as e, createColorScale as t, hexToRgbaString as n, readableForeground as r } from "./color.js";
2
- import { buildDivergingRamp as i, buildRamp as a, hueOf as o } from "./data-viz-ramps.js";
1
+ import { isDevBuild as e } from "../utils/dev-mode.js";
2
+ import { contrastRatio as t, createColorScale as n, hexToRgbaString as r, readableForeground as i } from "./color.js";
3
+ import { buildDivergingRamp as a, buildRamp as o, hueOf as s } from "./data-viz-ramps.js";
3
4
  //#region src/theme/create-theme.ts
4
- var s = {
5
+ var c = {
5
6
  none: {
6
7
  xs: "0",
7
8
  sm: "0",
@@ -50,7 +51,7 @@ var s = {
50
51
  xl: "9999px",
51
52
  "2xl": "9999px"
52
53
  }
53
- }, c = [
54
+ }, l = [
54
55
  50,
55
56
  100,
56
57
  200,
@@ -62,105 +63,156 @@ var s = {
62
63
  800,
63
64
  900
64
65
  ];
65
- function l(e, t, n) {
66
- for (let r of c) e[`--tempest-${t}-${r}`] = n[r];
66
+ function u(e, t, n) {
67
+ for (let r of l) e[`--tempest-${t}-${r}`] = n[r];
67
68
  }
68
- var u = 4.5;
69
- function d(t, n, r) {
70
- for (let i of r) if (e(t[n], t[i]) >= u) return i;
69
+ var d = 4.5;
70
+ function f(e, n, r) {
71
+ for (let i of r) if (t(e[n], e[i]) >= d) return i;
71
72
  return r[r.length - 1];
72
73
  }
73
- var f = "#1f0606";
74
- function p(e, t, i, a) {
75
- e["--tempest-primary"] = "var(--tempest-primary-500)", i === "light" ? (e["--tempest-primary-hover"] = "var(--tempest-primary-600)", e["--tempest-primary-active"] = "var(--tempest-primary-700)", e["--tempest-primary-soft"] = "var(--tempest-primary-50)", e["--tempest-primary-soft-hover"] = "var(--tempest-primary-100)", e["--tempest-primary-on-soft"] = `var(--tempest-primary-${d(t, 50, [
74
+ var p = 3, m = {
75
+ light: [
76
+ "#ffffff",
77
+ "#f8f9fb",
78
+ "#f1f3f6",
79
+ "#e4e7ec"
80
+ ],
81
+ dark: [
82
+ "#0b0d12",
83
+ "#14171f",
84
+ "#1d2230",
85
+ "#262d3f"
86
+ ]
87
+ }, h = [
88
+ 500,
89
+ 600,
90
+ 700,
91
+ 800,
92
+ 900
93
+ ];
94
+ function g(e, n) {
95
+ let r = (r) => Math.min(...n.map((n) => t(e[r], n))), i = h[0], a = -1;
96
+ for (let e of h) {
97
+ let t = r(e);
98
+ if (t >= p) return e;
99
+ t > a && (i = e, a = t);
100
+ }
101
+ return i;
102
+ }
103
+ function _(e, t) {
104
+ if (!t) return m[e];
105
+ let n = t[e];
106
+ return e === "light" ? [
107
+ "#ffffff",
108
+ n[50],
109
+ n[100],
110
+ n[200]
111
+ ] : [
112
+ n[50],
113
+ n[100],
114
+ n[200],
115
+ n[300]
116
+ ];
117
+ }
118
+ function v(t) {
119
+ t === void 0 || t >= 1 || e() && console.warn(`[tempest-react-sdk] createTheme({ focusRingAlpha: ${t} }) makes the focus ring translucent, so its contrast becomes whatever it composites over — measured below the 3:1 of WCAG 2.2 SC 1.4.11 on every surface the SDK paints. Drop the option to get the opaque ring, which is derived from your brand ramp and measured against those surfaces.`);
120
+ }
121
+ var y = "#1f0606";
122
+ function b(e, t, n, a, o) {
123
+ e["--tempest-primary"] = "var(--tempest-primary-500)", n === "light" ? (e["--tempest-primary-hover"] = "var(--tempest-primary-600)", e["--tempest-primary-active"] = "var(--tempest-primary-700)", e["--tempest-primary-soft"] = "var(--tempest-primary-50)", e["--tempest-primary-soft-hover"] = "var(--tempest-primary-100)", e["--tempest-primary-on-soft"] = `var(--tempest-primary-${f(t, 50, [
76
124
  600,
77
125
  700,
78
126
  800,
79
127
  900
80
- ])})`) : (e["--tempest-primary-hover"] = "var(--tempest-primary-400)", e["--tempest-primary-active"] = "var(--tempest-primary-300)", e["--tempest-primary-soft"] = "var(--tempest-primary-100)", e["--tempest-primary-soft-hover"] = "var(--tempest-primary-200)", e["--tempest-primary-on-soft"] = `var(--tempest-primary-${d(t, 100, [
128
+ ])})`) : (e["--tempest-primary-hover"] = "var(--tempest-primary-400)", e["--tempest-primary-active"] = "var(--tempest-primary-300)", e["--tempest-primary-soft"] = "var(--tempest-primary-100)", e["--tempest-primary-soft-hover"] = "var(--tempest-primary-200)", e["--tempest-primary-on-soft"] = `var(--tempest-primary-${f(t, 100, [
81
129
  700,
82
130
  800,
83
131
  900
84
132
  ])})`);
85
- let o = r(t[500]);
86
- e["--tempest-primary-foreground"] = o, e["--tempest-text-on-primary"] = o, e["--tempest-focus-ring-color"] = n(t[500], a);
133
+ let s = i(t[500]);
134
+ e["--tempest-primary-foreground"] = s, e["--tempest-text-on-primary"] = s;
135
+ let c = t[g(t, a)];
136
+ e["--tempest-focus-ring-color"] = o === void 0 || o >= 1 ? c : r(c, o);
87
137
  }
88
- function m(e, t, n) {
89
- n === "light" ? (e["--tempest-bg"] = "#ffffff", e["--tempest-surface"] = "var(--tempest-gray-50)", e["--tempest-surface-2"] = "var(--tempest-gray-100)", e["--tempest-surface-3"] = "var(--tempest-gray-200)", e["--tempest-border"] = "var(--tempest-gray-200)", e["--tempest-border-strong"] = "var(--tempest-gray-300)", e["--tempest-text"] = "var(--tempest-gray-900)", e["--tempest-text-muted"] = "var(--tempest-gray-600)", e["--tempest-text-subtle"] = "var(--tempest-gray-500)") : (e["--tempest-bg"] = t[50], e["--tempest-surface"] = "var(--tempest-gray-100)", e["--tempest-surface-2"] = "var(--tempest-gray-200)", e["--tempest-surface-3"] = "var(--tempest-gray-300)", e["--tempest-border"] = "var(--tempest-gray-300)", e["--tempest-border-strong"] = "var(--tempest-gray-400)", e["--tempest-text"] = "var(--tempest-gray-900)", e["--tempest-text-muted"] = "var(--tempest-gray-700)", e["--tempest-text-subtle"] = "var(--tempest-gray-600)"), e["--tempest-neutral-on-solid"] = r(t[700], "#ffffff", f);
138
+ function x(e, t, n) {
139
+ n === "light" ? (e["--tempest-bg"] = "#ffffff", e["--tempest-surface"] = "var(--tempest-gray-50)", e["--tempest-surface-2"] = "var(--tempest-gray-100)", e["--tempest-surface-3"] = "var(--tempest-gray-200)", e["--tempest-border"] = "var(--tempest-gray-200)", e["--tempest-border-strong"] = "var(--tempest-gray-300)", e["--tempest-text"] = "var(--tempest-gray-900)", e["--tempest-text-muted"] = "var(--tempest-gray-600)", e["--tempest-text-subtle"] = "var(--tempest-gray-500)") : (e["--tempest-bg"] = t[50], e["--tempest-surface"] = "var(--tempest-gray-100)", e["--tempest-surface-2"] = "var(--tempest-gray-200)", e["--tempest-surface-3"] = "var(--tempest-gray-300)", e["--tempest-border"] = "var(--tempest-gray-300)", e["--tempest-border-strong"] = "var(--tempest-gray-400)", e["--tempest-text"] = "var(--tempest-gray-900)", e["--tempest-text-muted"] = "var(--tempest-gray-700)", e["--tempest-text-subtle"] = "var(--tempest-gray-600)"), e["--tempest-neutral-on-solid"] = i(t[700], "#ffffff", y);
90
140
  }
91
- function h(e, t, n, i) {
92
- i === "light" ? (e[`--tempest-${t}`] = n[700], e[`--tempest-${t}-fg`] = n[800], e[`--tempest-${t}-bg`] = n[50], e[`--tempest-${t}-border`] = n[200], e[`--tempest-${t}-solid`] = n[600], e[`--tempest-${t}-on-solid`] = r(n[600], "#ffffff", f)) : (e[`--tempest-${t}`] = n[700], e[`--tempest-${t}-fg`] = n[700], e[`--tempest-${t}-bg`] = n[50], e[`--tempest-${t}-border`] = n[200], e[`--tempest-${t}-solid`] = n[500], e[`--tempest-${t}-on-solid`] = r(n[500], "#ffffff", f));
141
+ function S(e, t, n, r) {
142
+ r === "light" ? (e[`--tempest-${t}`] = n[700], e[`--tempest-${t}-fg`] = n[800], e[`--tempest-${t}-bg`] = n[50], e[`--tempest-${t}-border`] = n[200], e[`--tempest-${t}-solid`] = n[600], e[`--tempest-${t}-on-solid`] = i(n[600], "#ffffff", y)) : (e[`--tempest-${t}`] = n[700], e[`--tempest-${t}-fg`] = n[700], e[`--tempest-${t}-bg`] = n[50], e[`--tempest-${t}-border`] = n[200], e[`--tempest-${t}-solid`] = n[500], e[`--tempest-${t}-on-solid`] = i(n[500], "#ffffff", y));
93
143
  }
94
- function g(e, t) {
144
+ function C(e, t) {
95
145
  let n = Object.entries(t);
96
146
  return n.length === 0 ? "" : `${e} {\n${n.map(([e, t]) => ` ${e}: ${t};`).join("\n")}\n}`;
97
147
  }
98
- function _(e = {}) {
99
- let { primary: n, gray: r, chart: c, radius: u, focusRingAlpha: d = .35, selector: f = ":root", darkSelector: _ = "[data-tempest-theme=\"dark\"]" } = e, v = {}, y = {};
100
- if (n) {
101
- let e = t(n, "light"), r = t(n, "dark");
102
- l(v, "primary", e), l(y, "primary", r), p(v, e, "light", d), p(y, r, "dark", d);
103
- }
104
- if (r) {
105
- let e = t(r, "light", {
148
+ function w(e = {}) {
149
+ let { primary: t, gray: r, chart: i, radius: l, focusRingAlpha: d, selector: f = ":root", darkSelector: p = "[data-tempest-theme=\"dark\"]" } = e;
150
+ v(d);
151
+ let m = {}, h = {}, g = r ? {
152
+ light: n(r, "light", {
106
153
  anchor: !1,
107
154
  neutral: !0
108
- }), n = t(r, "dark", {
155
+ }),
156
+ dark: n(r, "dark", {
109
157
  anchor: !1,
110
158
  neutral: !0
111
- });
112
- l(v, "gray", e), l(y, "gray", n), m(v, e, "light"), m(y, n, "dark");
159
+ })
160
+ } : void 0;
161
+ if (t) {
162
+ let e = n(t, "light"), r = n(t, "dark");
163
+ u(m, "primary", e), u(h, "primary", r), b(m, e, "light", _("light", g), d), b(h, r, "dark", _("dark", g), d);
113
164
  }
114
- for (let n of [
165
+ g && (u(m, "gray", g.light), u(h, "gray", g.dark), x(m, g.light, "light"), x(h, g.dark, "dark"));
166
+ for (let t of [
115
167
  "success",
116
168
  "warning",
117
169
  "danger",
118
170
  "info"
119
171
  ]) {
120
- let r = e[n];
121
- r && (h(v, n, t(r, "light"), "light"), h(y, n, t(r, "dark"), "dark"));
172
+ let r = e[t];
173
+ r && (S(m, t, n(r, "light"), "light"), S(h, t, n(r, "dark"), "dark"));
122
174
  }
123
- c?.length && (c.forEach((e, t) => {
124
- v[`--tempest-chart-${t + 1}`] = e;
125
- }), v["--tempest-chart-count"] = String(c.length));
126
- let b = c?.[0] ?? n;
127
- if (b) {
128
- let t = o(b), n = e.danger ? o(e.danger) : (t + 180) % 360;
129
- for (let [e, r] of [[v, "light"], [y, "dark"]]) {
130
- a(t, r).forEach((t, n) => {
175
+ i?.length && (i.forEach((e, t) => {
176
+ m[`--tempest-chart-${t + 1}`] = e;
177
+ }), m["--tempest-chart-count"] = String(i.length));
178
+ let y = i?.[0] ?? t;
179
+ if (y) {
180
+ let t = s(y), n = e.danger ? s(e.danger) : (t + 180) % 360;
181
+ for (let [e, r] of [[m, "light"], [h, "dark"]]) {
182
+ o(t, r).forEach((t, n) => {
131
183
  e[`--tempest-chart-sequential-${n + 1}`] = t;
132
184
  });
133
- let o = i({
185
+ let i = a({
134
186
  coolHue: t,
135
187
  warmHue: n,
136
188
  mid: r === "light" ? "#e4e7ec" : "#262d3f",
137
189
  mode: r
138
190
  });
139
191
  [
140
- ...o.cool,
141
- o.mid,
142
- ...o.warm
192
+ ...i.cool,
193
+ i.mid,
194
+ ...i.warm
143
195
  ].forEach((t, n) => {
144
196
  e[`--tempest-chart-diverging-${n + 1}`] = t;
145
197
  });
146
198
  }
147
199
  }
148
- if (u) {
149
- let e = typeof u == "string" ? s[u] : u;
150
- for (let [t, n] of Object.entries(e)) v[`--tempest-radius-${t}`] = n;
200
+ if (l) {
201
+ let e = typeof l == "string" ? c[l] : l;
202
+ for (let [t, n] of Object.entries(e)) m[`--tempest-radius-${t}`] = n;
151
203
  }
152
204
  return {
153
- light: v,
154
- dark: y,
155
- css: [g(f, v), g(_, y)].filter(Boolean).join("\n\n")
205
+ light: m,
206
+ dark: h,
207
+ css: [C(f, m), C(p, h)].filter(Boolean).join("\n\n")
156
208
  };
157
209
  }
158
- function v(n) {
159
- if (!n.primary) return null;
160
- let i = t(n.primary, "light");
161
- return e(i[500], r(i[500]));
210
+ function T(e) {
211
+ if (!e.primary) return null;
212
+ let r = n(e.primary, "light");
213
+ return t(r[500], i(r[500]));
162
214
  }
163
215
  //#endregion
164
- export { _ as createTheme, v as themeContrast };
216
+ export { w as createTheme, T as themeContrast };
165
217
 
166
218
  //# sourceMappingURL=create-theme.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"create-theme.js","names":[],"sources":["../../src/theme/create-theme.ts"],"sourcesContent":["/**\n * @tempest-limits file-lines — one pass that emits the whole token set — surfaces,\n * text, borders, states, the chart ramps — for both modes, with every value checked\n * against the surface it will sit on. The checks are what make the length: each\n * token is derived and then verified against the same background table.\n */\n/**\n * Theme factory: turns a handful of brand colors into the full set of\n * `--tempest-*` token overrides, for both light and dark.\n *\n * Rebranding used to mean hand-writing ~167 custom properties (and getting the\n * dark ramp inversion right by hand). `createTheme({ primary: \"#7c3aed\" })`\n * emits the same thing, derived in OKLCH so the ramp stays perceptually even.\n */\nimport {\n contrastRatio,\n createColorScale,\n hexToRgbaString,\n readableForeground,\n type ColorScale,\n type ScaleStep,\n} from \"./color\";\nimport { buildDivergingRamp, buildRamp, hueOf } from \"./data-viz-ramps\";\n\n/** Radius presets, applied to the whole `--tempest-radius-*` family at once. */\nexport type ThemeRadius = \"none\" | \"sm\" | \"md\" | \"lg\" | \"xl\" | \"full\";\n\n/** Status token families that {@link createTheme} can regenerate. */\nexport type ThemeStatus = \"success\" | \"warning\" | \"danger\" | \"info\";\n\n/** Input for {@link createTheme}. Every field is optional — omitted families keep the built-in tokens. */\nexport interface CreateThemeOptions {\n /** Brand color, used as the `500` step of the primary scale. */\n primary?: string;\n /** Neutral color, used as the `500` step of the gray scale (surfaces, borders, text). */\n gray?: string;\n /** Success color (`--tempest-success*`). */\n success?: string;\n /** Warning color (`--tempest-warning*`). */\n warning?: string;\n /** Danger color (`--tempest-danger*`). */\n danger?: string;\n /** Info color (`--tempest-info*`). */\n info?: string;\n /**\n * Categorical series colors for `tempest-react-sdk/charts`, in cycle order.\n * Written to `--tempest-chart-1` … `--tempest-chart-N`, so charts follow the\n * theme instead of a hardcoded palette.\n */\n chart?: string[];\n /** Corner radius scale. A preset name, or explicit per-step values. */\n radius?: ThemeRadius | Partial<Record<\"xs\" | \"sm\" | \"md\" | \"lg\" | \"xl\" | \"2xl\", string>>;\n /** Alpha of `--tempest-focus-ring-color`, derived from the brand color. Default `0.35`. */\n focusRingAlpha?: number;\n /** Selector the light tokens are written under. Default `\":root\"`. */\n selector?: string;\n /** Selector the dark tokens are written under. Default `'[data-tempest-theme=\"dark\"]'`. */\n darkSelector?: string;\n}\n\n/** A generated theme: token maps per color scheme, plus the CSS text that carries them. */\nexport interface GeneratedTheme {\n /** Light-scheme custom properties, without the leading `--`-less names (keys include `--`). */\n light: Record<string, string>;\n /** Dark-scheme custom properties. */\n dark: Record<string, string>;\n /** Both blocks rendered as CSS, ready for {@link applyTheme} or a stylesheet. */\n css: string;\n}\n\nconst RADIUS_PRESETS: Record<ThemeRadius, Record<string, string>> = {\n none: { xs: \"0\", sm: \"0\", md: \"0\", lg: \"0\", xl: \"0\", \"2xl\": \"0\" },\n sm: { xs: \"1px\", sm: \"2px\", md: \"4px\", lg: \"6px\", xl: \"8px\", \"2xl\": \"12px\" },\n md: { xs: \"2px\", sm: \"4px\", md: \"8px\", lg: \"12px\", xl: \"16px\", \"2xl\": \"24px\" },\n lg: { xs: \"4px\", sm: \"6px\", md: \"12px\", lg: \"16px\", xl: \"22px\", \"2xl\": \"32px\" },\n xl: { xs: \"6px\", sm: \"10px\", md: \"16px\", lg: \"24px\", xl: \"32px\", \"2xl\": \"44px\" },\n full: { xs: \"4px\", sm: \"8px\", md: \"9999px\", lg: \"9999px\", xl: \"9999px\", \"2xl\": \"9999px\" },\n};\n\nconst SCALE_STEPS: ScaleStep[] = [50, 100, 200, 300, 400, 500, 600, 700, 800, 900];\n\nfunction writeScale(tokens: Record<string, string>, name: string, scale: ColorScale): void {\n for (const step of SCALE_STEPS) {\n tokens[`--tempest-${name}-${step}`] = scale[step];\n }\n}\n\n/** Minimum contrast for body text, WCAG 2.x AA. */\nconst AA_TEXT_CONTRAST = 4.5;\n\n/**\n * Choose the ramp step for text sitting on the soft tint.\n *\n * A fixed step does not survive an arbitrary brand color: the built-in blue only\n * reaches 4.37:1 at `500` over its own `50` tint, and a generated emerald lands\n * at 4.41:1 at `600` — both fail AA for body text by a hair. So the step is\n * picked by measuring, walking away from the tint until it clears AA, and\n * falling back to the most extreme candidate when even that cannot (a very light\n * or very desaturated brand).\n *\n * @param scale - The generated ramp.\n * @param softStep - Step used as `--tempest-primary-soft`.\n * @param candidates - Steps to try, in order of preference.\n * @returns The first candidate clearing {@link AA_TEXT_CONTRAST}, else the last.\n */\nfunction pickOnSoftStep(\n scale: ColorScale,\n softStep: ScaleStep,\n candidates: ScaleStep[],\n): ScaleStep {\n for (const step of candidates) {\n if (contrastRatio(scale[softStep], scale[step]) >= AA_TEXT_CONTRAST) return step;\n }\n return candidates[candidates.length - 1];\n}\n\n/**\n * The dark ink for content sitting on a saturated fill.\n *\n * Near-black tinted toward warm rather than pure black, matching the value\n * `colors.css` uses for the same job: it reads as part of the swatch instead of\n * a hole punched in it.\n */\nconst ON_SOLID_INK = \"#1f0606\";\n\n/**\n * Emit the primary aliases for one scheme.\n *\n * The dark scheme walks the ramp the other way (hover is *lighter*, the soft\n * tint is a dark shade, and readable text on that tint is a light shade) — the\n * same inversion the built-in `colors.css` dark block does by hand.\n */\nfunction writePrimaryAliases(\n tokens: Record<string, string>,\n scale: ColorScale,\n scheme: \"light\" | \"dark\",\n focusRingAlpha: number,\n): void {\n tokens[\"--tempest-primary\"] = \"var(--tempest-primary-500)\";\n if (scheme === \"light\") {\n tokens[\"--tempest-primary-hover\"] = \"var(--tempest-primary-600)\";\n tokens[\"--tempest-primary-active\"] = \"var(--tempest-primary-700)\";\n tokens[\"--tempest-primary-soft\"] = \"var(--tempest-primary-50)\";\n tokens[\"--tempest-primary-soft-hover\"] = \"var(--tempest-primary-100)\";\n tokens[\"--tempest-primary-on-soft\"] =\n `var(--tempest-primary-${pickOnSoftStep(scale, 50, [600, 700, 800, 900])})`;\n } else {\n tokens[\"--tempest-primary-hover\"] = \"var(--tempest-primary-400)\";\n tokens[\"--tempest-primary-active\"] = \"var(--tempest-primary-300)\";\n tokens[\"--tempest-primary-soft\"] = \"var(--tempest-primary-100)\";\n tokens[\"--tempest-primary-soft-hover\"] = \"var(--tempest-primary-200)\";\n tokens[\"--tempest-primary-on-soft\"] =\n `var(--tempest-primary-${pickOnSoftStep(scale, 100, [700, 800, 900])})`;\n }\n\n const foreground = readableForeground(scale[500]);\n tokens[\"--tempest-primary-foreground\"] = foreground;\n tokens[\"--tempest-text-on-primary\"] = foreground;\n tokens[\"--tempest-focus-ring-color\"] = hexToRgbaString(scale[500], focusRingAlpha);\n}\n\n/**\n * Emit the neutral surface/border/text aliases from a generated gray scale.\n *\n * `--tempest-bg` is pushed past the ramp on purpose: pure white in light mode and\n * a shade darker than `gray-50` in dark mode, so a raised surface still reads as\n * raised against the page.\n */\nfunction writeNeutralAliases(\n tokens: Record<string, string>,\n scale: ColorScale,\n scheme: \"light\" | \"dark\",\n): void {\n if (scheme === \"light\") {\n tokens[\"--tempest-bg\"] = \"#ffffff\";\n tokens[\"--tempest-surface\"] = \"var(--tempest-gray-50)\";\n tokens[\"--tempest-surface-2\"] = \"var(--tempest-gray-100)\";\n tokens[\"--tempest-surface-3\"] = \"var(--tempest-gray-200)\";\n tokens[\"--tempest-border\"] = \"var(--tempest-gray-200)\";\n tokens[\"--tempest-border-strong\"] = \"var(--tempest-gray-300)\";\n tokens[\"--tempest-text\"] = \"var(--tempest-gray-900)\";\n tokens[\"--tempest-text-muted\"] = \"var(--tempest-gray-600)\";\n tokens[\"--tempest-text-subtle\"] = \"var(--tempest-gray-500)\";\n } else {\n tokens[\"--tempest-bg\"] = scale[50];\n tokens[\"--tempest-surface\"] = \"var(--tempest-gray-100)\";\n tokens[\"--tempest-surface-2\"] = \"var(--tempest-gray-200)\";\n tokens[\"--tempest-surface-3\"] = \"var(--tempest-gray-300)\";\n tokens[\"--tempest-border\"] = \"var(--tempest-gray-300)\";\n tokens[\"--tempest-border-strong\"] = \"var(--tempest-gray-400)\";\n tokens[\"--tempest-text\"] = \"var(--tempest-gray-900)\";\n tokens[\"--tempest-text-muted\"] = \"var(--tempest-gray-700)\";\n tokens[\"--tempest-text-subtle\"] = \"var(--tempest-gray-600)\";\n }\n tokens[\"--tempest-neutral-on-solid\"] = readableForeground(scale[700], \"#ffffff\", ON_SOLID_INK);\n}\n\n/**\n * Emit one status family (`--tempest-danger`, `-fg`, `-bg`, `-border`, `-solid`).\n *\n * `-fg` is the text shade over `-bg`, so it has to cross the ramp in opposite\n * directions per scheme; `-solid` stays the saturated fill used by badges.\n *\n * `-on-solid` is derived from the `-solid` this call just emitted, rather than\n * left to fall through. Falling through was the bug: the SDK's own\n * `-on-solid` values are measured against the SDK's own fills, so a brand whose\n * `danger-600` lands light kept white ink over it and nothing said so. The\n * generated neutral hit exactly that — white over a generated `gray-700` of\n * `#a8b2c6` measures 2.13:1.\n */\nfunction writeStatus(\n tokens: Record<string, string>,\n name: ThemeStatus,\n scale: ColorScale,\n scheme: \"light\" | \"dark\",\n): void {\n if (scheme === \"light\") {\n tokens[`--tempest-${name}`] = scale[700];\n tokens[`--tempest-${name}-fg`] = scale[800];\n tokens[`--tempest-${name}-bg`] = scale[50];\n tokens[`--tempest-${name}-border`] = scale[200];\n tokens[`--tempest-${name}-solid`] = scale[600];\n tokens[`--tempest-${name}-on-solid`] = readableForeground(\n scale[600],\n \"#ffffff\",\n ON_SOLID_INK,\n );\n } else {\n tokens[`--tempest-${name}`] = scale[700];\n tokens[`--tempest-${name}-fg`] = scale[700];\n tokens[`--tempest-${name}-bg`] = scale[50];\n tokens[`--tempest-${name}-border`] = scale[200];\n tokens[`--tempest-${name}-solid`] = scale[500];\n tokens[`--tempest-${name}-on-solid`] = readableForeground(\n scale[500],\n \"#ffffff\",\n ON_SOLID_INK,\n );\n }\n}\n\nfunction renderBlock(selector: string, tokens: Record<string, string>): string {\n const entries = Object.entries(tokens);\n if (entries.length === 0) return \"\";\n const body = entries.map(([name, value]) => ` ${name}: ${value};`).join(\"\\n\");\n return `${selector} {\\n${body}\\n}`;\n}\n\n/**\n * Generate `--tempest-*` overrides from a small brand description.\n *\n * Only the families you pass are generated; everything else falls through to the\n * SDK's own tokens, so a theme stays a patch and not a fork of `colors.css`.\n *\n * @example\n * ```ts\n * import { applyTheme, createTheme } from \"tempest-react-sdk\";\n *\n * const theme = createTheme({\n * primary: \"#7c3aed\",\n * radius: \"lg\",\n * chart: [\"#7c3aed\", \"#0ea5e9\", \"#22c55e\", \"#f59e0b\"],\n * });\n *\n * applyTheme(theme);\n * ```\n *\n * @param options - Brand colors plus optional radius / chart / focus-ring tuning.\n * @returns The light and dark token maps and the CSS text that carries them.\n */\nexport function createTheme(options: CreateThemeOptions = {}): GeneratedTheme {\n const {\n primary,\n gray,\n chart,\n radius,\n focusRingAlpha = 0.35,\n selector = \":root\",\n darkSelector = '[data-tempest-theme=\"dark\"]',\n } = options;\n\n const light: Record<string, string> = {};\n const dark: Record<string, string> = {};\n\n if (primary) {\n const lightScale = createColorScale(primary, \"light\");\n const darkScale = createColorScale(primary, \"dark\");\n writeScale(light, \"primary\", lightScale);\n writeScale(dark, \"primary\", darkScale);\n writePrimaryAliases(light, lightScale, \"light\", focusRingAlpha);\n writePrimaryAliases(dark, darkScale, \"dark\", focusRingAlpha);\n }\n\n if (gray) {\n // `anchor: false`: a neutral ramp has to keep its tuned lightness curve.\n // Anchoring it at the input compressed both halves and dropped\n // text-muted-on-surface-3 to ~4.2:1 — below AA — which the browser axe\n // sweep caught on the generated themes.\n const lightScale = createColorScale(gray, \"light\", { anchor: false, neutral: true });\n const darkScale = createColorScale(gray, \"dark\", { anchor: false, neutral: true });\n writeScale(light, \"gray\", lightScale);\n writeScale(dark, \"gray\", darkScale);\n writeNeutralAliases(light, lightScale, \"light\");\n writeNeutralAliases(dark, darkScale, \"dark\");\n }\n\n for (const status of [\"success\", \"warning\", \"danger\", \"info\"] as const) {\n const value = options[status];\n if (!value) continue;\n writeStatus(light, status, createColorScale(value, \"light\"), \"light\");\n writeStatus(dark, status, createColorScale(value, \"dark\"), \"dark\");\n }\n\n if (chart?.length) {\n chart.forEach((color, index) => {\n light[`--tempest-chart-${index + 1}`] = color;\n });\n // Declares how many series colors this theme owns. Without it the reader\n // keeps walking into the SDK's built-in `--tempest-chart-7`/`-8`, so a\n // 6-color brand palette silently mixes with two leftover defaults — which\n // is exactly what a 7-series chart would show.\n light[\"--tempest-chart-count\"] = String(chart.length);\n }\n\n /*\n * Continuous scales follow the brand too.\n *\n * Without this a rebranded app gets its categorical slots recoloured and then a\n * heatmap still painted in the SDK's blue — the one chart on the page that\n * silently ignores the brand. Both scales derive from the first series hue (or\n * the primary), stepped by perceptual lightness for each mode separately.\n *\n * Skipped entirely when the theme names no colour to derive from, so the\n * built-in tokens survive instead of being overwritten with a guess.\n */\n const scaleSource = chart?.[0] ?? primary;\n if (scaleSource) {\n const coolHue = hueOf(scaleSource);\n // The opposite pole: the brand's own danger colour when it has one, since a\n // diverging scale's warm arm and \"bad\" should not disagree on screen.\n const warmHue = options.danger ? hueOf(options.danger) : (coolHue + 180) % 360;\n for (const [target, mode] of [\n [light, \"light\"],\n [dark, \"dark\"],\n ] as const) {\n buildRamp(coolHue, mode).forEach((stepColor, index) => {\n target[`--tempest-chart-sequential-${index + 1}`] = stepColor;\n });\n const diverging = buildDivergingRamp({\n coolHue,\n warmHue,\n mid: mode === \"light\" ? \"#e4e7ec\" : \"#262d3f\",\n mode,\n });\n [...diverging.cool, diverging.mid, ...diverging.warm].forEach((stepColor, index) => {\n target[`--tempest-chart-diverging-${index + 1}`] = stepColor;\n });\n }\n }\n\n if (radius) {\n const steps = typeof radius === \"string\" ? RADIUS_PRESETS[radius] : radius;\n for (const [step, value] of Object.entries(steps)) {\n light[`--tempest-radius-${step}`] = value;\n }\n }\n\n const css = [renderBlock(selector, light), renderBlock(darkSelector, dark)]\n .filter(Boolean)\n .join(\"\\n\\n\");\n\n return { light, dark, css };\n}\n\n/**\n * Contrast ratio of `--tempest-primary-foreground` over the brand color.\n *\n * Exposed so an app (or a test) can assert its own brand clears WCAG AA (4.5) for\n * body text or AA-large (3.0) for button labels, instead of trusting the pick.\n *\n * @param options - The same input given to {@link createTheme}.\n * @returns The ratio, or `null` when no `primary` was provided.\n */\nexport function themeContrast(options: CreateThemeOptions): number | null {\n if (!options.primary) return null;\n const scale = createColorScale(options.primary, \"light\");\n return contrastRatio(scale[500], readableForeground(scale[500]));\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"create-theme.js","names":[],"sources":["../../src/theme/create-theme.ts"],"sourcesContent":["/**\n * @tempest-limits file-lines — one pass that emits the whole token set — surfaces,\n * text, borders, states, the chart ramps — for both modes, with every value checked\n * against the surface it will sit on. The checks are what make the length: each\n * token is derived and then verified against the same background table.\n */\n/**\n * Theme factory: turns a handful of brand colors into the full set of\n * `--tempest-*` token overrides, for both light and dark.\n *\n * Rebranding used to mean hand-writing ~167 custom properties (and getting the\n * dark ramp inversion right by hand). `createTheme({ primary: \"#7c3aed\" })`\n * emits the same thing, derived in OKLCH so the ramp stays perceptually even.\n */\nimport {\n contrastRatio,\n createColorScale,\n hexToRgbaString,\n readableForeground,\n type ColorScale,\n type ScaleStep,\n} from \"./color\";\nimport { buildDivergingRamp, buildRamp, hueOf } from \"./data-viz-ramps\";\nimport { isDevBuild } from \"../utils/dev-mode\";\n\n/** Radius presets, applied to the whole `--tempest-radius-*` family at once. */\nexport type ThemeRadius = \"none\" | \"sm\" | \"md\" | \"lg\" | \"xl\" | \"full\";\n\n/** Status token families that {@link createTheme} can regenerate. */\nexport type ThemeStatus = \"success\" | \"warning\" | \"danger\" | \"info\";\n\n/** Input for {@link createTheme}. Every field is optional — omitted families keep the built-in tokens. */\nexport interface CreateThemeOptions {\n /** Brand color, used as the `500` step of the primary scale. */\n primary?: string;\n /** Neutral color, used as the `500` step of the gray scale (surfaces, borders, text). */\n gray?: string;\n /** Success color (`--tempest-success*`). */\n success?: string;\n /** Warning color (`--tempest-warning*`). */\n warning?: string;\n /** Danger color (`--tempest-danger*`). */\n danger?: string;\n /** Info color (`--tempest-info*`). */\n info?: string;\n /**\n * Categorical series colors for `tempest-react-sdk/charts`, in cycle order.\n * Written to `--tempest-chart-1` … `--tempest-chart-N`, so charts follow the\n * theme instead of a hardcoded palette.\n */\n chart?: string[];\n /** Corner radius scale. A preset name, or explicit per-step values. */\n radius?: ThemeRadius | Partial<Record<\"xs\" | \"sm\" | \"md\" | \"lg\" | \"xl\" | \"2xl\", string>>;\n /**\n * Opacity of `--tempest-focus-ring-color`. Omit it — the default ring is opaque.\n *\n * A translucent ring has no contrast of its own; it has the contrast of\n * whatever it composites over. Passing a value below `1` reintroduces the\n * failure 0.61.0 fixed in the built-in tokens, and logs a warning in a\n * development build. Kept because a translucent ring over a background you\n * control is a legitimate choice.\n */\n focusRingAlpha?: number;\n /** Selector the light tokens are written under. Default `\":root\"`. */\n selector?: string;\n /** Selector the dark tokens are written under. Default `'[data-tempest-theme=\"dark\"]'`. */\n darkSelector?: string;\n}\n\n/** A generated theme: token maps per color scheme, plus the CSS text that carries them. */\nexport interface GeneratedTheme {\n /** Light-scheme custom properties, without the leading `--`-less names (keys include `--`). */\n light: Record<string, string>;\n /** Dark-scheme custom properties. */\n dark: Record<string, string>;\n /** Both blocks rendered as CSS, ready for {@link applyTheme} or a stylesheet. */\n css: string;\n}\n\nconst RADIUS_PRESETS: Record<ThemeRadius, Record<string, string>> = {\n none: { xs: \"0\", sm: \"0\", md: \"0\", lg: \"0\", xl: \"0\", \"2xl\": \"0\" },\n sm: { xs: \"1px\", sm: \"2px\", md: \"4px\", lg: \"6px\", xl: \"8px\", \"2xl\": \"12px\" },\n md: { xs: \"2px\", sm: \"4px\", md: \"8px\", lg: \"12px\", xl: \"16px\", \"2xl\": \"24px\" },\n lg: { xs: \"4px\", sm: \"6px\", md: \"12px\", lg: \"16px\", xl: \"22px\", \"2xl\": \"32px\" },\n xl: { xs: \"6px\", sm: \"10px\", md: \"16px\", lg: \"24px\", xl: \"32px\", \"2xl\": \"44px\" },\n full: { xs: \"4px\", sm: \"8px\", md: \"9999px\", lg: \"9999px\", xl: \"9999px\", \"2xl\": \"9999px\" },\n};\n\nconst SCALE_STEPS: ScaleStep[] = [50, 100, 200, 300, 400, 500, 600, 700, 800, 900];\n\nfunction writeScale(tokens: Record<string, string>, name: string, scale: ColorScale): void {\n for (const step of SCALE_STEPS) {\n tokens[`--tempest-${name}-${step}`] = scale[step];\n }\n}\n\n/** Minimum contrast for body text, WCAG 2.x AA. */\nconst AA_TEXT_CONTRAST = 4.5;\n\n/**\n * Choose the ramp step for text sitting on the soft tint.\n *\n * A fixed step does not survive an arbitrary brand color: the built-in blue only\n * reaches 4.37:1 at `500` over its own `50` tint, and a generated emerald lands\n * at 4.41:1 at `600` — both fail AA for body text by a hair. So the step is\n * picked by measuring, walking away from the tint until it clears AA, and\n * falling back to the most extreme candidate when even that cannot (a very light\n * or very desaturated brand).\n *\n * @param scale - The generated ramp.\n * @param softStep - Step used as `--tempest-primary-soft`.\n * @param candidates - Steps to try, in order of preference.\n * @returns The first candidate clearing {@link AA_TEXT_CONTRAST}, else the last.\n */\nfunction pickOnSoftStep(\n scale: ColorScale,\n softStep: ScaleStep,\n candidates: ScaleStep[],\n): ScaleStep {\n for (const step of candidates) {\n if (contrastRatio(scale[softStep], scale[step]) >= AA_TEXT_CONTRAST) return step;\n }\n return candidates[candidates.length - 1];\n}\n\n/** Minimum contrast for a non-text indicator, WCAG 2.2 SC 1.4.11. */\nconst INDICATOR_CONTRAST = 3;\n\n/**\n * The four surfaces a focus ring can land on, as the SDK's own `colors.css`\n * paints them.\n *\n * Ported from `src/styles/colors.css` (`--tempest-bg`, `--tempest-surface`,\n * `--tempest-surface-2`, `--tempest-surface-3`, resolved through the gray ramp),\n * and pinned by a test that reads that file — a theme that only names `primary`\n * keeps these, so the ring has to be measured against them and not against a\n * guess. The light values resolve through `--tempest-gray-50/100/200`; the dark\n * ones are literals in the dark block.\n */\nconst SDK_SURFACES: Record<\"light\" | \"dark\", readonly string[]> = {\n light: [\"#ffffff\", \"#f8f9fb\", \"#f1f3f6\", \"#e4e7ec\"],\n dark: [\"#0b0d12\", \"#14171f\", \"#1d2230\", \"#262d3f\"],\n};\n\n/**\n * Ramp steps to try for the focus ring, in order.\n *\n * `500` first, because the ring should read as the brand when it can, then up\n * the ramp — which moves away from the surfaces in **both** schemes, because\n * `createColorScale` inverts the dark ramp: there `50` is the darkest step (it\n * is what `--tempest-bg` is made of) and `900` the lightest. Walking down in\n * dark mode looks like the right inversion and is the wrong direction; measured,\n * it left a near-black brand's ring at 1.04:1 over its own background.\n */\nconst FOCUS_RING_CANDIDATES: readonly ScaleStep[] = [500, 600, 700, 800, 900];\n\n/**\n * Choose the ramp step for the focus ring, by measuring it against the surfaces\n * it will actually be drawn on.\n *\n * A fixed step does not survive an arbitrary brand, and the measurement says so\n * loudly: of twelve brands checked against the four surfaces in both schemes —\n * 96 pairings — `500` opaque clears 3:1 in 58 of them, and `500` at the old\n * default alpha of 0.35 in 3. Picking the step by measurement clears all 96. The\n * brand from the report that opened this\n * (`#8100D7`) passes in light at 7.20:1 and fails in **dark** at 2.70:1 down to\n * 1.91:1 on `surface-3`; a yellow fails in light at 1.43:1. So the step is\n * picked the way {@link pickOnSoftStep} picks text on a tint: walk away from the\n * surfaces until the ring clears the floor against *all* of them.\n *\n * The fallback is the candidate with the best worst case rather than the last\n * one, because \"the most extreme step\" is not always the most contrasting one\n * once a brand is near-neutral.\n *\n * @param scale - The generated ramp.\n * @param surfaces - The four surfaces this theme will paint, opaque hex.\n * @returns The first candidate clearing {@link INDICATOR_CONTRAST} on every\n * surface, else the candidate whose weakest pairing is strongest.\n */\nfunction pickFocusRingStep(scale: ColorScale, surfaces: readonly string[]): ScaleStep {\n const worstCase = (step: ScaleStep): number =>\n Math.min(...surfaces.map((surface) => contrastRatio(scale[step], surface)));\n let best: ScaleStep = FOCUS_RING_CANDIDATES[0] as ScaleStep;\n let bestRatio = -1;\n for (const step of FOCUS_RING_CANDIDATES) {\n const measured = worstCase(step);\n if (measured >= INDICATOR_CONTRAST) return step;\n if (measured > bestRatio) {\n best = step;\n bestRatio = measured;\n }\n }\n return best;\n}\n\n/**\n * The surfaces this theme will actually paint, per scheme.\n *\n * A theme that names `gray` repaints all four, so measuring the ring against the\n * SDK's would be measuring the wrong backdrop — and a theme that does not keeps\n * the SDK's, which is the common case. The order and the ramp steps mirror\n * {@link writeNeutralAliases}, which is what emits them.\n *\n * @param scheme - Which scheme is being emitted.\n * @param grayScales - The generated neutral ramps, when the theme names one.\n * @returns Four opaque hex colors: bg, surface, surface-2, surface-3.\n */\nfunction surfacesOf(\n scheme: \"light\" | \"dark\",\n grayScales: { light: ColorScale; dark: ColorScale } | undefined,\n): readonly string[] {\n if (!grayScales) return SDK_SURFACES[scheme];\n const scale = grayScales[scheme];\n return scheme === \"light\"\n ? [\"#ffffff\", scale[50], scale[100], scale[200]]\n : [scale[50], scale[100], scale[200], scale[300]];\n}\n\n/**\n * Warn, in a development build, that an alpha was asked for the focus ring.\n *\n * A translucent ring has no contrast of its own — it has the contrast of\n * whatever it composites over — and that is the failure this option used to\n * ship by default: measured at alpha `0.35`, twelve brands across four surfaces\n * and both schemes produced 96 pairings, of which 3 cleared the 3:1 of WCAG 2.2\n * SC 1.4.11. It stays available, because a translucent ring over a\n * known background is a legitimate choice, but it is a choice a theme now has to\n * make on purpose.\n *\n * The warning is the difficult part to notice otherwise: a failing focus ring is\n * visible, it just does not separate.\n *\n * @param focusRingAlpha - The opacity the caller asked for, if any.\n */\nfunction warnOnTranslucentFocusRing(focusRingAlpha: number | undefined): void {\n if (focusRingAlpha === undefined || focusRingAlpha >= 1) return;\n if (!isDevBuild()) return;\n console.warn(\n `[tempest-react-sdk] createTheme({ focusRingAlpha: ${focusRingAlpha} }) makes the focus ring ` +\n \"translucent, so its contrast becomes whatever it composites over — measured below the 3:1 \" +\n \"of WCAG 2.2 SC 1.4.11 on every surface the SDK paints. Drop the option to get the opaque \" +\n \"ring, which is derived from your brand ramp and measured against those surfaces.\",\n );\n}\n\n/**\n * The dark ink for content sitting on a saturated fill.\n *\n * Near-black tinted toward warm rather than pure black, matching the value\n * `colors.css` uses for the same job: it reads as part of the swatch instead of\n * a hole punched in it.\n */\nconst ON_SOLID_INK = \"#1f0606\";\n\n/**\n * Emit the primary aliases for one scheme.\n *\n * The dark scheme walks the ramp the other way (hover is *lighter*, the soft\n * tint is a dark shade, and readable text on that tint is a light shade) — the\n * same inversion the built-in `colors.css` dark block does by hand.\n *\n * @param tokens - The token map for this scheme, written in place.\n * @param scale - The generated primary ramp.\n * @param scheme - Which scheme is being emitted.\n * @param surfaces - The surfaces this theme paints, for the focus-ring measurement.\n * @param focusRingAlpha - Opacity asked for the ring, or `undefined` for opaque.\n */\nfunction writePrimaryAliases(\n tokens: Record<string, string>,\n scale: ColorScale,\n scheme: \"light\" | \"dark\",\n surfaces: readonly string[],\n focusRingAlpha: number | undefined,\n): void {\n tokens[\"--tempest-primary\"] = \"var(--tempest-primary-500)\";\n if (scheme === \"light\") {\n tokens[\"--tempest-primary-hover\"] = \"var(--tempest-primary-600)\";\n tokens[\"--tempest-primary-active\"] = \"var(--tempest-primary-700)\";\n tokens[\"--tempest-primary-soft\"] = \"var(--tempest-primary-50)\";\n tokens[\"--tempest-primary-soft-hover\"] = \"var(--tempest-primary-100)\";\n tokens[\"--tempest-primary-on-soft\"] =\n `var(--tempest-primary-${pickOnSoftStep(scale, 50, [600, 700, 800, 900])})`;\n } else {\n tokens[\"--tempest-primary-hover\"] = \"var(--tempest-primary-400)\";\n tokens[\"--tempest-primary-active\"] = \"var(--tempest-primary-300)\";\n tokens[\"--tempest-primary-soft\"] = \"var(--tempest-primary-100)\";\n tokens[\"--tempest-primary-soft-hover\"] = \"var(--tempest-primary-200)\";\n tokens[\"--tempest-primary-on-soft\"] =\n `var(--tempest-primary-${pickOnSoftStep(scale, 100, [700, 800, 900])})`;\n }\n\n const foreground = readableForeground(scale[500]);\n tokens[\"--tempest-primary-foreground\"] = foreground;\n tokens[\"--tempest-text-on-primary\"] = foreground;\n const ring = scale[pickFocusRingStep(scale, surfaces)];\n tokens[\"--tempest-focus-ring-color\"] =\n focusRingAlpha === undefined || focusRingAlpha >= 1\n ? ring\n : hexToRgbaString(ring, focusRingAlpha);\n}\n\n/**\n * Emit the neutral surface/border/text aliases from a generated gray scale.\n *\n * `--tempest-bg` is pushed past the ramp on purpose: pure white in light mode and\n * a shade darker than `gray-50` in dark mode, so a raised surface still reads as\n * raised against the page.\n */\nfunction writeNeutralAliases(\n tokens: Record<string, string>,\n scale: ColorScale,\n scheme: \"light\" | \"dark\",\n): void {\n if (scheme === \"light\") {\n tokens[\"--tempest-bg\"] = \"#ffffff\";\n tokens[\"--tempest-surface\"] = \"var(--tempest-gray-50)\";\n tokens[\"--tempest-surface-2\"] = \"var(--tempest-gray-100)\";\n tokens[\"--tempest-surface-3\"] = \"var(--tempest-gray-200)\";\n tokens[\"--tempest-border\"] = \"var(--tempest-gray-200)\";\n tokens[\"--tempest-border-strong\"] = \"var(--tempest-gray-300)\";\n tokens[\"--tempest-text\"] = \"var(--tempest-gray-900)\";\n tokens[\"--tempest-text-muted\"] = \"var(--tempest-gray-600)\";\n tokens[\"--tempest-text-subtle\"] = \"var(--tempest-gray-500)\";\n } else {\n tokens[\"--tempest-bg\"] = scale[50];\n tokens[\"--tempest-surface\"] = \"var(--tempest-gray-100)\";\n tokens[\"--tempest-surface-2\"] = \"var(--tempest-gray-200)\";\n tokens[\"--tempest-surface-3\"] = \"var(--tempest-gray-300)\";\n tokens[\"--tempest-border\"] = \"var(--tempest-gray-300)\";\n tokens[\"--tempest-border-strong\"] = \"var(--tempest-gray-400)\";\n tokens[\"--tempest-text\"] = \"var(--tempest-gray-900)\";\n tokens[\"--tempest-text-muted\"] = \"var(--tempest-gray-700)\";\n tokens[\"--tempest-text-subtle\"] = \"var(--tempest-gray-600)\";\n }\n tokens[\"--tempest-neutral-on-solid\"] = readableForeground(scale[700], \"#ffffff\", ON_SOLID_INK);\n}\n\n/**\n * Emit one status family (`--tempest-danger`, `-fg`, `-bg`, `-border`, `-solid`).\n *\n * `-fg` is the text shade over `-bg`, so it has to cross the ramp in opposite\n * directions per scheme; `-solid` stays the saturated fill used by badges.\n *\n * `-on-solid` is derived from the `-solid` this call just emitted, rather than\n * left to fall through. Falling through was the bug: the SDK's own\n * `-on-solid` values are measured against the SDK's own fills, so a brand whose\n * `danger-600` lands light kept white ink over it and nothing said so. The\n * generated neutral hit exactly that — white over a generated `gray-700` of\n * `#a8b2c6` measures 2.13:1.\n */\nfunction writeStatus(\n tokens: Record<string, string>,\n name: ThemeStatus,\n scale: ColorScale,\n scheme: \"light\" | \"dark\",\n): void {\n if (scheme === \"light\") {\n tokens[`--tempest-${name}`] = scale[700];\n tokens[`--tempest-${name}-fg`] = scale[800];\n tokens[`--tempest-${name}-bg`] = scale[50];\n tokens[`--tempest-${name}-border`] = scale[200];\n tokens[`--tempest-${name}-solid`] = scale[600];\n tokens[`--tempest-${name}-on-solid`] = readableForeground(\n scale[600],\n \"#ffffff\",\n ON_SOLID_INK,\n );\n } else {\n tokens[`--tempest-${name}`] = scale[700];\n tokens[`--tempest-${name}-fg`] = scale[700];\n tokens[`--tempest-${name}-bg`] = scale[50];\n tokens[`--tempest-${name}-border`] = scale[200];\n tokens[`--tempest-${name}-solid`] = scale[500];\n tokens[`--tempest-${name}-on-solid`] = readableForeground(\n scale[500],\n \"#ffffff\",\n ON_SOLID_INK,\n );\n }\n}\n\nfunction renderBlock(selector: string, tokens: Record<string, string>): string {\n const entries = Object.entries(tokens);\n if (entries.length === 0) return \"\";\n const body = entries.map(([name, value]) => ` ${name}: ${value};`).join(\"\\n\");\n return `${selector} {\\n${body}\\n}`;\n}\n\n/**\n * Generate `--tempest-*` overrides from a small brand description.\n *\n * Only the families you pass are generated; everything else falls through to the\n * SDK's own tokens, so a theme stays a patch and not a fork of `colors.css`.\n *\n * @example\n * ```ts\n * import { applyTheme, createTheme } from \"tempest-react-sdk\";\n *\n * const theme = createTheme({\n * primary: \"#7c3aed\",\n * radius: \"lg\",\n * chart: [\"#7c3aed\", \"#0ea5e9\", \"#22c55e\", \"#f59e0b\"],\n * });\n *\n * applyTheme(theme);\n * ```\n *\n * @param options - Brand colors plus optional radius / chart / focus-ring tuning.\n * @returns The light and dark token maps and the CSS text that carries them.\n */\nexport function createTheme(options: CreateThemeOptions = {}): GeneratedTheme {\n const {\n primary,\n gray,\n chart,\n radius,\n focusRingAlpha,\n selector = \":root\",\n darkSelector = '[data-tempest-theme=\"dark\"]',\n } = options;\n\n warnOnTranslucentFocusRing(focusRingAlpha);\n\n const light: Record<string, string> = {};\n const dark: Record<string, string> = {};\n\n // `anchor: false`: a neutral ramp has to keep its tuned lightness curve.\n // Anchoring it at the input compressed both halves and dropped\n // text-muted-on-surface-3 to ~4.2:1 — below AA — which the browser axe\n // sweep caught on the generated themes.\n const grayScales = gray\n ? {\n light: createColorScale(gray, \"light\", { anchor: false, neutral: true }),\n dark: createColorScale(gray, \"dark\", { anchor: false, neutral: true }),\n }\n : undefined;\n\n if (primary) {\n const lightScale = createColorScale(primary, \"light\");\n const darkScale = createColorScale(primary, \"dark\");\n writeScale(light, \"primary\", lightScale);\n writeScale(dark, \"primary\", darkScale);\n writePrimaryAliases(\n light,\n lightScale,\n \"light\",\n surfacesOf(\"light\", grayScales),\n focusRingAlpha,\n );\n writePrimaryAliases(\n dark,\n darkScale,\n \"dark\",\n surfacesOf(\"dark\", grayScales),\n focusRingAlpha,\n );\n }\n\n if (grayScales) {\n writeScale(light, \"gray\", grayScales.light);\n writeScale(dark, \"gray\", grayScales.dark);\n writeNeutralAliases(light, grayScales.light, \"light\");\n writeNeutralAliases(dark, grayScales.dark, \"dark\");\n }\n\n for (const status of [\"success\", \"warning\", \"danger\", \"info\"] as const) {\n const value = options[status];\n if (!value) continue;\n writeStatus(light, status, createColorScale(value, \"light\"), \"light\");\n writeStatus(dark, status, createColorScale(value, \"dark\"), \"dark\");\n }\n\n if (chart?.length) {\n chart.forEach((color, index) => {\n light[`--tempest-chart-${index + 1}`] = color;\n });\n // Declares how many series colors this theme owns. Without it the reader\n // keeps walking into the SDK's built-in `--tempest-chart-7`/`-8`, so a\n // 6-color brand palette silently mixes with two leftover defaults — which\n // is exactly what a 7-series chart would show.\n light[\"--tempest-chart-count\"] = String(chart.length);\n }\n\n /*\n * Continuous scales follow the brand too.\n *\n * Without this a rebranded app gets its categorical slots recoloured and then a\n * heatmap still painted in the SDK's blue — the one chart on the page that\n * silently ignores the brand. Both scales derive from the first series hue (or\n * the primary), stepped by perceptual lightness for each mode separately.\n *\n * Skipped entirely when the theme names no colour to derive from, so the\n * built-in tokens survive instead of being overwritten with a guess.\n */\n const scaleSource = chart?.[0] ?? primary;\n if (scaleSource) {\n const coolHue = hueOf(scaleSource);\n // The opposite pole: the brand's own danger colour when it has one, since a\n // diverging scale's warm arm and \"bad\" should not disagree on screen.\n const warmHue = options.danger ? hueOf(options.danger) : (coolHue + 180) % 360;\n for (const [target, mode] of [\n [light, \"light\"],\n [dark, \"dark\"],\n ] as const) {\n buildRamp(coolHue, mode).forEach((stepColor, index) => {\n target[`--tempest-chart-sequential-${index + 1}`] = stepColor;\n });\n const diverging = buildDivergingRamp({\n coolHue,\n warmHue,\n mid: mode === \"light\" ? \"#e4e7ec\" : \"#262d3f\",\n mode,\n });\n [...diverging.cool, diverging.mid, ...diverging.warm].forEach((stepColor, index) => {\n target[`--tempest-chart-diverging-${index + 1}`] = stepColor;\n });\n }\n }\n\n if (radius) {\n const steps = typeof radius === \"string\" ? RADIUS_PRESETS[radius] : radius;\n for (const [step, value] of Object.entries(steps)) {\n light[`--tempest-radius-${step}`] = value;\n }\n }\n\n const css = [renderBlock(selector, light), renderBlock(darkSelector, dark)]\n .filter(Boolean)\n .join(\"\\n\\n\");\n\n return { light, dark, css };\n}\n\n/**\n * Contrast ratio of `--tempest-primary-foreground` over the brand color.\n *\n * Exposed so an app (or a test) can assert its own brand clears WCAG AA (4.5) for\n * body text or AA-large (3.0) for button labels, instead of trusting the pick.\n *\n * @param options - The same input given to {@link createTheme}.\n * @returns The ratio, or `null` when no `primary` was provided.\n */\nexport function themeContrast(options: CreateThemeOptions): number | null {\n if (!options.primary) return null;\n const scale = createColorScale(options.primary, \"light\");\n return contrastRatio(scale[500], readableForeground(scale[500]));\n}\n"],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ var e=/var\(\s*(--[A-Za-z0-9-]+)/g,t=/--tempest-[A-Za-z0-9-]*(?:\$\{|["'`]\s*\+|\s*\+\s*["'`])/;function n(e){let t=[];for(let n of e.matchAll(/([^{}]+)\{([^{}]*)\}/g)){let e=new Map;for(let t of(n[2]??``).split(`;`)){let n=t.indexOf(`:`);if(n<0)continue;let r=t.slice(0,n).trim();r&&e.set(r,t.slice(n+1).trim())}e.size!==0&&t.push({selector:(n[1]??``).trim(),declarations:e})}return t}function r(t,n){let r=new Set;for(let e of t)for(let t of e.declarations.keys())r.add(t);let i=new Set,a=[...n.matchAll(e)].map(e=>e[1]??``);for(;a.length>0;){let n=a.pop()??``;if(!i.has(n)&&r.has(n)){i.add(n);for(let r of t){let t=r.declarations.get(n);if(t!==void 0)for(let n of t.matchAll(e))a.push(n[1]??``)}}}return i}function i(e,i){if(t.test(i))return null;let a=n(e),o=r(a,i);if(o.size===0)return null;let s=[];for(let e of a){let t=[...e.declarations].filter(([e])=>e.startsWith(`--`)===!1||o.has(e));t.every(([e])=>e.startsWith(`--`)===!1)||s.push(`${e.selector}{${t.map(([e,t])=>`${e}:${t}`).join(`;`)}}`)}return s.join(`
2
+ `)}exports.narrowTokens=i,exports.parseTokenBlocks=n,exports.reachableTokens=r;
3
+ //# sourceMappingURL=narrow-tokens.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"narrow-tokens.cjs","names":[],"sources":["../../src/vite/narrow-tokens.ts"],"sourcesContent":["/**\n * Cut the token sheet down to the tokens a set of stylesheets can reach.\n *\n * Once every component loads its own stylesheet, `tokens.css` stops being a rounding\n * error and becomes the biggest single thing an app downloads: measured on a probe\n * app mounting `Button`, `Card` and `Badge`, the sheet is 2516 B brotli of a 4927 B\n * total. The components read 105 of its 223 tokens, so the other 118 are bytes\n * nothing on the page can consult.\n *\n * The cut is a reachability closure, not a filter: a token's value routinely names\n * another token (`--tempest-primary: var(--tempest-primary-500)`), so keeping only\n * the names a stylesheet mentions literally would keep aliases whose targets were\n * dropped — `var()` would resolve to nothing and the component would render with the\n * property unset, which is worse than shipping the whole sheet.\n */\n\n/** A token block: one selector and the custom properties it declares, in order. */\ninterface TokenBlock {\n /** The block's selector text, e.g. `:root` or `[data-tempest-theme=dark]`. */\n selector: string;\n /** Declaration name → value, in source order. */\n declarations: Map<string, string>;\n}\n\n/**\n * Any custom property being read, not only the `--tempest-*` ones.\n *\n * Deliberately wider than the tokens this cut is about. `tokens.css` also carries\n * the `--lightningcss-light`/`--lightningcss-dark` pair the compiler emits, which\n * nothing reads today — measured: two declarations, zero reads — and which a\n * `--tempest-`-only scan would therefore always drop. That is the right answer right\n * up until one rule uses `light-dark()`, at which point the compiler emits the read\n * and a narrow scan would drop the pair it depends on. Matching every custom\n * property costs nothing (a name the sheet does not declare is discarded) and makes\n * the closure correct for names this file does not know about.\n */\nconst TOKEN_REFERENCE = /var\\(\\s*(--[A-Za-z0-9-]+)/g;\n\n/**\n * A token name being assembled at runtime rather than written out.\n *\n * `style={{ color: `var(--tempest-${tone})` }}` names a token no static scan can\n * know, so a cut made without it would drop the one the app is about to read. The\n * caller falls back to the whole sheet when this matches — the same shape as the\n * plugin's own namespace-import fallback, and for the same reason: serve more than\n * asked for rather than less than needed.\n */\nconst DYNAMIC_TOKEN = /--tempest-[A-Za-z0-9-]*(?:\\$\\{|[\"'`]\\s*\\+|\\s*\\+\\s*[\"'`])/;\n\n/**\n * Parse a token stylesheet into its blocks.\n *\n * Written against the compiler's own output, which is already valid and flat — every\n * block in `tokens.css` is either a bare selector or one nested inside a single\n * at-rule — so a brace-depth reader is enough and a full parser would not be more\n * correct here.\n *\n * @param css - Contents of `tokens.css`.\n * @returns One entry per block that declares anything.\n */\nexport function parseTokenBlocks(css: string): TokenBlock[] {\n const blocks: TokenBlock[] = [];\n for (const match of css.matchAll(/([^{}]+)\\{([^{}]*)\\}/g)) {\n const declarations = new Map<string, string>();\n for (const declaration of (match[2] ?? \"\").split(\";\")) {\n const colon = declaration.indexOf(\":\");\n if (colon < 0) continue;\n const name = declaration.slice(0, colon).trim();\n if (name) declarations.set(name, declaration.slice(colon + 1).trim());\n }\n if (declarations.size === 0) continue;\n blocks.push({ selector: (match[1] ?? \"\").trim(), declarations });\n }\n return blocks;\n}\n\n/**\n * Every token a body of CSS reaches, following token-to-token references.\n *\n * @param blocks - The parsed token sheet.\n * @param usage - CSS and source text to scan for `var(--tempest-*)`.\n * @returns The reachable token names.\n */\nexport function reachableTokens(blocks: readonly TokenBlock[], usage: string): Set<string> {\n const declared = new Set<string>();\n for (const block of blocks) for (const name of block.declarations.keys()) declared.add(name);\n\n const reached = new Set<string>();\n const queue = [...usage.matchAll(TOKEN_REFERENCE)].map((match) => match[1] ?? \"\");\n while (queue.length > 0) {\n const token = queue.pop() ?? \"\";\n if (reached.has(token) || !declared.has(token)) continue;\n reached.add(token);\n for (const block of blocks) {\n const value = block.declarations.get(token);\n if (value === undefined) continue;\n for (const match of value.matchAll(TOKEN_REFERENCE)) queue.push(match[1] ?? \"\");\n }\n }\n return reached;\n}\n\n/**\n * Rebuild the token sheet with only the tokens a set of stylesheets reaches.\n *\n * Companion declarations that are not custom properties travel with the block that\n * survives — `color-scheme` is the one, and dropping it would leave the browser\n * painting its own surfaces (scrollbar, `<select>` popup, autofill) in the wrong\n * theme while every `.tempest_*` rule was correct.\n *\n * @param tokensCss - Contents of `tokens.css`.\n * @param usage - The CSS the app will load, plus its own source, scanned for reads.\n * @returns The narrowed sheet, or `null` when a token name is built at runtime and\n * no static answer is safe.\n */\nexport function narrowTokens(tokensCss: string, usage: string): string | null {\n if (DYNAMIC_TOKEN.test(usage)) return null;\n\n const blocks = parseTokenBlocks(tokensCss);\n const reached = reachableTokens(blocks, usage);\n if (reached.size === 0) return null;\n\n const out: string[] = [];\n for (const block of blocks) {\n const kept = [...block.declarations].filter(\n ([name]) => name.startsWith(\"--\") === false || reached.has(name),\n );\n if (kept.every(([name]) => name.startsWith(\"--\") === false)) continue;\n out.push(`${block.selector}{${kept.map(([name, value]) => `${name}:${value}`).join(\";\")}}`);\n }\n return out.join(\"\\n\");\n}\n"],"mappings":"AAoCA,IAAM,EAAkB,6BAWlB,EAAgB,2DAatB,SAAgB,EAAiB,EAA2B,CACxD,IAAM,EAAuB,CAAC,EAC9B,IAAK,IAAM,KAAS,EAAI,SAAS,uBAAuB,EAAG,CACvD,IAAM,EAAe,IAAI,IACzB,IAAK,IAAM,KAAgB,EAAM,IAAM,GAAA,CAAI,MAAM,GAAG,EAAG,CACnD,IAAM,EAAQ,EAAY,QAAQ,GAAG,EACrC,GAAI,EAAQ,EAAG,SACf,IAAM,EAAO,EAAY,MAAM,EAAG,CAAK,CAAC,CAAC,KAAK,EAC1C,GAAM,EAAa,IAAI,EAAM,EAAY,MAAM,EAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CACxE,CACI,EAAa,OAAS,GAC1B,EAAO,KAAK,CAAE,UAAW,EAAM,IAAM,GAAA,CAAI,KAAK,EAAG,cAAa,CAAC,CACnE,CACA,OAAO,CACX,CASA,SAAgB,EAAgB,EAA+B,EAA4B,CACvF,IAAM,EAAW,IAAI,IACrB,IAAK,IAAM,KAAS,EAAQ,IAAK,IAAM,KAAQ,EAAM,aAAa,KAAK,EAAG,EAAS,IAAI,CAAI,EAE3F,IAAM,EAAU,IAAI,IACd,EAAQ,CAAC,GAAG,EAAM,SAAS,CAAe,CAAC,CAAC,CAAC,IAAK,GAAU,EAAM,IAAM,EAAE,EAChF,KAAO,EAAM,OAAS,GAAG,CACrB,IAAM,EAAQ,EAAM,IAAI,GAAK,GACzB,MAAQ,IAAI,CAAK,GAAM,EAAS,IAAI,CAAK,EAC7C,GAAQ,IAAI,CAAK,EACjB,IAAK,IAAM,KAAS,EAAQ,CACxB,IAAM,EAAQ,EAAM,aAAa,IAAI,CAAK,EACtC,OAAU,IAAA,GACd,IAAK,IAAM,KAAS,EAAM,SAAS,CAAe,EAAG,EAAM,KAAK,EAAM,IAAM,EAAE,CAClF,CALiB,CAMrB,CACA,OAAO,CACX,CAeA,SAAgB,EAAa,EAAmB,EAA8B,CAC1E,GAAI,EAAc,KAAK,CAAK,EAAG,OAAO,KAEtC,IAAM,EAAS,EAAiB,CAAS,EACnC,EAAU,EAAgB,EAAQ,CAAK,EAC7C,GAAI,EAAQ,OAAS,EAAG,OAAO,KAE/B,IAAM,EAAgB,CAAC,EACvB,IAAK,IAAM,KAAS,EAAQ,CACxB,IAAM,EAAO,CAAC,GAAG,EAAM,YAAY,CAAC,CAAC,QAChC,CAAC,KAAU,EAAK,WAAW,IAAI,IAAM,IAAS,EAAQ,IAAI,CAAI,CACnE,EACI,EAAK,OAAO,CAAC,KAAU,EAAK,WAAW,IAAI,IAAM,EAAK,GAC1D,EAAI,KAAK,GAAG,EAAM,SAAS,GAAG,EAAK,KAAK,CAAC,EAAM,KAAW,GAAG,EAAK,GAAG,GAAO,CAAC,CAAC,KAAK,GAAG,EAAE,EAAE,CAC9F,CACA,OAAO,EAAI,KAAK;CAAI,CACxB"}
@@ -0,0 +1,50 @@
1
+ //#region src/vite/narrow-tokens.ts
2
+ var e = /var\(\s*(--[A-Za-z0-9-]+)/g, t = /--tempest-[A-Za-z0-9-]*(?:\$\{|["'`]\s*\+|\s*\+\s*["'`])/;
3
+ function n(e) {
4
+ let t = [];
5
+ for (let n of e.matchAll(/([^{}]+)\{([^{}]*)\}/g)) {
6
+ let e = /* @__PURE__ */ new Map();
7
+ for (let t of (n[2] ?? "").split(";")) {
8
+ let n = t.indexOf(":");
9
+ if (n < 0) continue;
10
+ let r = t.slice(0, n).trim();
11
+ r && e.set(r, t.slice(n + 1).trim());
12
+ }
13
+ e.size !== 0 && t.push({
14
+ selector: (n[1] ?? "").trim(),
15
+ declarations: e
16
+ });
17
+ }
18
+ return t;
19
+ }
20
+ function r(t, n) {
21
+ let r = /* @__PURE__ */ new Set();
22
+ for (let e of t) for (let t of e.declarations.keys()) r.add(t);
23
+ let i = /* @__PURE__ */ new Set(), a = [...n.matchAll(e)].map((e) => e[1] ?? "");
24
+ for (; a.length > 0;) {
25
+ let n = a.pop() ?? "";
26
+ if (!i.has(n) && r.has(n)) {
27
+ i.add(n);
28
+ for (let r of t) {
29
+ let t = r.declarations.get(n);
30
+ if (t !== void 0) for (let n of t.matchAll(e)) a.push(n[1] ?? "");
31
+ }
32
+ }
33
+ }
34
+ return i;
35
+ }
36
+ function i(e, i) {
37
+ if (t.test(i)) return null;
38
+ let a = n(e), o = r(a, i);
39
+ if (o.size === 0) return null;
40
+ let s = [];
41
+ for (let e of a) {
42
+ let t = [...e.declarations].filter(([e]) => e.startsWith("--") === !1 || o.has(e));
43
+ t.every(([e]) => e.startsWith("--") === !1) || s.push(`${e.selector}{${t.map(([e, t]) => `${e}:${t}`).join(";")}}`);
44
+ }
45
+ return s.join("\n");
46
+ }
47
+ //#endregion
48
+ export { i as narrowTokens, n as parseTokenBlocks, r as reachableTokens };
49
+
50
+ //# sourceMappingURL=narrow-tokens.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"narrow-tokens.js","names":[],"sources":["../../src/vite/narrow-tokens.ts"],"sourcesContent":["/**\n * Cut the token sheet down to the tokens a set of stylesheets can reach.\n *\n * Once every component loads its own stylesheet, `tokens.css` stops being a rounding\n * error and becomes the biggest single thing an app downloads: measured on a probe\n * app mounting `Button`, `Card` and `Badge`, the sheet is 2516 B brotli of a 4927 B\n * total. The components read 105 of its 223 tokens, so the other 118 are bytes\n * nothing on the page can consult.\n *\n * The cut is a reachability closure, not a filter: a token's value routinely names\n * another token (`--tempest-primary: var(--tempest-primary-500)`), so keeping only\n * the names a stylesheet mentions literally would keep aliases whose targets were\n * dropped — `var()` would resolve to nothing and the component would render with the\n * property unset, which is worse than shipping the whole sheet.\n */\n\n/** A token block: one selector and the custom properties it declares, in order. */\ninterface TokenBlock {\n /** The block's selector text, e.g. `:root` or `[data-tempest-theme=dark]`. */\n selector: string;\n /** Declaration name → value, in source order. */\n declarations: Map<string, string>;\n}\n\n/**\n * Any custom property being read, not only the `--tempest-*` ones.\n *\n * Deliberately wider than the tokens this cut is about. `tokens.css` also carries\n * the `--lightningcss-light`/`--lightningcss-dark` pair the compiler emits, which\n * nothing reads today — measured: two declarations, zero reads — and which a\n * `--tempest-`-only scan would therefore always drop. That is the right answer right\n * up until one rule uses `light-dark()`, at which point the compiler emits the read\n * and a narrow scan would drop the pair it depends on. Matching every custom\n * property costs nothing (a name the sheet does not declare is discarded) and makes\n * the closure correct for names this file does not know about.\n */\nconst TOKEN_REFERENCE = /var\\(\\s*(--[A-Za-z0-9-]+)/g;\n\n/**\n * A token name being assembled at runtime rather than written out.\n *\n * `style={{ color: `var(--tempest-${tone})` }}` names a token no static scan can\n * know, so a cut made without it would drop the one the app is about to read. The\n * caller falls back to the whole sheet when this matches — the same shape as the\n * plugin's own namespace-import fallback, and for the same reason: serve more than\n * asked for rather than less than needed.\n */\nconst DYNAMIC_TOKEN = /--tempest-[A-Za-z0-9-]*(?:\\$\\{|[\"'`]\\s*\\+|\\s*\\+\\s*[\"'`])/;\n\n/**\n * Parse a token stylesheet into its blocks.\n *\n * Written against the compiler's own output, which is already valid and flat — every\n * block in `tokens.css` is either a bare selector or one nested inside a single\n * at-rule — so a brace-depth reader is enough and a full parser would not be more\n * correct here.\n *\n * @param css - Contents of `tokens.css`.\n * @returns One entry per block that declares anything.\n */\nexport function parseTokenBlocks(css: string): TokenBlock[] {\n const blocks: TokenBlock[] = [];\n for (const match of css.matchAll(/([^{}]+)\\{([^{}]*)\\}/g)) {\n const declarations = new Map<string, string>();\n for (const declaration of (match[2] ?? \"\").split(\";\")) {\n const colon = declaration.indexOf(\":\");\n if (colon < 0) continue;\n const name = declaration.slice(0, colon).trim();\n if (name) declarations.set(name, declaration.slice(colon + 1).trim());\n }\n if (declarations.size === 0) continue;\n blocks.push({ selector: (match[1] ?? \"\").trim(), declarations });\n }\n return blocks;\n}\n\n/**\n * Every token a body of CSS reaches, following token-to-token references.\n *\n * @param blocks - The parsed token sheet.\n * @param usage - CSS and source text to scan for `var(--tempest-*)`.\n * @returns The reachable token names.\n */\nexport function reachableTokens(blocks: readonly TokenBlock[], usage: string): Set<string> {\n const declared = new Set<string>();\n for (const block of blocks) for (const name of block.declarations.keys()) declared.add(name);\n\n const reached = new Set<string>();\n const queue = [...usage.matchAll(TOKEN_REFERENCE)].map((match) => match[1] ?? \"\");\n while (queue.length > 0) {\n const token = queue.pop() ?? \"\";\n if (reached.has(token) || !declared.has(token)) continue;\n reached.add(token);\n for (const block of blocks) {\n const value = block.declarations.get(token);\n if (value === undefined) continue;\n for (const match of value.matchAll(TOKEN_REFERENCE)) queue.push(match[1] ?? \"\");\n }\n }\n return reached;\n}\n\n/**\n * Rebuild the token sheet with only the tokens a set of stylesheets reaches.\n *\n * Companion declarations that are not custom properties travel with the block that\n * survives — `color-scheme` is the one, and dropping it would leave the browser\n * painting its own surfaces (scrollbar, `<select>` popup, autofill) in the wrong\n * theme while every `.tempest_*` rule was correct.\n *\n * @param tokensCss - Contents of `tokens.css`.\n * @param usage - The CSS the app will load, plus its own source, scanned for reads.\n * @returns The narrowed sheet, or `null` when a token name is built at runtime and\n * no static answer is safe.\n */\nexport function narrowTokens(tokensCss: string, usage: string): string | null {\n if (DYNAMIC_TOKEN.test(usage)) return null;\n\n const blocks = parseTokenBlocks(tokensCss);\n const reached = reachableTokens(blocks, usage);\n if (reached.size === 0) return null;\n\n const out: string[] = [];\n for (const block of blocks) {\n const kept = [...block.declarations].filter(\n ([name]) => name.startsWith(\"--\") === false || reached.has(name),\n );\n if (kept.every(([name]) => name.startsWith(\"--\") === false)) continue;\n out.push(`${block.selector}{${kept.map(([name, value]) => `${name}:${value}`).join(\";\")}}`);\n }\n return out.join(\"\\n\");\n}\n"],"mappings":";AAoCA,IAAM,IAAkB,8BAWlB,IAAgB;AAatB,SAAgB,EAAiB,GAA2B;CACxD,IAAM,IAAuB,CAAC;CAC9B,KAAK,IAAM,KAAS,EAAI,SAAS,uBAAuB,GAAG;EACvD,IAAM,oBAAe,IAAI,IAAoB;EAC7C,KAAK,IAAM,MAAgB,EAAM,MAAM,GAAA,CAAI,MAAM,GAAG,GAAG;GACnD,IAAM,IAAQ,EAAY,QAAQ,GAAG;GACrC,IAAI,IAAQ,GAAG;GACf,IAAM,IAAO,EAAY,MAAM,GAAG,CAAK,CAAC,CAAC,KAAK;GAC9C,AAAI,KAAM,EAAa,IAAI,GAAM,EAAY,MAAM,IAAQ,CAAC,CAAC,CAAC,KAAK,CAAC;EACxE;EACI,EAAa,SAAS,KAC1B,EAAO,KAAK;GAAE,WAAW,EAAM,MAAM,GAAA,CAAI,KAAK;GAAG;EAAa,CAAC;CACnE;CACA,OAAO;AACX;AASA,SAAgB,EAAgB,GAA+B,GAA4B;CACvF,IAAM,oBAAW,IAAI,IAAY;CACjC,KAAK,IAAM,KAAS,GAAQ,KAAK,IAAM,KAAQ,EAAM,aAAa,KAAK,GAAG,EAAS,IAAI,CAAI;CAE3F,IAAM,oBAAU,IAAI,IAAY,GAC1B,IAAQ,CAAC,GAAG,EAAM,SAAS,CAAe,CAAC,CAAC,CAAC,KAAK,MAAU,EAAM,MAAM,EAAE;CAChF,OAAO,EAAM,SAAS,IAAG;EACrB,IAAM,IAAQ,EAAM,IAAI,KAAK;EACzB,OAAQ,IAAI,CAAK,KAAM,EAAS,IAAI,CAAK,GAC7C;KAAQ,IAAI,CAAK;GACjB,KAAK,IAAM,KAAS,GAAQ;IACxB,IAAM,IAAQ,EAAM,aAAa,IAAI,CAAK;IACtC,UAAU,KAAA,GACd,KAAK,IAAM,KAAS,EAAM,SAAS,CAAe,GAAG,EAAM,KAAK,EAAM,MAAM,EAAE;GAClF;EALiB;CAMrB;CACA,OAAO;AACX;AAeA,SAAgB,EAAa,GAAmB,GAA8B;CAC1E,IAAI,EAAc,KAAK,CAAK,GAAG,OAAO;CAEtC,IAAM,IAAS,EAAiB,CAAS,GACnC,IAAU,EAAgB,GAAQ,CAAK;CAC7C,IAAI,EAAQ,SAAS,GAAG,OAAO;CAE/B,IAAM,IAAgB,CAAC;CACvB,KAAK,IAAM,KAAS,GAAQ;EACxB,IAAM,IAAO,CAAC,GAAG,EAAM,YAAY,CAAC,CAAC,QAChC,CAAC,OAAU,EAAK,WAAW,IAAI,MAAM,MAAS,EAAQ,IAAI,CAAI,CACnE;EACI,EAAK,OAAO,CAAC,OAAU,EAAK,WAAW,IAAI,MAAM,EAAK,KAC1D,EAAI,KAAK,GAAG,EAAM,SAAS,GAAG,EAAK,KAAK,CAAC,GAAM,OAAW,GAAG,EAAK,GAAG,GAAO,CAAC,CAAC,KAAK,GAAG,EAAE,EAAE;CAC9F;CACA,OAAO,EAAI,KAAK,IAAI;AACxB"}