@psnext/design-system 1.5.1 → 2.1.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 (646) hide show
  1. package/DESIGN.md +639 -0
  2. package/README.md +39 -2
  3. package/SKILL.md +101 -0
  4. package/bin/install-agent-skill.mjs +54 -0
  5. package/dist/Header.cjs +32 -29
  6. package/dist/Header.cjs.map +1 -1
  7. package/dist/Header.js +32 -29
  8. package/dist/Header.js.map +1 -1
  9. package/dist/Icon.cjs +19 -19
  10. package/dist/Icon.cjs.map +1 -1
  11. package/dist/Icon.js +19 -19
  12. package/dist/Icon.js.map +1 -1
  13. package/dist/Logo.cjs +4 -14
  14. package/dist/Logo.cjs.map +1 -1
  15. package/dist/Logo.js +4 -14
  16. package/dist/Logo.js.map +1 -1
  17. package/dist/Sidebar.cjs +26 -20
  18. package/dist/Sidebar.cjs.map +1 -1
  19. package/dist/Sidebar.js +21 -21
  20. package/dist/Sidebar.js.map +1 -1
  21. package/dist/cn.cjs +14 -1
  22. package/dist/cn.cjs.map +1 -1
  23. package/dist/cn.js +14 -1
  24. package/dist/cn.js.map +1 -1
  25. package/dist/index.cjs +13 -10
  26. package/dist/index.d.cts +5 -5
  27. package/dist/index.d.cts.map +1 -1
  28. package/dist/index.d.ts +5 -5
  29. package/dist/index.d.ts.map +1 -1
  30. package/dist/index.js +5 -4
  31. package/dist/index10.d.cts +4 -4
  32. package/dist/index10.d.cts.map +1 -1
  33. package/dist/index10.d.ts +7 -7
  34. package/dist/index11.d.cts +3 -3
  35. package/dist/index11.d.cts.map +1 -1
  36. package/dist/index11.d.ts +3 -3
  37. package/dist/index11.d.ts.map +1 -1
  38. package/dist/index12.d.cts +18 -17
  39. package/dist/index12.d.cts.map +1 -1
  40. package/dist/index12.d.ts +18 -17
  41. package/dist/index12.d.ts.map +1 -1
  42. package/dist/index13.d.cts +6 -6
  43. package/dist/index13.d.cts.map +1 -1
  44. package/dist/index13.d.ts +6 -6
  45. package/dist/index14.d.cts +5 -5
  46. package/dist/index14.d.cts.map +1 -1
  47. package/dist/index14.d.ts +5 -5
  48. package/dist/index14.d.ts.map +1 -1
  49. package/dist/index15.d.cts +3 -3
  50. package/dist/index15.d.cts.map +1 -1
  51. package/dist/index15.d.ts +3 -3
  52. package/dist/index15.d.ts.map +1 -1
  53. package/dist/index16.d.cts +2 -2
  54. package/dist/index16.d.cts.map +1 -1
  55. package/dist/index16.d.ts +2 -2
  56. package/dist/index17.d.cts +4 -4
  57. package/dist/index17.d.cts.map +1 -1
  58. package/dist/index17.d.ts +4 -4
  59. package/dist/index17.d.ts.map +1 -1
  60. package/dist/index18.d.cts +11 -11
  61. package/dist/index18.d.cts.map +1 -1
  62. package/dist/index18.d.ts +11 -11
  63. package/dist/index19.d.cts +10 -10
  64. package/dist/index19.d.cts.map +1 -1
  65. package/dist/index19.d.ts +10 -10
  66. package/dist/index19.d.ts.map +1 -1
  67. package/dist/index2.d.cts +8 -8
  68. package/dist/index2.d.cts.map +1 -1
  69. package/dist/index2.d.ts +8 -8
  70. package/dist/index2.d.ts.map +1 -1
  71. package/dist/index20.d.cts +16 -16
  72. package/dist/index20.d.cts.map +1 -1
  73. package/dist/index20.d.ts +16 -16
  74. package/dist/index20.d.ts.map +1 -1
  75. package/dist/index21.d.cts +4 -4
  76. package/dist/index21.d.cts.map +1 -1
  77. package/dist/index21.d.ts +4 -4
  78. package/dist/index22.d.cts +11 -11
  79. package/dist/index22.d.cts.map +1 -1
  80. package/dist/index22.d.ts +11 -11
  81. package/dist/index22.d.ts.map +1 -1
  82. package/dist/index23.d.cts +16 -16
  83. package/dist/index23.d.cts.map +1 -1
  84. package/dist/index23.d.ts +16 -16
  85. package/dist/index23.d.ts.map +1 -1
  86. package/dist/index24.d.cts +10 -10
  87. package/dist/index24.d.cts.map +1 -1
  88. package/dist/index24.d.ts +10 -10
  89. package/dist/index25.d.cts +2 -2
  90. package/dist/index25.d.ts +2 -2
  91. package/dist/index26.d.cts +13 -13
  92. package/dist/index26.d.ts +14 -14
  93. package/dist/index26.d.ts.map +1 -1
  94. package/dist/index27.d.cts +7 -7
  95. package/dist/index27.d.cts.map +1 -1
  96. package/dist/index27.d.ts +7 -7
  97. package/dist/index27.d.ts.map +1 -1
  98. package/dist/index28.d.cts +5 -5
  99. package/dist/index28.d.ts +5 -5
  100. package/dist/index28.d.ts.map +1 -1
  101. package/dist/index29.d.cts +4 -4
  102. package/dist/index29.d.ts +4 -4
  103. package/dist/index29.d.ts.map +1 -1
  104. package/dist/index3.d.cts +13 -13
  105. package/dist/index3.d.cts.map +1 -1
  106. package/dist/index3.d.ts +13 -13
  107. package/dist/index3.d.ts.map +1 -1
  108. package/dist/index30.d.cts +5 -5
  109. package/dist/index30.d.ts +5 -5
  110. package/dist/index31.d.cts +5 -5
  111. package/dist/index31.d.cts.map +1 -1
  112. package/dist/index31.d.ts +5 -5
  113. package/dist/index31.d.ts.map +1 -1
  114. package/dist/index32.d.cts +8 -5
  115. package/dist/index32.d.cts.map +1 -1
  116. package/dist/index32.d.ts +9 -6
  117. package/dist/index32.d.ts.map +1 -1
  118. package/dist/index33.d.cts +14 -10
  119. package/dist/index33.d.cts.map +1 -1
  120. package/dist/index33.d.ts +14 -10
  121. package/dist/index33.d.ts.map +1 -1
  122. package/dist/index34.d.cts +5 -5
  123. package/dist/index34.d.ts +5 -5
  124. package/dist/index35.d.cts +14 -14
  125. package/dist/index35.d.ts +16 -16
  126. package/dist/index35.d.ts.map +1 -1
  127. package/dist/index36.d.cts +3 -3
  128. package/dist/index36.d.cts.map +1 -1
  129. package/dist/index36.d.ts +3 -3
  130. package/dist/index36.d.ts.map +1 -1
  131. package/dist/index37.d.cts +5 -5
  132. package/dist/index37.d.cts.map +1 -1
  133. package/dist/index37.d.ts +4 -4
  134. package/dist/index37.d.ts.map +1 -1
  135. package/dist/index38.d.cts +2 -2
  136. package/dist/index38.d.ts +2 -2
  137. package/dist/index39.d.cts +17 -17
  138. package/dist/index39.d.cts.map +1 -1
  139. package/dist/index39.d.ts +17 -17
  140. package/dist/index39.d.ts.map +1 -1
  141. package/dist/index4.d.cts +2 -2
  142. package/dist/index4.d.cts.map +1 -1
  143. package/dist/index4.d.ts +2 -2
  144. package/dist/index4.d.ts.map +1 -1
  145. package/dist/index40.d.cts +4 -4
  146. package/dist/index40.d.ts +5 -5
  147. package/dist/index40.d.ts.map +1 -1
  148. package/dist/index41.d.cts +11 -11
  149. package/dist/index41.d.cts.map +1 -1
  150. package/dist/index41.d.ts +11 -11
  151. package/dist/index41.d.ts.map +1 -1
  152. package/dist/index42.d.cts +8 -8
  153. package/dist/index42.d.cts.map +1 -1
  154. package/dist/index42.d.ts +8 -8
  155. package/dist/index42.d.ts.map +1 -1
  156. package/dist/index43.d.cts +10 -10
  157. package/dist/index43.d.cts.map +1 -1
  158. package/dist/index43.d.ts +10 -10
  159. package/dist/index43.d.ts.map +1 -1
  160. package/dist/index44.d.cts +1 -48
  161. package/dist/index44.d.ts +1 -48
  162. package/dist/index45.d.cts +42 -22
  163. package/dist/index45.d.cts.map +1 -1
  164. package/dist/index45.d.ts +42 -22
  165. package/dist/index45.d.ts.map +1 -1
  166. package/dist/index46.d.cts +21 -34
  167. package/dist/index46.d.cts.map +1 -1
  168. package/dist/index46.d.ts +21 -34
  169. package/dist/index46.d.ts.map +1 -1
  170. package/dist/index47.d.cts +33 -17
  171. package/dist/index47.d.cts.map +1 -1
  172. package/dist/index47.d.ts +33 -17
  173. package/dist/index47.d.ts.map +1 -1
  174. package/dist/index48.d.cts +18 -14
  175. package/dist/index48.d.cts.map +1 -1
  176. package/dist/index48.d.ts +18 -14
  177. package/dist/index48.d.ts.map +1 -1
  178. package/dist/index49.d.cts +12 -60
  179. package/dist/index49.d.cts.map +1 -1
  180. package/dist/index49.d.ts +12 -60
  181. package/dist/index49.d.ts.map +1 -1
  182. package/dist/index5.d.cts +7 -7
  183. package/dist/index5.d.cts.map +1 -1
  184. package/dist/index5.d.ts +7 -7
  185. package/dist/index5.d.ts.map +1 -1
  186. package/dist/index50.d.cts +55 -49
  187. package/dist/index50.d.cts.map +1 -1
  188. package/dist/index50.d.ts +55 -49
  189. package/dist/index50.d.ts.map +1 -1
  190. package/dist/index51.d.cts +56 -24
  191. package/dist/index51.d.cts.map +1 -1
  192. package/dist/index51.d.ts +56 -24
  193. package/dist/index51.d.ts.map +1 -1
  194. package/dist/index52.d.cts +25 -203
  195. package/dist/index52.d.cts.map +1 -1
  196. package/dist/index52.d.ts +25 -203
  197. package/dist/index52.d.ts.map +1 -1
  198. package/dist/index53.d.cts +198 -15
  199. package/dist/index53.d.cts.map +1 -1
  200. package/dist/index53.d.ts +198 -15
  201. package/dist/index53.d.ts.map +1 -1
  202. package/dist/index54.d.cts +21 -23
  203. package/dist/index54.d.cts.map +1 -1
  204. package/dist/index54.d.ts +21 -23
  205. package/dist/index54.d.ts.map +1 -1
  206. package/dist/index55.d.cts +21 -18
  207. package/dist/index55.d.cts.map +1 -1
  208. package/dist/index55.d.ts +21 -18
  209. package/dist/index55.d.ts.map +1 -1
  210. package/dist/index56.d.cts +21 -8
  211. package/dist/index56.d.cts.map +1 -1
  212. package/dist/index56.d.ts +21 -8
  213. package/dist/index56.d.ts.map +1 -1
  214. package/dist/index57.d.cts +6 -44
  215. package/dist/index57.d.cts.map +1 -1
  216. package/dist/index57.d.ts +6 -44
  217. package/dist/index57.d.ts.map +1 -1
  218. package/dist/index58.d.cts +46 -47
  219. package/dist/index58.d.cts.map +1 -1
  220. package/dist/index58.d.ts +46 -47
  221. package/dist/index58.d.ts.map +1 -1
  222. package/dist/index59.d.cts +47 -59
  223. package/dist/index59.d.cts.map +1 -1
  224. package/dist/index59.d.ts +47 -59
  225. package/dist/index59.d.ts.map +1 -1
  226. package/dist/index6.d.cts +7 -7
  227. package/dist/index6.d.cts.map +1 -1
  228. package/dist/index6.d.ts +7 -7
  229. package/dist/index6.d.ts.map +1 -1
  230. package/dist/index60.d.cts +55 -37
  231. package/dist/index60.d.cts.map +1 -1
  232. package/dist/index60.d.ts +56 -38
  233. package/dist/index60.d.ts.map +1 -1
  234. package/dist/index61.d.cts +38 -14
  235. package/dist/index61.d.cts.map +1 -1
  236. package/dist/index61.d.ts +38 -14
  237. package/dist/index61.d.ts.map +1 -1
  238. package/dist/index62.d.cts +20 -41
  239. package/dist/index62.d.cts.map +1 -1
  240. package/dist/index62.d.ts +20 -41
  241. package/dist/index62.d.ts.map +1 -1
  242. package/dist/index63.d.cts +41 -19
  243. package/dist/index63.d.cts.map +1 -1
  244. package/dist/index63.d.ts +41 -19
  245. package/dist/index63.d.ts.map +1 -1
  246. package/dist/index64.d.cts +14 -39
  247. package/dist/index64.d.cts.map +1 -1
  248. package/dist/index64.d.ts +14 -39
  249. package/dist/index64.d.ts.map +1 -1
  250. package/dist/index65.d.cts +39 -16
  251. package/dist/index65.d.cts.map +1 -1
  252. package/dist/index65.d.ts +39 -16
  253. package/dist/index65.d.ts.map +1 -1
  254. package/dist/index66.d.cts +18 -12
  255. package/dist/index66.d.cts.map +1 -1
  256. package/dist/index66.d.ts +18 -12
  257. package/dist/index66.d.ts.map +1 -1
  258. package/dist/index67.d.cts +12 -30
  259. package/dist/index67.d.cts.map +1 -1
  260. package/dist/index67.d.ts +12 -30
  261. package/dist/index67.d.ts.map +1 -1
  262. package/dist/index68.d.cts +26 -25
  263. package/dist/index68.d.cts.map +1 -1
  264. package/dist/index68.d.ts +28 -27
  265. package/dist/index68.d.ts.map +1 -1
  266. package/dist/index69.d.cts +36 -69
  267. package/dist/index69.d.cts.map +1 -0
  268. package/dist/index69.d.ts +36 -69
  269. package/dist/index69.d.ts.map +1 -0
  270. package/dist/index7.d.cts +8 -8
  271. package/dist/index7.d.cts.map +1 -1
  272. package/dist/index7.d.ts +8 -8
  273. package/dist/index70.d.cts +76 -237
  274. package/dist/index70.d.cts.map +1 -1
  275. package/dist/index70.d.ts +76 -237
  276. package/dist/index70.d.ts.map +1 -1
  277. package/dist/index71.d.cts +249 -0
  278. package/dist/index71.d.cts.map +1 -0
  279. package/dist/index71.d.ts +249 -0
  280. package/dist/index71.d.ts.map +1 -0
  281. package/dist/index8.d.cts +4 -4
  282. package/dist/index8.d.cts.map +1 -1
  283. package/dist/index8.d.ts +4 -4
  284. package/dist/index8.d.ts.map +1 -1
  285. package/dist/index9.d.cts +2 -2
  286. package/dist/index9.d.cts.map +1 -1
  287. package/dist/index9.d.ts +2 -2
  288. package/dist/layouts/Container/index.cjs +4 -4
  289. package/dist/layouts/Container/index.cjs.map +1 -1
  290. package/dist/layouts/Container/index.d.cts +1 -1
  291. package/dist/layouts/Container/index.d.ts +1 -1
  292. package/dist/layouts/Container/index.js +4 -4
  293. package/dist/layouts/Container/index.js.map +1 -1
  294. package/dist/layouts/PageBackground/index.cjs +2 -2
  295. package/dist/layouts/PageBackground/index.cjs.map +1 -1
  296. package/dist/layouts/PageBackground/index.d.cts +1 -1
  297. package/dist/layouts/PageBackground/index.d.ts +1 -1
  298. package/dist/layouts/PageBackground/index.js +2 -2
  299. package/dist/layouts/PageBackground/index.js.map +1 -1
  300. package/dist/layouts/Stack/index.d.cts +1 -1
  301. package/dist/layouts/Stack/index.d.ts +1 -1
  302. package/dist/layouts/TwoColumn/index.d.cts +1 -1
  303. package/dist/layouts/TwoColumn/index.d.ts +1 -1
  304. package/dist/layouts/index.d.cts +4 -4
  305. package/dist/layouts/index.d.ts +4 -4
  306. package/dist/patterns/DataTable/index.cjs +12 -7
  307. package/dist/patterns/DataTable/index.cjs.map +1 -1
  308. package/dist/patterns/DataTable/index.d.cts +3 -3
  309. package/dist/patterns/DataTable/index.d.cts.map +1 -1
  310. package/dist/patterns/DataTable/index.d.ts +3 -3
  311. package/dist/patterns/DataTable/index.d.ts.map +1 -1
  312. package/dist/patterns/DataTable/index.js +12 -7
  313. package/dist/patterns/DataTable/index.js.map +1 -1
  314. package/dist/patterns/Footer/index.cjs +5 -5
  315. package/dist/patterns/Footer/index.cjs.map +1 -1
  316. package/dist/patterns/Footer/index.d.cts +9 -9
  317. package/dist/patterns/Footer/index.d.cts.map +1 -1
  318. package/dist/patterns/Footer/index.d.ts +9 -9
  319. package/dist/patterns/Footer/index.d.ts.map +1 -1
  320. package/dist/patterns/Footer/index.js +5 -5
  321. package/dist/patterns/Footer/index.js.map +1 -1
  322. package/dist/patterns/Header/index.d.cts +1 -1
  323. package/dist/patterns/Header/index.d.ts +1 -1
  324. package/dist/patterns/MediaObject/index.cjs +1 -1
  325. package/dist/patterns/MediaObject/index.cjs.map +1 -1
  326. package/dist/patterns/MediaObject/index.d.cts +13 -13
  327. package/dist/patterns/MediaObject/index.d.cts.map +1 -1
  328. package/dist/patterns/MediaObject/index.d.ts +10 -10
  329. package/dist/patterns/MediaObject/index.js +1 -1
  330. package/dist/patterns/MediaObject/index.js.map +1 -1
  331. package/dist/patterns/NavRail/index.cjs +195 -0
  332. package/dist/patterns/NavRail/index.cjs.map +1 -0
  333. package/dist/patterns/NavRail/index.d.cts +2 -0
  334. package/dist/patterns/NavRail/index.d.ts +2 -0
  335. package/dist/patterns/NavRail/index.js +185 -0
  336. package/dist/patterns/NavRail/index.js.map +1 -0
  337. package/dist/patterns/SectionCard/index.cjs +1 -1
  338. package/dist/patterns/SectionCard/index.cjs.map +1 -1
  339. package/dist/patterns/SectionCard/index.d.cts +2 -2
  340. package/dist/patterns/SectionCard/index.d.cts.map +1 -1
  341. package/dist/patterns/SectionCard/index.d.ts +2 -2
  342. package/dist/patterns/SectionCard/index.d.ts.map +1 -1
  343. package/dist/patterns/SectionCard/index.js +1 -1
  344. package/dist/patterns/SectionCard/index.js.map +1 -1
  345. package/dist/patterns/SectionHeading/index.d.cts +2 -2
  346. package/dist/patterns/SectionHeading/index.d.cts.map +1 -1
  347. package/dist/patterns/SectionHeading/index.d.ts +2 -2
  348. package/dist/patterns/SectionHeading/index.d.ts.map +1 -1
  349. package/dist/patterns/index.cjs +9 -0
  350. package/dist/patterns/index.d.cts +3 -2
  351. package/dist/patterns/index.d.ts +3 -2
  352. package/dist/patterns/index.js +2 -1
  353. package/dist/primitives/Accordion/index.cjs +6 -6
  354. package/dist/primitives/Accordion/index.cjs.map +1 -1
  355. package/dist/primitives/Accordion/index.js +6 -6
  356. package/dist/primitives/Accordion/index.js.map +1 -1
  357. package/dist/primitives/Alert/index.cjs +4 -4
  358. package/dist/primitives/Alert/index.cjs.map +1 -1
  359. package/dist/primitives/Alert/index.js +4 -4
  360. package/dist/primitives/Alert/index.js.map +1 -1
  361. package/dist/primitives/AlertDialog/index.cjs +4 -4
  362. package/dist/primitives/AlertDialog/index.cjs.map +1 -1
  363. package/dist/primitives/AlertDialog/index.js +4 -4
  364. package/dist/primitives/AlertDialog/index.js.map +1 -1
  365. package/dist/primitives/Avatar/index.cjs +5 -5
  366. package/dist/primitives/Avatar/index.cjs.map +1 -1
  367. package/dist/primitives/Avatar/index.js +5 -5
  368. package/dist/primitives/Avatar/index.js.map +1 -1
  369. package/dist/primitives/Badge/index.cjs +11 -10
  370. package/dist/primitives/Badge/index.cjs.map +1 -1
  371. package/dist/primitives/Badge/index.js +11 -10
  372. package/dist/primitives/Badge/index.js.map +1 -1
  373. package/dist/primitives/Breadcrumb/index.cjs +4 -4
  374. package/dist/primitives/Breadcrumb/index.cjs.map +1 -1
  375. package/dist/primitives/Breadcrumb/index.js +4 -4
  376. package/dist/primitives/Breadcrumb/index.js.map +1 -1
  377. package/dist/primitives/Button/index.cjs +20 -13
  378. package/dist/primitives/Button/index.cjs.map +1 -1
  379. package/dist/primitives/Button/index.js +20 -13
  380. package/dist/primitives/Button/index.js.map +1 -1
  381. package/dist/primitives/ButtonGroup/index.cjs +3 -3
  382. package/dist/primitives/ButtonGroup/index.cjs.map +1 -1
  383. package/dist/primitives/ButtonGroup/index.js +3 -3
  384. package/dist/primitives/ButtonGroup/index.js.map +1 -1
  385. package/dist/primitives/Calendar/index.cjs +22 -21
  386. package/dist/primitives/Calendar/index.cjs.map +1 -1
  387. package/dist/primitives/Calendar/index.js +22 -21
  388. package/dist/primitives/Calendar/index.js.map +1 -1
  389. package/dist/primitives/Card/index.cjs +18 -16
  390. package/dist/primitives/Card/index.cjs.map +1 -1
  391. package/dist/primitives/Card/index.js +18 -16
  392. package/dist/primitives/Card/index.js.map +1 -1
  393. package/dist/primitives/Carousel/index.cjs +2 -2
  394. package/dist/primitives/Carousel/index.cjs.map +1 -1
  395. package/dist/primitives/Carousel/index.js +2 -2
  396. package/dist/primitives/Carousel/index.js.map +1 -1
  397. package/dist/primitives/Chart/index.cjs +12 -12
  398. package/dist/primitives/Chart/index.cjs.map +1 -1
  399. package/dist/primitives/Chart/index.js +12 -12
  400. package/dist/primitives/Chart/index.js.map +1 -1
  401. package/dist/primitives/Checkbox/index.cjs +6 -6
  402. package/dist/primitives/Checkbox/index.cjs.map +1 -1
  403. package/dist/primitives/Checkbox/index.js +6 -6
  404. package/dist/primitives/Checkbox/index.js.map +1 -1
  405. package/dist/primitives/CheckboxTree/index.cjs +2 -2
  406. package/dist/primitives/CheckboxTree/index.cjs.map +1 -1
  407. package/dist/primitives/CheckboxTree/index.js +2 -2
  408. package/dist/primitives/CheckboxTree/index.js.map +1 -1
  409. package/dist/primitives/Command/index.cjs +9 -9
  410. package/dist/primitives/Command/index.cjs.map +1 -1
  411. package/dist/primitives/Command/index.js +9 -9
  412. package/dist/primitives/Command/index.js.map +1 -1
  413. package/dist/primitives/ContextMenu/index.cjs +10 -10
  414. package/dist/primitives/ContextMenu/index.cjs.map +1 -1
  415. package/dist/primitives/ContextMenu/index.js +10 -10
  416. package/dist/primitives/ContextMenu/index.js.map +1 -1
  417. package/dist/primitives/Credits/index.cjs +4 -4
  418. package/dist/primitives/Credits/index.cjs.map +1 -1
  419. package/dist/primitives/Credits/index.js +4 -4
  420. package/dist/primitives/Credits/index.js.map +1 -1
  421. package/dist/primitives/Dialog/index.cjs +5 -5
  422. package/dist/primitives/Dialog/index.cjs.map +1 -1
  423. package/dist/primitives/Dialog/index.js +5 -5
  424. package/dist/primitives/Dialog/index.js.map +1 -1
  425. package/dist/primitives/Drawer/index.cjs +5 -5
  426. package/dist/primitives/Drawer/index.cjs.map +1 -1
  427. package/dist/primitives/Drawer/index.js +5 -5
  428. package/dist/primitives/Drawer/index.js.map +1 -1
  429. package/dist/primitives/DropdownMenu/index.cjs +9 -9
  430. package/dist/primitives/DropdownMenu/index.cjs.map +1 -1
  431. package/dist/primitives/DropdownMenu/index.js +9 -9
  432. package/dist/primitives/DropdownMenu/index.js.map +1 -1
  433. package/dist/primitives/Empty/index.cjs +4 -4
  434. package/dist/primitives/Empty/index.cjs.map +1 -1
  435. package/dist/primitives/Empty/index.js +4 -4
  436. package/dist/primitives/Empty/index.js.map +1 -1
  437. package/dist/primitives/Field/index.cjs +5 -5
  438. package/dist/primitives/Field/index.cjs.map +1 -1
  439. package/dist/primitives/Field/index.js +5 -5
  440. package/dist/primitives/Field/index.js.map +1 -1
  441. package/dist/primitives/Form/index.cjs +1 -1
  442. package/dist/primitives/Form/index.cjs.map +1 -1
  443. package/dist/primitives/Form/index.js +1 -1
  444. package/dist/primitives/Form/index.js.map +1 -1
  445. package/dist/primitives/Heading/index.cjs +2 -2
  446. package/dist/primitives/Heading/index.cjs.map +1 -1
  447. package/dist/primitives/Heading/index.js +2 -2
  448. package/dist/primitives/Heading/index.js.map +1 -1
  449. package/dist/primitives/HoverCard/index.cjs +1 -1
  450. package/dist/primitives/HoverCard/index.cjs.map +1 -1
  451. package/dist/primitives/HoverCard/index.js +1 -1
  452. package/dist/primitives/HoverCard/index.js.map +1 -1
  453. package/dist/primitives/InfoBanner/index.cjs +12 -12
  454. package/dist/primitives/InfoBanner/index.cjs.map +1 -1
  455. package/dist/primitives/InfoBanner/index.js +12 -12
  456. package/dist/primitives/InfoBanner/index.js.map +1 -1
  457. package/dist/primitives/Input/index.cjs +13 -7
  458. package/dist/primitives/Input/index.cjs.map +1 -1
  459. package/dist/primitives/Input/index.js +13 -7
  460. package/dist/primitives/Input/index.js.map +1 -1
  461. package/dist/primitives/InputGroup/index.cjs +7 -7
  462. package/dist/primitives/InputGroup/index.cjs.map +1 -1
  463. package/dist/primitives/InputGroup/index.js +7 -7
  464. package/dist/primitives/InputGroup/index.js.map +1 -1
  465. package/dist/primitives/InputOtp/index.cjs +3 -3
  466. package/dist/primitives/InputOtp/index.cjs.map +1 -1
  467. package/dist/primitives/InputOtp/index.js +3 -3
  468. package/dist/primitives/InputOtp/index.js.map +1 -1
  469. package/dist/primitives/Item/index.cjs +6 -6
  470. package/dist/primitives/Item/index.cjs.map +1 -1
  471. package/dist/primitives/Item/index.js +6 -6
  472. package/dist/primitives/Item/index.js.map +1 -1
  473. package/dist/primitives/Kbd/index.cjs +1 -1
  474. package/dist/primitives/Kbd/index.cjs.map +1 -1
  475. package/dist/primitives/Kbd/index.js +1 -1
  476. package/dist/primitives/Kbd/index.js.map +1 -1
  477. package/dist/primitives/Link/index.cjs +4 -4
  478. package/dist/primitives/Link/index.cjs.map +1 -1
  479. package/dist/primitives/Link/index.js +4 -4
  480. package/dist/primitives/Link/index.js.map +1 -1
  481. package/dist/primitives/Menubar/index.cjs +12 -12
  482. package/dist/primitives/Menubar/index.cjs.map +1 -1
  483. package/dist/primitives/Menubar/index.js +12 -12
  484. package/dist/primitives/Menubar/index.js.map +1 -1
  485. package/dist/primitives/NativeSelect/index.cjs +5 -5
  486. package/dist/primitives/NativeSelect/index.cjs.map +1 -1
  487. package/dist/primitives/NativeSelect/index.js +5 -5
  488. package/dist/primitives/NativeSelect/index.js.map +1 -1
  489. package/dist/primitives/NavRail/index.cjs +9 -194
  490. package/dist/primitives/NavRail/index.d.cts +1 -0
  491. package/dist/primitives/NavRail/index.d.ts +1 -0
  492. package/dist/primitives/NavRail/index.js +1 -184
  493. package/dist/primitives/NavigationMenu/index.cjs +7 -7
  494. package/dist/primitives/NavigationMenu/index.cjs.map +1 -1
  495. package/dist/primitives/NavigationMenu/index.js +7 -7
  496. package/dist/primitives/NavigationMenu/index.js.map +1 -1
  497. package/dist/primitives/Pagination/index.cjs +7 -13
  498. package/dist/primitives/Pagination/index.cjs.map +1 -1
  499. package/dist/primitives/Pagination/index.d.cts +1 -1
  500. package/dist/primitives/Pagination/index.d.ts +1 -1
  501. package/dist/primitives/Pagination/index.js +8 -14
  502. package/dist/primitives/Pagination/index.js.map +1 -1
  503. package/dist/primitives/Popover/index.cjs +4 -4
  504. package/dist/primitives/Popover/index.cjs.map +1 -1
  505. package/dist/primitives/Popover/index.js +4 -4
  506. package/dist/primitives/Popover/index.js.map +1 -1
  507. package/dist/primitives/Progress/index.cjs +16 -16
  508. package/dist/primitives/Progress/index.cjs.map +1 -1
  509. package/dist/primitives/Progress/index.d.cts +1 -1
  510. package/dist/primitives/Progress/index.d.ts +1 -1
  511. package/dist/primitives/Progress/index.js +16 -16
  512. package/dist/primitives/Progress/index.js.map +1 -1
  513. package/dist/primitives/RadioGroup/index.cjs +7 -7
  514. package/dist/primitives/RadioGroup/index.cjs.map +1 -1
  515. package/dist/primitives/RadioGroup/index.d.cts +1 -1
  516. package/dist/primitives/RadioGroup/index.d.ts +1 -1
  517. package/dist/primitives/RadioGroup/index.js +7 -7
  518. package/dist/primitives/RadioGroup/index.js.map +1 -1
  519. package/dist/primitives/Resizable/index.cjs +2 -2
  520. package/dist/primitives/Resizable/index.cjs.map +1 -1
  521. package/dist/primitives/Resizable/index.d.cts +1 -1
  522. package/dist/primitives/Resizable/index.d.ts +1 -1
  523. package/dist/primitives/Resizable/index.js +2 -2
  524. package/dist/primitives/Resizable/index.js.map +1 -1
  525. package/dist/primitives/ScrollArea/index.cjs +2 -2
  526. package/dist/primitives/ScrollArea/index.cjs.map +1 -1
  527. package/dist/primitives/ScrollArea/index.d.cts +1 -1
  528. package/dist/primitives/ScrollArea/index.d.ts +1 -1
  529. package/dist/primitives/ScrollArea/index.js +2 -2
  530. package/dist/primitives/ScrollArea/index.js.map +1 -1
  531. package/dist/primitives/Select/index.cjs +8 -8
  532. package/dist/primitives/Select/index.cjs.map +1 -1
  533. package/dist/primitives/Select/index.d.cts +1 -1
  534. package/dist/primitives/Select/index.d.ts +1 -1
  535. package/dist/primitives/Select/index.js +8 -8
  536. package/dist/primitives/Select/index.js.map +1 -1
  537. package/dist/primitives/Separator/index.cjs +1 -1
  538. package/dist/primitives/Separator/index.cjs.map +1 -1
  539. package/dist/primitives/Separator/index.js +1 -1
  540. package/dist/primitives/Separator/index.js.map +1 -1
  541. package/dist/primitives/Sheet/index.cjs +8 -8
  542. package/dist/primitives/Sheet/index.cjs.map +1 -1
  543. package/dist/primitives/Sheet/index.d.cts +1 -1
  544. package/dist/primitives/Sheet/index.d.ts +1 -1
  545. package/dist/primitives/Sheet/index.js +8 -8
  546. package/dist/primitives/Sheet/index.js.map +1 -1
  547. package/dist/primitives/Sidebar/index.d.cts +1 -1
  548. package/dist/primitives/Sidebar/index.d.ts +1 -1
  549. package/dist/primitives/Skeleton/index.cjs +2 -2
  550. package/dist/primitives/Skeleton/index.cjs.map +1 -1
  551. package/dist/primitives/Skeleton/index.d.cts +1 -1
  552. package/dist/primitives/Skeleton/index.d.ts +1 -1
  553. package/dist/primitives/Skeleton/index.js +2 -2
  554. package/dist/primitives/Skeleton/index.js.map +1 -1
  555. package/dist/primitives/Slider/index.cjs +3 -3
  556. package/dist/primitives/Slider/index.cjs.map +1 -1
  557. package/dist/primitives/Slider/index.d.cts +1 -1
  558. package/dist/primitives/Slider/index.d.ts +1 -1
  559. package/dist/primitives/Slider/index.js +3 -3
  560. package/dist/primitives/Slider/index.js.map +1 -1
  561. package/dist/primitives/Sonner/index.cjs +13 -6
  562. package/dist/primitives/Sonner/index.cjs.map +1 -1
  563. package/dist/primitives/Sonner/index.d.cts +1 -1
  564. package/dist/primitives/Sonner/index.d.ts +1 -1
  565. package/dist/primitives/Sonner/index.js +13 -6
  566. package/dist/primitives/Sonner/index.js.map +1 -1
  567. package/dist/primitives/Spinner/index.d.cts +1 -1
  568. package/dist/primitives/Spinner/index.d.ts +1 -1
  569. package/dist/primitives/Switch/index.cjs +7 -7
  570. package/dist/primitives/Switch/index.cjs.map +1 -1
  571. package/dist/primitives/Switch/index.d.cts +1 -1
  572. package/dist/primitives/Switch/index.d.ts +1 -1
  573. package/dist/primitives/Switch/index.js +7 -7
  574. package/dist/primitives/Switch/index.js.map +1 -1
  575. package/dist/primitives/Table/index.cjs +7 -7
  576. package/dist/primitives/Table/index.cjs.map +1 -1
  577. package/dist/primitives/Table/index.d.cts +1 -1
  578. package/dist/primitives/Table/index.d.ts +1 -1
  579. package/dist/primitives/Table/index.js +7 -7
  580. package/dist/primitives/Table/index.js.map +1 -1
  581. package/dist/primitives/Tabs/index.cjs +21 -21
  582. package/dist/primitives/Tabs/index.cjs.map +1 -1
  583. package/dist/primitives/Tabs/index.d.cts +1 -1
  584. package/dist/primitives/Tabs/index.d.ts +1 -1
  585. package/dist/primitives/Tabs/index.js +21 -21
  586. package/dist/primitives/Tabs/index.js.map +1 -1
  587. package/dist/primitives/Text/index.cjs +5 -5
  588. package/dist/primitives/Text/index.cjs.map +1 -1
  589. package/dist/primitives/Text/index.d.cts +1 -1
  590. package/dist/primitives/Text/index.d.ts +1 -1
  591. package/dist/primitives/Text/index.js +5 -5
  592. package/dist/primitives/Text/index.js.map +1 -1
  593. package/dist/primitives/Textarea/index.cjs +20 -8
  594. package/dist/primitives/Textarea/index.cjs.map +1 -1
  595. package/dist/primitives/Textarea/index.d.cts +1 -1
  596. package/dist/primitives/Textarea/index.d.ts +1 -1
  597. package/dist/primitives/Textarea/index.js +20 -8
  598. package/dist/primitives/Textarea/index.js.map +1 -1
  599. package/dist/primitives/ThemeProvider/index.d.cts +1 -1
  600. package/dist/primitives/ThemeProvider/index.d.ts +1 -1
  601. package/dist/primitives/Toggle/index.cjs +11 -10
  602. package/dist/primitives/Toggle/index.cjs.map +1 -1
  603. package/dist/primitives/Toggle/index.d.cts +1 -1
  604. package/dist/primitives/Toggle/index.d.ts +1 -1
  605. package/dist/primitives/Toggle/index.js +11 -10
  606. package/dist/primitives/Toggle/index.js.map +1 -1
  607. package/dist/primitives/ToggleGroup/index.cjs +2 -2
  608. package/dist/primitives/ToggleGroup/index.cjs.map +1 -1
  609. package/dist/primitives/ToggleGroup/index.d.cts +1 -1
  610. package/dist/primitives/ToggleGroup/index.d.ts +1 -1
  611. package/dist/primitives/ToggleGroup/index.js +2 -2
  612. package/dist/primitives/ToggleGroup/index.js.map +1 -1
  613. package/dist/primitives/Tooltip/index.cjs +2 -2
  614. package/dist/primitives/Tooltip/index.cjs.map +1 -1
  615. package/dist/primitives/Tooltip/index.d.cts +1 -1
  616. package/dist/primitives/Tooltip/index.d.ts +1 -1
  617. package/dist/primitives/Tooltip/index.js +2 -2
  618. package/dist/primitives/Tooltip/index.js.map +1 -1
  619. package/dist/primitives/index.cjs +10 -10
  620. package/dist/primitives/index.d.cts +21 -21
  621. package/dist/primitives/index.d.ts +21 -21
  622. package/dist/primitives/index.js +2 -2
  623. package/dist/styles/base.css +23 -4
  624. package/dist/styles/brand-scopes.css +49 -0
  625. package/dist/styles/glass.css +13 -8
  626. package/dist/styles/index.css +8 -9
  627. package/dist/styles/theme.css +141 -90
  628. package/dist/styles/tokens/border-radius.css +8 -8
  629. package/dist/styles/tokens/mode-dark.css +71 -94
  630. package/dist/styles/tokens/mode-light.css +71 -94
  631. package/dist/styles/tokens/shadows.css +4 -7
  632. package/dist/styles/tokens/spacing.css +17 -37
  633. package/dist/styles/tokens/theme-bodhi.css +6 -28
  634. package/dist/styles/tokens/theme-slingshot.css +7 -28
  635. package/dist/styles/tokens/theme-sustain.css +6 -28
  636. package/dist/styles/typography.css +9 -9
  637. package/package.json +8 -2
  638. package/dist/index44.d.cts.map +0 -1
  639. package/dist/index44.d.ts.map +0 -1
  640. package/dist/primitives/NavRail/index.cjs.map +0 -1
  641. package/dist/primitives/NavRail/index.js.map +0 -1
  642. package/dist/styles/semantic.css +0 -178
  643. package/dist/styles/tokens/alpha.css +0 -39
  644. package/dist/styles/tokens/chart-colors-dark.css +0 -18
  645. package/dist/styles/tokens/chart-colors-light.css +0 -18
  646. package/dist/styles/tokens/colors.css +0 -251
package/DESIGN.md ADDED
@@ -0,0 +1,639 @@
1
+ # @psnext/design-system — Design Reference
2
+
3
+ > Audience: **AI agents and developers** building product UI with this design system.
4
+ > This file is the exhaustive reference — what exists, what it's called, and the rules
5
+ > that make output look native to the system. For the hands-on workflow (recipes,
6
+ > guardrails, verification), read [`SKILL.md`](./SKILL.md).
7
+
8
+ - Package: `@psnext/design-system` · React 18.3+/19 · Tailwind **v4** (consumer-compiled)
9
+ - Source of truth for visuals: Figma "PS AI Helix" (tokens are generated from its exports)
10
+ - Live catalog: Storybook (`pnpm storybook:dev` in this repo, port 6006). Every component
11
+ has stories plus a `Screenshot` story used for visual regression — treat stories as
12
+ canonical usage examples.
13
+
14
+ ---
15
+
16
+ ## 1. Install & wiring
17
+
18
+ ```bash
19
+ pnpm add @psnext/design-system
20
+ ```
21
+
22
+ The DS ships **raw, uncompiled CSS**. The consuming app owns Tailwind v4 and compiles
23
+ the DS sheet together with its own code — one preflight, one `:root`, no duplication.
24
+ The DS sheet carries an `@source` directive so the app's Tailwind automatically scans
25
+ DS component source for utility classes; no `content`/config needed for the DS itself.
26
+
27
+ ```css
28
+ /* app.css — order matters */
29
+ @import "tailwindcss";
30
+ @import "@psnext/design-system/styles"; /* tokens + light/dark + brand themes + @theme bridge */
31
+ ```
32
+
33
+ App shell:
34
+
35
+ ```tsx
36
+ import { ThemeProvider } from "@psnext/design-system/primitives/ThemeProvider";
37
+ import { Toaster } from "@psnext/design-system/primitives/Sonner";
38
+
39
+ <ThemeProvider defaultTheme="light" defaultProduct="slingshot">
40
+ <App />
41
+ <Toaster /> {/* once, near the root */}
42
+ </ThemeProvider>
43
+ ```
44
+
45
+ - Peer deps: `react`, `react-dom` only. Radix, cva, lucide-react, recharts, sonner,
46
+ react-hook-form, zod, etc. are bundled dependencies — do not install your own copies
47
+ to interoperate; import from the DS component subpaths.
48
+ - Fonts: **Outfit** (headings), **Inter** (body), **Geist Mono** (mono), each with
49
+ system fallback stacks. The styles import wires the families; host the font files in
50
+ the app (see the Storybook app for a self-hosted example).
51
+
52
+ ### Import paths
53
+
54
+ Every component is a subpath export (best for tree-shaking and for agents — the path
55
+ tells you the layer):
56
+
57
+ ```ts
58
+ import { Button } from "@psnext/design-system/primitives/Button";
59
+ import { Header } from "@psnext/design-system/patterns/Header";
60
+ import { Container } from "@psnext/design-system/layouts/Container";
61
+ import { cn } from "@psnext/design-system"; // root also re-exports utils
62
+ ```
63
+
64
+ Layers: **primitives** (single-purpose building blocks) → **patterns** (opinionated
65
+ compositions: Header, DataTable, Footer…) → **layouts** (page scaffolding: Container,
66
+ Stack, TwoColumn, PageBackground). Prefer the highest layer that fits; do not rebuild
67
+ a pattern out of primitives if the pattern exists.
68
+
69
+ ---
70
+
71
+ ## 2. Theming model
72
+
73
+ Three additive axes, all **CSS-class driven** (never JS-driven — anything driven by JS
74
+ state alone breaks class-toggled captures and SSR):
75
+
76
+ | Axis | Mechanism | Values |
77
+ |---|---|---|
78
+ | Mode | `.dark` class (absence = light) | light / dark |
79
+ | Product (brand) | `.theme-slingshot` / `.theme-bodhi` / `.theme-sustain` (absence = PS AI base) | 4 products |
80
+ | Org (white-label) | reserved — future layer | — |
81
+
82
+ - `ThemeProvider` applies mode + product classes to `<html>` and persists the choice
83
+ (localStorage, falling back to system `prefers-color-scheme`); `useTheme()` exposes
84
+ `{ theme, product, setTheme, toggleTheme, setProduct }`. Products: `slingshot`
85
+ (default), `sustain`, `bodhi`, `psai` (base ramp).
86
+ - **Nested brand scoping is supported**: wrapping any subtree in a `.theme-*` class
87
+ re-scopes the whole brand ramp (and glass tints) for that subtree — brands can be
88
+ shown side by side (`styles/brand-scopes.css` makes the derived aliases re-resolve).
89
+ - **Never use Tailwind's `dark:` variant.** Tokens flip themselves under `.dark`;
90
+ a CI guard (`pnpm lint:dark-variant`) fails the build if `dark:` appears in DS code.
91
+ Consumer code should follow the same rule — if you feel the need for `dark:`, you
92
+ are using a raw color instead of a token.
93
+
94
+ ---
95
+
96
+ ## 3. The token language
97
+
98
+ ### 3.1 Color: context-suffix convention
99
+
100
+ Tailwind puts every theme color into one namespace (any color is technically available
101
+ to `bg-*`, `text-*`, `border-*`, …). The token **name** therefore carries the intended
102
+ usage context as a suffix — always pick the token whose suffix matches the CSS
103
+ property you are setting:
104
+
105
+ | Suffix | Use with | Example |
106
+ |---|---|---|
107
+ | `*-bg` | `bg-*` | `bg-primary-bg`, `bg-info-bg`, `bg-glass-none-bg` |
108
+ | `*-txt` | `text-*` (and `fill-*` for icon glyphs) | `text-primary-txt`, `text-danger-txt` |
109
+ | `*-border` | `border-*`, `divide-*`, `outline-*` | `border-primary-border` |
110
+ | focus tokens | `ring-*` / `outline-*` | `ring-focus`, `ring-focus-error` |
111
+ | `chart-*` | `bg-*`/`fill-*`/`stroke-*` in charts | `fill-chart-blue` |
112
+ | `brand-*`, `*-gradient-from/-to` | context-free brand ramp | `bg-brand-200`, `from-brand-gradient-from` |
113
+
114
+ Writing `text-primary-bg` or `bg-danger-txt` is a smell — the suffix and the property
115
+ must agree. The complete token inventory is in §6 and the CSS variable reference in §7.
116
+
117
+ ### 3.2 Spacing — stock Tailwind
118
+
119
+ Spacing is the **default Tailwind scale**: `p-1` = 4px, `p-4` = 16px, `gap-2` = 8px.
120
+ The number is *steps of 4px*, *not pixels*. When translating from Figma, divide the
121
+ px value by 4 (16px padding → `p-4`; 2px → `p-0.5`). Values off the 4px grid use
122
+ arbitrary syntax (`py-[5.5px]`) — prefer grid values when the design allows.
123
+
124
+ ### 3.3 Radius — px-named design scale
125
+
126
+ Radius is **not** the Tailwind t-shirt scale. The design steps are px-named:
127
+
128
+ `rounded-2 · rounded-4 · rounded-6 · rounded-8 · rounded-10 · rounded-12 · rounded-16 · rounded-24 · rounded-32 · rounded-full · rounded-none`
129
+
130
+ Here the number **is** the pixel value (`rounded-8` = 8px). `rounded-sm/md/lg/xl` are
131
+ cleared and do not exist. The DS `cn()` is configured so numeric radii merge correctly
132
+ against `rounded-full` etc. — always use `cn()` (never bare template strings) when
133
+ combining/overriding classes.
134
+
135
+ ### 3.4 Shadows
136
+
137
+ Only `shadow-sm · shadow-md · shadow-lg · shadow-xl` exist (tokenized); other Tailwind
138
+ shadow steps are cleared.
139
+
140
+ ### 3.5 Typography
141
+
142
+ - Families: `font-sans` (Inter, body — also the default), `font-heading` (Outfit),
143
+ `font-mono` (Geist Mono).
144
+ - Headings: use the `Heading` primitive (`size` 1–7 mapped to the Figma heading ramp;
145
+ `as` controls the rendered tag). Body copy: the `Text` primitive (`size` maps to the
146
+ paragraph tokens: large/regular/small/mini/caption).
147
+ - Raw-tag typography: global styles give bare `h1…h6`/`p` in flow content sensible
148
+ defaults (see `styles/typography.css`); inside components prefer the primitives.
149
+ - Text sizes/line-heights on utilities are stock Tailwind (`text-sm`, `leading-5`, …).
150
+
151
+ ---
152
+
153
+ ## 4. Base layer & escape hatch
154
+
155
+ `styles/base.css` sets suite-wide defaults in `@layer base`: default border color
156
+ (`--primary-border`), focus outline (`outline-focus/50`), page surface
157
+ (`bg-primary-bg text-primary-txt` on `body`).
158
+
159
+ **`ds-no-base`**: add `class="ds-no-base"` to any element to exclude it *and its
160
+ subtree* from those base defaults — the escape hatch for embedding legacy or
161
+ third-party UI during incremental migration. Multiple holes are independent.
162
+
163
+ ---
164
+
165
+ ## 5. Hard rules (things that will look broken if ignored)
166
+
167
+ 1. **No `dark:` variant** — tokens flip under `.dark` by themselves (§2).
168
+ 2. **No shadcn-era names** — these were deleted in the token hard-swap and silently
169
+ compile to nothing: `bg-background`, `text-foreground`, `text-muted-foreground`,
170
+ `bg-card`, `bg-popover`, `bg-accent`, `text-destructive`, `border-border`,
171
+ `ring-ring`, `bg-muted` (alone), `rounded-lg`… Use the context-suffixed tokens.
172
+ 3. **No raw hex / arbitrary colors** for anything the token set covers.
173
+ 4. **Spacing numbers are 4px steps, not px** (§3.2). Radius numbers *are* px (§3.3).
174
+ 5. **Logos are brand identity**: use the `Logo` primitive; never recolor the mark
175
+ (its red + white cut-out are hard-coded on purpose; only the wordmark ink follows
176
+ mode, via CSS).
177
+ 6. **Compose with `cn()`** from `@psnext/design-system` for any conditional/merged
178
+ class strings.
179
+ 7. **Severity mapping** — the DS severity family is `info / success / warning /
180
+ danger`. Libraries that say "error" (Sonner) map to `danger-*` tokens.
181
+ 8. **Charts**: colors come from the `chart-*` palette or the brand ramp; wrap chart
182
+ config colors in `var(--chart-*)` / `var(--brand-500-primary)` — never hex.
183
+
184
+ ---
185
+
186
+ ## 6. Component catalog
187
+
188
+ Format: exports · variant enumerations (`*` = default) · custom props · usage notes.
189
+ Stories in `src/<layer>/<Component>/<Component>.stories.tsx` are the canonical examples.
190
+
191
+ ### Primitives
192
+
193
+ ### Accordion
194
+ - **Exports**: Accordion, AccordionItem, AccordionTrigger, AccordionContent
195
+ - **Variants**: Accordion `variant: line* | bordered`
196
+ - **Notes**: Radix Accordion (controlled/uncontrolled via `type`/`value`); `bordered` wraps the group in a rounded border. AccordionItem needs a `value`.
197
+
198
+ ### Alert
199
+ - **Exports**: Alert, AlertTitle, AlertDescription, AlertContent, AlertAction
200
+ - **Variants**: `variant: default* | destructive`
201
+ - **Custom props**: `flipIcon` — moves leading icon to trailing edge (default `false`).
202
+ - **Notes**: `role="alert"`; compose `AlertContent` (title+description) with a leading `<svg>` and optional `AlertAction`. Not dismissible (use InfoBanner for that).
203
+
204
+ ### AlertDialog
205
+ - **Exports**: AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogMedia, AlertDialogOverlay, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger
206
+ - **Variants**: AlertDialogContent `size: default* | large`; AlertDialogAction `variant: default* | destructive`
207
+ - **Notes**: Radix AlertDialog; `AlertDialogContent` auto-renders portal+overlay. `default` size centers/compacts, `large` left-aligns/widens. Action/Cancel use `buttonVariants` (Cancel = outline).
208
+
209
+ ### AspectRatio
210
+ - **Exports**: AspectRatio
211
+ - **Notes**: Radix AspectRatio.Root passthrough; pass numeric `ratio` prop.
212
+
213
+ ### Avatar
214
+ - **Exports**: Avatar, AvatarImage, AvatarFallback, AvatarBadge, AvatarGroup, AvatarGroupCount
215
+ - **Variants**: Avatar `size: default* | sm | xs | xxs`, `shape: round* | roundrect`
216
+ - **Notes**: Radix Avatar; `AvatarFallback`/`AvatarBadge` read size/shape from the root via group-data. Use `AvatarGroup` to overlap a row + `AvatarGroupCount` for overflow chip.
217
+
218
+ ### Badge
219
+ - **Exports**: Badge, badgeVariants
220
+ - **Variants**: `variant: default* | secondary | destructive | outline | ghost | success | warning | info | ai`, `shape: default* | round`
221
+ - **Custom props**: `asChild` — render child element via Radix Slot (default `false`).
222
+ - **Notes**: Renders `<span>` by default; `ai` variant is a gradient ring with brand label.
223
+
224
+ ### Breadcrumb
225
+ - **Exports**: Breadcrumb, BreadcrumbList, BreadcrumbItem, BreadcrumbLink, BreadcrumbPage, BreadcrumbSeparator, BreadcrumbEllipsis
226
+ - **Custom props**: BreadcrumbLink `asChild` — render passed child (e.g. router Link) instead of `<a>`.
227
+ - **Notes**: Compose `Breadcrumb>BreadcrumbList>BreadcrumbItem`; separator defaults to chevron, overridable via children.
228
+
229
+ ### Button
230
+ - **Exports**: Button, buttonVariants, ButtonProps (type)
231
+ - **Variants**: `variant: default* | destructive | outline | secondary | ghost | link | ai | destructive-ghost`, `size: xs | sm | default* | lg | xl | icon | icon-xs | icon-sm | icon-lg | icon-xl`, `shape: default* (pill) | square`
232
+ - **Custom props**: `asChild` — Radix Slot composition (default `false`); `loading` — show Spinner + disable (default `false`).
233
+ - **Notes**: forwardRef (usable as overlay trigger via `asChild`); spinner only rendered when not `asChild`.
234
+
235
+ ### ButtonGroup
236
+ - **Exports**: ButtonGroup, ButtonGroupSeparator, ButtonGroupText, buttonGroupVariants
237
+ - **Variants**: ButtonGroup `orientation: horizontal* | vertical`
238
+ - **Custom props**: ButtonGroupText `asChild` (default `false`).
239
+ - **Notes**: Merges child borders/corners into one attached unit; `role="group"`.
240
+
241
+ ### Calendar
242
+ - **Exports**: Calendar, CalendarDayButton
243
+ - **Custom props**: `buttonVariant` — Button variant for prev/next nav (default `outline`); `showOutsideDays` (default `true`); `captionLayout` (default `label`, `dropdown` for month/year selects).
244
+ - **Notes**: Wraps react-day-picker `DayPicker` (all its props pass through); themed with DS Button + tokens, `--cell-size:48px`.
245
+
246
+ ### Card
247
+ - **Exports**: Card, CardHeader, CardFooter, CardTitle, CardAction, CardDescription, CardContent, cardVariants, CardProps (type)
248
+ - **Variants**: Card `variant: default* | glass | brand | ai | inverted`, `tint: subtle | light* | medium | heavy` (glass only); CardHeader `align: start | center* | end`; CardFooter `tone: default* | brand | muted | card`
249
+ - **Notes**: `tint` applies only to `variant="glass"`; footer `brand`/`muted`/`card` render a full-width band — pair with `<Card className="overflow-hidden">`. Card defaults to `justify-between` vertical distribution (overridable via className).
250
+
251
+ ### Carousel
252
+ - **Exports**: CarouselApi (type), Carousel, CarouselContent, CarouselItem, CarouselPrevious, CarouselNext
253
+ - **Custom props**: `opts` (Embla options), `plugins`, `orientation: horizontal* | vertical`, `setApi` (receives Embla API).
254
+ - **Notes**: Embla-backed; children must be `CarouselContent>CarouselItem`. Prev/Next auto-disable at ends.
255
+
256
+ ### Chart
257
+ - **Exports**: ChartContainer, ChartTooltip, ChartTooltipContent, ChartLegend, ChartLegendContent, ChartStyle, ChartConfig (type)
258
+ - **Variants**: ChartTooltipContent `indicator: dot* | line | dashed`
259
+ - **Custom props**: ChartContainer `config` (ChartConfig — maps series keys to label/icon/color; required); tooltip `hideLabel`/`hideIndicator`/`nameKey`/`labelKey`; legend `hideIcon`/`nameKey`/`verticalAlign`.
260
+ - **Notes**: Recharts wrapper; must wrap chart JSX in `ChartContainer`. Injects per-series `--color-<key>` CSS vars from config — reference them as `var(--color-<key>)` in Recharts elements.
261
+
262
+ ### Checkbox
263
+ - **Exports**: Checkbox, RichCheckbox
264
+ - **Custom props**: RichCheckbox `title`, `description`, `flipped` — checkbox on right (default `false`).
265
+ - **Notes**: Radix Checkbox; supports `indeterminate` and `aria-invalid` error styling. `RichCheckbox` is a bordered label card.
266
+
267
+ ### CheckboxTree
268
+ - **Exports**: CheckboxTree, CheckboxTreeNode (type)
269
+ - **Custom props**: `nodes` (hierarchical `{id, label, children}` data); `value` (controlled selected ids, required); `onValueChange`; `defaultExpandedIds`.
270
+ - **Notes**: Controlled only; tri-state propagation across subtrees; `role="tree"`. This is the DS answer to hierarchical multi-select.
271
+
272
+ ### Collapsible
273
+ - **Exports**: Collapsible, CollapsibleTrigger, CollapsibleContent
274
+ - **Notes**: Radix Collapsible passthrough (controlled/uncontrolled via `open`/`defaultOpen`); no styling applied.
275
+
276
+ ### Command
277
+ - **Exports**: Command, CommandDialog, CommandInput, CommandList, CommandEmpty, CommandGroup, CommandItem, CommandShortcut, CommandSeparator
278
+ - **Custom props**: CommandDialog `title`/`description` (sr-only a11y strings), `showCloseButton` (default `true`).
279
+ - **Notes**: Built on `cmdk`; `CommandDialog` wraps `Command` inside DS `Dialog` (⌘K palette). Compose `CommandInput`+`CommandList`(`CommandEmpty`/`CommandGroup`/`CommandItem`).
280
+
281
+ ### ContextMenu
282
+ - **Exports**: ContextMenu, ContextMenuTrigger, ContextMenuContent, ContextMenuItem, ContextMenuCheckboxItem, ContextMenuRadioItem, ContextMenuLabel, ContextMenuSeparator, ContextMenuShortcut, ContextMenuGroup, ContextMenuPortal, ContextMenuSub, ContextMenuSubContent, ContextMenuSubTrigger, ContextMenuRadioGroup
283
+ - **Variants**: ContextMenuItem `variant: default* | destructive`
284
+ - **Custom props**: `inset` (Item/SubTrigger/Label) — left-pad to align with icon rows.
285
+ - **Notes**: Radix ContextMenu (right-click); content self-portals. Checkbox/radio items reserve a 32px indicator column.
286
+
287
+ ### Credits
288
+ - **Exports**: Credits, creditsVariants, CreditsProps (type)
289
+ - **Variants**: `variant: default* | warning | critical` (auto-derived from `value` unless overridden)
290
+ - **Custom props**: `value` (balance, required); `lowThreshold` (default `200`); `icon` override; `format` override (default floor+thousands).
291
+ - **Notes**: Color escalates as balance drops (neutral → amber ≤ threshold → red ≤ 0).
292
+
293
+ ### Dialog
294
+ - **Exports**: Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger
295
+ - **Variants**: DialogContent `size: sm | default* | lg | xl`
296
+ - **Custom props**: DialogContent `showCloseButton` (default `true`); DialogFooter `showCloseButton` (default `false`) — appends built-in outline Close.
297
+ - **Notes**: Radix Dialog; `DialogContent` auto-renders portal+overlay and top-right X.
298
+
299
+ ### Drawer
300
+ - **Exports**: Drawer, DrawerPortal, DrawerOverlay, DrawerTrigger, DrawerClose, DrawerContent, DrawerHeader, DrawerFooter, DrawerTitle, DrawerDescription
301
+ - **Notes**: Built on `vaul`; slide `direction` (top/bottom/left/right) set on the `Drawer` root. `DrawerContent` self-portals + renders overlay; bottom drawer shows a drag handle.
302
+
303
+ ### DropdownMenu
304
+ - **Exports**: DropdownMenu, DropdownMenuPortal, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuGroup, DropdownMenuLabel, DropdownMenuItem, DropdownMenuCheckboxItem, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubTrigger, DropdownMenuSubContent
305
+ - **Variants**: DropdownMenuItem `variant: default* | destructive`
306
+ - **Custom props**: `inset` (Item/Label/SubTrigger); Content `sideOffset` (default `4`).
307
+ - **Notes**: Radix DropdownMenu; content self-portals. Checkbox/radio items reserve a 32px indicator column.
308
+
309
+ ### Empty
310
+ - **Exports**: Empty, EmptyHeader, EmptyTitle, EmptyDescription, EmptyContent, EmptyMedia, emptyVariants
311
+ - **Variants**: Empty `variant: default* | outline | background | outline-dashed`; EmptyMedia `variant: default* | icon`
312
+ - **Notes**: Centered empty-state; compose `EmptyHeader`(Media/Title/Description) + `EmptyContent` for actions.
313
+
314
+ ### Field
315
+ - **Exports**: Field, FieldLabel, FieldDescription, FieldError, FieldGroup, FieldLegend, FieldSeparator, FieldSet, FieldContent, FieldTitle
316
+ - **Variants**: Field `orientation: vertical* | horizontal | responsive`; FieldLegend `variant: legend* | label`
317
+ - **Custom props**: FieldError accepts `errors` array (deduped, listed when >1) or `children`; FieldSeparator optional centered label.
318
+ - **Notes**: Layout primitives for forms (non-react-hook-form); `FieldError` is `role="alert"` and renders nothing when empty.
319
+
320
+ ### Form
321
+ - **Exports**: useFormField, Form, FormItem, FormLabel, FormControl, FormDescription, FormMessage, FormField
322
+ - **Notes**: react-hook-form binding layer over the Field primitives; `Form` = RHF `FormProvider`, `FormField` wraps `Controller`. `FormControl` wires id/aria-describedby/aria-invalid via Slot; must be used within `FormField`/`FormItem`.
323
+
324
+ ### Heading
325
+ - **Exports**: Heading, headingVariants, HeadingProps (type)
326
+ - **Variants**: `size: 1 | 2* | 3 | 4 | 5 | 6 | 7`, `weight: normal | medium | semibold` (per-step default: 1–4 normal, 5–7 medium), `align: left | center | right`, `gradient: true | false*`
327
+ - **Custom props**: `as` — semantic element (default `h2`, independent of visual `size`).
328
+ - **Notes**: `gradient` fills text with the brand gradient.
329
+
330
+ ### HoverCard
331
+ - **Exports**: HoverCard, HoverCardTrigger, HoverCardContent
332
+ - **Custom props**: HoverCardContent `align` (default `center`), `sideOffset` (default `4`).
333
+ - **Notes**: Radix HoverCard; content self-portals; fixed 256px surface opened on hover/focus.
334
+
335
+ ### Icon
336
+ - **Exports**: Icon, IconProps (type), IconName (type), ICON_NAMES
337
+ - **Variants**: `color: default* | muted | primary | success | destructive | inverted`, `shape: square | round` (unset = bare glyph), `fill: subtle* | solid` (boxed only), `size: xs | sm | md* | lg | xl`
338
+ - **Custom props**: `icon` (typed lucide name, required); `strokeWidth`; `label` — a11y label (sets `role="img"`, else aria-hidden).
339
+ - **Notes**: Lazily code-splits each lucide icon; `shape` wraps the glyph in a padded box where `fill`/`color` apply.
340
+
341
+ ### InfoBanner
342
+ - **Exports**: InfoBanner, infoBannerVariants, InfoBannerProps (type)
343
+ - **Variants**: `variant: info* | success | warning | error | neutral`
344
+ - **Custom props**: `title` (required); `description`; `icon` override; `dismissible` (default `true`); `visible` (controlled); `onDismiss`.
345
+ - **Notes**: `role="status"`; dismissible — distinct from the non-dismissible Alert.
346
+
347
+ ### Input
348
+ - **Exports**: Input, inputVariants
349
+ - **Variants**: `variant: default* | ai`, `size: xs | sm | default* | lg`, `shape: default* (12px) | round (pill)`
350
+ - **Notes**: Native `<input>` passthrough; `ai` swaps border for the AI gradient; `aria-invalid` triggers the error ring.
351
+
352
+ ### InputGroup
353
+ - **Exports**: InputGroup, InputGroupAddon, InputGroupButton, InputGroupText, InputGroupInput, InputGroupTextarea
354
+ - **Variants**: InputGroup `variant: default* | ai`; InputGroupAddon `align: inline-start* | inline-end | block-start | block-end`; InputGroupButton `size: xs* | sm | icon-xs | icon-sm`
355
+ - **Notes**: `role="group"` bordered container; use `InputGroupInput`/`InputGroupTextarea` (borderless) so the group provides the chrome; clicking an addon focuses the input; focus/error bubble via `has-`.
356
+
357
+ ### InputOtp
358
+ - **Exports**: InputOTP, InputOTPGroup, InputOTPSlot, InputOTPSeparator
359
+ - **Variants**: InputOTP `size: default* | lg | sm | xs`
360
+ - **Custom props**: `containerClassName`; `placeholder` (single hint char).
361
+ - **Notes**: Built on `input-otp`; compose `InputOTPGroup>InputOTPSlot index={n}` around `InputOTPSeparator`; size shared via context.
362
+
363
+ ### Item
364
+ - **Exports**: Item, ItemMedia, ItemContent, ItemActions, ItemGroup, ItemSeparator, ItemTitle, ItemDescription, ItemHeader, ItemFooter
365
+ - **Variants**: Item `variant: default* | outline | muted`, `size: default* | sm`; ItemMedia `variant: default* | icon | image`
366
+ - **Custom props**: Item `asChild` (default `false`)
367
+ - **Notes**: Compose ItemMedia/ItemContent(ItemTitle+ItemDescription)/ItemActions inside Item; ItemGroup is `role="list"`.
368
+
369
+ ### Kbd
370
+ - **Exports**: Kbd, KbdGroup
371
+ - **Notes**: Renders a `<kbd>` keycap; wrap multiple in KbdGroup for a combo. Special styling inside tooltip content.
372
+
373
+ ### Label
374
+ - **Exports**: Label
375
+ - **Variants**: `align: block* | inline`
376
+ - **Notes**: Radix Label.Root; dims via peer-disabled / group-data-[disabled]. Pair with control via `htmlFor`.
377
+
378
+ ### Link
379
+ - **Exports**: Link, linkVariants, LinkProps (type)
380
+ - **Variants**: `variant: default* | muted | subtle`, `underline: always* | hover`
381
+ - **Custom props**: `asChild` — render a router link instead of `<a>` (default `false`).
382
+
383
+ ### Logo
384
+ - **Exports**: Logo, LogoBrand (type), LogoVariant (type)
385
+ - **Variants**: `variant: logo* | icon`
386
+ - **Custom props**: `brand: bodhi | slingshot | sustain | psai` (required)
387
+ - **Notes**: Inline SVG; never recolor — brand colors are fixed; wordmark ink follows mode via CSS (no provider needed). psai `icon` falls back to the full logo.
388
+
389
+ ### Menubar
390
+ - **Exports**: Menubar, MenubarPortal, MenubarMenu, MenubarTrigger, MenubarContent, MenubarGroup, MenubarSeparator, MenubarLabel, MenubarItem, MenubarShortcut, MenubarCheckboxItem, MenubarRadioGroup, MenubarRadioItem, MenubarSub, MenubarSubTrigger, MenubarSubContent
391
+ - **Variants**: MenubarItem `variant: default* | destructive`
392
+ - **Custom props**: Item/Label/SubTrigger `inset` (default `false`)
393
+ - **Notes**: Radix Menubar; content self-portals; auto-indents plain items when checkbox/radio items present.
394
+
395
+ ### NativeSelect
396
+ - **Exports**: NativeSelect, nativeSelectVariants
397
+ - **Variants**: `size: xs | sm | default* | lg`
398
+ - **Notes**: Styled native `<select>` with chevron affordance; pass `<option>`/`<optgroup>` children; mirrors Input visuals.
399
+
400
+ ### NavigationMenu
401
+ - **Exports**: NavigationMenu, NavigationMenuList, NavigationMenuItem, NavigationMenuContent, NavigationMenuTrigger, NavigationMenuLink, NavigationMenuIndicator, NavigationMenuViewport, navigationMenuTriggerStyle
402
+ - **Custom props**: NavigationMenu `viewport` (default `true` — shared animated viewport; `false` renders content inline)
403
+ - **Notes**: Radix NavigationMenu; `NavigationMenuLink` takes `active` to mark the current page.
404
+
405
+ ### Pagination
406
+ - **Exports**: Pagination, PaginationContent, PaginationLink, PaginationItem, PaginationPrevious, PaginationNext, PaginationEllipsis
407
+ - **Custom props**: PaginationLink `isActive` (aria-current; default `false`), `size` (default `icon`)
408
+ - **Notes**: Links styled via buttonVariants (active = outline, else ghost).
409
+
410
+ ### Popover
411
+ - **Exports**: Popover, PopoverTrigger, PopoverContent, PopoverAnchor, PopoverHeader, PopoverTitle, PopoverDescription
412
+ - **Custom props**: PopoverContent `align` (default `center`), `sideOffset` (default `6`)
413
+ - **Notes**: Radix Popover; content self-portals; Card-style surface (w-72, glass-none-bg).
414
+
415
+ ### Progress
416
+ - **Exports**: Progress
417
+ - **Variants**: `variant: default* | brand | success | warning | info | destructive | analyzing | ingesting`
418
+ - **Custom props**: `value` (omit/null → indeterminate sliding segment)
419
+ - **Notes**: Radix Progress; variant sets both track and indicator colors.
420
+
421
+ ### RadioGroup
422
+ - **Exports**: RadioGroup, RadioGroupItem, RichRadioItem
423
+ - **Variants**: RadioGroup `orientation: vertical* | horizontal`
424
+ - **Custom props**: RichRadioItem `value` (required), `title`, `description`, `flipped` (default `false`)
425
+ - **Notes**: Radix RadioGroup; RichRadioItem is a card-style label, highlights on checked; aria-invalid flips dot to danger.
426
+
427
+ ### Resizable
428
+ - **Exports**: ResizableHandle, ResizablePanel, ResizablePanelGroup
429
+ - **Custom props**: ResizableHandle `withHandle` — visible grip (default `false`)
430
+ - **Notes**: react-resizable-panels; set `orientation` on the group; size via defaultSize/minSize/maxSize.
431
+
432
+ ### ScrollArea
433
+ - **Exports**: ScrollArea, ScrollBar
434
+ - **Variants**: ScrollBar `orientation: vertical* | horizontal`
435
+ - **Notes**: Radix ScrollArea; ScrollArea auto-renders viewport + vertical bar + corner.
436
+
437
+ ### Select
438
+ - **Exports**: Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue
439
+ - **Variants**: SelectTrigger `size: sm | default* | lg`, `width: full* | fit`
440
+ - **Custom props**: SelectTrigger `label` — stacked label above value (2-line trigger)
441
+ - **Notes**: Radix Select; content self-portals, defaults `position="popper"`.
442
+
443
+ ### Separator
444
+ - **Exports**: Separator, SeparatorSpacing (type)
445
+ - **Variants**: `spacing: none* | regular | spacious`; `orientation: horizontal* | vertical`
446
+ - **Custom props**: `decorative` (default `true`)
447
+
448
+ ### Sheet
449
+ - **Exports**: Sheet, SheetTrigger, SheetClose, SheetContent, SheetHeader, SheetFooter, SheetTitle, SheetDescription
450
+ - **Variants**: SheetContent `side: top | right* | bottom | left`, `overlay: default* | dark | glass | none`
451
+ - **Custom props**: SheetContent `showCloseButton` (default `true`)
452
+ - **Notes**: Radix Dialog under the hood; content self-portals with overlay; radius on the inward edge only.
453
+
454
+ ### Sidebar
455
+ - **Exports**: Sidebar, SidebarProvider, SidebarTrigger, SidebarRail, SidebarInset, SidebarInput, SidebarHeader, SidebarFooter, SidebarContent, SidebarGroup, SidebarGroupLabel, SidebarGroupAction, SidebarGroupContent, SidebarMenu, SidebarMenuItem, SidebarMenuButton, SidebarMenuAction, SidebarMenuBadge, SidebarMenuSkeleton, SidebarMenuSub, SidebarMenuSubItem, SidebarMenuSubButton, SidebarSeparator, useSidebar
456
+ - **Variants**: Sidebar `side: left* | right`, `variant: sidebar* | floating | inset`, `collapsible: offcanvas* | icon | none`
457
+ - **Notes**: Wrap the layout in `SidebarProvider` (owns open state, cookie persistence, and the keyboard shortcut); renders as a fixed desktop rail or a mobile Sheet. `useSidebar()` must be inside the provider. For a compact app rail prefer `NavRail`.
458
+
459
+ ### Skeleton
460
+ - **Exports**: Skeleton, SkeletonAvatar, SkeletonLine, SkeletonObject
461
+ - **Notes**: `skeleton-shimmer` divs; presets: Avatar (size-10 round), Line (h-4 full), Object (96px block).
462
+
463
+ ### Slider
464
+ - **Exports**: Slider
465
+ - **Custom props**: `min` (default `0`), `max` (default `100`); array `value`/`defaultValue` → one thumb per item (two = range)
466
+ - **Notes**: Radix Slider; step/orientation/disabled/onValueChange pass through.
467
+
468
+ ### Sonner
469
+ - **Exports**: Toaster
470
+ - **Custom props**: `theme` (default `system`), `position` (default `top-center`), `closeButton` (default `true`)
471
+ - **Notes**: Render `<Toaster />` once at app root; fire with `toast()` / `toast.success/error/warning/info(...)` imported from `"sonner"`. Severity colors are tokenized via `data-[type=…]` classes (error → danger tokens).
472
+
473
+ ### Spinner
474
+ - **Exports**: Spinner
475
+ - **Notes**: Loader2 with animate-spin, `role="status"`; size/color via className.
476
+
477
+ ### Switch
478
+ - **Exports**: Switch, SwitchGroup, RichSwitchGroup
479
+ - **Variants**: `size: sm | default*`
480
+ - **Custom props**: SwitchGroup `label`, `flipped`; RichSwitchGroup `title`, `description`, `flipped`
481
+ - **Notes**: Radix Switch; groups auto-wire label htmlFor; RichSwitchGroup is a bordered card label.
482
+
483
+ ### Table
484
+ - **Exports**: Table, TableHeader, TableBody, TableFooter, TableHead, TableRow, TableCell, TableCaption
485
+ - **Custom props**: Table `striped` (default `false`)
486
+ - **Notes**: Wraps `<table>` in an overflow-x-auto container; TableRow supports hover + `data-state="selected"`. For sorting/pagination use the DataTable pattern.
487
+
488
+ ### Tabs
489
+ - **Exports**: Tabs, TabsList, TabsTrigger, TabsContent, TabsCounter, tabsListVariants, tabsTriggerVariants
490
+ - **Variants**: Tabs `variant: line | pill* | segmented | fancy`, `size: sm | md* | lg`, `orientation: horizontal* | vertical`
491
+ - **Custom props**: TabsList `tabPrefix`/`tabSuffix` (nodes)
492
+ - **Notes**: Set variant/size/orientation on the root only (shared via context). `segmented` has an animated sliding indicator; `fancy` merges the active tab into the TabsContent glass panel.
493
+
494
+ ### Text
495
+ - **Exports**: Text, textVariants, TextProps (type)
496
+ - **Variants**: `size: large | regular* | small | mini | caption`, `weight: normal* | medium | semibold`, `variant: default* | muted | primary | destructive | success`, `font: body* | heading | mono`, `align: left | center | right`, `truncate: true`
497
+ - **Custom props**: `as` (default `p`)
498
+ - **Notes**: Body-copy primitive; sizes map to the paragraph type-scale tokens.
499
+
500
+ ### Textarea
501
+ - **Exports**: Textarea, textareaVariants
502
+ - **Variants**: `variant: default* | ai` (gradient border), `shape: default* (12px) | round (16px)`
503
+ - **Notes**: Auto-grows via `field-sizing-content`; chrome matches Input; supports aria-invalid.
504
+
505
+ ### ThemeProvider
506
+ - **Exports**: ThemeProvider, useTheme, ThemeContext, ThemeMode (type), ThemeProduct (type)
507
+ - **Custom props**: `defaultTheme: light* | dark`, `defaultProduct: slingshot* | sustain | bodhi | psai`, `storageKey` (default `ds-theme-preferences`)
508
+ - **Notes**: Applies to `<html>`: dark toggles `.dark`, product toggles `.theme-{product}`. Persists `{theme, product}` in one localStorage entry; first load: stored → system `prefers-color-scheme` → defaults. `useTheme()` → `{ theme, product, setTheme, toggleTheme, setProduct }`; throws outside the provider.
509
+
510
+ ### Toggle
511
+ - **Exports**: Toggle, toggleVariants
512
+ - **Variants**: `variant: default* | outline`, `size: xs | sm | default* | lg`, `shape: default* (8px) | round | left | middle | right`
513
+ - **Notes**: Radix Toggle; active = `data-[state=on]`; left/middle/right shapes join into segmented groups.
514
+
515
+ ### ToggleGroup
516
+ - **Exports**: ToggleGroup, ToggleGroupItem
517
+ - **Variants**: shared toggleVariants `variant: default | outline`, `size: sm | default | lg`; ToggleGroup `radius: default* (8px) | round`
518
+ - **Custom props**: ToggleGroup `spacing` (gap units; `0`* collapses into one segmented control); ToggleGroupItem `value` (required)
519
+ - **Notes**: Set `type="single"` or `"multiple"`; variant/size/radius/spacing flow to items via context.
520
+
521
+ ### Tooltip
522
+ - **Exports**: Tooltip, TooltipTrigger, TooltipContent, TooltipProvider
523
+ - **Custom props**: TooltipProvider `delayDuration` (default `0`); TooltipContent `sideOffset` (default `0`)
524
+ - **Notes**: `Tooltip` self-wraps a provider (no outer provider needed); content self-portals with arrow; inverted pill surface; trigger supports `asChild`.
525
+
526
+ ### Patterns
527
+
528
+ ### DataTable
529
+ - **Exports**: `DataTable`, `DataTableColumnHeader`, type `ColumnDef` (re-exported from @tanstack/react-table)
530
+ - **Custom props** (DataTable): `columns` — TanStack ColumnDef array; `data` — row objects array; `striped` — zebra rows (default `true`); `enablePagination` — client-side pagination (default `true`); `pageSize` — rows per page (default `10`). (DataTableColumnHeader): `column` — TanStack Column instance; `title` — column label; `className`.
531
+ - **Notes**: Generic `<TData, TValue>`, built on TanStack Table (sorting + row selection built in); drop `DataTableColumnHeader` into a column's `header` for click-to-sort.
532
+
533
+ ### Footer
534
+ - **Exports**: `Footer`, `FooterStart`, `FooterCenter`, `FooterEnd`, `FooterPoweredBy`, `FooterSeparator`
535
+ - **Custom props** (Footer): `bordered` — subtle top border (default `false`); `background` — `none` (default) | `muted` | `glass`. (FooterPoweredBy): `label` — override "Powered by" text.
536
+ - **Notes**: Responsive 3-region grid (start/center/end), stacks centered on mobile, spreads on md+. Compositional — assemble from the region parts + Text/Link/Logo.
537
+
538
+ ### Header
539
+ - **Exports**: `Header` (wired), `HeaderBar`, `HeaderLogo`, `OrgPill`, `ProfileMenu`, `ThemeToggle`, `ProjectPicker`; hooks/data layer `useGlobalHeader`, `useHeaderCredits`, `useHeaderProject`, `getSessionToken`, `isSessionValid`, `buildEndpoints`, `DEFAULT_LABELS`; consts/types `TOGGLE_PROJECT_DROPDOWN_EVENT`, `GlobalHeaderState`, `ToggleProjectDropdownDetail`, `HeaderSelection`, `UseHeaderProjectResult`, `Labels`, `Fetcher`, `HeaderEndpoints`, `HeaderProps`, `ProjectNode`
540
+ - **Custom props** (HeaderProps): `apiBaseUrl` — studio-auth API host (required); `environmentId` — reads `{environmentId}-sessionId` cookie (required); `logoType` — ThemeProduct, defaults to active product; `logoHref` — logo link destination (defaults to the product's public site); `showOrg`/`showProjectDropdown`/`showProfile`/`showThemeSwitcher`/`showCredits` — visibility toggles (all default `false`); `pageTitle`; `feedbackUrl`; `clientId` — active org id; `_dangerouslyInjectAccessToken` — escape hatch, avoid; `onProjectChange`; `onCloseProjectOverlay`; `logoAddon` — node between logo and picker; `endpoints` — per-path overrides; `fetcher` — custom fetch (default global); `staleTime` (default 5 min); `gcTime` (default 10 min).
541
+ - **Notes**: Must render inside a `<ThemeProvider>`; owns an internal singleton QueryClient (no app setup). Logged-out users see no user content; `ProjectNode` shape = `{ id, name, children: ProjectNode[], isContextOnly? }`.
542
+
543
+ ### MediaObject
544
+ - **Exports**: `MediaObject`, `MediaObjectImage`, `MediaObjectIcon`, `MediaObjectContent`, `MediaObjectTitle`, `MediaObjectText`, `MediaObjectActions`, `MediaObjectGroup`, `mediaObjectGroupVariants`, types `MediaObjectProps`, `MediaObjectImageProps`, `MediaObjectTitleProps`, `MediaObjectGroupProps`
545
+ - **Variants** (MediaObjectGroup): `columns`: `1` | `2` | `3`* | `4`; `gap`: `sm` | `md` | `lg`*
546
+ - **Custom props**: (MediaObject) `interactive` — CSS hover lift + shadow. (MediaObjectImage) `alt` — required alt text. (MediaObjectTitle) `size` — Heading size (default `"4"`).
547
+ - **Notes**: Radix-style compositional card; root is `<article>`, image is 16/9 cover; pure-CSS hover (no JS state).
548
+
549
+ ### NavRail
550
+ - **Exports**: NavRail, NavRailItem, NavRailUser, NavRailSeparator, NavRailMenu, NavRailMenuTrigger, NavRailMenuContent, NavRailMenuItem, + prop types
551
+ - **Variants**: NavRail `mode: icon* | text | expanded | expand-on-hover`
552
+ - **Custom props**: NavRailItem `label` (required — tooltip+aria+inline label), `active`, `asChild`, `tooltipSide: top | right* | bottom | left`; NavRailUser `avatar`/`name`/`email`
553
+ - **Notes**: `mode` shared via context; icon mode wraps items in Tooltip; NavRailMenu wraps Popover (flyout submenu). Place the rail as a `shrink-0` flex child. Import from `@psnext/design-system/patterns` (also re-exported from `@psnext/design-system/primitives` for back-compat — it used to be a primitive).
554
+
555
+ ### SectionCard
556
+ - **Exports**: `SectionCard`, type `SectionCardProps`
557
+ - **Custom props**: `title` — header title node (required); `action` — optional right-aligned slot (e.g. Button).
558
+ - **Notes**: Wraps Card `variant="glass" tint="light"`; header row (title + action) plus body slot for arbitrary children.
559
+
560
+ ### SectionHeading
561
+ - **Exports**: `SectionHeading`, type `SectionHeadingProps`
562
+ - **Custom props**: `title` — main heading (required); `subtitle`; `eyebrow` — small label above; `align` — `center`* | `left`; `gradient` — brand-gradient title fill (default `false`); `titleSize` — Heading scale (default `"1"`); `titleAs` — title element (default `h2`).
563
+ - **Notes**: Composed from Stack + Heading + Text primitives; centered by default.
564
+
565
+ ### Layouts
566
+
567
+ ### Container
568
+ - **Exports**: `Container`, `containerVariants`, type `ContainerProps`
569
+ - **Variants**: `size`: `narrow` (900px) | `content`* (1200px) | `wide` (1440px) | `full`; `variant`: `default`* | `glass` (translucent blurred panel)
570
+ - **Custom props**: `as` — element/component to render (default `div`).
571
+ - **Notes**: Centered max-width column with gutters; `glass` uses `bg-glass-40-bg backdrop-blur-glass`.
572
+
573
+ ### PageBackground
574
+ - **Exports**: `PageBackground`, type `PageBackgroundProps`
575
+ - **Custom props**: `fixed` — fixed to viewport (default `true`) vs absolute-fill of positioned parent.
576
+ - **Notes**: Ambient theme-aware radial gradient built from `--brand-gradient-from/-to` (reacts to `.theme-*` + `.dark`); decorative (`aria-hidden`).
577
+
578
+ ### Stack
579
+ - **Exports**: `Stack`, `stackVariants`, type `StackProps`
580
+ - **Variants**: `direction`: `vertical`* | `horizontal`; `gap`: `none` | `xs` | `sm` | `md`* | `lg` | `xl` | `2xl`; `align`: `start` | `center` | `end` | `stretch`*; `justify`: `start` | `center` | `between` | `end`
581
+ - **Custom props**: `as` — render as different element (default `div`).
582
+
583
+ ### TwoColumn
584
+ - **Exports**: `TwoColumn`, `TwoColumnAside`, `TwoColumnMain`, `twoColumnVariants`, type `TwoColumnProps`
585
+ - **Variants** (TwoColumn): `gap`: `none` | `sm` | `md` | `lg`* | `xl`; `reverse`: aside after main at lg+
586
+ - **Notes**: Compose `<TwoColumn><TwoColumnAside/><TwoColumnMain/></TwoColumn>`; stacks below `lg`. Aside default `lg:w-64` (override via className); Main is `min-w-0 flex-1`.
587
+
588
+ ### Utils
589
+
590
+ ### cn
591
+ - **Exports**: `cn`
592
+ - **Notes**: `clsx` + `extendTailwindMerge` with the px-named radius class groups (`rounded-2/4/6/8/10/12/16/24/32`) so DS radii merge/override correctly. Always use it for combined/conditional class strings.
593
+
594
+ ### useIsMobile
595
+ - **Exports**: `useIsMobile`
596
+ - **Notes**: Returns boolean; `matchMedia` below 768px = mobile.
597
+
598
+ ---
599
+
600
+ ## 7. Token & utility inventory
601
+
602
+ ### 7.1 Tailwind utility surface
603
+
604
+ **Color tokens** (each usable with `bg-*`/`text-*`/`border-*`/`ring-*`/`fill-*`; the suffix signals the intended property — keep them matched):
605
+
606
+ - Backgrounds (`-bg`): `primary-bg`, `primary-invert-bg`, `secondary-bg`, `muted-bg`, `info-bg`, `success-bg`, `warning-bg`, `danger-bg`, `primary-invert-hover-bg`, `secondary-hover-bg`, `outline-bg`, `outline-hover-bg`, `ghost-bg`, `ghost-hover-bg`, `toggle-active-bg`, `input-bg`, `switch-active-bg`, `navbar-active-bg`, `overlay-bg`
607
+ - Glass surfaces (`-bg`, pair with `backdrop-blur-glass`): `glass-20-bg`, `glass-40-bg`, `glass-60-bg`, `glass-none-bg` (opaque card surface)
608
+ - Content (`-txt`): `primary-txt`, `primary-invert-txt`, `secondary-txt`, `muted-txt`, `info-txt`, `success-txt`, `warning-txt`, `danger-txt`
609
+ - Borders (`-border`): `primary-border`, `primary-invert-border`, `secondary-border`, `muted-border`, `selected-border`, `info-border`, `success-border`, `warning-border`, `danger-border`
610
+ - Focus rings: `ring-focus`, `ring-focus-error` (also valid as `outline-focus`)
611
+ - Brand ramp (context-free): `brand-50`, `brand-200`, `brand-500-primary`, `brand-700`, `brand-800`, `brand-950`
612
+ - Gradient stops (→ `from-*`/`to-*`): `brand-gradient-from`, `brand-gradient-to`, `ai-gradient-from`, `ai-gradient-to`
613
+ - Charts: `chart-1`…`chart-5` (categorical default order) and named pairs `chart-blue`, `chart-blue-subtle`, `chart-emerald(-subtle)`, `chart-amber(-subtle)`, `chart-red(-subtle)`, `chart-purple(-subtle)`, `chart-lime(-subtle)`, `chart-indigo(-subtle)`, `chart-orange(-subtle)`
614
+
615
+ **Radius** (t-shirt sizes cleared): `rounded-none`, `rounded-2`, `rounded-4`, `rounded-6`, `rounded-8`, `rounded-10`, `rounded-12`, `rounded-16`, `rounded-24`, `rounded-32`, `rounded-full` — number = px.
616
+
617
+ **Shadows** (only these): `shadow-sm`, `shadow-md`, `shadow-lg`, `shadow-xl`.
618
+
619
+ **Blur**: `backdrop-blur-glass` (45px — the glass surface blur).
620
+
621
+ **Special utility**: `ai-border` — 2px gradient "AI affordance" border (driven by `--ai-surface`, `--ai-gradient-from/-to`).
622
+
623
+ **Fonts**: `font-sans` (Inter, default body), `font-heading` (Outfit), `font-mono` (Geist Mono).
624
+
625
+ **Typography tokens** are raw CSS vars (not utilities) — normally consumed via the `Heading`/`Text` primitives; raw `h1`–`h6` in flow content pick up the scale automatically. Families (each with `-font-size`, `-line-height`, `-spacing`, `-letter-spacing`, `-weight`): `--heading-1` (48/48) … `--heading-7` (12/24); `--paragraph-large` (18/27), `--paragraph-regular` (16/24), `--paragraph-small` (14/20), `--paragraph-mini` (12/16); `--caption` (14/21, +1.5px tracking); `--monospaced` (16/24).
626
+
627
+ ### 7.2 Raw CSS variables (for rare arbitrary-value / chart-config use)
628
+
629
+ Both mode files define the identical names (`mode-light.css` on `:root`, `mode-dark.css` on `.dark`); only values differ. Use these as `var(--…)` only where a utility can't reach (chart configs, inline SVG fills, gradients):
630
+
631
+ - Backgrounds: `--primary-bg`, `--primary-invert-bg`, `--secondary-bg`, `--muted-bg`, `--info-bg`, `--success-bg`, `--warning-bg`, `--danger-bg`, `--primary-invert-hover-bg`, `--secondary-hover-bg`, `--outline-bg`, `--outline-hover-bg`, `--ghost-bg`, `--ghost-hover-bg`, `--toggle-active-bg`, `--input-bg`, `--switch-active-bg`, `--navbar-active-bg`, `--overlay-bg`
632
+ - Glass: `--glass-20-bg`, `--glass-40-bg`, `--glass-60-bg`, `--glass-none-bg`; blur: `--glass-blur`
633
+ - Text: `--primary-txt`, `--primary-invert-txt`, `--secondary-txt`, `--muted-txt`, `--info-txt`, `--success-txt`, `--warning-txt`, `--danger-txt`
634
+ - Borders: `--primary-border`, `--primary-invert-border`, `--secondary-border`, `--muted-border`, `--selected-border`, `--info-border`, `--success-border`, `--warning-border`, `--danger-border`
635
+ - Focus: `--focus`, `--focus-error`
636
+ - Brand: `--brand-50`, `--brand-200`, `--brand-500-primary`, `--brand-700`, `--brand-800`, `--brand-950`; gradient stops `--brand-gradient-from`, `--brand-gradient-to` (resolve from the per-product `--theme-brand-*` stops)
637
+ - Charts: `--chart-1`…`--chart-5`; `--chart-blue(-subtle)`, `--chart-emerald(-subtle)`, `--chart-amber(-subtle)`, `--chart-red(-subtle)`, `--chart-purple(-subtle)`, `--chart-lime(-subtle)`, `--chart-indigo(-subtle)`, `--chart-orange(-subtle)`
638
+ - AI affordance: `--ai-surface`, `--ai-gradient-from`, `--ai-gradient-to`
639
+ - Logo ink: `--logo-mark-dark` (mode-driven, defined in base.css)