@skdx/docs-kit 0.35.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 (505) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +22 -0
  3. package/dist/component-aliases.json +12 -0
  4. package/dist/data/THIRD-PARTY-NOTICES.md +21 -0
  5. package/dist/data/angular-inputs.json +1 -0
  6. package/dist/data/api-manifest.json +1 -0
  7. package/dist/data/exports-by-framework.json +1 -0
  8. package/dist/data/honoured-slots.json +1 -0
  9. package/dist/data/styling-hooks-manifest.json +10331 -0
  10. package/dist/frameworks.mjs +64 -0
  11. package/dist/shared/contracts/accordion.d.ts +3 -0
  12. package/dist/shared/contracts/accordion.js +1 -0
  13. package/dist/shared/contracts/alert.d.ts +3 -0
  14. package/dist/shared/contracts/alert.js +1 -0
  15. package/dist/shared/contracts/angle-slider.d.ts +3 -0
  16. package/dist/shared/contracts/angle-slider.js +1 -0
  17. package/dist/shared/contracts/aspect-ratio.d.ts +3 -0
  18. package/dist/shared/contracts/aspect-ratio.js +1 -0
  19. package/dist/shared/contracts/autocomplete.d.ts +3 -0
  20. package/dist/shared/contracts/autocomplete.js +1 -0
  21. package/dist/shared/contracts/avatar.d.ts +3 -0
  22. package/dist/shared/contracts/avatar.js +1 -0
  23. package/dist/shared/contracts/badge.d.ts +3 -0
  24. package/dist/shared/contracts/badge.js +1 -0
  25. package/dist/shared/contracts/box.d.ts +3 -0
  26. package/dist/shared/contracts/box.js +1 -0
  27. package/dist/shared/contracts/breadcrumb.d.ts +3 -0
  28. package/dist/shared/contracts/breadcrumb.js +1 -0
  29. package/dist/shared/contracts/button.d.ts +3 -0
  30. package/dist/shared/contracts/button.js +1 -0
  31. package/dist/shared/contracts/calendar.d.ts +5 -0
  32. package/dist/shared/contracts/calendar.js +1 -0
  33. package/dist/shared/contracts/card.d.ts +3 -0
  34. package/dist/shared/contracts/card.js +1 -0
  35. package/dist/shared/contracts/carousel.d.ts +3 -0
  36. package/dist/shared/contracts/carousel.js +1 -0
  37. package/dist/shared/contracts/change-reason.d.ts +29 -0
  38. package/dist/shared/contracts/change-reason.js +1 -0
  39. package/dist/shared/contracts/chat-composer.d.ts +3 -0
  40. package/dist/shared/contracts/chat-composer.js +1 -0
  41. package/dist/shared/contracts/chat-message.d.ts +3 -0
  42. package/dist/shared/contracts/chat-message.js +1 -0
  43. package/dist/shared/contracts/checkbox-card.d.ts +3 -0
  44. package/dist/shared/contracts/checkbox-card.js +1 -0
  45. package/dist/shared/contracts/checkbox-group.d.ts +3 -0
  46. package/dist/shared/contracts/checkbox-group.js +1 -0
  47. package/dist/shared/contracts/checkbox.d.ts +3 -0
  48. package/dist/shared/contracts/checkbox.js +1 -0
  49. package/dist/shared/contracts/clipboard.d.ts +3 -0
  50. package/dist/shared/contracts/clipboard.js +1 -0
  51. package/dist/shared/contracts/collapsible.d.ts +3 -0
  52. package/dist/shared/contracts/collapsible.js +1 -0
  53. package/dist/shared/contracts/color-picker.d.ts +3 -0
  54. package/dist/shared/contracts/color-picker.js +1 -0
  55. package/dist/shared/contracts/combobox.d.ts +3 -0
  56. package/dist/shared/contracts/combobox.js +1 -0
  57. package/dist/shared/contracts/command.d.ts +3 -0
  58. package/dist/shared/contracts/command.js +1 -0
  59. package/dist/shared/contracts/comment-thread.d.ts +3 -0
  60. package/dist/shared/contracts/comment-thread.js +1 -0
  61. package/dist/shared/contracts/comment.d.ts +3 -0
  62. package/dist/shared/contracts/comment.js +1 -0
  63. package/dist/shared/contracts/confirm-dialog.d.ts +3 -0
  64. package/dist/shared/contracts/confirm-dialog.js +1 -0
  65. package/dist/shared/contracts/conversation-list.d.ts +3 -0
  66. package/dist/shared/contracts/conversation-list.js +1 -0
  67. package/dist/shared/contracts/dashboard-layout.d.ts +3 -0
  68. package/dist/shared/contracts/dashboard-layout.js +1 -0
  69. package/dist/shared/contracts/date-field.d.ts +3 -0
  70. package/dist/shared/contracts/date-field.js +1 -0
  71. package/dist/shared/contracts/date-picker.d.ts +3 -0
  72. package/dist/shared/contracts/date-picker.js +1 -0
  73. package/dist/shared/contracts/date-value.d.ts +11 -0
  74. package/dist/shared/contracts/date-value.js +1 -0
  75. package/dist/shared/contracts/dialog.d.ts +3 -0
  76. package/dist/shared/contracts/dialog.js +1 -0
  77. package/dist/shared/contracts/divider.d.ts +5 -0
  78. package/dist/shared/contracts/divider.js +1 -0
  79. package/dist/shared/contracts/drawer.d.ts +3 -0
  80. package/dist/shared/contracts/drawer.js +1 -0
  81. package/dist/shared/contracts/editable.d.ts +3 -0
  82. package/dist/shared/contracts/editable.js +1 -0
  83. package/dist/shared/contracts/empty-state.d.ts +3 -0
  84. package/dist/shared/contracts/empty-state.js +1 -0
  85. package/dist/shared/contracts/field.d.ts +3 -0
  86. package/dist/shared/contracts/field.js +1 -0
  87. package/dist/shared/contracts/file-upload.d.ts +3 -0
  88. package/dist/shared/contracts/file-upload.js +1 -0
  89. package/dist/shared/contracts/filter-bar.d.ts +3 -0
  90. package/dist/shared/contracts/filter-bar.js +1 -0
  91. package/dist/shared/contracts/floating-panel.d.ts +3 -0
  92. package/dist/shared/contracts/floating-panel.js +1 -0
  93. package/dist/shared/contracts/forgot-password-page.d.ts +3 -0
  94. package/dist/shared/contracts/forgot-password-page.js +1 -0
  95. package/dist/shared/contracts/form-property.d.ts +3 -0
  96. package/dist/shared/contracts/form-property.js +1 -0
  97. package/dist/shared/contracts/form-section.d.ts +3 -0
  98. package/dist/shared/contracts/form-section.js +1 -0
  99. package/dist/shared/contracts/form-validity.d.ts +7 -0
  100. package/dist/shared/contracts/form-validity.js +1 -0
  101. package/dist/shared/contracts/form.d.ts +3 -0
  102. package/dist/shared/contracts/form.js +1 -0
  103. package/dist/shared/contracts/heading.d.ts +3 -0
  104. package/dist/shared/contracts/heading.js +1 -0
  105. package/dist/shared/contracts/image.d.ts +3 -0
  106. package/dist/shared/contracts/image.js +1 -0
  107. package/dist/shared/contracts/index.d.ts +8 -0
  108. package/dist/shared/contracts/index.js +1 -0
  109. package/dist/shared/contracts/kbd.d.ts +3 -0
  110. package/dist/shared/contracts/kbd.js +1 -0
  111. package/dist/shared/contracts/label.d.ts +3 -0
  112. package/dist/shared/contracts/label.js +1 -0
  113. package/dist/shared/contracts/link.d.ts +3 -0
  114. package/dist/shared/contracts/link.js +1 -0
  115. package/dist/shared/contracts/list.d.ts +3 -0
  116. package/dist/shared/contracts/list.js +1 -0
  117. package/dist/shared/contracts/listbox.d.ts +3 -0
  118. package/dist/shared/contracts/listbox.js +1 -0
  119. package/dist/shared/contracts/loading-overlay.d.ts +3 -0
  120. package/dist/shared/contracts/loading-overlay.js +1 -0
  121. package/dist/shared/contracts/member-id.d.ts +18 -0
  122. package/dist/shared/contracts/member-id.js +1 -0
  123. package/dist/shared/contracts/mentions.d.ts +3 -0
  124. package/dist/shared/contracts/mentions.js +1 -0
  125. package/dist/shared/contracts/menu.d.ts +3 -0
  126. package/dist/shared/contracts/menu.js +1 -0
  127. package/dist/shared/contracts/menubar.d.ts +3 -0
  128. package/dist/shared/contracts/menubar.js +1 -0
  129. package/dist/shared/contracts/navigation-menu.d.ts +6 -0
  130. package/dist/shared/contracts/navigation-menu.js +1 -0
  131. package/dist/shared/contracts/notification-center.d.ts +3 -0
  132. package/dist/shared/contracts/notification-center.js +1 -0
  133. package/dist/shared/contracts/number-field.d.ts +5 -0
  134. package/dist/shared/contracts/number-field.js +1 -0
  135. package/dist/shared/contracts/onboarding-checklist.d.ts +3 -0
  136. package/dist/shared/contracts/onboarding-checklist.js +1 -0
  137. package/dist/shared/contracts/overlay-parts.d.ts +73 -0
  138. package/dist/shared/contracts/overlay-parts.js +1 -0
  139. package/dist/shared/contracts/page-container.d.ts +3 -0
  140. package/dist/shared/contracts/page-container.js +1 -0
  141. package/dist/shared/contracts/pagination.d.ts +5 -0
  142. package/dist/shared/contracts/pagination.js +1 -0
  143. package/dist/shared/contracts/password-input.d.ts +6 -0
  144. package/dist/shared/contracts/password-input.js +1 -0
  145. package/dist/shared/contracts/pin-input.d.ts +6 -0
  146. package/dist/shared/contracts/pin-input.js +1 -0
  147. package/dist/shared/contracts/polymorphic.d.ts +6 -0
  148. package/dist/shared/contracts/polymorphic.js +1 -0
  149. package/dist/shared/contracts/popover.d.ts +7 -0
  150. package/dist/shared/contracts/popover.js +1 -0
  151. package/dist/shared/contracts/progress.d.ts +6 -0
  152. package/dist/shared/contracts/progress.js +1 -0
  153. package/dist/shared/contracts/qr-code.d.ts +5 -0
  154. package/dist/shared/contracts/qr-code.js +1 -0
  155. package/dist/shared/contracts/radio-card.d.ts +6 -0
  156. package/dist/shared/contracts/radio-card.js +1 -0
  157. package/dist/shared/contracts/radio-group.d.ts +6 -0
  158. package/dist/shared/contracts/radio-group.js +1 -0
  159. package/dist/shared/contracts/rating.d.ts +6 -0
  160. package/dist/shared/contracts/rating.js +1 -0
  161. package/dist/shared/contracts/reset-password-page.d.ts +3 -0
  162. package/dist/shared/contracts/reset-password-page.js +1 -0
  163. package/dist/shared/contracts/resizable.d.ts +7 -0
  164. package/dist/shared/contracts/resizable.js +1 -0
  165. package/dist/shared/contracts/rules.d.ts +11 -0
  166. package/dist/shared/contracts/rules.js +1 -0
  167. package/dist/shared/contracts/scroll-area.d.ts +6 -0
  168. package/dist/shared/contracts/scroll-area.js +1 -0
  169. package/dist/shared/contracts/select.d.ts +5 -0
  170. package/dist/shared/contracts/select.js +1 -0
  171. package/dist/shared/contracts/selection-value.d.ts +20 -0
  172. package/dist/shared/contracts/selection-value.js +1 -0
  173. package/dist/shared/contracts/sign-in-page.d.ts +3 -0
  174. package/dist/shared/contracts/sign-in-page.js +1 -0
  175. package/dist/shared/contracts/sign-up-page.d.ts +3 -0
  176. package/dist/shared/contracts/sign-up-page.js +1 -0
  177. package/dist/shared/contracts/skeleton.d.ts +5 -0
  178. package/dist/shared/contracts/skeleton.js +1 -0
  179. package/dist/shared/contracts/slider.d.ts +7 -0
  180. package/dist/shared/contracts/slider.js +1 -0
  181. package/dist/shared/contracts/speed-dial.d.ts +6 -0
  182. package/dist/shared/contracts/speed-dial.js +1 -0
  183. package/dist/shared/contracts/spinner.d.ts +6 -0
  184. package/dist/shared/contracts/spinner.js +1 -0
  185. package/dist/shared/contracts/split-button.d.ts +6 -0
  186. package/dist/shared/contracts/split-button.js +1 -0
  187. package/dist/shared/contracts/stat-card.d.ts +3 -0
  188. package/dist/shared/contracts/stat-card.js +1 -0
  189. package/dist/shared/contracts/stepper.d.ts +6 -0
  190. package/dist/shared/contracts/stepper.js +1 -0
  191. package/dist/shared/contracts/styling-hooks.d.ts +8 -0
  192. package/dist/shared/contracts/styling-hooks.js +1 -0
  193. package/dist/shared/contracts/switch.d.ts +6 -0
  194. package/dist/shared/contracts/switch.js +1 -0
  195. package/dist/shared/contracts/table.d.ts +7 -0
  196. package/dist/shared/contracts/table.js +1 -0
  197. package/dist/shared/contracts/tabs.d.ts +5 -0
  198. package/dist/shared/contracts/tabs.js +1 -0
  199. package/dist/shared/contracts/tag-group.d.ts +7 -0
  200. package/dist/shared/contracts/tag-group.js +1 -0
  201. package/dist/shared/contracts/tags-input.d.ts +8 -0
  202. package/dist/shared/contracts/tags-input.js +1 -0
  203. package/dist/shared/contracts/text-field.d.ts +6 -0
  204. package/dist/shared/contracts/text-field.js +1 -0
  205. package/dist/shared/contracts/text.d.ts +6 -0
  206. package/dist/shared/contracts/text.js +1 -0
  207. package/dist/shared/contracts/textarea.d.ts +5 -0
  208. package/dist/shared/contracts/textarea.js +1 -0
  209. package/dist/shared/contracts/time-field.d.ts +5 -0
  210. package/dist/shared/contracts/time-field.js +1 -0
  211. package/dist/shared/contracts/time.d.ts +6 -0
  212. package/dist/shared/contracts/time.js +1 -0
  213. package/dist/shared/contracts/timeline.d.ts +5 -0
  214. package/dist/shared/contracts/timeline.js +1 -0
  215. package/dist/shared/contracts/toast.d.ts +6 -0
  216. package/dist/shared/contracts/toast.js +1 -0
  217. package/dist/shared/contracts/toggle-group.d.ts +6 -0
  218. package/dist/shared/contracts/toggle-group.js +1 -0
  219. package/dist/shared/contracts/toggle.d.ts +5 -0
  220. package/dist/shared/contracts/toggle.js +1 -0
  221. package/dist/shared/contracts/toolbar.d.ts +3 -0
  222. package/dist/shared/contracts/toolbar.js +1 -0
  223. package/dist/shared/contracts/tour.d.ts +5 -0
  224. package/dist/shared/contracts/tour.js +1 -0
  225. package/dist/shared/contracts/transfer.d.ts +6 -0
  226. package/dist/shared/contracts/transfer.js +1 -0
  227. package/dist/shared/contracts/tree-select.d.ts +6 -0
  228. package/dist/shared/contracts/tree-select.js +1 -0
  229. package/dist/shared/contracts/tree.d.ts +6 -0
  230. package/dist/shared/contracts/tree.js +1 -0
  231. package/dist/shared/contracts/types.d.ts +230 -0
  232. package/dist/shared/contracts/types.js +1 -0
  233. package/dist/shared/contracts/usage-card.d.ts +3 -0
  234. package/dist/shared/contracts/usage-card.js +1 -0
  235. package/dist/shared/contracts/user-menu.d.ts +3 -0
  236. package/dist/shared/contracts/user-menu.js +1 -0
  237. package/dist/shared/contracts/verification-page.d.ts +3 -0
  238. package/dist/shared/contracts/verification-page.js +1 -0
  239. package/dist/shared/contracts/workspace-switcher.d.ts +3 -0
  240. package/dist/shared/contracts/workspace-switcher.js +1 -0
  241. package/dist/shared/core/announcer.d.ts +17 -0
  242. package/dist/shared/core/announcer.js +1 -0
  243. package/dist/shared/core/appearance.d.ts +14 -0
  244. package/dist/shared/core/appearance.js +1 -0
  245. package/dist/shared/core/arrow-keys.d.ts +7 -0
  246. package/dist/shared/core/arrow-keys.js +1 -0
  247. package/dist/shared/core/calendar-locale.d.ts +35 -0
  248. package/dist/shared/core/calendar-locale.js +1 -0
  249. package/dist/shared/core/color.d.ts +80 -0
  250. package/dist/shared/core/color.js +1 -0
  251. package/dist/shared/core/controllable.d.ts +42 -0
  252. package/dist/shared/core/controllable.js +1 -0
  253. package/dist/shared/core/csv.d.ts +43 -0
  254. package/dist/shared/core/csv.js +2 -0
  255. package/dist/shared/core/date-segments.d.ts +223 -0
  256. package/dist/shared/core/date-segments.js +1 -0
  257. package/dist/shared/core/date-value.d.ts +57 -0
  258. package/dist/shared/core/date-value.js +1 -0
  259. package/dist/shared/core/dev-mode.d.ts +12 -0
  260. package/dist/shared/core/dev-mode.js +1 -0
  261. package/dist/shared/core/dialogs.d.ts +96 -0
  262. package/dist/shared/core/dialogs.js +1 -0
  263. package/dist/shared/core/dismissal.d.ts +56 -0
  264. package/dist/shared/core/dismissal.js +1 -0
  265. package/dist/shared/core/field-core.d.ts +250 -0
  266. package/dist/shared/core/field-core.js +1 -0
  267. package/dist/shared/core/focus-targets.d.ts +77 -0
  268. package/dist/shared/core/focus-targets.js +1 -0
  269. package/dist/shared/core/format-file-size.d.ts +9 -0
  270. package/dist/shared/core/format-file-size.js +1 -0
  271. package/dist/shared/core/glyph-data.d.ts +13 -0
  272. package/dist/shared/core/glyph-data.js +1 -0
  273. package/dist/shared/core/measure-auto-resize.d.ts +5 -0
  274. package/dist/shared/core/measure-auto-resize.js +1 -0
  275. package/dist/shared/core/media-query.d.ts +7 -0
  276. package/dist/shared/core/media-query.js +1 -0
  277. package/dist/shared/core/mentions.d.ts +116 -0
  278. package/dist/shared/core/mentions.js +2 -0
  279. package/dist/shared/core/pin-chars.d.ts +13 -0
  280. package/dist/shared/core/pin-chars.js +1 -0
  281. package/dist/shared/core/placement.d.ts +102 -0
  282. package/dist/shared/core/placement.js +1 -0
  283. package/dist/shared/core/qr-encoder.d.ts +33 -0
  284. package/dist/shared/core/qr-encoder.js +1 -0
  285. package/dist/shared/core/roving-tab-stop.d.ts +37 -0
  286. package/dist/shared/core/roving-tab-stop.js +1 -0
  287. package/dist/shared/core/select-keyboard.d.ts +80 -0
  288. package/dist/shared/core/select-keyboard.js +1 -0
  289. package/dist/shared/core/selection.d.ts +58 -0
  290. package/dist/shared/core/selection.js +1 -0
  291. package/dist/shared/core/tabbable.d.ts +8 -0
  292. package/dist/shared/core/tabbable.js +1 -0
  293. package/dist/shared/core/timer.d.ts +82 -0
  294. package/dist/shared/core/timer.js +1 -0
  295. package/dist/shared/core/tree-columns.d.ts +48 -0
  296. package/dist/shared/core/tree-columns.js +1 -0
  297. package/dist/shared/core/typeahead.d.ts +27 -0
  298. package/dist/shared/core/typeahead.js +1 -0
  299. package/dist/shared/index.d.ts +113 -0
  300. package/dist/shared/index.js +1 -0
  301. package/dist/skins-src/_foundation-fallback.css +124 -0
  302. package/dist/skins-src/base.css +328 -0
  303. package/dist/skins-src/components/_actuator.css +203 -0
  304. package/dist/skins-src/components/_arrow.css +20 -0
  305. package/dist/skins-src/components/_card-control.css +27 -0
  306. package/dist/skins-src/components/_collection.css +281 -0
  307. package/dist/skins-src/components/_hit-target.css +28 -0
  308. package/dist/skins-src/components/_overlay.css +214 -0
  309. package/dist/skins-src/components/_status.css +38 -0
  310. package/dist/skins-src/components/_trigger.css +85 -0
  311. package/dist/skins-src/components/accordion.css +85 -0
  312. package/dist/skins-src/components/alert.css +118 -0
  313. package/dist/skins-src/components/angle-slider.css +110 -0
  314. package/dist/skins-src/components/aspect-ratio.css +26 -0
  315. package/dist/skins-src/components/autocomplete.css +112 -0
  316. package/dist/skins-src/components/avatar.css +87 -0
  317. package/dist/skins-src/components/badge.css +164 -0
  318. package/dist/skins-src/components/box.css +9 -0
  319. package/dist/skins-src/components/breadcrumb.css +78 -0
  320. package/dist/skins-src/components/button.css +304 -0
  321. package/dist/skins-src/components/calendar.css +269 -0
  322. package/dist/skins-src/components/card.css +116 -0
  323. package/dist/skins-src/components/carousel.css +192 -0
  324. package/dist/skins-src/components/chat-composer.css +89 -0
  325. package/dist/skins-src/components/chat-message.css +98 -0
  326. package/dist/skins-src/components/checkbox-card.css +153 -0
  327. package/dist/skins-src/components/checkbox-group.css +72 -0
  328. package/dist/skins-src/components/checkbox.css +141 -0
  329. package/dist/skins-src/components/clipboard.css +126 -0
  330. package/dist/skins-src/components/collapsible.css +64 -0
  331. package/dist/skins-src/components/color-picker.css +304 -0
  332. package/dist/skins-src/components/combobox.css +111 -0
  333. package/dist/skins-src/components/command.css +73 -0
  334. package/dist/skins-src/components/comment-thread.css +56 -0
  335. package/dist/skins-src/components/comment.css +59 -0
  336. package/dist/skins-src/components/confirm-dialog.css +43 -0
  337. package/dist/skins-src/components/conversation-list.css +142 -0
  338. package/dist/skins-src/components/dashboard-layout.css +106 -0
  339. package/dist/skins-src/components/date-field.css +95 -0
  340. package/dist/skins-src/components/date-picker.css +79 -0
  341. package/dist/skins-src/components/dialog.css +161 -0
  342. package/dist/skins-src/components/divider.css +64 -0
  343. package/dist/skins-src/components/drawer.css +166 -0
  344. package/dist/skins-src/components/editable.css +121 -0
  345. package/dist/skins-src/components/empty-state.css +85 -0
  346. package/dist/skins-src/components/field.css +104 -0
  347. package/dist/skins-src/components/file-upload.css +164 -0
  348. package/dist/skins-src/components/filter-bar.css +48 -0
  349. package/dist/skins-src/components/floating-panel.css +168 -0
  350. package/dist/skins-src/components/forgot-password-page.css +45 -0
  351. package/dist/skins-src/components/form-section.css +75 -0
  352. package/dist/skins-src/components/form.css +115 -0
  353. package/dist/skins-src/components/heading.css +38 -0
  354. package/dist/skins-src/components/image.css +43 -0
  355. package/dist/skins-src/components/kbd.css +76 -0
  356. package/dist/skins-src/components/label.css +45 -0
  357. package/dist/skins-src/components/link.css +72 -0
  358. package/dist/skins-src/components/list.css +104 -0
  359. package/dist/skins-src/components/listbox.css +90 -0
  360. package/dist/skins-src/components/loading-overlay.css +89 -0
  361. package/dist/skins-src/components/mentions.css +79 -0
  362. package/dist/skins-src/components/menu.css +102 -0
  363. package/dist/skins-src/components/menubar.css +130 -0
  364. package/dist/skins-src/components/navigation-menu.css +145 -0
  365. package/dist/skins-src/components/notification-center.css +139 -0
  366. package/dist/skins-src/components/number-field.css +95 -0
  367. package/dist/skins-src/components/onboarding-checklist.css +156 -0
  368. package/dist/skins-src/components/page-container.css +29 -0
  369. package/dist/skins-src/components/pagination.css +147 -0
  370. package/dist/skins-src/components/password-input.css +116 -0
  371. package/dist/skins-src/components/pin-input.css +115 -0
  372. package/dist/skins-src/components/popover.css +108 -0
  373. package/dist/skins-src/components/progress.css +207 -0
  374. package/dist/skins-src/components/qr-code.css +62 -0
  375. package/dist/skins-src/components/radio-card.css +158 -0
  376. package/dist/skins-src/components/radio-group.css +148 -0
  377. package/dist/skins-src/components/rating.css +150 -0
  378. package/dist/skins-src/components/reset-password-page.css +51 -0
  379. package/dist/skins-src/components/resizable.css +131 -0
  380. package/dist/skins-src/components/scroll-area.css +101 -0
  381. package/dist/skins-src/components/select.css +239 -0
  382. package/dist/skins-src/components/sign-in-page.css +47 -0
  383. package/dist/skins-src/components/sign-up-page.css +55 -0
  384. package/dist/skins-src/components/skeleton.css +55 -0
  385. package/dist/skins-src/components/skip-link.css +51 -0
  386. package/dist/skins-src/components/slider.css +164 -0
  387. package/dist/skins-src/components/speed-dial.css +162 -0
  388. package/dist/skins-src/components/spinner.css +59 -0
  389. package/dist/skins-src/components/split-button.css +167 -0
  390. package/dist/skins-src/components/stat-card.css +117 -0
  391. package/dist/skins-src/components/stepper.css +153 -0
  392. package/dist/skins-src/components/switch.css +155 -0
  393. package/dist/skins-src/components/table.css +336 -0
  394. package/dist/skins-src/components/tabs.css +116 -0
  395. package/dist/skins-src/components/tag-group.css +72 -0
  396. package/dist/skins-src/components/tags-input.css +176 -0
  397. package/dist/skins-src/components/text-field.css +182 -0
  398. package/dist/skins-src/components/text.css +83 -0
  399. package/dist/skins-src/components/textarea.css +118 -0
  400. package/dist/skins-src/components/time-field.css +43 -0
  401. package/dist/skins-src/components/time.css +13 -0
  402. package/dist/skins-src/components/timeline.css +206 -0
  403. package/dist/skins-src/components/toast.css +133 -0
  404. package/dist/skins-src/components/toggle-group.css +185 -0
  405. package/dist/skins-src/components/toggle.css +89 -0
  406. package/dist/skins-src/components/toolbar.css +84 -0
  407. package/dist/skins-src/components/tour.css +67 -0
  408. package/dist/skins-src/components/transfer.css +112 -0
  409. package/dist/skins-src/components/tree-select.css +124 -0
  410. package/dist/skins-src/components/tree.css +110 -0
  411. package/dist/skins-src/components/usage-card.css +129 -0
  412. package/dist/skins-src/components/user-menu.css +83 -0
  413. package/dist/skins-src/components/verification-page.css +64 -0
  414. package/dist/skins-src/components/workspace-switcher.css +133 -0
  415. package/dist/skins-src/utilities.css +130 -0
  416. package/dist/skins-src/web-components.css +64 -0
  417. package/dist/strip-paint.d.mts +7 -0
  418. package/dist/strip-paint.mjs +131 -0
  419. package/dist/themes/AntDark.md +14 -0
  420. package/dist/themes/AntDark.ts +47 -0
  421. package/dist/themes/AntLight.md +21 -0
  422. package/dist/themes/AntLight.ts +95 -0
  423. package/dist/themes/CatppuccinLatte.md +20 -0
  424. package/dist/themes/CatppuccinLatte.ts +93 -0
  425. package/dist/themes/CatppuccinMocha.md +15 -0
  426. package/dist/themes/CatppuccinMocha.ts +93 -0
  427. package/dist/themes/ChakraDark.md +8 -0
  428. package/dist/themes/ChakraDark.ts +47 -0
  429. package/dist/themes/ChakraLight.md +14 -0
  430. package/dist/themes/ChakraLight.ts +93 -0
  431. package/dist/themes/Contrast.test.ts +80 -0
  432. package/dist/themes/CupcakeDark.md +8 -0
  433. package/dist/themes/CupcakeDark.ts +39 -0
  434. package/dist/themes/CupcakeLight.md +31 -0
  435. package/dist/themes/CupcakeLight.ts +93 -0
  436. package/dist/themes/DefaultTheme.md +8 -0
  437. package/dist/themes/DefaultTheme.test.ts +96 -0
  438. package/dist/themes/DefaultTheme.ts +137 -0
  439. package/dist/themes/DraculaDark.md +14 -0
  440. package/dist/themes/DraculaDark.ts +93 -0
  441. package/dist/themes/DraculaLight.md +8 -0
  442. package/dist/themes/DraculaLight.ts +55 -0
  443. package/dist/themes/EmeraldDark.md +8 -0
  444. package/dist/themes/EmeraldDark.ts +35 -0
  445. package/dist/themes/EmeraldLight.md +8 -0
  446. package/dist/themes/EmeraldLight.ts +93 -0
  447. package/dist/themes/EverforestDark.md +26 -0
  448. package/dist/themes/EverforestDark.ts +99 -0
  449. package/dist/themes/EverforestLight.md +31 -0
  450. package/dist/themes/EverforestLight.ts +51 -0
  451. package/dist/themes/FluentDark.md +8 -0
  452. package/dist/themes/FluentDark.ts +47 -0
  453. package/dist/themes/FluentLight.md +8 -0
  454. package/dist/themes/FluentLight.ts +100 -0
  455. package/dist/themes/GraphiteDark.md +8 -0
  456. package/dist/themes/GraphiteDark.ts +35 -0
  457. package/dist/themes/GraphiteLight.md +14 -0
  458. package/dist/themes/GraphiteLight.ts +93 -0
  459. package/dist/themes/GruvboxDark.md +14 -0
  460. package/dist/themes/GruvboxDark.ts +93 -0
  461. package/dist/themes/GruvboxLight.md +27 -0
  462. package/dist/themes/GruvboxLight.ts +49 -0
  463. package/dist/themes/MaterialDark.md +8 -0
  464. package/dist/themes/MaterialDark.ts +47 -0
  465. package/dist/themes/MaterialLight.md +8 -0
  466. package/dist/themes/MaterialLight.ts +104 -0
  467. package/dist/themes/MidnightDark.md +8 -0
  468. package/dist/themes/MidnightDark.ts +19 -0
  469. package/dist/themes/MidnightLight.md +8 -0
  470. package/dist/themes/MidnightLight.ts +23 -0
  471. package/dist/themes/NordDark.md +28 -0
  472. package/dist/themes/NordDark.ts +93 -0
  473. package/dist/themes/NordLight.md +20 -0
  474. package/dist/themes/NordLight.ts +50 -0
  475. package/dist/themes/OneDark.md +26 -0
  476. package/dist/themes/OneDark.ts +93 -0
  477. package/dist/themes/OneLight.md +20 -0
  478. package/dist/themes/OneLight.ts +51 -0
  479. package/dist/themes/PrimerDark.md +26 -0
  480. package/dist/themes/PrimerDark.ts +99 -0
  481. package/dist/themes/PrimerLight.md +14 -0
  482. package/dist/themes/PrimerLight.ts +93 -0
  483. package/dist/themes/RosePine.md +23 -0
  484. package/dist/themes/RosePine.ts +93 -0
  485. package/dist/themes/RosePineDawn.md +20 -0
  486. package/dist/themes/RosePineDawn.ts +51 -0
  487. package/dist/themes/SkandaDark.md +8 -0
  488. package/dist/themes/SkandaDark.ts +57 -0
  489. package/dist/themes/SkandaLight.md +8 -0
  490. package/dist/themes/SkandaLight.ts +96 -0
  491. package/dist/themes/SolarizedDark.md +8 -0
  492. package/dist/themes/SolarizedDark.ts +93 -0
  493. package/dist/themes/SolarizedLight.md +32 -0
  494. package/dist/themes/SolarizedLight.ts +93 -0
  495. package/dist/themes/SynthwaveDark.md +8 -0
  496. package/dist/themes/SynthwaveDark.ts +93 -0
  497. package/dist/themes/SynthwaveLight.md +20 -0
  498. package/dist/themes/SynthwaveLight.ts +48 -0
  499. package/dist/themes/Themes.test.ts +110 -0
  500. package/dist/themes/brands.test.ts +63 -0
  501. package/dist/themes/brands.ts +121 -0
  502. package/dist/themes/createBrandTheme.test.ts +223 -0
  503. package/dist/themes/createBrandTheme.ts +298 -0
  504. package/dist/themes/index.ts +54 -0
  505. package/package.json +73 -0
@@ -0,0 +1,93 @@
1
+ /*
2
+ * Copyright (c) 2026 SkandaDX
3
+ * This file is part of the SkandaDX organization.
4
+ * Licensed under the MIT License. See LICENSE in the repository root.
5
+ */
6
+
7
+ import type { Theme } from '../utils/theme';
8
+
9
+ /** Synthwave inspired neon dark theme: deep indigo `#1a103d` background, hot-pink actions. Inspired by daisyUI's "synthwave" theme (saadeghi/daisyui, MIT). @public */
10
+ export const synthwaveDark: Theme = {
11
+ name: 'synthwave-dark',
12
+ mode: 'dark',
13
+ colors: {
14
+ primary: {
15
+ 50: '#fff7fd',
16
+ 100: '#ffedfa',
17
+ 200: '#ffd8f4',
18
+ 300: '#ffbfed',
19
+ 400: '#ffa7e7',
20
+ 500: '#ff93e1',
21
+ 600: '#ff7edb',
22
+ 700: '#ce67b2',
23
+ 800: '#a75492',
24
+ 900: '#854475',
25
+ 950: '#4f2a48',
26
+ },
27
+ neutral: {
28
+ 50: '#f4f2fb',
29
+ 100: '#e7e3f6',
30
+ 200: '#2f2465',
31
+ 300: '#443569',
32
+ 400: '#8b81b5',
33
+ 500: '#6f639c',
34
+ 600: '#55487f',
35
+ 700: '#443569',
36
+ 800: '#322557',
37
+ 900: '#241a47',
38
+ 950: '#170f33',
39
+ },
40
+ success: {
41
+ 50: '#f0fdfa',
42
+ 100: '#ccfbf1',
43
+ 200: '#99f6e4',
44
+ 300: '#71ead2',
45
+ 400: '#3ed4bd',
46
+ 500: '#22b8a3',
47
+ 600: '#189485',
48
+ 700: '#17766c',
49
+ 800: '#175e57',
50
+ 900: '#184e49',
51
+ 950: '#082f2c',
52
+ },
53
+ warning: {
54
+ 50: '#fefbe8',
55
+ 100: '#fef6c3',
56
+ 200: '#fdec8a',
57
+ 300: '#f3cc30',
58
+ 400: '#eebd20',
59
+ 500: '#dea70f',
60
+ 600: '#c0850a',
61
+ 700: '#99650c',
62
+ 800: '#7e5012',
63
+ 900: '#6b4215',
64
+ 950: '#3e2308',
65
+ },
66
+ danger: {
67
+ 50: '#fff1f3',
68
+ 100: '#ffe3e8',
69
+ 200: '#ffccd6',
70
+ 300: '#ffa1b4',
71
+ 400: '#fb7185',
72
+ 500: '#f43f5e',
73
+ 600: '#e11d48',
74
+ 700: '#be123c',
75
+ 800: '#9f1239',
76
+ 900: '#881337',
77
+ 950: '#4c0519',
78
+ },
79
+ semantic: {
80
+ background: '#1a103d',
81
+ surface: '#251b4f',
82
+ surfaceHover: '#2f2465',
83
+ overlay: 'rgb(10 4 32 / 0.7)',
84
+ text: '#f9f7fd',
85
+ textMuted: '#a89ed8',
86
+ textInverted: '#1a103d',
87
+ border: '#2f2465',
88
+ borderStrong: '#7660af',
89
+ focusRing: '#e779c1',
90
+ },
91
+ },
92
+ shadow: { color: '10 4 32', strength: '5.8' },
93
+ };
@@ -0,0 +1,20 @@
1
+ ---
2
+ upstream: daisyUI Synthwave
3
+ deviations:
4
+ - token: warning-600
5
+ upstream: #c0850a
6
+ ours: #bf840a
7
+ reason: Read 2.96:1 against the theme background, under the 3:1 floor for status
8
+ ramps. Darkened on lightness alone, hue and saturation kept, to reach 3.00:1
9
+ contrast against the theme background.
10
+ - token: text-muted
11
+ upstream: #6c5f92
12
+ ours: #665989
13
+ reason: Read 4.48:1 against hover and 4.13:1 against pressed, under the 4.5:1
14
+ floor for body text. Darkened on lightness alone, hue and saturation kept,
15
+ to clear 4.5:1 against both fills.
16
+ ---
17
+
18
+ # themes/synthwave-light.ts
19
+
20
+ Exports **`synthwaveLight`** — a light theme registered as `data-skdx-theme="synthwave-light"`, the `synthwave` brand's light mode — the neon pink primary darkened to `#b0327f` at 600 so white labels pass AA, on pale lavender surfaces (`background: #faf5ff`) with deep indigo text.
@@ -0,0 +1,48 @@
1
+ /*
2
+ * Copyright (c) 2026 SkandaDX
3
+ * This file is part of the SkandaDX organization.
4
+ * Licensed under the MIT License. See LICENSE in the repository root.
5
+ */
6
+
7
+ import type { Theme } from '../utils/theme';
8
+ import { createTheme } from './DefaultTheme';
9
+ import { synthwaveDark } from './SynthwaveDark';
10
+
11
+ /** Light counterpart of `synthwave-dark` — neon pink primary softened onto pale lavender to survive on paper. @public */
12
+ export const synthwaveLight: Theme = createTheme(
13
+ 'synthwave-light',
14
+ {
15
+ mode: 'light',
16
+ colors: {
17
+ primary: {
18
+ 50: '#faf3f7',
19
+ 100: '#f4e2ed',
20
+ 200: '#e7c2d9',
21
+ 300: '#d899bf',
22
+ 400: '#c974a8',
23
+ 500: '#bd5393',
24
+ 600: '#b0327f',
25
+ 700: '#8f2a69',
26
+ 800: '#742457',
27
+ 900: '#5d1e47',
28
+ 950: '#38152e',
29
+ },
30
+ neutral: { 200: '#e3d7f0', 300: '#cbbde0' },
31
+ warning: { 600: '#bf840a' },
32
+ semantic: {
33
+ background: '#faf5ff',
34
+ surface: '#f3ebfa',
35
+ surfaceHover: '#ebe0f5',
36
+ overlay: 'rgb(26 16 61 / 0.4)',
37
+ text: '#2b1b50',
38
+ textMuted: '#665989',
39
+ textInverted: '#ffffff',
40
+ border: '#e3d7f0',
41
+ borderStrong: '#977bc1',
42
+ focusRing: '#b0327f',
43
+ },
44
+ },
45
+ shadow: { color: '2 6 23', strength: '1' },
46
+ },
47
+ synthwaveDark,
48
+ );
@@ -0,0 +1,110 @@
1
+ /*
2
+ * Copyright (c) 2026 SkandaDX
3
+ * This file is part of the SkandaDX organization.
4
+ * Licensed under the MIT License. See LICENSE in the repository root.
5
+ */
6
+
7
+ import { describe, expect, it } from 'vitest';
8
+
9
+ import * as themeModules from './index';
10
+ import { themes } from './index';
11
+
12
+ const exportedThemes = Object.values(themeModules).filter(
13
+ (value): value is (typeof themes)[number] =>
14
+ typeof value === 'object' && value !== null && !Array.isArray(value) && 'mode' in value,
15
+ );
16
+
17
+ const scaleSteps = [50, 100, 200, 300, 400, 500, 600, 700, 800, 900, 950] as const;
18
+ const ramps = ['primary', 'neutral', 'success', 'warning', 'danger'] as const;
19
+ const semanticKeys = [
20
+ 'background',
21
+ 'surface',
22
+ 'surfaceHover',
23
+ 'overlay',
24
+ 'text',
25
+ 'textMuted',
26
+ 'textInverted',
27
+ 'border',
28
+ 'borderStrong',
29
+ 'focusRing',
30
+ ] as const;
31
+
32
+ describe('themes registry', () => {
33
+ it('registers every exported theme exactly once, and nothing else', () => {
34
+ expect(new Set(themes)).toEqual(new Set(exportedThemes));
35
+ expect(themes).toHaveLength(exportedThemes.length);
36
+ });
37
+
38
+ it('gives every theme a unique kebab-case name', () => {
39
+ const names = themes.map((t) => t.name);
40
+ expect(new Set(names).size).toBe(names.length);
41
+ for (const name of names) {
42
+ expect(name).toMatch(/^[a-z0-9]+(-[a-z0-9]+)*$/);
43
+ }
44
+ });
45
+
46
+ it('gives every theme an explicit light or dark mode', () => {
47
+ for (const theme of themes) {
48
+ expect(['light', 'dark']).toContain(theme.mode);
49
+ }
50
+ });
51
+
52
+ it.each(themes.map((t) => [t.name, t] as const))(
53
+ '%s defines a full 50-950 hex scale for every color ramp',
54
+ (_name, theme) => {
55
+ for (const ramp of ramps) {
56
+ for (const step of scaleSteps) {
57
+ expect(theme.colors[ramp][step]).toMatch(/^#[0-9a-f]{6}$/i);
58
+ }
59
+ }
60
+ },
61
+ );
62
+
63
+ it.each(themes.map((t) => [t.name, t] as const))(
64
+ '%s defines every semantic color token',
65
+ (_name, theme) => {
66
+ for (const key of semanticKeys) {
67
+ expect(theme.colors.semantic[key]).toBeTruthy();
68
+ }
69
+ },
70
+ );
71
+
72
+ it.each(themes.map((t) => [t.name, t] as const))(
73
+ '%s defines a shadow tint the foundation geometry can substitute',
74
+ (_name, theme) => {
75
+ // Must be space-separated channels: a hex string here silently produces no shadow.
76
+ expect(theme.shadow.color).toMatch(/^\d{1,3} \d{1,3} \d{1,3}$/);
77
+ expect(Number(theme.shadow.strength)).toBeGreaterThan(0);
78
+ },
79
+ );
80
+
81
+ it('confines the motion deviation to the three design-language themes', () => {
82
+ const deviating = themes.filter((t) => t.motion).map((t) => t.name);
83
+ expect(deviating.sort()).toEqual(
84
+ [
85
+ 'ant-dark',
86
+ 'ant-daybreak',
87
+ 'fluent',
88
+ 'fluent-dark',
89
+ 'material-you',
90
+ 'material-you-dark',
91
+ ].sort(),
92
+ );
93
+ });
94
+
95
+ it('confines the font deviation to the two themes with their own typeface', () => {
96
+ const deviating = themes.filter((t) => t.typography).map((t) => t.name);
97
+ expect(deviating.sort()).toEqual(
98
+ ['fluent', 'fluent-dark', 'material-you', 'material-you-dark'].sort(),
99
+ );
100
+ });
101
+
102
+ it('lets a deviating theme reach only the two stacks and the four base motion tokens', () => {
103
+ const allowedFont = new Set(['fontFamily', 'fontFamilyMono']);
104
+ const allowedMotion = new Set(['durationFast', 'durationNormal', 'durationSlow', 'easing']);
105
+ for (const theme of themes) {
106
+ for (const key of Object.keys(theme.typography ?? {})) expect(allowedFont).toContain(key);
107
+ for (const key of Object.keys(theme.motion ?? {})) expect(allowedMotion).toContain(key);
108
+ }
109
+ });
110
+ });
@@ -0,0 +1,63 @@
1
+ /*
2
+ * Copyright (c) 2026 SkandaDX
3
+ * This file is part of the SkandaDX organization.
4
+ * Licensed under the MIT License. See LICENSE in the repository root.
5
+ */
6
+
7
+ import { describe, expect, it } from 'vitest';
8
+
9
+ import { brands, defaultBrand, getBrand, getBrandByThemeName } from './brands';
10
+ import { themes } from './index';
11
+
12
+ describe('brands registry', () => {
13
+ it('gives every brand a unique kebab-case name', () => {
14
+ const names = brands.map((b) => b.name);
15
+ expect(new Set(names).size).toBe(names.length);
16
+ for (const name of names) {
17
+ expect(name).toMatch(/^[a-z0-9]+(-[a-z0-9]+)*$/);
18
+ }
19
+ });
20
+
21
+ it.each(brands.map((b) => [b.name, b] as const))(
22
+ '%s provides a complete light and dark theme with matching modes',
23
+ (_name, brand) => {
24
+ expect(brand.themes.light.mode).toBe('light');
25
+ expect(brand.themes.dark.mode).toBe('dark');
26
+ expect(brand.themes.light.name).not.toBe(brand.themes.dark.name);
27
+ },
28
+ );
29
+
30
+ it('claims each theme name in exactly one brand-and-mode slot', () => {
31
+ const claimed = brands.flatMap((b) => [b.themes.light.name, b.themes.dark.name]);
32
+ expect(new Set(claimed).size).toBe(claimed.length);
33
+ expect(claimed).toEqual(themes.map((t) => t.name));
34
+ });
35
+
36
+ it.each(brands.map((b) => [b.name, b] as const))(
37
+ "%s keeps its identity across modes — light and dark share the brand's primary hue family or an intentional inversion",
38
+ (_name, brand) => {
39
+ expect(brand.themes.light.colors.semantic.background).not.toBe(
40
+ brand.themes.dark.colors.semantic.background,
41
+ );
42
+ expect(brand.themes.light.colors.semantic.text).not.toBe(
43
+ brand.themes.dark.colors.semantic.text,
44
+ );
45
+ },
46
+ );
47
+
48
+ it('defaults to the skanda brand, whose light theme is skanda-light', () => {
49
+ expect(defaultBrand.name).toBe('skanda');
50
+ expect(defaultBrand.themes.light.name).toBe('skanda-light');
51
+ });
52
+
53
+ it('looks up brands by name and returns undefined for unknown names', () => {
54
+ expect(getBrand('nord')?.themes.dark.name).toBe('nord-dark');
55
+ expect(getBrand('not-a-brand')).toBeUndefined();
56
+ });
57
+
58
+ it('resolves legacy theme names to their owning brand', () => {
59
+ expect(getBrandByThemeName('one-dark')?.name).toBe('one');
60
+ expect(getBrandByThemeName('catppuccin-latte')?.name).toBe('catppuccin');
61
+ expect(getBrandByThemeName('not-a-theme')).toBeUndefined();
62
+ });
63
+ });
@@ -0,0 +1,121 @@
1
+ /*
2
+ * Copyright (c) 2026 SkandaDX
3
+ * This file is part of the SkandaDX organization.
4
+ * Licensed under the MIT License. See LICENSE in the repository root.
5
+ */
6
+
7
+ import type { Theme, ThemeColorMode } from '../utils/theme';
8
+ import { antDark } from './AntDark';
9
+ import { antLight } from './AntLight';
10
+ import { catppuccinLatte } from './CatppuccinLatte';
11
+ import { catppuccinMocha } from './CatppuccinMocha';
12
+ import { chakraDark } from './ChakraDark';
13
+ import { chakraLight } from './ChakraLight';
14
+ import { cupcakeDark } from './CupcakeDark';
15
+ import { cupcakeLight } from './CupcakeLight';
16
+ import { draculaDark } from './DraculaDark';
17
+ import { draculaLight } from './DraculaLight';
18
+ import { emeraldDark } from './EmeraldDark';
19
+ import { emeraldLight } from './EmeraldLight';
20
+ import { everforestDark } from './EverforestDark';
21
+ import { everforestLight } from './EverforestLight';
22
+ import { fluentDark } from './FluentDark';
23
+ import { fluentLight } from './FluentLight';
24
+ import { graphiteDark } from './GraphiteDark';
25
+ import { graphiteLight } from './GraphiteLight';
26
+ import { gruvboxDark } from './GruvboxDark';
27
+ import { gruvboxLight } from './GruvboxLight';
28
+ import { materialDark } from './MaterialDark';
29
+ import { materialLight } from './MaterialLight';
30
+ import { midnightDark } from './MidnightDark';
31
+ import { midnightLight } from './MidnightLight';
32
+ import { nordDark } from './NordDark';
33
+ import { nordLight } from './NordLight';
34
+ import { oneDark } from './OneDark';
35
+ import { oneLight } from './OneLight';
36
+ import { primerDark } from './PrimerDark';
37
+ import { primerLight } from './PrimerLight';
38
+ import { rosePine } from './RosePine';
39
+ import { rosePineDawn } from './RosePineDawn';
40
+ import { skandaDark } from './SkandaDark';
41
+ import { skandaLight } from './SkandaLight';
42
+ import { solarizedDark } from './SolarizedDark';
43
+ import { solarizedLight } from './SolarizedLight';
44
+ import { synthwaveDark } from './SynthwaveDark';
45
+ import { synthwaveLight } from './SynthwaveLight';
46
+
47
+ /** A visual identity with a complete {@link Theme} for each color mode. @public */
48
+ export interface Brand {
49
+ /** Stable brand identifier, e.g. `'skanda'` — safe to persist and use as a `data-*` value. */
50
+ name: string;
51
+ /** Human-readable brand name, e.g. `'Skanda'`. */
52
+ displayName: string;
53
+ /** The brand's complete theme for each resolved color mode. */
54
+ themes: Record<ThemeColorMode, Theme>;
55
+ }
56
+
57
+ /** Every bundled brand with its light/dark theme pair, in stable order. @public */
58
+ export const brands: Brand[] = [
59
+ { name: 'skanda', displayName: 'Skanda', themes: { light: skandaLight, dark: skandaDark } },
60
+ { name: 'emerald', displayName: 'Emerald', themes: { light: emeraldLight, dark: emeraldDark } },
61
+ {
62
+ name: 'midnight',
63
+ displayName: 'Midnight',
64
+ themes: { light: midnightLight, dark: midnightDark },
65
+ },
66
+ {
67
+ name: 'graphite',
68
+ displayName: 'Graphite',
69
+ themes: { light: graphiteLight, dark: graphiteDark },
70
+ },
71
+ {
72
+ name: 'material',
73
+ displayName: 'Material',
74
+ themes: { light: materialLight, dark: materialDark },
75
+ },
76
+ { name: 'ant', displayName: 'Ant', themes: { light: antLight, dark: antDark } },
77
+ { name: 'fluent', displayName: 'Fluent', themes: { light: fluentLight, dark: fluentDark } },
78
+ { name: 'chakra', displayName: 'Chakra', themes: { light: chakraLight, dark: chakraDark } },
79
+ { name: 'nord', displayName: 'Nord', themes: { light: nordLight, dark: nordDark } },
80
+ { name: 'dracula', displayName: 'Dracula', themes: { light: draculaLight, dark: draculaDark } },
81
+ {
82
+ name: 'catppuccin',
83
+ displayName: 'Catppuccin',
84
+ themes: { light: catppuccinLatte, dark: catppuccinMocha },
85
+ },
86
+ {
87
+ name: 'solarized',
88
+ displayName: 'Solarized',
89
+ themes: { light: solarizedLight, dark: solarizedDark },
90
+ },
91
+ { name: 'gruvbox', displayName: 'Gruvbox', themes: { light: gruvboxLight, dark: gruvboxDark } },
92
+ { name: 'rose-pine', displayName: 'Rosé Pine', themes: { light: rosePineDawn, dark: rosePine } },
93
+ {
94
+ name: 'everforest',
95
+ displayName: 'Everforest',
96
+ themes: { light: everforestLight, dark: everforestDark },
97
+ },
98
+ { name: 'one', displayName: 'One', themes: { light: oneLight, dark: oneDark } },
99
+ { name: 'primer', displayName: 'Primer', themes: { light: primerLight, dark: primerDark } },
100
+ { name: 'cupcake', displayName: 'Cupcake', themes: { light: cupcakeLight, dark: cupcakeDark } },
101
+ {
102
+ name: 'synthwave',
103
+ displayName: 'Synthwave',
104
+ themes: { light: synthwaveLight, dark: synthwaveDark },
105
+ },
106
+ ];
107
+
108
+ /** Default brand (`skanda-light`). @public */
109
+ export const defaultBrand: Brand = brands[0]!;
110
+
111
+ /** Looks up a brand by its stable identifier; `undefined` if not found. @public */
112
+ export function getBrand(name: string): Brand | undefined {
113
+ return brands.find((brand) => brand.name === name);
114
+ }
115
+
116
+ /** Looks up the brand that owns a theme name in either mode. @public */
117
+ export function getBrandByThemeName(themeName: string): Brand | undefined {
118
+ return brands.find(
119
+ (brand) => brand.themes.light.name === themeName || brand.themes.dark.name === themeName,
120
+ );
121
+ }
@@ -0,0 +1,223 @@
1
+ /*
2
+ * Copyright (c) 2026 SkandaDX
3
+ * This file is part of the SkandaDX organization.
4
+ * Licensed under the MIT License. See LICENSE in the repository root.
5
+ */
6
+
7
+ import { describe, expect, it } from 'vitest';
8
+
9
+ import { contrastRatio } from '../utils/contrast';
10
+ import type { ThemeColorMode } from '../utils/theme';
11
+ import { createBrandTheme } from './createBrandTheme';
12
+ import { defaultTheme } from './DefaultTheme';
13
+ import { midnightDark } from './MidnightDark';
14
+ import { midnightLight } from './MidnightLight';
15
+
16
+ const STEPS = [50, 100, 200, 300, 400, 500, 600, 700, 800, 900, 950] as const;
17
+ const RAMPS = ['primary', 'neutral', 'success', 'warning', 'danger'] as const;
18
+ const MODES: ThemeColorMode[] = ['light', 'dark'];
19
+ const HUES = [0, 30, 60, 90, 120, 150, 180, 210, 240, 270, 300, 330];
20
+
21
+ describe('createBrandTheme', () => {
22
+ it('carries the seed name and mode through', () => {
23
+ const theme = createBrandTheme({ name: 'acme-dark', mode: 'dark', primaryHue: 210 });
24
+ expect(theme.name).toBe('acme-dark');
25
+ expect(theme.mode).toBe('dark');
26
+ });
27
+
28
+ it('derives colours only, leaving the shared layer and the shadow tint alone', () => {
29
+ const theme = createBrandTheme({ name: 'acme', mode: 'light', primaryHue: 210 });
30
+ expect(theme.shadow).toEqual(defaultTheme.shadow);
31
+ expect(theme.typography).toBeUndefined();
32
+ expect(theme.motion).toBeUndefined();
33
+ });
34
+
35
+ it.each(MODES)('emits a full 11-step 6-digit hex ramp for every scale (%s)', (mode) => {
36
+ const theme = createBrandTheme({ name: 'acme', mode, primaryHue: 271, primaryChroma: 91 });
37
+ for (const ramp of RAMPS) {
38
+ for (const step of STEPS) {
39
+ expect(theme.colors[ramp][step]).toMatch(/^#[0-9a-f]{6}$/);
40
+ }
41
+ }
42
+ });
43
+
44
+ it.each(MODES)('produces a monotonically darkening neutral ramp (%s)', (mode) => {
45
+ const theme = createBrandTheme({ name: 'acme', mode, primaryHue: 271 });
46
+ const luminances = STEPS.map((step) => contrastRatio(theme.colors.neutral[step], '#000000'));
47
+ expect(luminances).toEqual([...luminances].sort((a, b) => b - a));
48
+ });
49
+
50
+ describe.each(MODES)('WCAG AA enforcement (%s)', (mode) => {
51
+ it.each(HUES)('hue %i: body text meets 4.5:1 against the background', (hue) => {
52
+ const { semantic } = createBrandTheme({ name: 'acme', mode, primaryHue: hue }).colors;
53
+ expect(contrastRatio(semantic.text, semantic.background)).toBeGreaterThanOrEqual(4.5);
54
+ });
55
+
56
+ it.each(HUES)('hue %i: muted text meets 3:1 against the background', (hue) => {
57
+ const { semantic } = createBrandTheme({ name: 'acme', mode, primaryHue: hue }).colors;
58
+ expect(contrastRatio(semantic.textMuted, semantic.background)).toBeGreaterThanOrEqual(3);
59
+ });
60
+
61
+ it.each(HUES)('hue %i: the focus ring meets 3:1 against the background', (hue) => {
62
+ const { semantic } = createBrandTheme({
63
+ name: 'acme',
64
+ mode,
65
+ primaryHue: hue,
66
+ primaryChroma: 91,
67
+ }).colors;
68
+ expect(contrastRatio(semantic.focusRing, semantic.background)).toBeGreaterThanOrEqual(3);
69
+ });
70
+
71
+ it.each(HUES)('hue %i: inverted text meets 4.5:1 against primary-500 and -600', (hue) => {
72
+ const colors = createBrandTheme({
73
+ name: 'acme',
74
+ mode,
75
+ primaryHue: hue,
76
+ primaryChroma: 91,
77
+ }).colors;
78
+ expect(
79
+ contrastRatio(colors.semantic.textInverted, colors.primary[500]),
80
+ ).toBeGreaterThanOrEqual(4.5);
81
+ expect(
82
+ contrastRatio(colors.semantic.textInverted, colors.primary[600]),
83
+ ).toBeGreaterThanOrEqual(4.5);
84
+ });
85
+ });
86
+
87
+ it.each([
88
+ ['violet', 271, 91],
89
+ ['yellow', 55, 95],
90
+ ])('keeps one inverted ink per mode and moves the accent to earn it (%s)', (_n, hue, chroma) => {
91
+ const light = createBrandTheme({
92
+ name: 'a',
93
+ mode: 'light',
94
+ primaryHue: hue,
95
+ primaryChroma: chroma,
96
+ });
97
+ expect(light.colors.semantic.textInverted).toBe('#ffffff');
98
+ expect(
99
+ contrastRatio(light.colors.semantic.textInverted, light.colors.primary[500]),
100
+ ).toBeGreaterThanOrEqual(4.5);
101
+
102
+ const dark = createBrandTheme({
103
+ name: 'b',
104
+ mode: 'dark',
105
+ primaryHue: hue,
106
+ primaryChroma: chroma,
107
+ });
108
+ expect(dark.colors.semantic.textInverted).toBe(dark.colors.neutral[950]);
109
+ expect(
110
+ contrastRatio(dark.colors.semantic.textInverted, dark.colors.primary[500]),
111
+ ).toBeGreaterThanOrEqual(4.5);
112
+ });
113
+
114
+ it('renders overlay as an alpha rgb() derived from the darkest neutral', () => {
115
+ const theme = createBrandTheme({ name: 'acme', mode: 'light', primaryHue: 271 });
116
+ expect(theme.colors.semantic.overlay).toMatch(/^rgb\(\d+ \d+ \d+ \/ 0\.5\)$/);
117
+ expect(
118
+ createBrandTheme({ name: 'a', mode: 'dark', primaryHue: 271 }).colors.semantic.overlay,
119
+ ).toMatch(/\/ 0\.65\)$/);
120
+ });
121
+
122
+ it('gives light and dark seeds genuinely different surfaces and text', () => {
123
+ const seed = { primaryHue: 271, primaryChroma: 91 } as const;
124
+ const light = createBrandTheme({ name: 'a-light', mode: 'light', ...seed });
125
+ const dark = createBrandTheme({ name: 'a-dark', mode: 'dark', ...seed });
126
+
127
+ expect(light.colors.semantic.background).not.toBe(dark.colors.semantic.background);
128
+ expect(light.colors.semantic.text).not.toBe(dark.colors.semantic.text);
129
+ const enforced = new Set([500, 600]);
130
+ for (const step of STEPS.filter((s) => !enforced.has(s))) {
131
+ expect(light.colors.primary[step], `primary-${step} should not vary by mode`).toBe(
132
+ dark.colors.primary[step],
133
+ );
134
+ }
135
+ expect(light.colors.primary[500]).not.toBe(dark.colors.primary[500]);
136
+ });
137
+
138
+ it('defaults the neutral hue to the primary hue and tints it only faintly', () => {
139
+ const tinted = createBrandTheme({ name: 'a', mode: 'light', primaryHue: 271 });
140
+ const explicit = createBrandTheme({
141
+ name: 'a',
142
+ mode: 'light',
143
+ primaryHue: 271,
144
+ neutralHue: 271,
145
+ });
146
+ expect(tinted.colors.neutral).toEqual(explicit.colors.neutral);
147
+
148
+ const heavier = createBrandTheme({
149
+ name: 'a',
150
+ mode: 'light',
151
+ primaryHue: 271,
152
+ neutralChroma: 60,
153
+ });
154
+ expect(heavier.colors.neutral[500]).not.toBe(tinted.colors.neutral[500]);
155
+ });
156
+
157
+ it('honours custom intent hues', () => {
158
+ const custom = createBrandTheme({
159
+ name: 'a',
160
+ mode: 'light',
161
+ primaryHue: 271,
162
+ intentHues: { success: 160, warning: 25, danger: 350 },
163
+ intentChroma: 80,
164
+ });
165
+ const base = createBrandTheme({ name: 'a', mode: 'light', primaryHue: 271 });
166
+ expect(custom.colors.success[500]).not.toBe(base.colors.success[500]);
167
+ expect(custom.colors.warning[500]).not.toBe(base.colors.warning[500]);
168
+ expect(custom.colors.danger[500]).not.toBe(base.colors.danger[500]);
169
+ });
170
+
171
+ it('applies the seed override last, so a brand can still hand-pick tokens', () => {
172
+ const theme = createBrandTheme({
173
+ name: 'acme',
174
+ mode: 'light',
175
+ primaryHue: 271,
176
+ override: { shadow: { strength: '3' }, colors: { semantic: { focusRing: '#123456' } } },
177
+ });
178
+ expect(theme.shadow.strength).toBe('3');
179
+ expect(theme.shadow.color).toBe(defaultTheme.shadow.color);
180
+ expect(theme.colors.semantic.focusRing).toBe('#123456');
181
+ });
182
+ });
183
+
184
+ describe('the generated midnight brand', () => {
185
+ it('keeps its published theme names and modes', () => {
186
+ expect(midnightLight.name).toBe('midnight-light');
187
+ expect(midnightLight.mode).toBe('light');
188
+ expect(midnightDark.name).toBe('midnight-brand');
189
+ expect(midnightDark.mode).toBe('dark');
190
+ });
191
+
192
+ it('shares one violet ramp across both modes, apart from the enforced action steps', () => {
193
+ const enforced = new Set([500, 600]);
194
+ for (const step of STEPS.filter((s) => !enforced.has(s))) {
195
+ expect(midnightLight.colors.primary[step]).toBe(midnightDark.colors.primary[step]);
196
+ }
197
+ });
198
+
199
+ it('clears AA on the painted accent in both modes', () => {
200
+ for (const theme of [midnightLight, midnightDark]) {
201
+ expect(
202
+ contrastRatio(theme.colors.semantic.textInverted, theme.colors.primary[500]),
203
+ `${theme.name}: textInverted on primary-500`,
204
+ ).toBeGreaterThanOrEqual(4.5);
205
+ }
206
+ });
207
+
208
+ it('keeps the hand-tuned dark shadow tint on the dark theme only', () => {
209
+ expect(midnightDark.shadow).toEqual({ color: '0 0 0', strength: '5.2' });
210
+ expect(midnightLight.shadow).toEqual(defaultTheme.shadow);
211
+ });
212
+
213
+ it.each([midnightLight, midnightDark])(
214
+ '$name clears every AA pair without an allowlist entry',
215
+ (theme) => {
216
+ const { semantic, primary } = theme.colors;
217
+ expect(contrastRatio(semantic.text, semantic.background)).toBeGreaterThanOrEqual(4.5);
218
+ expect(contrastRatio(semantic.textMuted, semantic.background)).toBeGreaterThanOrEqual(3);
219
+ expect(contrastRatio(semantic.focusRing, semantic.background)).toBeGreaterThanOrEqual(3);
220
+ expect(contrastRatio(semantic.textInverted, primary[600])).toBeGreaterThanOrEqual(4.5);
221
+ },
222
+ );
223
+ });