@elabs-ai/components-ui 5.0.0 → 5.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 (543) hide show
  1. package/README.md +1 -1
  2. package/dist/{chunk-E3ES2KR6.js → chunk-2DFB4YTK.js} +5 -5
  3. package/dist/{chunk-6QU7OVFA.js → chunk-2ZMPAD6C.js} +7 -7
  4. package/dist/{chunk-U4LHV5DS.js → chunk-36SY7TID.js} +2 -2
  5. package/dist/{chunk-IHMFEPIT.js → chunk-3BZBNDRP.js} +3 -3
  6. package/dist/{chunk-5AWXGBSH.js → chunk-3DJ4KY3U.js} +3 -3
  7. package/dist/{chunk-T4JNXV75.js → chunk-3EDNWHWD.js} +5 -5
  8. package/dist/{chunk-LR2CU7HK.js → chunk-3ZR5PMKB.js} +2 -2
  9. package/dist/{chunk-QDTGDYMM.js → chunk-47YSHR3H.js} +3 -3
  10. package/dist/{chunk-2HXVFC4B.js → chunk-4B2E4OCZ.js} +2 -2
  11. package/dist/{chunk-3B7W334A.js → chunk-4C4D6T5M.js} +3 -3
  12. package/dist/{chunk-U26XDHMX.js → chunk-4DWIMWR5.js} +4 -4
  13. package/dist/{chunk-H5UA5JW4.js → chunk-4DZGAY6R.js} +2 -2
  14. package/dist/{chunk-YWB7HLL7.js → chunk-4NSCLIES.js} +3 -3
  15. package/dist/{chunk-7P24I5OL.js → chunk-4VCU3GFI.js} +2 -2
  16. package/dist/{chunk-UPEMEBWH.js → chunk-55BM2IU2.js} +5 -5
  17. package/dist/{chunk-5V5J7APL.js → chunk-5C5W52O2.js} +2 -2
  18. package/dist/{chunk-FDPONOOT.js → chunk-5MXQ5CP7.js} +2 -2
  19. package/dist/{chunk-NBMF7SIS.js → chunk-6HTZBBTC.js} +2 -2
  20. package/dist/{chunk-5RC32MZH.js → chunk-72H7HUTH.js} +2 -2
  21. package/dist/{chunk-URVAZW44.js → chunk-7KV7H2TW.js} +2 -2
  22. package/dist/{chunk-VFF3AN4Y.js → chunk-7Z2RAGOA.js} +2 -2
  23. package/dist/{chunk-BM6NGS3A.js → chunk-AE6LFFME.js} +3 -3
  24. package/dist/{chunk-OPMMD25Z.js → chunk-ALNJV4XB.js} +4 -4
  25. package/dist/{chunk-KTH3GWAL.js → chunk-AXHMQOIZ.js} +4 -4
  26. package/dist/{chunk-RNC4M6SG.js → chunk-B3DANITU.js} +3 -3
  27. package/dist/{chunk-MGAXCPT7.js → chunk-B7FAQKHH.js} +2 -2
  28. package/dist/{chunk-BN4CKDFU.js → chunk-BDOG4YSM.js} +22 -22
  29. package/dist/{chunk-6HGS5Z2Z.js → chunk-BRL2HMZJ.js} +3 -3
  30. package/dist/{chunk-EY2PGOG3.js → chunk-BYFRDLDL.js} +3 -3
  31. package/dist/{chunk-LVRULYU4.js → chunk-C2ICCCP5.js} +8 -8
  32. package/dist/{chunk-VA2OONPE.js → chunk-C5QBV5RE.js} +2 -2
  33. package/dist/{chunk-7WXDSTNR.js → chunk-CDMJSXCB.js} +2 -2
  34. package/dist/{chunk-XMZ5LXL4.js → chunk-CEDK5GM2.js} +3 -3
  35. package/dist/{chunk-DFYPQ52O.js → chunk-CEHCVDYR.js} +7 -7
  36. package/dist/{chunk-A47AZPCL.js → chunk-CEQ3YKHR.js} +2 -2
  37. package/dist/{chunk-EHGIW7GA.js → chunk-CMP4F537.js} +2 -2
  38. package/dist/{chunk-YXHHUJOZ.js → chunk-CY5ISPFB.js} +3 -3
  39. package/dist/{chunk-6OFWWIEG.js → chunk-D5INX2EF.js} +3 -3
  40. package/dist/{chunk-3EKVSKGJ.js → chunk-DXC3DTCV.js} +3 -3
  41. package/dist/{chunk-XZ23AFOP.js → chunk-E3GNYOLS.js} +2 -2
  42. package/dist/{chunk-ZNFHDBUW.js → chunk-EBNPVPR7.js} +2 -2
  43. package/dist/{chunk-4PITSMJ3.js → chunk-EJ3XWNY3.js} +2 -2
  44. package/dist/{chunk-333EWYWL.js → chunk-ENL3CCZB.js} +5 -5
  45. package/dist/{chunk-HVFYAQLK.js → chunk-ERTYAID6.js} +4 -4
  46. package/dist/{chunk-B5QQLMEE.js → chunk-FG3PDWE3.js} +2 -2
  47. package/dist/{chunk-7PS5MKVH.js → chunk-FLCQKC64.js} +4 -4
  48. package/dist/{chunk-LMO3QK7Q.js → chunk-FXC64HLD.js} +2 -2
  49. package/dist/{chunk-KBNWM27Q.js → chunk-FXWWDMMP.js} +9 -2
  50. package/dist/chunk-FXWWDMMP.js.map +1 -0
  51. package/dist/{chunk-KUAVM54Y.js → chunk-FZEG2R3E.js} +2 -2
  52. package/dist/{chunk-QGX37P5L.js → chunk-GMXSCEYN.js} +2 -2
  53. package/dist/{chunk-FKUP7QRJ.js → chunk-GTBVTLZJ.js} +2 -2
  54. package/dist/{chunk-4GQFIJAE.js → chunk-GTDCC4YX.js} +2 -2
  55. package/dist/{chunk-XONGYCW3.js → chunk-GWHO5ACE.js} +2 -2
  56. package/dist/{chunk-NTTSHOOK.js → chunk-HF6BGFUV.js} +4 -4
  57. package/dist/{chunk-WTB4DDZP.js → chunk-HHZJALGA.js} +5 -5
  58. package/dist/{chunk-QNEOO22E.js → chunk-HND6FAMX.js} +2 -2
  59. package/dist/{chunk-ECCNRCC4.js → chunk-HNLYRHAU.js} +2 -2
  60. package/dist/{chunk-7G63B2B7.js → chunk-HUIYDDDL.js} +7 -7
  61. package/dist/{chunk-R3SYH7RG.js → chunk-HWVU636Q.js} +15 -10
  62. package/dist/chunk-HWVU636Q.js.map +1 -0
  63. package/dist/{chunk-4E73UAFA.js → chunk-HXQ4MDCH.js} +6 -6
  64. package/dist/{chunk-XYACSO57.js → chunk-I3U52BDH.js} +2 -2
  65. package/dist/{chunk-KZWC6JCI.js → chunk-IE5GWE72.js} +5 -5
  66. package/dist/{chunk-RRZUMIYG.js → chunk-IIY5JRNW.js} +3 -3
  67. package/dist/{chunk-UQHWOPUY.js → chunk-IVEDMK5U.js} +2 -2
  68. package/dist/{chunk-35ZTVB35.js → chunk-JTY3REOB.js} +5 -5
  69. package/dist/{chunk-YIVL6HWS.js → chunk-JVCIAEFT.js} +2 -2
  70. package/dist/{chunk-DUF2VZON.js → chunk-K4V2ELUZ.js} +2 -2
  71. package/dist/{chunk-OBEJUAN6.js → chunk-KBWHHAI3.js} +4 -4
  72. package/dist/{chunk-BPXLHGWI.js → chunk-KK2TIWTF.js} +2 -2
  73. package/dist/{chunk-NRSSSVWB.js → chunk-KPZFLTZ2.js} +2 -2
  74. package/dist/{chunk-OYM3NHSD.js → chunk-KXYL3CUS.js} +2 -2
  75. package/dist/{chunk-KOVHUAHG.js → chunk-L5O2O67Y.js} +6 -6
  76. package/dist/{chunk-3LWAAK3J.js → chunk-L6A3RXCU.js} +5 -5
  77. package/dist/{chunk-RM5JIUVW.js → chunk-LG33MONJ.js} +2 -2
  78. package/dist/{chunk-YACASX6X.js → chunk-LLYLDZXC.js} +2 -2
  79. package/dist/{chunk-RWUKMJYA.js → chunk-LMV225AS.js} +2 -2
  80. package/dist/{chunk-OV4GQOLC.js → chunk-M2KNQZUL.js} +2 -2
  81. package/dist/{chunk-WW3CD7AU.js → chunk-M5WPZXBA.js} +6 -6
  82. package/dist/{chunk-FINAKMC6.js → chunk-MDQYRES4.js} +5 -5
  83. package/dist/{chunk-XAFRTZQF.js → chunk-MJAIURHO.js} +2 -2
  84. package/dist/{chunk-KWQ6HV5Z.js → chunk-MRBDJASL.js} +3 -3
  85. package/dist/{chunk-NJAGSGPF.js → chunk-MY5H6D5Y.js} +3 -3
  86. package/dist/{chunk-J2P4YZLC.js → chunk-NRPZ3BH4.js} +5 -5
  87. package/dist/{chunk-YL7VBHPZ.js → chunk-NXCOVGDU.js} +3 -3
  88. package/dist/{chunk-IGP5E4FC.js → chunk-NZUKZRT7.js} +4 -4
  89. package/dist/{chunk-WX3LWMVU.js → chunk-O6V65J5J.js} +2 -2
  90. package/dist/{chunk-PYPNGKRD.js → chunk-OGTILHKP.js} +4 -4
  91. package/dist/{chunk-UXSV6RVS.js → chunk-OKY7ACZK.js} +2 -2
  92. package/dist/{chunk-ULIDYFM7.js → chunk-OPBSVEMX.js} +2 -2
  93. package/dist/{chunk-K6YRTASS.js → chunk-PGKQZBLZ.js} +2 -2
  94. package/dist/{chunk-57C25JYV.js → chunk-PQZD5W3E.js} +2 -2
  95. package/dist/{chunk-533R5EKD.js → chunk-PSXUEWUS.js} +4 -4
  96. package/dist/{chunk-5Z55AFOW.js → chunk-PT5P4AAU.js} +2 -2
  97. package/dist/{chunk-EL3OXVOW.js → chunk-PUACHQRH.js} +2 -2
  98. package/dist/{chunk-HRYH7XQP.js → chunk-QKZX5HDY.js} +2 -2
  99. package/dist/{chunk-LOSXINSS.js → chunk-QLM3KTAQ.js} +4 -4
  100. package/dist/{chunk-JGS2IHER.js → chunk-R27VUCWR.js} +4 -4
  101. package/dist/{chunk-X6J4KKZZ.js → chunk-RFTC5UVB.js} +4 -4
  102. package/dist/{chunk-LXW3GNF7.js → chunk-RHVYRQN4.js} +6 -6
  103. package/dist/{chunk-VRIAWF3A.js → chunk-RIYDAMSQ.js} +2 -2
  104. package/dist/{chunk-A43B4IT7.js → chunk-RYPK72YP.js} +4 -4
  105. package/dist/{chunk-GRWGNWIJ.js → chunk-SCCBEFVK.js} +6 -6
  106. package/dist/{chunk-PP7POY7C.js → chunk-SEGTBIR4.js} +2 -2
  107. package/dist/{chunk-D3C3VVCX.js → chunk-SGBCLZQF.js} +2 -2
  108. package/dist/{chunk-EKY3A5LO.js → chunk-SLDJYJEG.js} +3 -3
  109. package/dist/{chunk-YPLKH5H4.js → chunk-SSQG36MH.js} +6 -6
  110. package/dist/{chunk-WCCCW4KD.js → chunk-SWQCCR6Q.js} +5 -5
  111. package/dist/{chunk-NQY3QNLR.js → chunk-U5BZXNHW.js} +4 -4
  112. package/dist/{chunk-TEKBTTP2.js → chunk-U756JCDK.js} +2 -2
  113. package/dist/{chunk-W6HCXQBH.js → chunk-UG2T7LMX.js} +4 -4
  114. package/dist/{chunk-JNWXHPZG.js → chunk-UPGIQXUY.js} +2 -2
  115. package/dist/{chunk-QTIKGWU4.js → chunk-UQPW7INX.js} +4 -4
  116. package/dist/{chunk-WZTFU6FJ.js → chunk-UUSOIPM2.js} +2 -2
  117. package/dist/{chunk-FYCCNQXQ.js → chunk-V5QCJHDA.js} +6 -6
  118. package/dist/{chunk-V4DDHF7S.js → chunk-V6U75PIG.js} +3 -3
  119. package/dist/{chunk-ZXBUOHCR.js → chunk-VC4GKLZL.js} +2 -2
  120. package/dist/chunk-VFS52GGI.js +2 -0
  121. package/dist/chunk-VFS52GGI.js.map +1 -0
  122. package/dist/{chunk-DT6RNLCP.js → chunk-W26KFY35.js} +2 -2
  123. package/dist/{chunk-R7DDZIE3.js → chunk-W35X6J5P.js} +3 -3
  124. package/dist/{chunk-ITFDGFOT.js → chunk-W7OIVERI.js} +2 -2
  125. package/dist/chunk-WEEVXQIM.js +45 -0
  126. package/dist/chunk-WEEVXQIM.js.map +1 -0
  127. package/dist/{chunk-IZJOZJDL.js → chunk-WEM6XJ7Z.js} +2 -2
  128. package/dist/{chunk-5HBMI2DO.js → chunk-WKNOKJA3.js} +2 -2
  129. package/dist/{chunk-BLNXHETI.js → chunk-Y33ZFTMR.js} +3 -3
  130. package/dist/{chunk-AXKZBRZK.js → chunk-YA2QGLUL.js} +2 -2
  131. package/dist/{chunk-35DUHYPC.js → chunk-YFGFNFVW.js} +3 -3
  132. package/dist/{chunk-6NKILKS6.js → chunk-YFKKMDJL.js} +2 -2
  133. package/dist/chunk-YHVXYOL6.js +80 -0
  134. package/dist/chunk-YHVXYOL6.js.map +1 -0
  135. package/dist/{chunk-CQ5CH3SB.js → chunk-YUFDC6RW.js} +2 -2
  136. package/dist/{chunk-DCI6IOJX.js → chunk-ZALGMUSW.js} +3 -3
  137. package/dist/{chunk-N44PNGDS.js → chunk-ZFMM2NLA.js} +2 -2
  138. package/dist/{chunk-6OPDRLMU.js → chunk-ZRMF4YAS.js} +7 -7
  139. package/dist/{chunk-TU24Y4HN.js → chunk-ZSYT5H6U.js} +2 -2
  140. package/dist/components/accordion/accordion.js +2 -2
  141. package/dist/components/accordion/index.js +2 -2
  142. package/dist/components/advanced-group/advanced-group.js +4 -4
  143. package/dist/components/advanced-group/index.js +4 -4
  144. package/dist/components/alert/alert.js +2 -2
  145. package/dist/components/alert/index.js +2 -2
  146. package/dist/components/alert-dialog/alert-dialog.js +3 -3
  147. package/dist/components/alert-dialog/index.js +3 -3
  148. package/dist/components/ambient-field/ambient-field.js +2 -2
  149. package/dist/components/ambient-field/index.js +2 -2
  150. package/dist/components/app-shell/app-shell.js +4 -4
  151. package/dist/components/app-shell/index.js +4 -4
  152. package/dist/components/app-sidebar/app-sidebar.js +10 -10
  153. package/dist/components/app-sidebar/index.js +10 -10
  154. package/dist/components/attribution-panel/attribution-panel.js +4 -4
  155. package/dist/components/attribution-panel/index.js +4 -4
  156. package/dist/components/avatar/avatar.js +2 -2
  157. package/dist/components/avatar/index.js +2 -2
  158. package/dist/components/badge/badge.js +2 -2
  159. package/dist/components/badge/index.js +2 -2
  160. package/dist/components/bento-grid/bento-grid.js +3 -3
  161. package/dist/components/bento-grid/index.js +3 -3
  162. package/dist/components/bounded-number/bounded-number.js +7 -7
  163. package/dist/components/bounded-number/index.js +7 -7
  164. package/dist/components/breadcrumb/breadcrumb.js +2 -2
  165. package/dist/components/breadcrumb/index.js +2 -2
  166. package/dist/components/button/button.js +2 -2
  167. package/dist/components/button/index.js +2 -2
  168. package/dist/components/button-group/button-group.js +3 -3
  169. package/dist/components/button-group/index.js +3 -3
  170. package/dist/components/calendar/calendar.js +3 -3
  171. package/dist/components/calendar/index.js +3 -3
  172. package/dist/components/card/card.js +2 -2
  173. package/dist/components/card/index.js +2 -2
  174. package/dist/components/carousel/carousel.js +3 -3
  175. package/dist/components/carousel/index.js +3 -3
  176. package/dist/components/change-review/change-review.js +8 -8
  177. package/dist/components/change-review/index.js +8 -8
  178. package/dist/components/checkbox/checkbox.js +2 -2
  179. package/dist/components/checkbox/index.js +2 -2
  180. package/dist/components/collapsible/collapsible.js +2 -2
  181. package/dist/components/collapsible/index.js +2 -2
  182. package/dist/components/collapsible-panel/index.js +2 -2
  183. package/dist/components/collapsible-panel/use-collapsible-panel.js +2 -2
  184. package/dist/components/color-picker/color-picker.js +3 -3
  185. package/dist/components/color-picker/index.js +3 -3
  186. package/dist/components/combobox/combobox.js +8 -8
  187. package/dist/components/combobox/index.js +8 -8
  188. package/dist/components/command/command.js +5 -5
  189. package/dist/components/command/index.js +5 -5
  190. package/dist/components/command-chip/command-chip.js +3 -3
  191. package/dist/components/command-chip/index.js +3 -3
  192. package/dist/components/command-trigger/command-trigger.js +3 -3
  193. package/dist/components/command-trigger/index.js +3 -3
  194. package/dist/components/confirm-dialog/confirm-dialog.js +5 -5
  195. package/dist/components/confirm-dialog/index.js +5 -5
  196. package/dist/components/context-menu/context-menu.js +2 -2
  197. package/dist/components/context-menu/index.js +2 -2
  198. package/dist/components/context-rail/context-rail.js +12 -12
  199. package/dist/components/context-rail/index.js +12 -12
  200. package/dist/components/copyable-value/copyable-value.js +3 -3
  201. package/dist/components/copyable-value/index.js +3 -3
  202. package/dist/components/date-picker/date-picker.js +5 -5
  203. package/dist/components/date-picker/index.js +5 -5
  204. package/dist/components/date-range-picker/date-range-picker.js +5 -5
  205. package/dist/components/date-range-picker/index.js +5 -5
  206. package/dist/components/descriptions/descriptions.js +2 -2
  207. package/dist/components/descriptions/index.js +2 -2
  208. package/dist/components/dialog/dialog.js +4 -4
  209. package/dist/components/dialog/index.js +4 -4
  210. package/dist/components/drafting-marks/drafting-marks.js +14 -0
  211. package/dist/components/drafting-marks/drafting-marks.js.map +1 -0
  212. package/dist/components/drafting-marks/index.js +15 -0
  213. package/dist/components/drafting-marks/index.js.map +1 -0
  214. package/dist/components/drawer/drawer.js +2 -2
  215. package/dist/components/drawer/index.js +2 -2
  216. package/dist/components/dropdown-menu/dropdown-menu.js +2 -2
  217. package/dist/components/dropdown-menu/index.js +2 -2
  218. package/dist/components/empty-state/empty-state.js +4 -4
  219. package/dist/components/empty-state/index.js +4 -4
  220. package/dist/components/error-state/error-state.js +4 -4
  221. package/dist/components/error-state/index.js +4 -4
  222. package/dist/components/expand-dialog/expand-dialog.js +5 -5
  223. package/dist/components/expand-dialog/index.js +5 -5
  224. package/dist/components/field/field.js +4 -4
  225. package/dist/components/field/index.js +4 -4
  226. package/dist/components/field-row/field-row.js +3 -3
  227. package/dist/components/field-row/index.js +3 -3
  228. package/dist/components/file-upload/file-upload.js +4 -4
  229. package/dist/components/file-upload/index.js +4 -4
  230. package/dist/components/form/form.js +3 -3
  231. package/dist/components/hover-card/hover-card.js +2 -2
  232. package/dist/components/hover-card/index.js +2 -2
  233. package/dist/components/icon-button/icon-button.js +4 -4
  234. package/dist/components/icon-button/index.js +4 -4
  235. package/dist/components/input/index.js +2 -2
  236. package/dist/components/input/input.js +2 -2
  237. package/dist/components/input-group/index.js +5 -5
  238. package/dist/components/input-group/input-group.js +5 -5
  239. package/dist/components/input-otp/index.js +2 -2
  240. package/dist/components/input-otp/input-otp.js +2 -2
  241. package/dist/components/install-tabs/index.js +8 -8
  242. package/dist/components/install-tabs/install-tabs.js +8 -8
  243. package/dist/components/integration-matrix/index.js +7 -7
  244. package/dist/components/integration-matrix/integration-matrix.js +7 -7
  245. package/dist/components/kbd/index.js +2 -2
  246. package/dist/components/kbd/kbd.js +2 -2
  247. package/dist/components/key-value-editor/index.js +4 -4
  248. package/dist/components/key-value-editor/key-value-editor.js +4 -4
  249. package/dist/components/keyboard-shortcuts/index.js +8 -8
  250. package/dist/components/keyboard-shortcuts/keyboard-shortcuts.js +8 -8
  251. package/dist/components/label/index.js +2 -2
  252. package/dist/components/label/label.js +2 -2
  253. package/dist/components/link-preview/index.js +3 -3
  254. package/dist/components/link-preview/link-preview.js +3 -3
  255. package/dist/components/list-editor/index.js +4 -4
  256. package/dist/components/list-editor/list-editor.js +4 -4
  257. package/dist/components/loading-state/index.js +4 -4
  258. package/dist/components/loading-state/loading-state.js +4 -4
  259. package/dist/components/match-highlight/index.js +2 -2
  260. package/dist/components/match-highlight/match-highlight.js +2 -2
  261. package/dist/components/mention-input/index.js +4 -4
  262. package/dist/components/mention-input/mention-input.js +4 -4
  263. package/dist/components/menubar/index.js +2 -2
  264. package/dist/components/menubar/menubar.js +2 -2
  265. package/dist/components/meter/index.js +2 -2
  266. package/dist/components/meter/meter.js +2 -2
  267. package/dist/components/metric-card/index.js +6 -6
  268. package/dist/components/metric-card/metric-card.js +6 -6
  269. package/dist/components/model-picker/index.js +9 -9
  270. package/dist/components/model-picker/model-picker.js +9 -9
  271. package/dist/components/nav-main/index.js +11 -11
  272. package/dist/components/nav-main/nav-main.js +11 -11
  273. package/dist/components/nav-notifications/index.js +5 -5
  274. package/dist/components/nav-notifications/nav-notifications.js +5 -5
  275. package/dist/components/nav-user/index.js +12 -12
  276. package/dist/components/nav-user/nav-user.js +12 -12
  277. package/dist/components/navigation-menu/index.js +2 -2
  278. package/dist/components/navigation-menu/navigation-menu.js +2 -2
  279. package/dist/components/number-input/index.js +6 -6
  280. package/dist/components/number-input/number-input.js +6 -6
  281. package/dist/components/page-shell/index.js +2 -2
  282. package/dist/components/page-shell/page-shell.js +2 -2
  283. package/dist/components/pagination/index.js +3 -3
  284. package/dist/components/pagination/pagination.js +3 -3
  285. package/dist/components/popover/index.js +2 -2
  286. package/dist/components/popover/popover.js +2 -2
  287. package/dist/components/progress/index.js +2 -2
  288. package/dist/components/progress/progress.js +2 -2
  289. package/dist/components/radio-group/index.js +2 -2
  290. package/dist/components/radio-group/radio-group.js +2 -2
  291. package/dist/components/rating/index.js +2 -2
  292. package/dist/components/rating/rating.js +2 -2
  293. package/dist/components/resizable/index.js +2 -2
  294. package/dist/components/resizable/resizable.js +2 -2
  295. package/dist/components/reveal/index.js +2 -2
  296. package/dist/components/reveal/reveal.js +2 -2
  297. package/dist/components/revision-timeline/index.js +2 -2
  298. package/dist/components/revision-timeline/revision-timeline.js +2 -2
  299. package/dist/components/schema-form/index.js +27 -27
  300. package/dist/components/schema-form/schema-form.js +23 -23
  301. package/dist/components/scroll-area/index.js +2 -2
  302. package/dist/components/scroll-area/scroll-area.js +2 -2
  303. package/dist/components/section-header/index.js +2 -2
  304. package/dist/components/section-header/section-header.js +2 -2
  305. package/dist/components/segmented-field/index.js +5 -5
  306. package/dist/components/segmented-field/segmented-field.js +5 -5
  307. package/dist/components/select/index.js +2 -2
  308. package/dist/components/select/select.js +2 -2
  309. package/dist/components/separator/index.js +2 -2
  310. package/dist/components/separator/separator.js +2 -2
  311. package/dist/components/sheet/index.js +2 -2
  312. package/dist/components/sheet/sheet.js +2 -2
  313. package/dist/components/side-dock/index.js +4 -4
  314. package/dist/components/side-dock/side-dock.js +4 -4
  315. package/dist/components/sidebar/index.js +9 -9
  316. package/dist/components/sidebar/sidebar.js +9 -9
  317. package/dist/components/skeleton/index.js +2 -2
  318. package/dist/components/skeleton/skeleton.js +2 -2
  319. package/dist/components/skip-link/index.js +2 -2
  320. package/dist/components/skip-link/skip-link.js +2 -2
  321. package/dist/components/slider/index.js +2 -2
  322. package/dist/components/slider/slider.js +2 -2
  323. package/dist/components/slider-number/index.js +8 -8
  324. package/dist/components/slider-number/slider-number.js +8 -8
  325. package/dist/components/sonner/index.js +2 -2
  326. package/dist/components/sonner/sonner.js +2 -2
  327. package/dist/components/spec-playground/index.js +6 -6
  328. package/dist/components/spec-playground/spec-playground.js +6 -6
  329. package/dist/components/spinner/index.js +2 -2
  330. package/dist/components/spinner/spinner.js +2 -2
  331. package/dist/components/split-panel/index.js +2 -2
  332. package/dist/components/split-panel/split-panel.js +2 -2
  333. package/dist/components/state-panel/index.js +3 -3
  334. package/dist/components/state-panel/state-panel.js +3 -3
  335. package/dist/components/status-badge/index.js +3 -3
  336. package/dist/components/status-badge/status-badge.js +3 -3
  337. package/dist/components/surface-tour/index.js +8 -8
  338. package/dist/components/surface-tour/surface-tour.js +8 -8
  339. package/dist/components/switch/index.js +2 -2
  340. package/dist/components/switch/switch.js +2 -2
  341. package/dist/components/table/index.js +2 -2
  342. package/dist/components/table/table.js +2 -2
  343. package/dist/components/tabs/index.js +2 -2
  344. package/dist/components/tabs/tabs.js +2 -2
  345. package/dist/components/tag-input/index.js +7 -7
  346. package/dist/components/tag-input/tag-input.js +7 -7
  347. package/dist/components/team-switcher/index.js +11 -11
  348. package/dist/components/team-switcher/team-switcher.js +11 -11
  349. package/dist/components/textarea/index.js +2 -2
  350. package/dist/components/textarea/textarea.js +2 -2
  351. package/dist/components/theme-family-switch/index.js +5 -5
  352. package/dist/components/theme-family-switch/theme-family-switch.js +5 -5
  353. package/dist/components/theme-switcher/index.js +5 -5
  354. package/dist/components/theme-switcher/theme-switcher.js +5 -5
  355. package/dist/components/timeline/index.js +4 -4
  356. package/dist/components/timeline/timeline.js +4 -4
  357. package/dist/components/toggle/index.js +2 -2
  358. package/dist/components/toggle/toggle.js +2 -2
  359. package/dist/components/toggle-group/index.js +3 -3
  360. package/dist/components/toggle-group/toggle-group.js +3 -3
  361. package/dist/components/token-spotlight/index.js +2 -2
  362. package/dist/components/token-spotlight/token-spotlight.js +2 -2
  363. package/dist/components/toolbar/index.js +4 -4
  364. package/dist/components/toolbar/toolbar.js +4 -4
  365. package/dist/components/tooltip/index.js +2 -2
  366. package/dist/components/tooltip/tooltip.js +2 -2
  367. package/dist/components/top-nav/index.js +2 -2
  368. package/dist/components/top-nav/top-nav.js +2 -2
  369. package/dist/components/transfer/index.js +8 -8
  370. package/dist/components/transfer/transfer.js +8 -8
  371. package/dist/components/tree/index.js +5 -5
  372. package/dist/components/tree/tree.js +5 -5
  373. package/dist/components/tree-select/index.js +9 -9
  374. package/dist/components/tree-select/tree-select.js +9 -9
  375. package/dist/components/typography/index.js +3 -3
  376. package/dist/components/typography/prose.js +3 -3
  377. package/dist/components/typography/typography.js +2 -2
  378. package/dist/components/view-toolbar/index.js +6 -6
  379. package/dist/components/view-toolbar/view-toolbar.js +6 -6
  380. package/dist/components/virtual-select/index.js +6 -6
  381. package/dist/components/virtual-select/virtual-select.js +6 -6
  382. package/dist/components/wizard/index.js +3 -3
  383. package/dist/components/wizard/wizard.js +3 -3
  384. package/dist/components/workspace-picker/index.js +11 -11
  385. package/dist/components/workspace-picker/workspace-picker.js +11 -11
  386. package/dist/form.js +3 -3
  387. package/dist/illustrations/empty-list-illustration.js +3 -3
  388. package/dist/illustrations/error-illustration.js +3 -3
  389. package/dist/illustrations/first-run-illustration.js +3 -3
  390. package/dist/illustrations/illustration-base.js +2 -2
  391. package/dist/illustrations/index.js +11 -11
  392. package/dist/illustrations/no-access-illustration.js +3 -3
  393. package/dist/illustrations/no-results-illustration.js +3 -3
  394. package/dist/illustrations/offline-illustration.js +3 -3
  395. package/dist/illustrations/success-illustration.js +3 -3
  396. package/dist/index.d.ts +44 -4
  397. package/dist/index.js +221 -212
  398. package/dist/lib/cn.js +8 -1
  399. package/dist/lib/cn.js.map +1 -1
  400. package/package.json +4 -4
  401. package/src/components/drafting-marks/drafting-marks.stories.tsx +88 -0
  402. package/src/components/drafting-marks/drafting-marks.test.tsx +55 -0
  403. package/src/components/drafting-marks/drafting-marks.tsx +120 -0
  404. package/src/components/drafting-marks/index.ts +7 -0
  405. package/src/components/section-header/section-header.stories.tsx +23 -0
  406. package/src/components/section-header/section-header.tsx +26 -6
  407. package/src/components/sidebar/sidebar.tsx +6 -1
  408. package/src/decoration.stories.tsx +153 -123
  409. package/src/index.ts +1 -0
  410. package/src/lib/cn.test.ts +29 -0
  411. package/src/lib/cn.ts +7 -0
  412. package/dist/chunk-KBNWM27Q.js.map +0 -1
  413. package/dist/chunk-OZTM6PYF.js +0 -30
  414. package/dist/chunk-OZTM6PYF.js.map +0 -1
  415. package/dist/chunk-R3SYH7RG.js.map +0 -1
  416. /package/dist/{chunk-E3ES2KR6.js.map → chunk-2DFB4YTK.js.map} +0 -0
  417. /package/dist/{chunk-6QU7OVFA.js.map → chunk-2ZMPAD6C.js.map} +0 -0
  418. /package/dist/{chunk-U4LHV5DS.js.map → chunk-36SY7TID.js.map} +0 -0
  419. /package/dist/{chunk-IHMFEPIT.js.map → chunk-3BZBNDRP.js.map} +0 -0
  420. /package/dist/{chunk-5AWXGBSH.js.map → chunk-3DJ4KY3U.js.map} +0 -0
  421. /package/dist/{chunk-T4JNXV75.js.map → chunk-3EDNWHWD.js.map} +0 -0
  422. /package/dist/{chunk-LR2CU7HK.js.map → chunk-3ZR5PMKB.js.map} +0 -0
  423. /package/dist/{chunk-QDTGDYMM.js.map → chunk-47YSHR3H.js.map} +0 -0
  424. /package/dist/{chunk-2HXVFC4B.js.map → chunk-4B2E4OCZ.js.map} +0 -0
  425. /package/dist/{chunk-3B7W334A.js.map → chunk-4C4D6T5M.js.map} +0 -0
  426. /package/dist/{chunk-U26XDHMX.js.map → chunk-4DWIMWR5.js.map} +0 -0
  427. /package/dist/{chunk-H5UA5JW4.js.map → chunk-4DZGAY6R.js.map} +0 -0
  428. /package/dist/{chunk-YWB7HLL7.js.map → chunk-4NSCLIES.js.map} +0 -0
  429. /package/dist/{chunk-7P24I5OL.js.map → chunk-4VCU3GFI.js.map} +0 -0
  430. /package/dist/{chunk-UPEMEBWH.js.map → chunk-55BM2IU2.js.map} +0 -0
  431. /package/dist/{chunk-5V5J7APL.js.map → chunk-5C5W52O2.js.map} +0 -0
  432. /package/dist/{chunk-FDPONOOT.js.map → chunk-5MXQ5CP7.js.map} +0 -0
  433. /package/dist/{chunk-NBMF7SIS.js.map → chunk-6HTZBBTC.js.map} +0 -0
  434. /package/dist/{chunk-5RC32MZH.js.map → chunk-72H7HUTH.js.map} +0 -0
  435. /package/dist/{chunk-URVAZW44.js.map → chunk-7KV7H2TW.js.map} +0 -0
  436. /package/dist/{chunk-VFF3AN4Y.js.map → chunk-7Z2RAGOA.js.map} +0 -0
  437. /package/dist/{chunk-BM6NGS3A.js.map → chunk-AE6LFFME.js.map} +0 -0
  438. /package/dist/{chunk-OPMMD25Z.js.map → chunk-ALNJV4XB.js.map} +0 -0
  439. /package/dist/{chunk-KTH3GWAL.js.map → chunk-AXHMQOIZ.js.map} +0 -0
  440. /package/dist/{chunk-RNC4M6SG.js.map → chunk-B3DANITU.js.map} +0 -0
  441. /package/dist/{chunk-MGAXCPT7.js.map → chunk-B7FAQKHH.js.map} +0 -0
  442. /package/dist/{chunk-BN4CKDFU.js.map → chunk-BDOG4YSM.js.map} +0 -0
  443. /package/dist/{chunk-6HGS5Z2Z.js.map → chunk-BRL2HMZJ.js.map} +0 -0
  444. /package/dist/{chunk-EY2PGOG3.js.map → chunk-BYFRDLDL.js.map} +0 -0
  445. /package/dist/{chunk-LVRULYU4.js.map → chunk-C2ICCCP5.js.map} +0 -0
  446. /package/dist/{chunk-VA2OONPE.js.map → chunk-C5QBV5RE.js.map} +0 -0
  447. /package/dist/{chunk-7WXDSTNR.js.map → chunk-CDMJSXCB.js.map} +0 -0
  448. /package/dist/{chunk-XMZ5LXL4.js.map → chunk-CEDK5GM2.js.map} +0 -0
  449. /package/dist/{chunk-DFYPQ52O.js.map → chunk-CEHCVDYR.js.map} +0 -0
  450. /package/dist/{chunk-A47AZPCL.js.map → chunk-CEQ3YKHR.js.map} +0 -0
  451. /package/dist/{chunk-EHGIW7GA.js.map → chunk-CMP4F537.js.map} +0 -0
  452. /package/dist/{chunk-YXHHUJOZ.js.map → chunk-CY5ISPFB.js.map} +0 -0
  453. /package/dist/{chunk-6OFWWIEG.js.map → chunk-D5INX2EF.js.map} +0 -0
  454. /package/dist/{chunk-3EKVSKGJ.js.map → chunk-DXC3DTCV.js.map} +0 -0
  455. /package/dist/{chunk-XZ23AFOP.js.map → chunk-E3GNYOLS.js.map} +0 -0
  456. /package/dist/{chunk-ZNFHDBUW.js.map → chunk-EBNPVPR7.js.map} +0 -0
  457. /package/dist/{chunk-4PITSMJ3.js.map → chunk-EJ3XWNY3.js.map} +0 -0
  458. /package/dist/{chunk-333EWYWL.js.map → chunk-ENL3CCZB.js.map} +0 -0
  459. /package/dist/{chunk-HVFYAQLK.js.map → chunk-ERTYAID6.js.map} +0 -0
  460. /package/dist/{chunk-B5QQLMEE.js.map → chunk-FG3PDWE3.js.map} +0 -0
  461. /package/dist/{chunk-7PS5MKVH.js.map → chunk-FLCQKC64.js.map} +0 -0
  462. /package/dist/{chunk-LMO3QK7Q.js.map → chunk-FXC64HLD.js.map} +0 -0
  463. /package/dist/{chunk-KUAVM54Y.js.map → chunk-FZEG2R3E.js.map} +0 -0
  464. /package/dist/{chunk-QGX37P5L.js.map → chunk-GMXSCEYN.js.map} +0 -0
  465. /package/dist/{chunk-FKUP7QRJ.js.map → chunk-GTBVTLZJ.js.map} +0 -0
  466. /package/dist/{chunk-4GQFIJAE.js.map → chunk-GTDCC4YX.js.map} +0 -0
  467. /package/dist/{chunk-XONGYCW3.js.map → chunk-GWHO5ACE.js.map} +0 -0
  468. /package/dist/{chunk-NTTSHOOK.js.map → chunk-HF6BGFUV.js.map} +0 -0
  469. /package/dist/{chunk-WTB4DDZP.js.map → chunk-HHZJALGA.js.map} +0 -0
  470. /package/dist/{chunk-QNEOO22E.js.map → chunk-HND6FAMX.js.map} +0 -0
  471. /package/dist/{chunk-ECCNRCC4.js.map → chunk-HNLYRHAU.js.map} +0 -0
  472. /package/dist/{chunk-7G63B2B7.js.map → chunk-HUIYDDDL.js.map} +0 -0
  473. /package/dist/{chunk-4E73UAFA.js.map → chunk-HXQ4MDCH.js.map} +0 -0
  474. /package/dist/{chunk-XYACSO57.js.map → chunk-I3U52BDH.js.map} +0 -0
  475. /package/dist/{chunk-KZWC6JCI.js.map → chunk-IE5GWE72.js.map} +0 -0
  476. /package/dist/{chunk-RRZUMIYG.js.map → chunk-IIY5JRNW.js.map} +0 -0
  477. /package/dist/{chunk-UQHWOPUY.js.map → chunk-IVEDMK5U.js.map} +0 -0
  478. /package/dist/{chunk-35ZTVB35.js.map → chunk-JTY3REOB.js.map} +0 -0
  479. /package/dist/{chunk-YIVL6HWS.js.map → chunk-JVCIAEFT.js.map} +0 -0
  480. /package/dist/{chunk-DUF2VZON.js.map → chunk-K4V2ELUZ.js.map} +0 -0
  481. /package/dist/{chunk-OBEJUAN6.js.map → chunk-KBWHHAI3.js.map} +0 -0
  482. /package/dist/{chunk-BPXLHGWI.js.map → chunk-KK2TIWTF.js.map} +0 -0
  483. /package/dist/{chunk-NRSSSVWB.js.map → chunk-KPZFLTZ2.js.map} +0 -0
  484. /package/dist/{chunk-OYM3NHSD.js.map → chunk-KXYL3CUS.js.map} +0 -0
  485. /package/dist/{chunk-KOVHUAHG.js.map → chunk-L5O2O67Y.js.map} +0 -0
  486. /package/dist/{chunk-3LWAAK3J.js.map → chunk-L6A3RXCU.js.map} +0 -0
  487. /package/dist/{chunk-RM5JIUVW.js.map → chunk-LG33MONJ.js.map} +0 -0
  488. /package/dist/{chunk-YACASX6X.js.map → chunk-LLYLDZXC.js.map} +0 -0
  489. /package/dist/{chunk-RWUKMJYA.js.map → chunk-LMV225AS.js.map} +0 -0
  490. /package/dist/{chunk-OV4GQOLC.js.map → chunk-M2KNQZUL.js.map} +0 -0
  491. /package/dist/{chunk-WW3CD7AU.js.map → chunk-M5WPZXBA.js.map} +0 -0
  492. /package/dist/{chunk-FINAKMC6.js.map → chunk-MDQYRES4.js.map} +0 -0
  493. /package/dist/{chunk-XAFRTZQF.js.map → chunk-MJAIURHO.js.map} +0 -0
  494. /package/dist/{chunk-KWQ6HV5Z.js.map → chunk-MRBDJASL.js.map} +0 -0
  495. /package/dist/{chunk-NJAGSGPF.js.map → chunk-MY5H6D5Y.js.map} +0 -0
  496. /package/dist/{chunk-J2P4YZLC.js.map → chunk-NRPZ3BH4.js.map} +0 -0
  497. /package/dist/{chunk-YL7VBHPZ.js.map → chunk-NXCOVGDU.js.map} +0 -0
  498. /package/dist/{chunk-IGP5E4FC.js.map → chunk-NZUKZRT7.js.map} +0 -0
  499. /package/dist/{chunk-WX3LWMVU.js.map → chunk-O6V65J5J.js.map} +0 -0
  500. /package/dist/{chunk-PYPNGKRD.js.map → chunk-OGTILHKP.js.map} +0 -0
  501. /package/dist/{chunk-UXSV6RVS.js.map → chunk-OKY7ACZK.js.map} +0 -0
  502. /package/dist/{chunk-ULIDYFM7.js.map → chunk-OPBSVEMX.js.map} +0 -0
  503. /package/dist/{chunk-K6YRTASS.js.map → chunk-PGKQZBLZ.js.map} +0 -0
  504. /package/dist/{chunk-57C25JYV.js.map → chunk-PQZD5W3E.js.map} +0 -0
  505. /package/dist/{chunk-533R5EKD.js.map → chunk-PSXUEWUS.js.map} +0 -0
  506. /package/dist/{chunk-5Z55AFOW.js.map → chunk-PT5P4AAU.js.map} +0 -0
  507. /package/dist/{chunk-EL3OXVOW.js.map → chunk-PUACHQRH.js.map} +0 -0
  508. /package/dist/{chunk-HRYH7XQP.js.map → chunk-QKZX5HDY.js.map} +0 -0
  509. /package/dist/{chunk-LOSXINSS.js.map → chunk-QLM3KTAQ.js.map} +0 -0
  510. /package/dist/{chunk-JGS2IHER.js.map → chunk-R27VUCWR.js.map} +0 -0
  511. /package/dist/{chunk-X6J4KKZZ.js.map → chunk-RFTC5UVB.js.map} +0 -0
  512. /package/dist/{chunk-LXW3GNF7.js.map → chunk-RHVYRQN4.js.map} +0 -0
  513. /package/dist/{chunk-VRIAWF3A.js.map → chunk-RIYDAMSQ.js.map} +0 -0
  514. /package/dist/{chunk-A43B4IT7.js.map → chunk-RYPK72YP.js.map} +0 -0
  515. /package/dist/{chunk-GRWGNWIJ.js.map → chunk-SCCBEFVK.js.map} +0 -0
  516. /package/dist/{chunk-PP7POY7C.js.map → chunk-SEGTBIR4.js.map} +0 -0
  517. /package/dist/{chunk-D3C3VVCX.js.map → chunk-SGBCLZQF.js.map} +0 -0
  518. /package/dist/{chunk-EKY3A5LO.js.map → chunk-SLDJYJEG.js.map} +0 -0
  519. /package/dist/{chunk-YPLKH5H4.js.map → chunk-SSQG36MH.js.map} +0 -0
  520. /package/dist/{chunk-WCCCW4KD.js.map → chunk-SWQCCR6Q.js.map} +0 -0
  521. /package/dist/{chunk-NQY3QNLR.js.map → chunk-U5BZXNHW.js.map} +0 -0
  522. /package/dist/{chunk-TEKBTTP2.js.map → chunk-U756JCDK.js.map} +0 -0
  523. /package/dist/{chunk-W6HCXQBH.js.map → chunk-UG2T7LMX.js.map} +0 -0
  524. /package/dist/{chunk-JNWXHPZG.js.map → chunk-UPGIQXUY.js.map} +0 -0
  525. /package/dist/{chunk-QTIKGWU4.js.map → chunk-UQPW7INX.js.map} +0 -0
  526. /package/dist/{chunk-WZTFU6FJ.js.map → chunk-UUSOIPM2.js.map} +0 -0
  527. /package/dist/{chunk-FYCCNQXQ.js.map → chunk-V5QCJHDA.js.map} +0 -0
  528. /package/dist/{chunk-V4DDHF7S.js.map → chunk-V6U75PIG.js.map} +0 -0
  529. /package/dist/{chunk-ZXBUOHCR.js.map → chunk-VC4GKLZL.js.map} +0 -0
  530. /package/dist/{chunk-DT6RNLCP.js.map → chunk-W26KFY35.js.map} +0 -0
  531. /package/dist/{chunk-R7DDZIE3.js.map → chunk-W35X6J5P.js.map} +0 -0
  532. /package/dist/{chunk-ITFDGFOT.js.map → chunk-W7OIVERI.js.map} +0 -0
  533. /package/dist/{chunk-IZJOZJDL.js.map → chunk-WEM6XJ7Z.js.map} +0 -0
  534. /package/dist/{chunk-5HBMI2DO.js.map → chunk-WKNOKJA3.js.map} +0 -0
  535. /package/dist/{chunk-BLNXHETI.js.map → chunk-Y33ZFTMR.js.map} +0 -0
  536. /package/dist/{chunk-AXKZBRZK.js.map → chunk-YA2QGLUL.js.map} +0 -0
  537. /package/dist/{chunk-35DUHYPC.js.map → chunk-YFGFNFVW.js.map} +0 -0
  538. /package/dist/{chunk-6NKILKS6.js.map → chunk-YFKKMDJL.js.map} +0 -0
  539. /package/dist/{chunk-CQ5CH3SB.js.map → chunk-YUFDC6RW.js.map} +0 -0
  540. /package/dist/{chunk-DCI6IOJX.js.map → chunk-ZALGMUSW.js.map} +0 -0
  541. /package/dist/{chunk-N44PNGDS.js.map → chunk-ZFMM2NLA.js.map} +0 -0
  542. /package/dist/{chunk-6OPDRLMU.js.map → chunk-ZRMF4YAS.js.map} +0 -0
  543. /package/dist/{chunk-TU24Y4HN.js.map → chunk-ZSYT5H6U.js.map} +0 -0
@@ -254,10 +254,11 @@ export const ControlsAreUntouched: Story = {
254
254
  * | utility | the gesture |
255
255
  * | --- | --- |
256
256
  * | `bg-hairline-hatch` | a faded diagonal hatch — the recessed WELL behind media (`CardMedia` default) |
257
+ * | `bg-hairline-stripes` | stripes streaming out of one corner, thinning as they fade — a hero / header ground |
257
258
  * | `hairline-stack` | two sheet edges stacked under a card (`<Card stacked>`) |
258
259
  * | `hairline-slot` | a dashed placeholder outline |
259
260
  * | `hairline-frame` | dashed rails that run past a box's corners and fade |
260
- * | `hairline-rails` | the same for a full-bleed section: rails down the content column |
261
+ * | `hairline-rails` | the same for a full-bleed section: rails down the content column, inked only near the corners (`hairline-rails-full` for whole lines) |
261
262
  * | `hairline-corners` | crop marks on the focal item |
262
263
  * | `hairline-ticks-y` / `-x` | a tick ruler along an edge |
263
264
  * | `hairline-rule` / `-y` | a dashed separator |
@@ -269,135 +270,150 @@ export const ControlsAreUntouched: Story = {
269
270
  export const Hairlines: Story = {
270
271
  parameters: { layout: "fullscreen" },
271
272
  render: () => (
272
- <div className="bg-background px-6 py-12 text-foreground">
273
- <div className="mx-auto grid max-w-5xl gap-4 md:grid-cols-3">
274
- <Card>
275
- <CardMedia data-testid="hairline-well">
276
- <div className="flex w-full max-w-56 items-center gap-3 rounded-lg border border-card-border bg-card p-3 shadow-card">
277
- <span className="flex size-9 items-center justify-center rounded-md bg-surface-muted text-muted-foreground">
278
- <FileText aria-hidden="true" className="size-4" />
279
- </span>
280
- <span className="min-w-0 flex-1 space-y-1.5">
281
- <span className="block truncate text-caption font-medium">q3-board-pack.pdf</span>
282
- <span className="block h-1 rounded-full bg-surface-muted">
283
- <span className="block h-1 w-1/3 rounded-full bg-primary" />
273
+ <div className="bg-background text-foreground">
274
+ <header
275
+ data-testid="hairline-stripes"
276
+ className="bg-surface-muted bg-hairline-stripes px-6 py-14 text-center"
277
+ >
278
+ <p className="text-title font-semibold">Corner stripes</p>
279
+ <p className="mx-auto mt-1 max-w-prose text-caption text-muted-foreground">
280
+ <code>bg-hairline-stripes</code> on an offset fill — heavy at the corner, a hairline by
281
+ the middle, then gone, so the headline sits on clean ground.
282
+ </p>
283
+ </header>
284
+ <div
285
+ data-testid="hairline-rails"
286
+ className="hairline-rails px-6 py-12 [--hairline-rail-width:66rem]"
287
+ >
288
+ <div className="mx-auto grid max-w-5xl gap-4 md:grid-cols-3">
289
+ <Card>
290
+ <CardMedia data-testid="hairline-well">
291
+ <div className="flex w-full max-w-56 items-center gap-3 rounded-lg border border-card-border bg-card p-3 shadow-card">
292
+ <span className="flex size-9 items-center justify-center rounded-md bg-surface-muted text-muted-foreground">
293
+ <FileText aria-hidden="true" className="size-4" />
284
294
  </span>
285
- </span>
286
- </div>
287
- </CardMedia>
288
- <CardHeader>
289
- <CardTitle>Hatch well</CardTitle>
290
- <CardDescription>
291
- <code>CardMedia</code> — a faded hairline hatch behind whatever the card shows.
292
- </CardDescription>
293
- </CardHeader>
294
- </Card>
295
-
296
- <Card>
297
- <CardMedia ground="none" className="items-end pb-0">
298
- <Card
299
- stacked
300
- data-testid="hairline-stack"
301
- className="w-full max-w-56 rounded-b-none border-b-0"
302
- >
303
- <CardContent className="space-y-2 p-4">
304
- <p className="text-caption font-medium">Spending limit</p>
305
- <span className="block h-2 rounded-sm bg-surface-muted">
306
- <span className="block h-2 w-2/5 rounded-sm bg-primary" />
295
+ <span className="min-w-0 flex-1 space-y-1.5">
296
+ <span className="block truncate text-caption font-medium">q3-board-pack.pdf</span>
297
+ <span className="block h-1 rounded-full bg-surface-muted">
298
+ <span className="block h-1 w-1/3 rounded-full bg-primary" />
299
+ </span>
307
300
  </span>
308
- <p className="text-meta text-muted-foreground">40% used · 60% free</p>
309
- </CardContent>
310
- </Card>
311
- </CardMedia>
312
- <CardHeader>
313
- <CardTitle>Stacked sheets</CardTitle>
314
- <CardDescription>
315
- <code>{"<Card stacked>"}</code> — two sheet edges rise behind the top edge.
316
- </CardDescription>
317
- </CardHeader>
318
- </Card>
319
-
320
- <Card>
321
- <CardMedia ground="dots">
322
- <div
323
- data-testid="hairline-corners"
324
- className="hairline-corners flex items-center gap-2 rounded-md border border-card-border bg-card px-3 py-2 shadow-card [--hairline-ink-strong:var(--primary-text)]"
325
- >
326
- <ShieldCheck aria-hidden="true" className="size-4 text-success-text" />
327
- <span className="text-caption font-medium">Verified signer</span>
328
- <PenLine aria-hidden="true" className="size-4 text-muted-foreground" />
329
- </div>
330
- </CardMedia>
331
- <CardHeader>
332
- <CardTitle>Crop corners on a dot field</CardTitle>
333
- <CardDescription>
334
- <code>hairline-corners</code> marks the focal item; re-inked here with one variable.
335
- </CardDescription>
336
- </CardHeader>
337
- </Card>
301
+ </div>
302
+ </CardMedia>
303
+ <CardHeader>
304
+ <CardTitle>Hatch well</CardTitle>
305
+ <CardDescription>
306
+ <code>CardMedia</code> — a faded hairline hatch behind whatever the card shows.
307
+ </CardDescription>
308
+ </CardHeader>
309
+ </Card>
338
310
 
339
- <Card className="md:col-span-2">
340
- <CardHeader>
341
- <CardTitle>Dashed slots</CardTitle>
342
- <CardDescription>
343
- <code>hairline-slot</code> — the empty seats next to the filled ones.
344
- </CardDescription>
345
- </CardHeader>
346
- <CardContent>
347
- <div className="grid grid-cols-6 gap-3">
348
- {[
349
- Plug,
350
- null,
351
- Workflow,
352
- null,
353
- null,
354
- ShieldCheck,
355
- null,
356
- FileText,
357
- null,
358
- PenLine,
359
- null,
360
- null,
361
- ].map((Icon, i) =>
362
- Icon ? (
363
- <span
364
- key={i}
365
- className="flex aspect-square items-center justify-center rounded-lg border border-card-border bg-card text-muted-foreground shadow-card"
366
- >
367
- <Icon aria-hidden="true" className="size-5" />
311
+ <Card>
312
+ <CardMedia ground="none" className="items-end pb-0">
313
+ <Card
314
+ stacked
315
+ data-testid="hairline-stack"
316
+ className="w-full max-w-56 rounded-b-none border-b-0"
317
+ >
318
+ <CardContent className="space-y-2 p-4">
319
+ <p className="text-caption font-medium">Spending limit</p>
320
+ <span className="block h-2 rounded-sm bg-surface-muted">
321
+ <span className="block h-2 w-2/5 rounded-sm bg-primary" />
368
322
  </span>
369
- ) : (
370
- <span
371
- key={i}
372
- data-slot-empty
373
- className="hairline-slot aspect-square rounded-lg"
374
- />
375
- ),
376
- )}
377
- </div>
378
- </CardContent>
379
- </Card>
323
+ <p className="text-meta text-muted-foreground">40% used · 60% free</p>
324
+ </CardContent>
325
+ </Card>
326
+ </CardMedia>
327
+ <CardHeader>
328
+ <CardTitle>Stacked sheets</CardTitle>
329
+ <CardDescription>
330
+ <code>{"<Card stacked>"}</code> — two sheet edges rise behind the top edge.
331
+ </CardDescription>
332
+ </CardHeader>
333
+ </Card>
380
334
 
381
- <Card>
382
- <CardHeader>
383
- <CardTitle>Ruler and rule</CardTitle>
384
- <CardDescription>
385
- <code>hairline-ticks-y</code> and <code>hairline-rule</code>.
386
- </CardDescription>
387
- </CardHeader>
388
- <CardContent className="space-y-4">
389
- <div data-testid="hairline-ticks" className="hairline-ticks-y space-y-2 ps-5">
390
- <span className="block h-4 w-11/12 rounded-sm bg-primary" />
391
- <span className="block h-4 w-7/12 rounded-sm bg-surface-muted" />
392
- <span className="block h-4 w-4/12 rounded-sm bg-surface-muted" />
393
- </div>
394
- <hr className="hairline-rule" />
395
- <p className="text-caption text-muted-foreground">Below the dashed rule.</p>
396
- </CardContent>
397
- </Card>
335
+ <Card>
336
+ <CardMedia ground="dots">
337
+ <div
338
+ data-testid="hairline-corners"
339
+ className="hairline-corners flex items-center gap-2 rounded-md border border-card-border bg-card px-3 py-2 shadow-card [--hairline-ink-strong:var(--primary-text)]"
340
+ >
341
+ <ShieldCheck aria-hidden="true" className="size-4 text-success-text" />
342
+ <span className="text-caption font-medium">Verified signer</span>
343
+ <PenLine aria-hidden="true" className="size-4 text-muted-foreground" />
344
+ </div>
345
+ </CardMedia>
346
+ <CardHeader>
347
+ <CardTitle>Crop corners on a dot field</CardTitle>
348
+ <CardDescription>
349
+ <code>hairline-corners</code> marks the focal item; re-inked here with one variable.
350
+ </CardDescription>
351
+ </CardHeader>
352
+ </Card>
353
+
354
+ <Card className="md:col-span-2">
355
+ <CardHeader>
356
+ <CardTitle>Dashed slots</CardTitle>
357
+ <CardDescription>
358
+ <code>hairline-slot</code> — the empty seats next to the filled ones.
359
+ </CardDescription>
360
+ </CardHeader>
361
+ <CardContent>
362
+ <div className="grid grid-cols-6 gap-3">
363
+ {[
364
+ Plug,
365
+ null,
366
+ Workflow,
367
+ null,
368
+ null,
369
+ ShieldCheck,
370
+ null,
371
+ FileText,
372
+ null,
373
+ PenLine,
374
+ null,
375
+ null,
376
+ ].map((Icon, i) =>
377
+ Icon ? (
378
+ <span
379
+ key={i}
380
+ className="flex aspect-square items-center justify-center rounded-lg border border-card-border bg-card text-muted-foreground shadow-card"
381
+ >
382
+ <Icon aria-hidden="true" className="size-5" />
383
+ </span>
384
+ ) : (
385
+ <span
386
+ key={i}
387
+ data-slot-empty
388
+ className="hairline-slot aspect-square rounded-lg"
389
+ />
390
+ ),
391
+ )}
392
+ </div>
393
+ </CardContent>
394
+ </Card>
395
+
396
+ <Card>
397
+ <CardHeader>
398
+ <CardTitle>Ruler and rule</CardTitle>
399
+ <CardDescription>
400
+ <code>hairline-ticks-y</code> and <code>hairline-rule</code>.
401
+ </CardDescription>
402
+ </CardHeader>
403
+ <CardContent className="space-y-4">
404
+ <div data-testid="hairline-ticks" className="hairline-ticks-y space-y-2 ps-5">
405
+ <span className="block h-4 w-11/12 rounded-sm bg-primary" />
406
+ <span className="block h-4 w-7/12 rounded-sm bg-surface-muted" />
407
+ <span className="block h-4 w-4/12 rounded-sm bg-surface-muted" />
408
+ </div>
409
+ <hr className="hairline-rule" />
410
+ <p className="text-caption text-muted-foreground">Below the dashed rule.</p>
411
+ </CardContent>
412
+ </Card>
413
+ </div>
398
414
  </div>
399
415
 
400
- <div className="mx-auto mt-16 max-w-3xl">
416
+ <div className="mx-auto max-w-3xl px-6 py-16">
401
417
  <div data-testid="hairline-frame" className="hairline-frame p-8">
402
418
  <p className="text-subtitle font-medium">Frame rails</p>
403
419
  <p className="mt-1 text-caption text-muted-foreground">
@@ -439,6 +455,20 @@ export const Hairlines: Story = {
439
455
  await expect(getComputedStyle(host).maskImage).toBe("none");
440
456
  }
441
457
 
458
+ // The corner stripes are ONE inert layer: a flat ink fill whose mask draws the stripes.
459
+ const stripes = getComputedStyle(canvas.getByTestId("hairline-stripes"), "::before");
460
+ await expect(stripes.pointerEvents).toBe("none");
461
+ await expect(stripes.backgroundImage).toBe("none");
462
+ await expect(stripes.maskImage).toContain("repeating-linear-gradient");
463
+ await expect(stripes.maskComposite).toContain("intersect");
464
+
465
+ // The section rails are corner marks: both pseudo layers are masked, so the middle of
466
+ // every run is air.
467
+ const rails = canvas.getByTestId("hairline-rails");
468
+ await expect(getComputedStyle(rails, "::before").maskImage).toContain("gradient");
469
+ await expect(getComputedStyle(rails, "::after").maskImage).toContain("gradient");
470
+ await expect(getComputedStyle(rails).maskImage).toBe("none");
471
+
442
472
  // The frame's rails overshoot the box and fade — never a hard stop.
443
473
  const frame = getComputedStyle(canvas.getByTestId("hairline-frame"), "::before");
444
474
  await expect(frame.maskImage).toContain("gradient");
package/src/index.ts CHANGED
@@ -177,6 +177,7 @@ export * from "./components/date-range-picker";
177
177
  export * from "./components/descriptions";
178
178
  export * from "./components/dialog";
179
179
  export * from "./components/drawer";
180
+ export * from "./components/drafting-marks";
180
181
  export * from "./components/dropdown-menu";
181
182
  export * from "./components/empty-state";
182
183
  export * from "./components/error-state";
@@ -1,6 +1,19 @@
1
+ import { readFileSync } from "node:fs";
2
+ import { dirname, join } from "node:path";
3
+ import { fileURLToPath } from "node:url";
1
4
  import { describe, expect, it } from "vitest";
2
5
  import { cn } from "./cn";
3
6
 
7
+ /** Every `--text-<role>` companion-key root declared by the token engine. */
8
+ function typeRolesFromThemesCss(): string[] {
9
+ const here = dirname(fileURLToPath(import.meta.url));
10
+ const css = readFileSync(join(here, "../../../tokens/src/themes.css"), "utf8");
11
+ const roles = new Set<string>();
12
+ for (const m of css.matchAll(/^\s*--text-([a-z][a-z0-9-]*?)(?:--[a-z-]+)?:/gm))
13
+ if (m[1]) roles.add(m[1]);
14
+ return [...roles].sort();
15
+ }
16
+
4
17
  describe("cn", () => {
5
18
  it("later utilities win for a genuine conflict (e.g. padding)", () => {
6
19
  expect(cn("p-2", "p-4")).toBe("p-4");
@@ -46,6 +59,22 @@ describe("cn", () => {
46
59
  }
47
60
  });
48
61
 
62
+ // 2026-09-21 new-user test: the chart roles from RM-019 were never registered,
63
+ // so `cn("text-chart-source", "text-chart-foreground-muted")` returned only the
64
+ // colour and every ChartCard source row rendered at body size. The expected
65
+ // list is read from themes.css so the next `--text-<role>` cannot drift either.
66
+ it("registers every --text-<role> the token engine declares (chart roles included)", () => {
67
+ const roles = typeRolesFromThemesCss();
68
+ expect(roles).toContain("chart-source");
69
+ expect(roles).toContain("chart-value");
70
+ for (const role of roles) {
71
+ expect(cn(`text-${role}`, "text-chart-foreground-muted"), role).toBe(
72
+ `text-${role} text-chart-foreground-muted`,
73
+ );
74
+ expect(cn(`text-${role}`, "text-caption"), role).toBe("text-caption");
75
+ }
76
+ });
77
+
49
78
  it("lets a caller's utility replace a component-seam token default", () => {
50
79
  expect(cn("shadow-card", "shadow-none")).toBe("shadow-none");
51
80
  expect(cn("shadow-popover", "shadow-lg")).toBe("shadow-lg");
package/src/lib/cn.ts CHANGED
@@ -22,6 +22,13 @@ const TEXT_ROLES = [
22
22
  "kpi",
23
23
  "kpi-sm",
24
24
  "code",
25
+ // Chart type roles (RM-019, themes.css § chart type roles). They were missing
26
+ // here from RM-019 until the 2026-09-21 new-user test: `cn("text-chart-source",
27
+ // "text-chart-foreground-muted")` dropped the role and every ChartCard source
28
+ // row rendered at body size. `cn.test.ts` now derives the expected list from
29
+ // themes.css, so a new `--text-<role>` token cannot drift from this list again.
30
+ "chart-value",
31
+ "chart-source",
25
32
  ];
26
33
 
27
34
  /**
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/lib/cn.ts"],"sourcesContent":["import { clsx, type ClassValue } from \"clsx\";\nimport { extendTailwindMerge } from \"tailwind-merge\";\n\n/**\n * The semantic type roles (`--text-<role>` tokens → `text-<role>` utilities, #187).\n * tailwind-merge doesn't know custom theme keys, so without registration it\n * classifies `text-title` as a text COLOR — and `cn(\"text-kpi\", \"text-foreground\")`\n * would silently drop the role. Registering the roles in the `font-size` class\n * group makes role-vs-role and role-vs-raw-size conflicts resolve correctly while\n * keeping role + color independent.\n */\nconst TEXT_ROLES = [\n \"display-lg\",\n \"display\",\n \"title\",\n \"subtitle\",\n \"body\",\n \"caption\",\n \"meta\",\n \"eyebrow\",\n \"heading-xs\",\n \"kpi\",\n \"kpi-sm\",\n \"code\",\n];\n\n/**\n * Tailwind v4's CSS-variable shorthand (`leading-(--card-title-leading)`).\n * tailwind-merge 2.x predates it and leaves such a class beside a caller's\n * `leading-tight`, letting stylesheet order pick the winner. A typed hint\n * (`text-(length:--x)`) is read as a variant prefix by 2.x and cannot be\n * registered — give that seam a named `@theme` utility instead\n * (`text-table-header`).\n */\nconst isVarShorthand = (value: string) => /^\\(--[\\w-]+\\)$/.test(value);\n\nconst twMerge = extendTailwindMerge({\n extend: {\n classGroups: {\n \"font-size\": [{ text: [...TEXT_ROLES, \"table-header\"] }],\n leading: [{ leading: [isVarShorthand] }],\n tracking: [{ tracking: [isVarShorthand] }],\n // `font-display` is the display-face seam (sibling of font-mono, #187).\n \"font-family\": [{ font: [\"display\"] }],\n // Theme-driven control/table/surface knobs (themes.css § CONTROL UTILITIES\n // and the `@theme inline` bridge) — so a caller's `h-8` / `rounded-none` /\n // `font-bold` / `shadow-none` still replaces the token default.\n \"font-weight\": [{ font: [\"control\", \"table-header\", \"tabs-active\"] }],\n rounded: [{ rounded: [\"control\", \"badge\"] }],\n shadow: [{ shadow: [\"input\", \"card\", \"popover\", \"dialog\"] }],\n h: [{ h: [\"control\", \"control-sm\", \"control-lg\", \"header\"] }],\n size: [{ size: [\"control\", \"control-sm\", \"control-lg\"] }],\n \"min-w\": [{ \"min-w\": [\"control\", \"control-sm\", \"control-lg\"] }],\n },\n },\n});\n\n/**\n * Merge class names with conflict resolution. `clsx` handles conditionals;\n * `tailwind-merge` ensures later Tailwind utilities win (e.g. `p-2 p-4` -> `p-4`).\n * Use this in every component that accepts a `className` prop.\n */\nexport function cn(...inputs: ClassValue[]): string {\n return twMerge(clsx(inputs));\n}\n"],"mappings":";;;AAAA,SAAS,YAA6B;AACtC,SAAS,2BAA2B;AAUpC,IAAM,aAAa;AAAA,EACjB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAUA,IAAM,iBAAiB,CAAC,UAAkB,iBAAiB,KAAK,KAAK;AAErE,IAAM,UAAU,oBAAoB;AAAA,EAClC,QAAQ;AAAA,IACN,aAAa;AAAA,MACX,aAAa,CAAC,EAAE,MAAM,CAAC,GAAG,YAAY,cAAc,EAAE,CAAC;AAAA,MACvD,SAAS,CAAC,EAAE,SAAS,CAAC,cAAc,EAAE,CAAC;AAAA,MACvC,UAAU,CAAC,EAAE,UAAU,CAAC,cAAc,EAAE,CAAC;AAAA;AAAA,MAEzC,eAAe,CAAC,EAAE,MAAM,CAAC,SAAS,EAAE,CAAC;AAAA;AAAA;AAAA;AAAA,MAIrC,eAAe,CAAC,EAAE,MAAM,CAAC,WAAW,gBAAgB,aAAa,EAAE,CAAC;AAAA,MACpE,SAAS,CAAC,EAAE,SAAS,CAAC,WAAW,OAAO,EAAE,CAAC;AAAA,MAC3C,QAAQ,CAAC,EAAE,QAAQ,CAAC,SAAS,QAAQ,WAAW,QAAQ,EAAE,CAAC;AAAA,MAC3D,GAAG,CAAC,EAAE,GAAG,CAAC,WAAW,cAAc,cAAc,QAAQ,EAAE,CAAC;AAAA,MAC5D,MAAM,CAAC,EAAE,MAAM,CAAC,WAAW,cAAc,YAAY,EAAE,CAAC;AAAA,MACxD,SAAS,CAAC,EAAE,SAAS,CAAC,WAAW,cAAc,YAAY,EAAE,CAAC;AAAA,IAChE;AAAA,EACF;AACF,CAAC;AAOM,SAAS,MAAM,QAA8B;AAClD,SAAO,QAAQ,KAAK,MAAM,CAAC;AAC7B;","names":[]}
@@ -1,30 +0,0 @@
1
- "use client";
2
- import {
3
- cn
4
- } from "./chunk-KBNWM27Q.js";
5
-
6
- // src/components/section-header/section-header.tsx
7
- import "react";
8
- import { jsx, jsxs } from "react/jsx-runtime";
9
- function SectionHeader({
10
- title,
11
- description,
12
- actions,
13
- eyebrow,
14
- as: TitleTag = "h2",
15
- className
16
- }) {
17
- return /* @__PURE__ */ jsxs("div", { className: cn("flex flex-wrap items-end justify-between gap-4", className), children: [
18
- /* @__PURE__ */ jsxs("div", { className: "space-y-1", children: [
19
- eyebrow ? /* @__PURE__ */ jsx("div", { className: "text-eyebrow uppercase text-muted-foreground", children: eyebrow }) : null,
20
- /* @__PURE__ */ jsx(TitleTag, { className: "text-title text-foreground", children: title }),
21
- description ? /* @__PURE__ */ jsx("p", { className: "text-body text-muted-foreground", children: description }) : null
22
- ] }),
23
- actions ? /* @__PURE__ */ jsx("div", { className: "flex items-center gap-2", children: actions }) : null
24
- ] });
25
- }
26
-
27
- export {
28
- SectionHeader
29
- };
30
- //# sourceMappingURL=chunk-OZTM6PYF.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/components/section-header/section-header.tsx"],"sourcesContent":["import { type ReactNode } from \"react\";\nimport { cn } from \"../../lib/cn\";\n\nexport interface SectionHeaderProps {\n title: ReactNode;\n description?: ReactNode;\n /** Right-aligned actions (buttons, menus). */\n actions?: ReactNode;\n /** Optional element rendered above the title (eyebrow / breadcrumbs). */\n eyebrow?: ReactNode;\n /**\n * The heading LEVEL the title contributes to the document outline. The\n * visual (`text-title`) is identical for every value — pick the level the\n * page's structure calls for, not the size you want (WCAG 1.3.1).\n *\n * Use `as=\"h1\"` when this header titles the PAGE (a screen whose route it\n * names); leave it at the default when it titles a section INSIDE a page\n * that already has an `<h1>` elsewhere. @default \"h2\"\n */\n as?: \"h1\" | \"h2\" | \"h3\" | \"h4\" | \"h5\" | \"h6\";\n className?: string;\n}\n\n/** A consistent page/section heading row with optional actions. */\nexport function SectionHeader({\n title,\n description,\n actions,\n eyebrow,\n as: TitleTag = \"h2\",\n className,\n}: SectionHeaderProps) {\n return (\n <div className={cn(\"flex flex-wrap items-end justify-between gap-4\", className)}>\n <div className=\"space-y-1\">\n {eyebrow ? (\n <div className=\"text-eyebrow uppercase text-muted-foreground\">{eyebrow}</div>\n ) : null}\n <TitleTag className=\"text-title text-foreground\">{title}</TitleTag>\n {description ? <p className=\"text-body text-muted-foreground\">{description}</p> : null}\n </div>\n {actions ? <div className=\"flex items-center gap-2\">{actions}</div> : null}\n </div>\n );\n}\n"],"mappings":";;;;;;AAAA,OAA+B;AAkCzB,SAEI,KAFJ;AAVC,SAAS,cAAc;AAAA,EAC5B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,IAAI,WAAW;AAAA,EACf;AACF,GAAuB;AACrB,SACE,qBAAC,SAAI,WAAW,GAAG,kDAAkD,SAAS,GAC5E;AAAA,yBAAC,SAAI,WAAU,aACZ;AAAA,gBACC,oBAAC,SAAI,WAAU,gDAAgD,mBAAQ,IACrE;AAAA,MACJ,oBAAC,YAAS,WAAU,8BAA8B,iBAAM;AAAA,MACvD,cAAc,oBAAC,OAAE,WAAU,mCAAmC,uBAAY,IAAO;AAAA,OACpF;AAAA,IACC,UAAU,oBAAC,SAAI,WAAU,2BAA2B,mBAAQ,IAAS;AAAA,KACxE;AAEJ;","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/components/sidebar/sidebar.tsx"],"sourcesContent":["\"use client\";\n\nimport {\n createContext,\n forwardRef,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState,\n type ComponentProps,\n type CSSProperties,\n} from \"react\";\nimport { Slot } from \"@radix-ui/react-slot\";\nimport { cva, type VariantProps } from \"class-variance-authority\";\nimport { PanelLeftIcon } from \"lucide-react\";\nimport { cn } from \"../../lib/cn\";\nimport { useIsMobile } from \"../../lib/use-mobile\";\nimport { Button } from \"../button\";\nimport { useCollapsiblePanel, type CollapsiblePanelContainerPosition } from \"../collapsible-panel\";\nimport { Input } from \"../input\";\nimport { useLocale } from \"../locale-provider\";\nimport { Separator } from \"../separator\";\nimport { Sheet, SheetContent, SheetDescription, SheetHeader, SheetTitle } from \"../sheet\";\nimport { Skeleton } from \"../skeleton\";\nimport { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from \"../tooltip\";\n\nconst SIDEBAR_COOKIE_NAME = \"sidebar_state\";\nconst SIDEBAR_COOKIE_MAX_AGE = 60 * 60 * 24 * 7;\nconst SIDEBAR_WIDTH = \"16rem\";\nconst SIDEBAR_WIDTH_MOBILE = \"18rem\";\nconst SIDEBAR_WIDTH_ICON = \"3rem\";\nconst SIDEBAR_KEYBOARD_SHORTCUT = \"b\";\n\ntype SidebarContextProps = {\n state: \"expanded\" | \"collapsed\";\n open: boolean;\n setOpen: (open: boolean) => void;\n openMobile: boolean;\n setOpenMobile: (open: boolean) => void;\n isMobile: boolean;\n toggleSidebar: () => void;\n};\n\nconst SidebarContext = createContext<SidebarContextProps | null>(null);\n\nexport function useSidebar() {\n const context = useContext(SidebarContext);\n if (!context) throw new Error(\"useSidebar must be used within a SidebarProvider.\");\n return context;\n}\n\nexport const SidebarProvider = forwardRef<\n HTMLDivElement,\n ComponentProps<\"div\"> & {\n defaultOpen?: boolean;\n open?: boolean;\n onOpenChange?: (open: boolean) => void;\n /**\n * Drives the frame's inset treatment from an ANCESTOR the whole frame can\n * see — `SidebarInset` (#342 fix) reads it as `data-variant` on this\n * wrapper via `group-data-[variant=inset]/sidebar-wrapper:`, which reaches\n * regardless of DOM order (unlike the legacy `peer-*` combinator, which\n * only matches a Sidebar that comes AFTER). Optional and unset by\n * default, so an existing caller that only sets `variant` on `Sidebar`\n * is unaffected.\n */\n variant?: \"sidebar\" | \"floating\" | \"inset\";\n /**\n * Default `\"app\"` — today's behaviour, byte-identical. `\"nested\"` is for\n * a `SidebarProvider` a compound component (e.g. `ContextRail`, ADR 0035\n * §4) mounts internally so `useSidebar()` reports ITS OWN state to its\n * own parts: it still provides `SidebarContext` and the two\n * `--sidebar-width*` custom properties (which survive `display:\n * contents`), but renders no frame box, no `data-slot`/`data-variant`/\n * `data-state`, registers no global `⌘B`/`Ctrl+B` listener, and writes no\n * `sidebar_state` cookie — so a nested rail can never be mistaken for a\n * second app frame. See the emission table in ADR 0035 §4.\n */\n frame?: \"app\" | \"nested\";\n }\n>(function SidebarProvider(\n {\n defaultOpen = true,\n open: openProp,\n onOpenChange: setOpenProp,\n variant,\n frame = \"app\",\n className,\n style,\n children,\n ...props\n },\n ref,\n) {\n const isNested = frame === \"nested\";\n const isMobile = useIsMobile();\n const [openMobile, setOpenMobile] = useState(false);\n\n const [_open, _setOpen] = useState(defaultOpen);\n const open = openProp ?? _open;\n const setOpen = useCallback(\n (value: boolean | ((value: boolean) => boolean)) => {\n const openState = typeof value === \"function\" ? value(open) : value;\n if (setOpenProp) setOpenProp(openState);\n else _setOpen(openState);\n // A nested provider (ADR 0035 §4) is not the app frame, so it must not\n // persist ITS state as if it were — only `frame=\"app\"` (the default)\n // owns the `sidebar_state` cookie.\n if (!isNested && typeof document !== \"undefined\") {\n document.cookie = `${SIDEBAR_COOKIE_NAME}=${openState}; path=/; max-age=${SIDEBAR_COOKIE_MAX_AGE}`;\n }\n },\n [setOpenProp, open, isNested],\n );\n\n const toggleSidebar = useCallback(() => {\n return isMobile ? setOpenMobile((o) => !o) : setOpen((o) => !o);\n }, [isMobile, setOpen]);\n\n // `toggleSidebar` is a NEW function on every `open` change (it closes over\n // `setOpen`, which itself closes over `open`) — a `useEffect` depending on\n // it directly would tear down and re-add the global `keydown` listener on\n // every single toggle. A ref holding the latest callback keeps the listener\n // registration stable across toggles; only `isNested` (which never changes\n // after mount) re-runs the effect.\n const toggleSidebarRef = useRef(toggleSidebar);\n useEffect(() => {\n toggleSidebarRef.current = toggleSidebar;\n }, [toggleSidebar]);\n\n useEffect(() => {\n // Same reasoning as the cookie write above: the global keyboard shortcut\n // belongs to the ONE app frame, not to every nested provider a compound\n // component happens to mount.\n if (isNested) return;\n const handleKeyDown = (event: KeyboardEvent) => {\n if (event.key === SIDEBAR_KEYBOARD_SHORTCUT && (event.metaKey || event.ctrlKey)) {\n event.preventDefault();\n toggleSidebarRef.current();\n }\n };\n window.addEventListener(\"keydown\", handleKeyDown);\n return () => window.removeEventListener(\"keydown\", handleKeyDown);\n }, [isNested]);\n\n const state = open ? \"expanded\" : \"collapsed\";\n\n const contextValue = useMemo<SidebarContextProps>(\n () => ({ state, open, setOpen, isMobile, openMobile, setOpenMobile, toggleSidebar }),\n [state, open, setOpen, isMobile, openMobile, toggleSidebar],\n );\n\n return (\n <SidebarContext.Provider value={contextValue}>\n <TooltipProvider delayDuration={0}>\n <div\n ref={ref}\n // `data-slot`/`data-variant`/`data-state`/`group/sidebar-wrapper`\n // (in the class list below) are ADR 0035 §8 refinement 3's\n // `frame=\"app\"` surface. `frame=\"nested\"` (ADR 0035 §4, Task 9A)\n // omits all four: a nested rail's own state must never drive the\n // outer frame's geometry through the same group name or be mistaken\n // for a second \"sidebar wrapper\" by a selector/test targeting the\n // slot. The literal string \"sidebar-wrapper\" stays below (as a\n // conditional value) so `pnpm data-slot:check` still sees this\n // module's declaration.\n data-slot={isNested ? undefined : \"sidebar-wrapper\"}\n data-variant={isNested ? undefined : variant}\n data-state={isNested ? undefined : state}\n style={\n {\n // These two custom properties are the ONE thing a nested\n // provider still emits (ADR 0035 §4) — they survive `display:\n // contents` because custom properties inherit down the DOM\n // tree regardless of the box an element generates, which is\n // exactly how a nested rail publishes its width to whatever it\n // wraps. Never move them onto a child.\n \"--sidebar-width\": SIDEBAR_WIDTH,\n \"--sidebar-width-icon\": SIDEBAR_WIDTH_ICON,\n ...style,\n } as CSSProperties\n }\n className={cn(\n // The wrapper spans the WHOLE app frame — chrome AND content — so its\n // ink is the ordinary page ink, not the chrome's. `Sidebar` (desktop\n // and mobile) sets `text-sidebar-foreground` on itself, so the chrome\n // is covered without painting chrome ink onto the canvas. Putting the\n // chrome ink here was invisible only while a theme happened to give\n // `--sidebar` and `--background` the same polarity: a theme with dark\n // chrome under a light canvas rendered near-white text on the canvas\n // for every element that inherits its colour (outline Buttons, list\n // rows). See the chrome<canvas elevation invariant in\n // .claude/rules/styling-and-tokens.md.\n // Omitted under `frame=\"nested\"` — a nested provider is a pure\n // context + custom-property carrier, not a second frame box.\n !isNested && \"group/sidebar-wrapper flex min-h-svh w-full text-foreground\",\n // The frame's OWN `variant` is authoritative once set (ADR 0035 §8\n // refinement 4): resolved in JS, not by a CSS descendant match, so\n // a nested rail three levels down that happens to render\n // `variant=\"inset\"` can never repaint THIS frame's ground merely\n // because `:has()` is depth-unlimited. `has-data-[variant=inset]`\n // stays as the fallback ONLY while this provider's own `variant`\n // is unset, which is exactly every existing caller (this prop\n // didn't exist before #342) — so they render exactly as today.\n // Also omitted under `frame=\"nested\"`, same reasoning as above.\n !isNested &&\n (variant === undefined\n ? \"has-data-[variant=inset]:bg-sidebar\"\n : variant === \"inset\" && \"bg-sidebar\"),\n // `frame=\"nested\"` renders no box of its own: `display: contents`\n // (the literal Tailwind class, never an inline style or a\n // concatenated name) removes this element from layout while\n // keeping its children — and the custom properties above —\n // reachable.\n isNested && \"contents\",\n className,\n )}\n {...props}\n >\n {children}\n </div>\n </TooltipProvider>\n </SidebarContext.Provider>\n );\n});\n\nexport const Sidebar = forwardRef<\n HTMLDivElement,\n ComponentProps<\"div\"> & {\n side?: \"left\" | \"right\";\n variant?: \"sidebar\" | \"floating\" | \"inset\";\n collapsible?: \"offcanvas\" | \"icon\" | \"none\";\n /**\n * Where the rail's container pins itself. Default `\"viewport\"` (`fixed` to the window\n * edge — today's behaviour, byte-identical). `\"inset\"` pins to the rail's own place in\n * the layout instead (`absolute` against a `relative` wrapper this component provides),\n * for a whole app frame rendered INSIDE a box — a preview pane, a docs page, a\n * dashboard tile — where a `fixed` rail would escape to the window. Same seam as\n * `SideDock`'s `containerPosition`. No effect on the mobile `Sheet` or on\n * `collapsible=\"none\"`.\n */\n containerPosition?: CollapsiblePanelContainerPosition;\n }\n>(function Sidebar(\n {\n side = \"left\",\n variant = \"sidebar\",\n collapsible = \"offcanvas\",\n containerPosition = \"viewport\",\n className,\n children,\n ...props\n },\n ref,\n) {\n const { isMobile, openMobile, setOpenMobile, open, setOpen } = useSidebar();\n const { t } = useLocale();\n\n // The collapse mechanism (gap spacer + fixed slide) is the canonical\n // useCollapsiblePanel hook (#190, research 09 §B.2) — Sidebar passes its\n // literal width/collapse/slide utilities (Tailwind scans THIS file for\n // them) and gets back its original class fragments byte-identically.\n const panel = useCollapsiblePanel({\n side,\n open,\n onOpenChange: setOpen,\n containerPosition,\n widthClassName: \"w-(--sidebar-width)\",\n spacerCollapsedClassName: \"group-data-[collapsible=offcanvas]:w-0\",\n containerSlideClassNames: {\n left: \"left-0 group-data-[collapsible=offcanvas]:left-[calc(var(--sidebar-width)*-1)]\",\n right: \"right-0 group-data-[collapsible=offcanvas]:right-[calc(var(--sidebar-width)*-1)]\",\n },\n });\n\n if (collapsible === \"none\") {\n return (\n <div\n ref={ref}\n data-slot=\"sidebar\"\n className={cn(\n \"flex h-full w-(--sidebar-width) flex-col bg-sidebar text-sidebar-foreground\",\n className,\n )}\n {...props}\n >\n {children}\n </div>\n );\n }\n\n if (isMobile) {\n return (\n <Sheet open={openMobile} onOpenChange={setOpenMobile} {...props}>\n <SheetContent\n data-sidebar=\"sidebar\"\n data-slot=\"sidebar\"\n data-mobile=\"true\"\n side={side}\n className=\"w-[var(--sidebar-width)] bg-sidebar p-0 text-sidebar-foreground [&>button]:hidden\"\n style={{ \"--sidebar-width\": SIDEBAR_WIDTH_MOBILE } as CSSProperties}\n >\n <SheetHeader className=\"sr-only\">\n <SheetTitle>{t(\"ui.sidebar.title\")}</SheetTitle>\n <SheetDescription>{t(\"ui.sidebar.mobileDescription\")}</SheetDescription>\n </SheetHeader>\n <div className=\"flex h-full w-full flex-col\">{children}</div>\n </SheetContent>\n </Sheet>\n );\n }\n\n return (\n <div\n ref={ref}\n className={cn(\n \"group peer hidden text-sidebar-foreground md:block\",\n // The `absolute` container needs a positioned ancestor of the rail's own height.\n containerPosition === \"inset\" && \"relative h-full\",\n )}\n data-state={panel.attrs[\"data-state\"]}\n data-collapsible={panel.state === \"collapsed\" ? collapsible : \"\"}\n data-variant={variant}\n data-side={panel.attrs[\"data-side\"]}\n data-slot=\"sidebar\"\n >\n <div\n data-slot=\"sidebar-gap\"\n className={cn(\n panel.spacerClassName,\n \"group-data-[side=right]:rotate-180\",\n variant === \"floating\" || variant === \"inset\"\n ? \"group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+(--spacing(4)))]\"\n : \"group-data-[collapsible=icon]:w-(--sidebar-width-icon)\",\n )}\n />\n <div\n data-slot=\"sidebar-container\"\n className={cn(\n panel.containerClassName,\n variant === \"floating\" || variant === \"inset\"\n ? \"p-2 group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+(--spacing(4))+2px)]\"\n : // `border-sidebar-border`, not the inherited canvas `--border`:\n // this edge is CHROME, so it takes the chrome edge token — the\n // same one the `floating` variant's inner surface and\n // `SidebarSeparator` already use. Left to the canvas token it was\n // a near-white hairline (light: L 0.88), invisible against the\n // page but a bright line as soon as the rail sits on a\n // `bg-sidebar` ground — which is exactly what an `inset` frame\n // puts behind it, measured at the dashboard shell's right-hand\n // `ContextRail`.\n \"group-data-[collapsible=icon]:w-(--sidebar-width-icon) border-sidebar-border group-data-[side=left]:border-r group-data-[side=right]:border-l\",\n className,\n )}\n {...props}\n >\n <div\n data-sidebar=\"sidebar\"\n data-slot=\"sidebar-inner\"\n className=\"flex h-full w-full flex-col bg-sidebar group-data-[variant=floating]:rounded-lg group-data-[variant=floating]:border group-data-[variant=floating]:border-sidebar-border group-data-[variant=floating]:shadow-sm\"\n >\n {children}\n </div>\n </div>\n </div>\n );\n});\n\nexport const SidebarTrigger = forwardRef<HTMLButtonElement, ComponentProps<typeof Button>>(\n function SidebarTrigger({ className, onClick, ...props }, ref) {\n const { t } = useLocale();\n const { isMobile, open, openMobile, toggleSidebar } = useSidebar();\n // `toggleSidebar` flips `openMobile` below the mobile breakpoint and `open`\n // above it, so the state this button EXPOSES has to be read the same way —\n // reporting the desktop `open` on a mobile viewport would announce the\n // opposite of what the button does.\n const expanded = isMobile ? openMobile : open;\n return (\n <Button\n ref={ref}\n data-sidebar=\"trigger\"\n data-slot=\"sidebar-trigger\"\n variant=\"ghost\"\n size=\"icon\"\n // A disclosure control must EXPOSE the state it toggles (WCAG 4.1.2).\n // This button's whole accessible name is the static \"Toggle Sidebar\"\n // below, so without this attribute nothing tells a screen-reader user\n // whether the rail is currently open — and no axe rule catches it,\n // because a <button> has no REQUIRED expanded state.\n //\n // `aria-controls` is deliberately omitted, not forgotten: on mobile the\n // sidebar renders into a `Sheet` that is not in the document while\n // closed, so the attribute would point at an absent id — worse than\n // leaving it off. Spread last, so a caller that really does own a\n // stable target can still supply both.\n aria-expanded={expanded}\n className={cn(\"size-7\", className)}\n onClick={(event) => {\n onClick?.(event);\n toggleSidebar();\n }}\n {...props}\n >\n <PanelLeftIcon />\n <span className=\"sr-only\">{t(\"ui.sidebar.toggle\")}</span>\n </Button>\n );\n },\n);\n\nexport const SidebarRail = forwardRef<HTMLButtonElement, ComponentProps<\"button\">>(\n function SidebarRail({ className, ...props }, ref) {\n const { t } = useLocale();\n const { toggleSidebar } = useSidebar();\n return (\n <button\n ref={ref}\n data-sidebar=\"rail\"\n data-slot=\"sidebar-rail\"\n aria-label={t(\"ui.sidebar.toggle\")}\n tabIndex={-1}\n onClick={toggleSidebar}\n title={t(\"ui.sidebar.toggle\")}\n className={cn(\n \"absolute inset-y-0 z-20 hidden w-4 -translate-x-1/2 transition-all ease-linear group-data-[side=left]:-right-4 group-data-[side=right]:left-0 after:absolute after:inset-y-0 after:left-1/2 after:w-[2px] hover:after:bg-sidebar-border sm:flex\",\n \"in-data-[side=left]:cursor-w-resize in-data-[side=right]:cursor-e-resize\",\n \"[[data-side=left][data-collapsible=offcanvas]_&]:-right-2 [[data-side=right][data-collapsible=offcanvas]_&]:-left-2\",\n className,\n )}\n {...props}\n />\n );\n },\n);\n\n/**\n * Which sides of the floating \"inset\" surface get a gutter, once an ancestor\n * drives the treatment (`SidebarProvider variant=\"inset\"`, or the legacy\n * immediately-preceding `Sidebar variant=\"inset\"`).\n *\n * - `\"auto\"` (default) — today's rule, unchanged: a gutter on every side\n * except the leading edge (`m-2 ms-0`, because the classic layout puts the\n * sidebar there), plus the leading edge's gutter returns (`ms-2`) once that\n * sidebar collapses and its own gap closes.\n * - `\"none\"` — no gutter margin (the unconditional radius/shadow below still\n * apply).\n * - An object — pick sides explicitly. `{ start: true, bottom: true }` is the\n * \"flush rail\" geometry: a leading + bottom gutter only, no top, no\n * trailing, because the trailing edge sits flush against a rail — a tab\n * must touch the page it belongs to.\n *\n * PRECEDENCE (fix round 1, #342): a caller composing BOTH mechanisms at once\n * — `SidebarProvider variant=\"inset\"` AND a LEFT `Sidebar variant=\"inset\"`,\n * the shape a left-hand shell (e.g. the sidebar-02 rebuild) uses — never hits\n * a class-order race, because the ancestor-scoped and legacy peer-scoped\n * margin classes are BOTH derived from this same `gutter` value, so whenever\n * both selectors match they emit identical declarations instead of competing\n * ones; the resolved geometry is always exactly what `gutter` says, decided\n * by this prop, never by the generated stylesheet's rule order.\n */\nexport type SidebarInsetGutter =\n | \"auto\"\n | \"none\"\n | { top?: boolean; bottom?: boolean; start?: boolean; end?: boolean };\n\nexport interface SidebarInsetProps extends ComponentProps<\"main\"> {\n gutter?: SidebarInsetGutter;\n}\n\n// Each side is a COMPLETE literal utility string, one per SELECTOR SCOPE:\n// `ancestor` (`group-data-…/sidebar-wrapper:`, reaches a `SidebarProvider\n// variant=\"inset\"` regardless of DOM order — the #342 fix) and `legacy`\n// (`peer-data-…:`, reaches a `Sidebar variant=\"inset\"` that immediately\n// precedes this element — every caller before #342). Both scopes read the\n// SAME `gutter` value below, which is what keeps them from ever disagreeing.\n// Tailwind's content scanner only recognises literal class text in source —\n// never a name assembled by concatenation/interpolation\n// (.claude/rules/styling-and-tokens.md) — so the object form below picks\n// among these literals, it never builds one.\nconst SIDEBAR_INSET_GUTTER_SIDE_CLASS = {\n top: {\n ancestor: \"md:group-data-[variant=inset]/sidebar-wrapper:mt-2\",\n legacy: \"md:peer-data-[variant=inset]:mt-2\",\n },\n bottom: {\n ancestor: \"md:group-data-[variant=inset]/sidebar-wrapper:mb-2\",\n legacy: \"md:peer-data-[variant=inset]:mb-2\",\n },\n start: {\n ancestor: \"md:group-data-[variant=inset]/sidebar-wrapper:ms-2\",\n legacy: \"md:peer-data-[variant=inset]:ms-2\",\n },\n end: {\n ancestor: \"md:group-data-[variant=inset]/sidebar-wrapper:me-2\",\n legacy: \"md:peer-data-[variant=inset]:me-2\",\n },\n} as const;\n\n// \"auto\" is its own complete literal pair, not composed from the map above,\n// because it also carries the collapsed-state clause: the sidebar's own gap\n// closes on collapse, so the inset's leading margin has to come back.\nconst SIDEBAR_INSET_GUTTER_AUTO_CLASS = {\n ancestor:\n \"md:group-data-[variant=inset]/sidebar-wrapper:m-2 md:group-data-[variant=inset]/sidebar-wrapper:ms-0 md:group-data-[variant=inset]/sidebar-wrapper:group-data-[state=collapsed]/sidebar-wrapper:ms-2\",\n legacy:\n \"md:peer-data-[variant=inset]:m-2 md:peer-data-[variant=inset]:ms-0 md:peer-data-[variant=inset]:peer-data-[state=collapsed]:ms-2\",\n} as const;\n\nfunction sidebarInsetGutterClassName(\n gutter: SidebarInsetGutter,\n scope: \"ancestor\" | \"legacy\",\n): string {\n if (gutter === \"auto\") return SIDEBAR_INSET_GUTTER_AUTO_CLASS[scope];\n if (gutter === \"none\") return \"\";\n return cn(\n gutter.top && SIDEBAR_INSET_GUTTER_SIDE_CLASS.top[scope],\n gutter.bottom && SIDEBAR_INSET_GUTTER_SIDE_CLASS.bottom[scope],\n gutter.start && SIDEBAR_INSET_GUTTER_SIDE_CLASS.start[scope],\n gutter.end && SIDEBAR_INSET_GUTTER_SIDE_CLASS.end[scope],\n );\n}\n\nexport const SidebarInset = forwardRef<HTMLDivElement, SidebarInsetProps>(function SidebarInset(\n { className, gutter = \"auto\", ...props },\n ref,\n) {\n return (\n <main\n ref={ref}\n data-slot=\"sidebar-inset\"\n className={cn(\n \"relative flex w-full flex-1 flex-col bg-background\",\n // Ancestor-scoped (#342 fix): `group/sidebar-wrapper` spans the whole\n // frame, so this reaches a right-hand or reordered `Sidebar` the old\n // peer-* combinator could not (it only matches a sibling that comes\n // AFTER). Reads `SidebarProvider`'s own `data-variant`/`data-state`.\n // Radius/shadow are unconditional here — not gated by `gutter`.\n \"md:group-data-[variant=inset]/sidebar-wrapper:rounded-xl md:group-data-[variant=inset]/sidebar-wrapper:shadow-sm\",\n sidebarInsetGutterClassName(gutter, \"ancestor\"),\n // Legacy peer rule — reaches a shell that sets `variant` only on\n // `Sidebar` (every caller before #342). Radius/shadow unconditional\n // here too; the margin is driven by the SAME `gutter` value as the\n // ancestor rule above (fix round 1, #342), so a caller composing both\n // mechanisms at once never hits a stylesheet-order race — whichever\n // selector matches emits the identical declaration.\n \"md:peer-data-[variant=inset]:rounded-xl md:peer-data-[variant=inset]:shadow-sm\",\n sidebarInsetGutterClassName(gutter, \"legacy\"),\n className,\n )}\n {...props}\n />\n );\n});\n\nexport const SidebarInput = forwardRef<HTMLInputElement, ComponentProps<typeof Input>>(\n function SidebarInput({ className, ...props }, ref) {\n return (\n <Input\n ref={ref}\n data-slot=\"sidebar-input\"\n data-sidebar=\"input\"\n className={cn(\"h-8 w-full bg-background shadow-none\", className)}\n {...props}\n />\n );\n },\n);\n\nexport const SidebarHeader = forwardRef<HTMLDivElement, ComponentProps<\"div\">>(\n function SidebarHeader({ className, ...props }, ref) {\n return (\n <div\n ref={ref}\n data-slot=\"sidebar-header\"\n data-sidebar=\"header\"\n className={cn(\"flex flex-col gap-2 p-2\", className)}\n {...props}\n />\n );\n },\n);\n\nexport const SidebarFooter = forwardRef<HTMLDivElement, ComponentProps<\"div\">>(\n function SidebarFooter({ className, ...props }, ref) {\n return (\n <div\n ref={ref}\n data-slot=\"sidebar-footer\"\n data-sidebar=\"footer\"\n className={cn(\"flex flex-col gap-2 p-2\", className)}\n {...props}\n />\n );\n },\n);\n\nexport const SidebarSeparator = forwardRef<HTMLDivElement, ComponentProps<typeof Separator>>(\n function SidebarSeparator({ className, ...props }, ref) {\n return (\n <Separator\n ref={ref}\n data-slot=\"sidebar-separator\"\n data-sidebar=\"separator\"\n className={cn(\"mx-2 w-auto bg-sidebar-border\", className)}\n {...props}\n />\n );\n },\n);\n\nexport const SidebarContent = forwardRef<HTMLDivElement, ComponentProps<\"div\">>(\n function SidebarContent({ className, ...props }, ref) {\n return (\n <div\n ref={ref}\n data-slot=\"sidebar-content\"\n data-sidebar=\"content\"\n className={cn(\n \"flex min-h-0 flex-1 flex-col gap-2 overflow-auto group-data-[collapsible=icon]:overflow-hidden\",\n className,\n )}\n {...props}\n />\n );\n },\n);\n\nexport const SidebarGroup = forwardRef<HTMLDivElement, ComponentProps<\"div\">>(function SidebarGroup(\n { className, ...props },\n ref,\n) {\n return (\n <div\n ref={ref}\n data-slot=\"sidebar-group\"\n data-sidebar=\"group\"\n className={cn(\"relative flex w-full min-w-0 flex-col p-2\", className)}\n {...props}\n />\n );\n});\n\nexport const SidebarGroupLabel = forwardRef<\n HTMLDivElement,\n ComponentProps<\"div\"> & { asChild?: boolean }\n>(function SidebarGroupLabel({ className, asChild = false, ...props }, ref) {\n const Comp = asChild ? Slot : \"div\";\n return (\n <Comp\n ref={ref}\n data-slot=\"sidebar-group-label\"\n data-sidebar=\"group-label\"\n className={cn(\n \"flex h-8 shrink-0 items-center rounded-md px-2 text-meta font-medium text-sidebar-muted-foreground focus-ring [--focus-ring-color:var(--sidebar-ring)] transition-[opacity] duration-base ease-linear [&>svg]:size-4 [&>svg]:shrink-0\",\n \"group-data-[collapsible=icon]:hidden\",\n className,\n )}\n {...props}\n />\n );\n});\n\nexport const SidebarGroupAction = forwardRef<\n HTMLButtonElement,\n ComponentProps<\"button\"> & { asChild?: boolean }\n>(function SidebarGroupAction({ className, asChild = false, ...props }, ref) {\n const Comp = asChild ? Slot : \"button\";\n return (\n <Comp\n ref={ref}\n data-slot=\"sidebar-group-action\"\n data-sidebar=\"group-action\"\n className={cn(\n \"absolute end-3 top-3.5 flex aspect-square w-5 items-center justify-center rounded-md p-0 text-sidebar-foreground focus-ring [--focus-ring-color:var(--sidebar-ring)] transition-transform hover:bg-sidebar-accent hover:text-sidebar-accent-foreground [&>svg]:size-4 [&>svg]:shrink-0 after:absolute after:-inset-2 md:after:hidden\",\n \"group-data-[collapsible=icon]:hidden\",\n className,\n )}\n {...props}\n />\n );\n});\n\nexport const SidebarGroupContent = forwardRef<HTMLDivElement, ComponentProps<\"div\">>(\n function SidebarGroupContent({ className, ...props }, ref) {\n return (\n <div\n ref={ref}\n data-slot=\"sidebar-group-content\"\n data-sidebar=\"group-content\"\n className={cn(\"w-full text-body\", className)}\n {...props}\n />\n );\n },\n);\n\nexport const SidebarMenu = forwardRef<HTMLUListElement, ComponentProps<\"ul\">>(function SidebarMenu(\n { className, ...props },\n ref,\n) {\n return (\n <ul\n ref={ref}\n data-slot=\"sidebar-menu\"\n data-sidebar=\"menu\"\n className={cn(\"flex w-full min-w-0 flex-col gap-1\", className)}\n {...props}\n />\n );\n});\n\nexport const SidebarMenuItem = forwardRef<HTMLLIElement, ComponentProps<\"li\">>(\n function SidebarMenuItem({ className, ...props }, ref) {\n return (\n <li\n ref={ref}\n data-slot=\"sidebar-menu-item\"\n data-sidebar=\"menu-item\"\n className={cn(\"group/menu-item relative\", className)}\n {...props}\n />\n );\n },\n);\n\nexport const sidebarMenuButtonVariants = cva(\n \"peer/menu-button relative flex w-full items-center gap-2 overflow-hidden rounded-md p-2 text-start text-body text-sidebar-foreground focus-ring [--focus-ring-color:var(--sidebar-ring)] transition-[width,height,padding] hover:bg-sidebar-accent hover:text-sidebar-accent-foreground active:bg-sidebar-accent active:text-sidebar-accent-foreground disabled:pointer-events-none disabled:opacity-50 group-has-data-[sidebar=menu-action]/menu-item:pe-8 aria-disabled:pointer-events-none aria-disabled:opacity-50 data-[active=true]:bg-sidebar-accent data-[active=true]:font-semibold data-[active=true]:text-sidebar-accent-foreground data-[active=true]:[&>svg]:text-sidebar-primary data-[active=true]:before:pointer-events-none data-[active=true]:before:absolute data-[active=true]:before:inset-y-(--sidebar-indicator-inset) data-[active=true]:before:start-0 data-[active=true]:before:w-(--sidebar-indicator-width) data-[active=true]:before:rounded-(--sidebar-indicator-radius) data-[active=true]:before:bg-sidebar-indicator data-[state=open]:hover:bg-sidebar-accent data-[state=open]:hover:text-sidebar-accent-foreground group-data-[collapsible=icon]:size-8! [&>span:last-child]:truncate [&>svg]:size-4 [&>svg]:shrink-0\",\n {\n variants: {\n variant: {\n default: \"hover:bg-sidebar-accent hover:text-sidebar-accent-foreground\",\n // A 1px outline drawn as the ring layer, not a `border` — the button sits\n // in a fixed-height menu row, so an edge that took layout space would\n // change its metrics. `shadow-hairline` reads --shadow-ring-color, so the\n // sidebar retints it (chrome has its own edge tokens) instead of\n // hand-rolling `shadow-[0_0_0_1px_…]`.\n outline:\n \"bg-background shadow-hairline [--shadow-ring-color:var(--sidebar-border)] hover:bg-sidebar-accent hover:text-sidebar-accent-foreground hover:[--shadow-ring-color:var(--sidebar-accent)]\",\n },\n size: {\n // The icon-rail padding lives PER SIZE, never as a base `p-2!` that `lg`\n // overrides: tailwind-merge keeps both `…:p-2!` and `…:p-0!`, and the\n // stylesheet order then let `p-2` win — an 8px inset inside the 32px\n // collapsed square that clipped every `lg` avatar (NavUser, TeamSwitcher).\n default: \"h-8 text-body group-data-[collapsible=icon]:p-2!\",\n sm: \"h-7 text-meta group-data-[collapsible=icon]:p-2!\",\n lg: \"h-12 text-body group-data-[collapsible=icon]:p-0!\",\n },\n },\n defaultVariants: { variant: \"default\", size: \"default\" },\n },\n);\n\nexport const SidebarMenuButton = forwardRef<\n HTMLButtonElement,\n ComponentProps<\"button\"> & {\n asChild?: boolean;\n isActive?: boolean;\n tooltip?: string | ComponentProps<typeof TooltipContent>;\n } & VariantProps<typeof sidebarMenuButtonVariants>\n>(function SidebarMenuButton(\n {\n asChild = false,\n isActive = false,\n variant = \"default\",\n size = \"default\",\n tooltip,\n className,\n ...props\n },\n ref,\n) {\n const Comp = asChild ? Slot : \"button\";\n const { isMobile, state } = useSidebar();\n\n const button = (\n <Comp\n ref={ref}\n data-slot=\"sidebar-menu-button\"\n data-sidebar=\"menu-button\"\n data-size={size}\n data-active={isActive}\n className={cn(sidebarMenuButtonVariants({ variant, size }), className)}\n {...props}\n />\n );\n\n if (!tooltip) return button;\n const tooltipProps = typeof tooltip === \"string\" ? { children: tooltip } : tooltip;\n\n return (\n <Tooltip>\n <TooltipTrigger asChild>{button}</TooltipTrigger>\n <TooltipContent\n side=\"right\"\n align=\"center\"\n hidden={state !== \"collapsed\" || isMobile}\n {...tooltipProps}\n />\n </Tooltip>\n );\n});\n\nexport const SidebarMenuAction = forwardRef<\n HTMLButtonElement,\n ComponentProps<\"button\"> & { asChild?: boolean; showOnHover?: boolean }\n>(function SidebarMenuAction({ className, asChild = false, showOnHover = false, ...props }, ref) {\n const Comp = asChild ? Slot : \"button\";\n return (\n <Comp\n ref={ref}\n data-slot=\"sidebar-menu-action\"\n data-sidebar=\"menu-action\"\n className={cn(\n \"absolute end-1 top-1.5 flex aspect-square w-5 items-center justify-center rounded-md p-0 text-sidebar-foreground focus-ring [--focus-ring-color:var(--sidebar-ring)] transition-transform hover:bg-sidebar-accent hover:text-sidebar-accent-foreground peer-hover/menu-button:text-sidebar-accent-foreground [&>svg]:size-4 [&>svg]:shrink-0 after:absolute after:-inset-2 md:after:hidden\",\n \"group-data-[collapsible=icon]:hidden\",\n showOnHover &&\n \"group-focus-within/menu-item:opacity-100 group-hover/menu-item:opacity-100 data-[state=open]:opacity-100 peer-data-[active=true]/menu-button:text-sidebar-accent-foreground md:opacity-0\",\n className,\n )}\n {...props}\n />\n );\n});\n\nexport const SidebarMenuBadge = forwardRef<HTMLDivElement, ComponentProps<\"div\">>(\n function SidebarMenuBadge({ className, ...props }, ref) {\n return (\n <div\n ref={ref}\n data-slot=\"sidebar-menu-badge\"\n data-sidebar=\"menu-badge\"\n className={cn(\n \"pointer-events-none absolute end-1 flex h-5 min-w-5 select-none items-center justify-center rounded-md px-1 text-meta font-medium tabular-nums text-sidebar-foreground\",\n \"peer-hover/menu-button:text-sidebar-accent-foreground peer-data-[active=true]/menu-button:text-sidebar-accent-foreground\",\n \"peer-data-[size=sm]/menu-button:top-1 peer-data-[size=default]/menu-button:top-1.5 peer-data-[size=lg]/menu-button:top-2.5\",\n \"group-data-[collapsible=icon]:hidden\",\n className,\n )}\n {...props}\n />\n );\n },\n);\n\nexport function SidebarMenuSkeleton({\n className,\n showIcon = false,\n ...props\n}: ComponentProps<\"div\"> & { showIcon?: boolean }) {\n const width = useMemo(() => `${Math.floor(Math.random() * 40) + 50}%`, []);\n return (\n <div\n data-slot=\"sidebar-menu-skeleton\"\n data-sidebar=\"menu-skeleton\"\n className={cn(\"flex h-8 items-center gap-2 rounded-md px-2\", className)}\n {...props}\n >\n {/* `bg-sidebar-accent`, overriding `Skeleton`'s own `bg-muted`. `--muted`\n is a CANVAS token: in the light theme it is a near-white\n `oklch(0.968 …)` sitting on this sidebar's dark `oklch(0.3 …)` ground,\n which measures 12.42:1 — the placeholder becomes the loudest thing on\n a screen that has nothing loaded yet. The sidebar's own quiet rung\n measures 1.26:1 on light and 1.29:1 on dark, i.e. a placeholder in\n both themes instead of an inversion in one. */}\n {showIcon && (\n <Skeleton\n className=\"size-4 rounded-md bg-sidebar-accent\"\n data-sidebar=\"menu-skeleton-icon\"\n />\n )}\n <Skeleton\n className=\"h-4 max-w-(--skeleton-width) flex-1 bg-sidebar-accent\"\n data-sidebar=\"menu-skeleton-text\"\n style={{ \"--skeleton-width\": width } as CSSProperties}\n />\n </div>\n );\n}\n\nexport const SidebarMenuSub = forwardRef<HTMLUListElement, ComponentProps<\"ul\">>(\n function SidebarMenuSub({ className, ...props }, ref) {\n return (\n <ul\n ref={ref}\n data-slot=\"sidebar-menu-sub\"\n data-sidebar=\"menu-sub\"\n className={cn(\n \"mx-3.5 flex min-w-0 translate-x-px flex-col gap-1 border-s border-sidebar-border px-2.5 py-0.5\",\n \"group-data-[collapsible=icon]:hidden\",\n className,\n )}\n {...props}\n />\n );\n },\n);\n\nexport const SidebarMenuSubItem = forwardRef<HTMLLIElement, ComponentProps<\"li\">>(\n function SidebarMenuSubItem({ className, ...props }, ref) {\n return (\n <li\n ref={ref}\n data-slot=\"sidebar-menu-sub-item\"\n data-sidebar=\"menu-sub-item\"\n className={cn(\"group/menu-sub-item relative\", className)}\n {...props}\n />\n );\n },\n);\n\nexport const SidebarMenuSubButton = forwardRef<\n HTMLAnchorElement,\n ComponentProps<\"a\"> & { asChild?: boolean; size?: \"sm\" | \"md\"; isActive?: boolean }\n>(function SidebarMenuSubButton(\n { asChild = false, size = \"md\", isActive = false, className, ...props },\n ref,\n) {\n const Comp = asChild ? Slot : \"a\";\n return (\n <Comp\n ref={ref}\n data-slot=\"sidebar-menu-sub-button\"\n data-sidebar=\"menu-sub-button\"\n data-size={size}\n data-active={isActive}\n className={cn(\n \"relative flex h-7 min-w-0 -translate-x-px items-center gap-2 overflow-hidden rounded-md px-2 text-sidebar-foreground focus-ring [--focus-ring-color:var(--sidebar-ring)] hover:bg-sidebar-accent hover:text-sidebar-accent-foreground active:bg-sidebar-accent active:text-sidebar-accent-foreground disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 [&>span:last-child]:truncate [&>svg]:size-4 [&>svg]:shrink-0 [&>svg]:text-sidebar-accent-foreground\",\n \"data-[active=true]:bg-sidebar-accent data-[active=true]:font-semibold data-[active=true]:text-sidebar-accent-foreground data-[active=true]:before:pointer-events-none data-[active=true]:before:absolute data-[active=true]:before:inset-y-(--sidebar-indicator-inset) data-[active=true]:before:start-0 data-[active=true]:before:w-(--sidebar-indicator-width) data-[active=true]:before:rounded-(--sidebar-indicator-radius) data-[active=true]:before:bg-sidebar-indicator\",\n size === \"sm\" && \"text-meta\",\n size === \"md\" && \"text-body\",\n \"group-data-[collapsible=icon]:hidden\",\n className,\n )}\n {...props}\n />\n );\n});\n"],"mappings":"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","names":["SidebarProvider","Sidebar","SidebarTrigger","SidebarRail","SidebarInset","SidebarInput","SidebarHeader","SidebarFooter","SidebarSeparator","SidebarContent","SidebarGroup","SidebarGroupLabel","SidebarGroupAction","SidebarGroupContent","SidebarMenu","SidebarMenuItem","SidebarMenuButton","SidebarMenuAction","SidebarMenuBadge","SidebarMenuSub","SidebarMenuSubItem","SidebarMenuSubButton"]}