poetry-ui 0.0.2

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 (442) hide show
  1. checksums.yaml +7 -0
  2. data/.gitattributes +6 -0
  3. data/CHANGELOG.md +3 -0
  4. data/LICENSE.txt +21 -0
  5. data/README.md +87 -0
  6. data/THIRD_PARTY_NOTICES.md +201 -0
  7. data/app/components/poetry/ui/accordion/component.html.erb +3 -0
  8. data/app/components/poetry/ui/accordion/component.rb +197 -0
  9. data/app/components/poetry/ui/accordion/preview.rb +39 -0
  10. data/app/components/poetry/ui/accordion/style.rb +37 -0
  11. data/app/components/poetry/ui/alert/component.html.erb +6 -0
  12. data/app/components/poetry/ui/alert/component.rb +61 -0
  13. data/app/components/poetry/ui/alert/preview.rb +35 -0
  14. data/app/components/poetry/ui/alert/style.rb +24 -0
  15. data/app/components/poetry/ui/alert_dialog/component.html.erb +17 -0
  16. data/app/components/poetry/ui/alert_dialog/component.rb +208 -0
  17. data/app/components/poetry/ui/alert_dialog/preview.rb +48 -0
  18. data/app/components/poetry/ui/alert_dialog/style.rb +46 -0
  19. data/app/components/poetry/ui/aspect_ratio/component.rb +63 -0
  20. data/app/components/poetry/ui/aspect_ratio/preview.rb +29 -0
  21. data/app/components/poetry/ui/aspect_ratio/style.rb +13 -0
  22. data/app/components/poetry/ui/attachment/component.html.erb +13 -0
  23. data/app/components/poetry/ui/attachment/component.rb +139 -0
  24. data/app/components/poetry/ui/attachment/preview.rb +83 -0
  25. data/app/components/poetry/ui/attachment/style.rb +59 -0
  26. data/app/components/poetry/ui/autocomplete/component.html.erb +16 -0
  27. data/app/components/poetry/ui/autocomplete/component.rb +193 -0
  28. data/app/components/poetry/ui/autocomplete/preview.rb +39 -0
  29. data/app/components/poetry/ui/autocomplete/style.rb +18 -0
  30. data/app/components/poetry/ui/avatar/component.rb +103 -0
  31. data/app/components/poetry/ui/avatar/group_preview.html.erb +11 -0
  32. data/app/components/poetry/ui/avatar/preview.rb +50 -0
  33. data/app/components/poetry/ui/avatar/style.rb +34 -0
  34. data/app/components/poetry/ui/badge/component.rb +73 -0
  35. data/app/components/poetry/ui/badge/preview.rb +54 -0
  36. data/app/components/poetry/ui/badge/style.rb +35 -0
  37. data/app/components/poetry/ui/breadcrumb/component.html.erb +32 -0
  38. data/app/components/poetry/ui/breadcrumb/component.rb +102 -0
  39. data/app/components/poetry/ui/breadcrumb/dropdown_crumb_preview.html.erb +21 -0
  40. data/app/components/poetry/ui/breadcrumb/preview.rb +45 -0
  41. data/app/components/poetry/ui/breadcrumb/style.rb +25 -0
  42. data/app/components/poetry/ui/bubble/component.html.erb +4 -0
  43. data/app/components/poetry/ui/bubble/component.rb +106 -0
  44. data/app/components/poetry/ui/bubble/preview.rb +62 -0
  45. data/app/components/poetry/ui/bubble/style.rb +47 -0
  46. data/app/components/poetry/ui/button/component.html.erb +14 -0
  47. data/app/components/poetry/ui/button/component.rb +168 -0
  48. data/app/components/poetry/ui/button/preview.rb +94 -0
  49. data/app/components/poetry/ui/button/style.rb +41 -0
  50. data/app/components/poetry/ui/button_group/component.rb +70 -0
  51. data/app/components/poetry/ui/button_group/popup_triggers_preview.html.erb +21 -0
  52. data/app/components/poetry/ui/button_group/preview.rb +46 -0
  53. data/app/components/poetry/ui/button_group/style.rb +27 -0
  54. data/app/components/poetry/ui/button_group/text_prefix_preview.html.erb +7 -0
  55. data/app/components/poetry/ui/calendar/component.html.erb +72 -0
  56. data/app/components/poetry/ui/calendar/component.rb +366 -0
  57. data/app/components/poetry/ui/calendar/preview.rb +55 -0
  58. data/app/components/poetry/ui/calendar/style.rb +55 -0
  59. data/app/components/poetry/ui/card/component.html.erb +11 -0
  60. data/app/components/poetry/ui/card/component.rb +90 -0
  61. data/app/components/poetry/ui/card/preview.rb +29 -0
  62. data/app/components/poetry/ui/card/style.rb +23 -0
  63. data/app/components/poetry/ui/carousel/component.html.erb +17 -0
  64. data/app/components/poetry/ui/carousel/component.rb +179 -0
  65. data/app/components/poetry/ui/carousel/preview.rb +67 -0
  66. data/app/components/poetry/ui/carousel/style.rb +39 -0
  67. data/app/components/poetry/ui/checkbox/component.html.erb +22 -0
  68. data/app/components/poetry/ui/checkbox/component.rb +179 -0
  69. data/app/components/poetry/ui/checkbox/preview.rb +68 -0
  70. data/app/components/poetry/ui/checkbox/style.rb +28 -0
  71. data/app/components/poetry/ui/clipboard_text/component.html.erb +15 -0
  72. data/app/components/poetry/ui/clipboard_text/component.rb +154 -0
  73. data/app/components/poetry/ui/clipboard_text/preview.rb +24 -0
  74. data/app/components/poetry/ui/clipboard_text/style.rb +23 -0
  75. data/app/components/poetry/ui/code_block/component.html.erb +13 -0
  76. data/app/components/poetry/ui/code_block/component.rb +141 -0
  77. data/app/components/poetry/ui/code_block/preview.rb +40 -0
  78. data/app/components/poetry/ui/code_block/style.rb +38 -0
  79. data/app/components/poetry/ui/collapsible/component.html.erb +4 -0
  80. data/app/components/poetry/ui/collapsible/component.rb +134 -0
  81. data/app/components/poetry/ui/collapsible/preview.rb +24 -0
  82. data/app/components/poetry/ui/combobox/component.html.erb +49 -0
  83. data/app/components/poetry/ui/combobox/component.rb +1086 -0
  84. data/app/components/poetry/ui/combobox/preview.rb +164 -0
  85. data/app/components/poetry/ui/combobox/style.rb +148 -0
  86. data/app/components/poetry/ui/command/component.html.erb +20 -0
  87. data/app/components/poetry/ui/command/component.rb +526 -0
  88. data/app/components/poetry/ui/command/dialog_component.html.erb +14 -0
  89. data/app/components/poetry/ui/command/dialog_component.rb +206 -0
  90. data/app/components/poetry/ui/command/dialog_preview.rb +39 -0
  91. data/app/components/poetry/ui/command/preview.rb +121 -0
  92. data/app/components/poetry/ui/command/style.rb +78 -0
  93. data/app/components/poetry/ui/composable_trigger.rb +63 -0
  94. data/app/components/poetry/ui/context_menu/component.html.erb +6 -0
  95. data/app/components/poetry/ui/context_menu/component.rb +358 -0
  96. data/app/components/poetry/ui/context_menu/preview.rb +111 -0
  97. data/app/components/poetry/ui/context_menu/style.rb +59 -0
  98. data/app/components/poetry/ui/data_table/component.html.erb +78 -0
  99. data/app/components/poetry/ui/data_table/component.rb +277 -0
  100. data/app/components/poetry/ui/data_table/preview.rb +68 -0
  101. data/app/components/poetry/ui/data_table/state.rb +115 -0
  102. data/app/components/poetry/ui/data_table/style.rb +42 -0
  103. data/app/components/poetry/ui/date_field/component.html.erb +7 -0
  104. data/app/components/poetry/ui/date_field/component.rb +209 -0
  105. data/app/components/poetry/ui/date_field/preview.rb +42 -0
  106. data/app/components/poetry/ui/date_field/style.rb +35 -0
  107. data/app/components/poetry/ui/date_picker/component.html.erb +23 -0
  108. data/app/components/poetry/ui/date_picker/component.rb +242 -0
  109. data/app/components/poetry/ui/date_picker/preview.rb +31 -0
  110. data/app/components/poetry/ui/date_picker/style.rb +25 -0
  111. data/app/components/poetry/ui/deferred/component.html.erb +16 -0
  112. data/app/components/poetry/ui/deferred/component.rb +90 -0
  113. data/app/components/poetry/ui/deferred/preview.rb +24 -0
  114. data/app/components/poetry/ui/dialog/component.html.erb +21 -0
  115. data/app/components/poetry/ui/dialog/component.rb +194 -0
  116. data/app/components/poetry/ui/dialog/preview.rb +33 -0
  117. data/app/components/poetry/ui/dialog/style.rb +30 -0
  118. data/app/components/poetry/ui/drawer/component.html.erb +16 -0
  119. data/app/components/poetry/ui/drawer/component.rb +207 -0
  120. data/app/components/poetry/ui/drawer/preview.rb +69 -0
  121. data/app/components/poetry/ui/drawer/style.rb +105 -0
  122. data/app/components/poetry/ui/dropdown_menu/component.html.erb +6 -0
  123. data/app/components/poetry/ui/dropdown_menu/component.rb +350 -0
  124. data/app/components/poetry/ui/dropdown_menu/preview.rb +101 -0
  125. data/app/components/poetry/ui/dropdown_menu/style.rb +60 -0
  126. data/app/components/poetry/ui/empty/component.html.erb +10 -0
  127. data/app/components/poetry/ui/empty/component.rb +79 -0
  128. data/app/components/poetry/ui/empty/preview.rb +27 -0
  129. data/app/components/poetry/ui/empty/style.rb +27 -0
  130. data/app/components/poetry/ui/family_identity.rb +52 -0
  131. data/app/components/poetry/ui/field/component.html.erb +19 -0
  132. data/app/components/poetry/ui/field/component.rb +183 -0
  133. data/app/components/poetry/ui/field/preview.html.erb +30 -0
  134. data/app/components/poetry/ui/field/preview.rb +72 -0
  135. data/app/components/poetry/ui/field/style.rb +68 -0
  136. data/app/components/poetry/ui/field_group/component.rb +61 -0
  137. data/app/components/poetry/ui/field_group/preview.html.erb +30 -0
  138. data/app/components/poetry/ui/field_group/preview.rb +20 -0
  139. data/app/components/poetry/ui/field_group/style.rb +25 -0
  140. data/app/components/poetry/ui/field_separator/component.rb +70 -0
  141. data/app/components/poetry/ui/field_separator/preview.rb +18 -0
  142. data/app/components/poetry/ui/field_separator/style.rb +20 -0
  143. data/app/components/poetry/ui/fieldset/component.rb +90 -0
  144. data/app/components/poetry/ui/fieldset/preview.html.erb +22 -0
  145. data/app/components/poetry/ui/fieldset/preview.rb +25 -0
  146. data/app/components/poetry/ui/fieldset/style.rb +18 -0
  147. data/app/components/poetry/ui/file_input/component.html.erb +14 -0
  148. data/app/components/poetry/ui/file_input/component.rb +188 -0
  149. data/app/components/poetry/ui/file_input/preview.rb +30 -0
  150. data/app/components/poetry/ui/file_input/style.rb +35 -0
  151. data/app/components/poetry/ui/hover_card/component.html.erb +6 -0
  152. data/app/components/poetry/ui/hover_card/component.rb +201 -0
  153. data/app/components/poetry/ui/hover_card/preview.rb +60 -0
  154. data/app/components/poetry/ui/hover_card/style.rb +17 -0
  155. data/app/components/poetry/ui/icon/component.rb +127 -0
  156. data/app/components/poetry/ui/icon/preview.rb +21 -0
  157. data/app/components/poetry/ui/input/component.rb +80 -0
  158. data/app/components/poetry/ui/input/preview.rb +35 -0
  159. data/app/components/poetry/ui/input/style.rb +18 -0
  160. data/app/components/poetry/ui/input_group/button_preview.html.erb +12 -0
  161. data/app/components/poetry/ui/input_group/component.rb +69 -0
  162. data/app/components/poetry/ui/input_group/preview.rb +23 -0
  163. data/app/components/poetry/ui/input_group/search_preview.html.erb +13 -0
  164. data/app/components/poetry/ui/input_group/style.rb +40 -0
  165. data/app/components/poetry/ui/input_group/textarea_preview.html.erb +10 -0
  166. data/app/components/poetry/ui/input_group_field.rb +61 -0
  167. data/app/components/poetry/ui/input_otp/component.html.erb +25 -0
  168. data/app/components/poetry/ui/input_otp/component.rb +250 -0
  169. data/app/components/poetry/ui/input_otp/preview.rb +91 -0
  170. data/app/components/poetry/ui/input_otp/style.rb +36 -0
  171. data/app/components/poetry/ui/item/component.html.erb +13 -0
  172. data/app/components/poetry/ui/item/component.rb +99 -0
  173. data/app/components/poetry/ui/item/group_preview.html.erb +15 -0
  174. data/app/components/poetry/ui/item/preview.rb +52 -0
  175. data/app/components/poetry/ui/item/style.rb +45 -0
  176. data/app/components/poetry/ui/kbd/component.rb +47 -0
  177. data/app/components/poetry/ui/kbd/group_preview.html.erb +4 -0
  178. data/app/components/poetry/ui/kbd/preview.rb +23 -0
  179. data/app/components/poetry/ui/kbd/style.rb +13 -0
  180. data/app/components/poetry/ui/label/component.rb +46 -0
  181. data/app/components/poetry/ui/label/preview.html.erb +5 -0
  182. data/app/components/poetry/ui/label/preview.rb +16 -0
  183. data/app/components/poetry/ui/label/style.rb +13 -0
  184. data/app/components/poetry/ui/link/component.rb +62 -0
  185. data/app/components/poetry/ui/link/preview.rb +31 -0
  186. data/app/components/poetry/ui/link/style.rb +20 -0
  187. data/app/components/poetry/ui/marker/component.html.erb +4 -0
  188. data/app/components/poetry/ui/marker/component.rb +81 -0
  189. data/app/components/poetry/ui/marker/preview.rb +43 -0
  190. data/app/components/poetry/ui/marker/style.rb +24 -0
  191. data/app/components/poetry/ui/menubar/component.html.erb +3 -0
  192. data/app/components/poetry/ui/menubar/component.rb +493 -0
  193. data/app/components/poetry/ui/menubar/preview.rb +164 -0
  194. data/app/components/poetry/ui/menubar/style.rb +71 -0
  195. data/app/components/poetry/ui/menus.rb +386 -0
  196. data/app/components/poetry/ui/message/component.html.erb +8 -0
  197. data/app/components/poetry/ui/message/component.rb +64 -0
  198. data/app/components/poetry/ui/message/preview.rb +33 -0
  199. data/app/components/poetry/ui/message/style.rb +29 -0
  200. data/app/components/poetry/ui/message_scroller/component.html.erb +15 -0
  201. data/app/components/poetry/ui/message_scroller/component.rb +163 -0
  202. data/app/components/poetry/ui/message_scroller/preview.rb +33 -0
  203. data/app/components/poetry/ui/message_scroller/style.rb +39 -0
  204. data/app/components/poetry/ui/metadata_list/component.rb +88 -0
  205. data/app/components/poetry/ui/metadata_list/preview.rb +55 -0
  206. data/app/components/poetry/ui/metadata_list/style.rb +35 -0
  207. data/app/components/poetry/ui/meter/component.rb +117 -0
  208. data/app/components/poetry/ui/meter/preview.rb +28 -0
  209. data/app/components/poetry/ui/meter/style.rb +16 -0
  210. data/app/components/poetry/ui/native_select/component.rb +124 -0
  211. data/app/components/poetry/ui/native_select/labelled_preview.html.erb +7 -0
  212. data/app/components/poetry/ui/native_select/preview.rb +20 -0
  213. data/app/components/poetry/ui/native_select/style.rb +22 -0
  214. data/app/components/poetry/ui/navigation_menu/bar_preview.html.erb +14 -0
  215. data/app/components/poetry/ui/navigation_menu/component.html.erb +25 -0
  216. data/app/components/poetry/ui/navigation_menu/component.rb +254 -0
  217. data/app/components/poetry/ui/navigation_menu/preview.rb +20 -0
  218. data/app/components/poetry/ui/navigation_menu/style.rb +73 -0
  219. data/app/components/poetry/ui/navigation_menu/viewport_preview.html.erb +23 -0
  220. data/app/components/poetry/ui/number_field/component.html.erb +19 -0
  221. data/app/components/poetry/ui/number_field/component.rb +263 -0
  222. data/app/components/poetry/ui/number_field/preview.rb +66 -0
  223. data/app/components/poetry/ui/number_field/style.rb +14 -0
  224. data/app/components/poetry/ui/pagination/component.html.erb +40 -0
  225. data/app/components/poetry/ui/pagination/component.rb +182 -0
  226. data/app/components/poetry/ui/pagination/preview.rb +47 -0
  227. data/app/components/poetry/ui/pagination/style.rb +27 -0
  228. data/app/components/poetry/ui/popover/component.html.erb +17 -0
  229. data/app/components/poetry/ui/popover/component.rb +203 -0
  230. data/app/components/poetry/ui/popover/preview.html.erb +29 -0
  231. data/app/components/poetry/ui/popover/preview.rb +66 -0
  232. data/app/components/poetry/ui/popover/style.rb +26 -0
  233. data/app/components/poetry/ui/popper_consumer.rb +69 -0
  234. data/app/components/poetry/ui/progress/component.rb +95 -0
  235. data/app/components/poetry/ui/progress/preview.rb +22 -0
  236. data/app/components/poetry/ui/progress/style.rb +19 -0
  237. data/app/components/poetry/ui/questionnaire/component.html.erb +80 -0
  238. data/app/components/poetry/ui/questionnaire/component.rb +396 -0
  239. data/app/components/poetry/ui/questionnaire/preview.rb +99 -0
  240. data/app/components/poetry/ui/questionnaire/style.rb +53 -0
  241. data/app/components/poetry/ui/radio_group/component.html.erb +4 -0
  242. data/app/components/poetry/ui/radio_group/component.rb +323 -0
  243. data/app/components/poetry/ui/radio_group/preview.rb +109 -0
  244. data/app/components/poetry/ui/radio_group/style.rb +53 -0
  245. data/app/components/poetry/ui/resizable/component.html.erb +10 -0
  246. data/app/components/poetry/ui/resizable/component.rb +178 -0
  247. data/app/components/poetry/ui/resizable/preview.rb +42 -0
  248. data/app/components/poetry/ui/resizable/style.rb +30 -0
  249. data/app/components/poetry/ui/scroll_area/component.rb +76 -0
  250. data/app/components/poetry/ui/scroll_area/preview.rb +35 -0
  251. data/app/components/poetry/ui/scroll_area/style.rb +19 -0
  252. data/app/components/poetry/ui/search_field/component.html.erb +15 -0
  253. data/app/components/poetry/ui/search_field/component.rb +137 -0
  254. data/app/components/poetry/ui/search_field/preview.rb +23 -0
  255. data/app/components/poetry/ui/search_field/style.rb +18 -0
  256. data/app/components/poetry/ui/select/component.html.erb +15 -0
  257. data/app/components/poetry/ui/select/component.rb +639 -0
  258. data/app/components/poetry/ui/select/preview.rb +113 -0
  259. data/app/components/poetry/ui/select/style.rb +58 -0
  260. data/app/components/poetry/ui/sensitive_input/component.html.erb +29 -0
  261. data/app/components/poetry/ui/sensitive_input/component.rb +274 -0
  262. data/app/components/poetry/ui/sensitive_input/preview.rb +40 -0
  263. data/app/components/poetry/ui/sensitive_input/style.rb +49 -0
  264. data/app/components/poetry/ui/separator/component.rb +57 -0
  265. data/app/components/poetry/ui/separator/preview.rb +19 -0
  266. data/app/components/poetry/ui/separator/style.rb +15 -0
  267. data/app/components/poetry/ui/sheet/component.html.erb +21 -0
  268. data/app/components/poetry/ui/sheet/component.rb +97 -0
  269. data/app/components/poetry/ui/sheet/preview.rb +57 -0
  270. data/app/components/poetry/ui/sheet/style.rb +47 -0
  271. data/app/components/poetry/ui/sidebar/component.html.erb +20 -0
  272. data/app/components/poetry/ui/sidebar/component.rb +249 -0
  273. data/app/components/poetry/ui/sidebar/preview.rb +21 -0
  274. data/app/components/poetry/ui/sidebar/shell_preview.html.erb +47 -0
  275. data/app/components/poetry/ui/sidebar/style.rb +139 -0
  276. data/app/components/poetry/ui/skeleton/component.rb +39 -0
  277. data/app/components/poetry/ui/skeleton/preview.rb +22 -0
  278. data/app/components/poetry/ui/skeleton/style.rb +13 -0
  279. data/app/components/poetry/ui/slider/component.html.erb +13 -0
  280. data/app/components/poetry/ui/slider/component.rb +360 -0
  281. data/app/components/poetry/ui/slider/preview.rb +73 -0
  282. data/app/components/poetry/ui/slider/style.rb +55 -0
  283. data/app/components/poetry/ui/spinner/component.rb +58 -0
  284. data/app/components/poetry/ui/spinner/preview.rb +22 -0
  285. data/app/components/poetry/ui/spinner/style.rb +12 -0
  286. data/app/components/poetry/ui/stat/component.html.erb +13 -0
  287. data/app/components/poetry/ui/stat/component.rb +102 -0
  288. data/app/components/poetry/ui/stat/preview.rb +47 -0
  289. data/app/components/poetry/ui/stat/style.rb +29 -0
  290. data/app/components/poetry/ui/switch/component.html.erb +15 -0
  291. data/app/components/poetry/ui/switch/component.rb +136 -0
  292. data/app/components/poetry/ui/switch/preview.rb +66 -0
  293. data/app/components/poetry/ui/switch/style.rb +22 -0
  294. data/app/components/poetry/ui/table/component.html.erb +3 -0
  295. data/app/components/poetry/ui/table/component.rb +93 -0
  296. data/app/components/poetry/ui/table/preview.rb +96 -0
  297. data/app/components/poetry/ui/table/style.rb +26 -0
  298. data/app/components/poetry/ui/tabs/component.html.erb +10 -0
  299. data/app/components/poetry/ui/tabs/component.rb +253 -0
  300. data/app/components/poetry/ui/tabs/preview.rb +43 -0
  301. data/app/components/poetry/ui/tabs/style.rb +49 -0
  302. data/app/components/poetry/ui/tag_group/component.html.erb +8 -0
  303. data/app/components/poetry/ui/tag_group/component.rb +203 -0
  304. data/app/components/poetry/ui/tag_group/preview.rb +43 -0
  305. data/app/components/poetry/ui/tag_group/style.rb +29 -0
  306. data/app/components/poetry/ui/textarea/component.rb +64 -0
  307. data/app/components/poetry/ui/textarea/preview.rb +75 -0
  308. data/app/components/poetry/ui/textarea/style.rb +18 -0
  309. data/app/components/poetry/ui/time_field/component.html.erb +6 -0
  310. data/app/components/poetry/ui/time_field/component.rb +85 -0
  311. data/app/components/poetry/ui/time_field/preview.rb +40 -0
  312. data/app/components/poetry/ui/time_field/style.rb +30 -0
  313. data/app/components/poetry/ui/timeline/component.rb +134 -0
  314. data/app/components/poetry/ui/timeline/preview.rb +61 -0
  315. data/app/components/poetry/ui/timeline/style.rb +54 -0
  316. data/app/components/poetry/ui/toast/component.html.erb +24 -0
  317. data/app/components/poetry/ui/toast/component.rb +178 -0
  318. data/app/components/poetry/ui/toast/preview.rb +69 -0
  319. data/app/components/poetry/ui/toast/style.rb +33 -0
  320. data/app/components/poetry/ui/toast_trigger/addressed_preview.html.erb +12 -0
  321. data/app/components/poetry/ui/toast_trigger/component.html.erb +3 -0
  322. data/app/components/poetry/ui/toast_trigger/component.rb +82 -0
  323. data/app/components/poetry/ui/toast_trigger/default_preview.html.erb +11 -0
  324. data/app/components/poetry/ui/toast_trigger/preview.rb +19 -0
  325. data/app/components/poetry/ui/toaster/component.html.erb +1 -0
  326. data/app/components/poetry/ui/toaster/component.rb +99 -0
  327. data/app/components/poetry/ui/toaster/positions_preview.html.erb +24 -0
  328. data/app/components/poetry/ui/toaster/preview.rb +46 -0
  329. data/app/components/poetry/ui/toaster/stamp_preview.html.erb +15 -0
  330. data/app/components/poetry/ui/toaster/style.rb +26 -0
  331. data/app/components/poetry/ui/toggle/component.rb +120 -0
  332. data/app/components/poetry/ui/toggle/preview.rb +79 -0
  333. data/app/components/poetry/ui/toggle/style.rb +33 -0
  334. data/app/components/poetry/ui/toggle_group/component.html.erb +4 -0
  335. data/app/components/poetry/ui/toggle_group/component.rb +252 -0
  336. data/app/components/poetry/ui/toggle_group/preview.rb +143 -0
  337. data/app/components/poetry/ui/toggle_group/style.rb +33 -0
  338. data/app/components/poetry/ui/toolbar/component.rb +125 -0
  339. data/app/components/poetry/ui/toolbar/preview.rb +41 -0
  340. data/app/components/poetry/ui/toolbar/style.rb +20 -0
  341. data/app/components/poetry/ui/tooltip/component.html.erb +20 -0
  342. data/app/components/poetry/ui/tooltip/component.rb +185 -0
  343. data/app/components/poetry/ui/tooltip/preview.rb +74 -0
  344. data/app/components/poetry/ui/tooltip/previews/provider_row.html.erb +25 -0
  345. data/app/components/poetry/ui/tooltip/style.rb +24 -0
  346. data/app/components/poetry/ui/tree/component.html.erb +32 -0
  347. data/app/components/poetry/ui/tree/component.rb +233 -0
  348. data/app/components/poetry/ui/tree/preview.rb +55 -0
  349. data/app/components/poetry/ui/tree/style.rb +29 -0
  350. data/app/components/poetry/ui/typeset/component.rb +73 -0
  351. data/app/components/poetry/ui/typeset/preview.rb +45 -0
  352. data/app/components/poetry/ui/typeset/style.rb +15 -0
  353. data/app/controllers/poetry/ui/llms_controller.rb +28 -0
  354. data/app/helpers/poetry/ui/components_helper.rb +1794 -0
  355. data/app/helpers/poetry/ui/form_builder/type_inference.rb +117 -0
  356. data/app/helpers/poetry/ui/form_builder.rb +916 -0
  357. data/app/helpers/poetry/ui/optimistic_form_builder.rb +55 -0
  358. data/app/helpers/poetry/ui/toast_stream_actions.rb +27 -0
  359. data/config/component_descriptions.yml +96 -0
  360. data/config/component_registry.yml +12257 -0
  361. data/config/locales/en.yml +93 -0
  362. data/config/routes.rb +8 -0
  363. data/config/template_classes.txt +113 -0
  364. data/lib/generators/poetry/add/add_generator.rb +218 -0
  365. data/lib/generators/poetry/agent_rules/agent_rules_generator.rb +91 -0
  366. data/lib/generators/poetry/agents/agents_generator.rb +24 -0
  367. data/lib/generators/poetry/agents_section.rb +148 -0
  368. data/lib/generators/poetry/block/block_generator.rb +67 -0
  369. data/lib/generators/poetry/block/templates/action_bar.html.erb +45 -0
  370. data/lib/generators/poetry/block/templates/app_shell.html.erb +139 -0
  371. data/lib/generators/poetry/block/templates/data_index.html.erb +85 -0
  372. data/lib/generators/poetry/block/templates/destructive_panel.html.erb +26 -0
  373. data/lib/generators/poetry/block/templates/page_header.html.erb +25 -0
  374. data/lib/generators/poetry/block/templates/section_card.html.erb +42 -0
  375. data/lib/generators/poetry/block/templates/stepper.html.erb +79 -0
  376. data/lib/generators/poetry/block/templates/top_nav.html.erb +44 -0
  377. data/lib/generators/poetry/diff/diff_generator.rb +135 -0
  378. data/lib/generators/poetry/editor/editor_generator.rb +344 -0
  379. data/lib/generators/poetry/editor/templates/poetry-check-hook +81 -0
  380. data/lib/generators/poetry/install/install_generator.rb +364 -0
  381. data/lib/generators/poetry/pagination/pagination_generator.rb +76 -0
  382. data/lib/generators/poetry/pagination/templates/kaminari_paginator.html.erb +29 -0
  383. data/lib/generators/poetry/pagination/templates/poetry_link_renderer.rb +34 -0
  384. data/lib/generators/poetry/pagination/templates/poetry_pagy_helper.rb +28 -0
  385. data/lib/generators/poetry/recipes/agent_embed/app/javascript/controllers/agent_demo_controller.js +131 -0
  386. data/lib/generators/poetry/recipes/screen_data_index/app/controllers/orders_controller.rb +15 -0
  387. data/lib/generators/poetry/recipes/screen_data_index/app/views/orders/index.html.erb +7 -0
  388. data/lib/generators/poetry/recipes/screen_data_index/test/system/orders_index_test.rb +16 -0
  389. data/lib/generators/poetry/recipes/screen_settings/app/controllers/settings_controller.rb +14 -0
  390. data/lib/generators/poetry/recipes/screen_settings/app/views/settings/show.html.erb +9 -0
  391. data/lib/generators/poetry/recipes/screen_settings/test/system/settings_show_test.rb +16 -0
  392. data/lib/generators/poetry/scaffold_templates/scaffold_templates_generator.rb +60 -0
  393. data/lib/generators/poetry/scaffold_templates/templates/_form.html.erb.tt +77 -0
  394. data/lib/generators/poetry/scaffold_templates/templates/controller.rb.tt +78 -0
  395. data/lib/generators/poetry/scaffold_templates/templates/edit.html.erb.tt +14 -0
  396. data/lib/generators/poetry/scaffold_templates/templates/index.html.erb.tt +24 -0
  397. data/lib/generators/poetry/scaffold_templates/templates/new.html.erb.tt +11 -0
  398. data/lib/generators/poetry/scaffold_templates/templates/partial.html.erb.tt +13 -0
  399. data/lib/generators/poetry/scaffold_templates/templates/show.html.erb.tt +18 -0
  400. data/lib/generators/poetry/skill/skill_generator.rb +34 -0
  401. data/lib/generators/poetry/skill/templates/poetry-component/SKILL.md +58 -0
  402. data/lib/generators/poetry/skill/templates/poetry-component/references/anatomy.md +152 -0
  403. data/lib/generators/poetry/skill/templates/poetry-component/references/checklist.md +67 -0
  404. data/lib/generators/poetry/skill/templates/poetry-component/references/documentation.md +137 -0
  405. data/lib/generators/poetry/skill/templates/poetry-design/SKILL.md +56 -0
  406. data/lib/generators/poetry/skill/templates/poetry-design/references/audit.md +123 -0
  407. data/lib/generators/poetry/skill/templates/poetry-design/references/compose.md +73 -0
  408. data/lib/generators/poetry/skill/templates/poetry-design/references/figma.md +68 -0
  409. data/lib/generators/poetry/skill/templates/poetry-design/references/paper.md +56 -0
  410. data/lib/generators/poetry/skill/templates/poetry-design/references/study.md +47 -0
  411. data/lib/generators/poetry/skill/templates/poetry-design/references/theme.md +70 -0
  412. data/lib/generators/poetry/skills_section.rb +58 -0
  413. data/lib/poetry/ui/chat.rb +283 -0
  414. data/lib/poetry/ui/code_block_highlighter.rb +60 -0
  415. data/lib/poetry/ui/engine.rb +55 -0
  416. data/lib/poetry/ui/recipes.rb +157 -0
  417. data/lib/poetry/ui/testing/combobox.rb +167 -0
  418. data/lib/poetry/ui/testing/dialog.rb +73 -0
  419. data/lib/poetry/ui/testing/menu.rb +127 -0
  420. data/lib/poetry/ui/testing/registration.rb +58 -0
  421. data/lib/poetry/ui/testing/select.rb +147 -0
  422. data/lib/poetry/ui/testing/tester.rb +130 -0
  423. data/lib/poetry/ui/testing.rb +130 -0
  424. data/lib/poetry/ui/themes.rb +109 -0
  425. data/lib/poetry/ui/version.rb +8 -0
  426. data/lib/poetry/ui/webmcp.rb +91 -0
  427. data/lib/poetry/ui.rb +285 -0
  428. data/lib/poetry-ui.rb +5 -0
  429. data/lib/tasks/poetry/check.rake +73 -0
  430. data/lib/tasks/poetry/design.rake +293 -0
  431. data/lib/tasks/poetry/verify.rake +36 -0
  432. data/themes/default.css +1793 -0
  433. data/themes/luma.css +1764 -0
  434. data/themes/lyra.css +1768 -0
  435. data/themes/maia.css +1768 -0
  436. data/themes/mira.css +1760 -0
  437. data/themes/nova.css +1755 -0
  438. data/themes/rhea.css +1771 -0
  439. data/themes/sera.css +1757 -0
  440. data/themes/vega.css +1775 -0
  441. data/typeset/typeset.css +499 -0
  442. metadata +502 -0
data/themes/lyra.css ADDED
@@ -0,0 +1,1768 @@
1
+ /* poetry lyra theme - upstream style-lyra.css ported onto the
2
+ * cn-* layer (pinned clone 1773ecfe, the shadcn@4.19.0 release). Same contract as default.css:
3
+ * imported layer(base); bare selectors while installs carry ONE theme;
4
+ * rule order per component = base < elements < variants < compounds;
5
+ * split-side, no-empty-rules and cross-component-last rules apply.
6
+ *
7
+ * Port disciplines identical to vega/rhea (see
8
+ * docs/lyra-port-ledger.txt): verbatim where poetry
9
+ * speaks the vocabulary; data-vertical -> data-[orientation=*];
10
+ * data-[state=on] -> data-pressed; overlays -> native-dialog
11
+ * backdrop:* (black/10 blur-xs - the faintest scrim of the series);
12
+ * upstream ! stripped except the sidebar collapse geometry and
13
+ * default-inherited precedents; icon paddings ship upstream's
14
+ * has-data-[icon=*] (inert) plus working >svg:first/last-child twins;
15
+ * soft destructive holds AA via relative-oklch light-mode darkening
16
+ * (AA-contrast posture). Lyra-specific: rounded-none universal with the
17
+ * whole type scale one step down (text-xs bodies), ring-1 focus
18
+ * temperature, muted-based hovers, right-side menu indicators, filled
19
+ * radios (dot flips to fill-primary-foreground), press-nudge buttons,
20
+ * --card-spacing var cards on ring-foreground/10, flat ring-only
21
+ * dialogs (sheets keep upstream shadow-lg), button-group caps squared
22
+ * over poetry's collapse
23
+ * machinery, and NO AA kit beyond the destructive pair: lyra's tints
24
+ * are disabled fills (WCAG-exempt) and /30 dropdown search boxes (the
25
+ * maia class). Fonts move via size/weight/tracking utilities only -
26
+ * the mono-family pairing is upstream create-flow metadata, told in
27
+ * docs, not CSS. Upstream parse quirk ledgered: style-lyra.css:1358
28
+ * lacks a semicolon (cn-menu-translucent), so cn-bubble ships as an
29
+ * explicit transcribed value.
30
+ */
31
+
32
+ /* MARK: Alert */
33
+ .cn-alert {
34
+ @apply grid grid-cols-[0_1fr] items-start gap-y-0.5 rounded-none border px-2.5 py-2 text-left text-xs has-data-[slot=alert-action]:relative has-data-[slot=alert-action]:pr-18 has-[>svg]:grid-cols-[auto_1fr] has-[>svg]:gap-x-2 [&>svg]:size-4 [&>svg]:translate-y-0 [&>svg]:text-current;
35
+ }
36
+
37
+ .cn-alert-action {
38
+ @apply absolute top-[calc(--spacing(1.25))] right-[calc(--spacing(1.25))];
39
+ }
40
+
41
+ .cn-alert-title {
42
+ @apply col-start-2 font-medium;
43
+ }
44
+
45
+ .cn-alert-description {
46
+ @apply col-start-2 text-xs/relaxed text-muted-foreground text-balance md:text-pretty [&_p:not(:last-child)]:mb-2;
47
+ }
48
+
49
+ .cn-alert-variant-default {
50
+ @apply bg-card text-card-foreground;
51
+ }
52
+
53
+ .cn-alert-variant-destructive {
54
+ @apply text-destructive bg-card *:data-[slot=alert-description]:text-destructive/90 *:[svg]:text-current;
55
+ }
56
+
57
+ /* MARK: Accordion */
58
+ /* Root hook: boxed-root themes (mira/rhea, later luma/maia)
59
+ * style this; every fragment must give the name content (the compile
60
+ * gate), so default carries the upstream demo idiom. */
61
+ .cn-accordion {
62
+ @apply w-full;
63
+ }
64
+
65
+ .cn-accordion-item {
66
+ @apply not-last:border-b;
67
+ }
68
+
69
+ .cn-accordion-trigger {
70
+ @apply focus-visible:ring-ring/50 focus-visible:border-ring focus-visible:after:border-ring rounded-none py-2.5 text-left text-xs font-medium hover:underline focus-visible:ring-1;
71
+ }
72
+
73
+ .cn-accordion-trigger-icon {
74
+ @apply ml-auto size-4 text-muted-foreground;
75
+ }
76
+
77
+ .cn-accordion-content {
78
+ @apply data-open:animate-accordion-down data-closed:animate-accordion-up text-xs;
79
+ }
80
+
81
+ .cn-accordion-content-inner {
82
+ @apply pt-0 pb-2.5;
83
+ }
84
+
85
+ /* MARK: AlertDialog */
86
+ .cn-alert-dialog-content {
87
+ @apply w-full max-w-[calc(100%-2rem)] bg-popover text-popover-foreground ring-foreground/10 gap-4 rounded-none p-4 ring-1 duration-100 data-[size=default]:max-w-xs data-[size=sm]:max-w-xs data-[size=default]:sm:max-w-sm backdrop:bg-black/10 supports-backdrop-filter:backdrop:backdrop-blur-xs data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95;
88
+ }
89
+
90
+ .cn-alert-dialog-header {
91
+ @apply gap-1.5 has-data-[slot=alert-dialog-media]:gap-x-4;
92
+ }
93
+
94
+ .cn-alert-dialog-media {
95
+ @apply mb-2 size-16 rounded-none bg-muted *:[svg:not([class*='size-'])]:size-8;
96
+ }
97
+
98
+ .cn-alert-dialog-title {
99
+ @apply text-sm font-medium;
100
+ }
101
+
102
+ .cn-alert-dialog-description {
103
+ @apply text-muted-foreground *:[a]:hover:text-foreground text-xs/relaxed text-balance md:text-pretty *:[a]:underline *:[a]:underline-offset-3;
104
+ }
105
+
106
+ /* Footer hook: nova bands it; gap-2 moved here from the inline
107
+ * set with the name (direction/justify stay inline - the sm-size grid
108
+ * branch replaces them consumer-side). */
109
+ .cn-alert-dialog-footer {
110
+ @apply gap-2;
111
+ }
112
+
113
+ /* MARK: Attachment */
114
+ /* w-fit lives here so the vertical orientation's w-24 beats it in-layer
115
+ * (split-side rule). */
116
+ .cn-attachment {
117
+ @apply rounded-none w-fit focus-within:ring-1 focus-within:ring-ring/50;
118
+ }
119
+
120
+ .cn-attachment-actions {
121
+ @apply group-data-[orientation=vertical]/attachment:absolute group-data-[orientation=vertical]/attachment:top-3 group-data-[orientation=vertical]/attachment:right-3 relative z-20 group-data-[orientation=vertical]/attachment:gap-1;
122
+ }
123
+
124
+ .cn-attachment-trigger {
125
+ @apply absolute inset-0 z-10 outline-none;
126
+ }
127
+
128
+ .cn-attachment-media-variant-image {
129
+ @apply opacity-60 group-data-[state=idle]/attachment:opacity-100 group-data-[state=done]/attachment:opacity-100;
130
+ }
131
+
132
+ .cn-attachment-size-default {
133
+ @apply gap-2 has-data-[slot=attachment-content]:px-2 has-data-[slot=attachment-content]:py-1.5 has-data-[slot=attachment-media]:p-1.5 text-xs;
134
+ }
135
+
136
+ .cn-attachment-size-sm {
137
+ @apply gap-2.5 has-data-[slot=attachment-content]:px-1.5 has-data-[slot=attachment-content]:py-1 has-data-[slot=attachment-media]:p-1 text-xs;
138
+ }
139
+
140
+ .cn-attachment-size-xs {
141
+ @apply gap-1.5 has-data-[slot=attachment-content]:px-1.5 has-data-[slot=attachment-content]:py-1 has-data-[slot=attachment-media]:p-1 text-xs rounded-none;
142
+ }
143
+
144
+ .cn-attachment-orientation-horizontal {
145
+ @apply min-w-40;
146
+ }
147
+
148
+ .cn-attachment-orientation-vertical {
149
+ @apply w-24 has-data-[slot=attachment-content]:w-30;
150
+ }
151
+
152
+ .cn-attachment-media {
153
+ @apply bg-muted text-foreground w-10 rounded-none group-data-[size=sm]/attachment:w-8 group-data-[size=xs]/attachment:w-7 group-data-[size=xs]/attachment:rounded-none [&_svg:not([class*='size-'])]:size-4 group-data-[size=xs]/attachment:[&_svg:not([class*='size-'])]:size-3.5 group-data-[orientation=vertical]/attachment:w-full group-data-[orientation=vertical]/attachment:[&_svg:not([class*='size-'])]:size-6 group-data-[orientation=vertical]/attachment:*:data-[slot=spinner]:size-6;
154
+ }
155
+
156
+ .cn-attachment-content {
157
+ @apply leading-tight group-data-[orientation=vertical]/attachment:px-1;
158
+ }
159
+
160
+ .cn-attachment-title {
161
+ @apply font-medium;
162
+ }
163
+
164
+ .cn-attachment-description {
165
+ @apply mt-0.5 text-xs;
166
+ }
167
+
168
+ .cn-attachment-group {
169
+ @apply gap-3 py-1 scroll-px-1;
170
+ }
171
+
172
+ /* MARK: Avatar */
173
+ .cn-avatar {
174
+ @apply size-8 rounded-full after:rounded-full data-[size=lg]:size-10 data-[size=sm]:size-6;
175
+ }
176
+
177
+ .cn-avatar-image {
178
+ @apply rounded-full;
179
+ }
180
+
181
+ .cn-avatar-fallback {
182
+ @apply rounded-full bg-muted text-muted-foreground;
183
+ }
184
+
185
+ .cn-avatar-badge {
186
+ @apply bg-primary text-primary-foreground ring-background group-data-[size=sm]/avatar:size-2 group-data-[size=sm]/avatar:[&>svg]:hidden group-data-[size=default]/avatar:size-2.5 group-data-[size=default]/avatar:[&>svg]:size-2 group-data-[size=lg]/avatar:size-3 group-data-[size=lg]/avatar:[&>svg]:size-2;
187
+ }
188
+
189
+ .cn-avatar-group-count {
190
+ @apply bg-muted text-muted-foreground size-8 rounded-full text-xs group-has-data-[size=lg]/avatar-group:size-10 group-has-data-[size=sm]/avatar-group:size-6 [&>svg]:size-4 group-has-data-[size=lg]/avatar-group:[&>svg]:size-5 group-has-data-[size=sm]/avatar-group:[&>svg]:size-3;
191
+ }
192
+
193
+ /* MARK: Badge */
194
+ /* The focus/invalid ring chain lives HERE (upstream keeps it inline): the
195
+ * destructive variant re-colors focus-visible:ring-* and can only beat
196
+ * the base treatment from the same layer. */
197
+ .cn-badge {
198
+ @apply h-5 gap-1 rounded-none border border-transparent px-2 py-0.5 text-xs font-medium transition-all has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 has-[>svg:first-child]:pl-1.5 has-[>svg:last-child]:pr-1.5 [&>svg]:size-3 focus-visible:border-ring focus-visible:ring-1 focus-visible:ring-ring/50 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 aria-invalid:ring-1 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40;
199
+ }
200
+
201
+ .cn-badge-variant-ghost {
202
+ @apply hover:bg-muted hover:text-muted-foreground dark:hover:bg-muted/50;
203
+ }
204
+
205
+ .cn-badge-variant-link {
206
+ @apply text-primary underline-offset-4 hover:underline;
207
+ }
208
+
209
+ .cn-badge-variant-default {
210
+ @apply bg-primary text-primary-foreground [a]:hover:bg-primary/80;
211
+ }
212
+
213
+ .cn-badge-variant-secondary {
214
+ @apply bg-secondary text-secondary-foreground [a]:hover:bg-secondary/80;
215
+ }
216
+
217
+ .cn-badge-variant-destructive {
218
+ @apply bg-destructive/10 [a]:hover:bg-destructive/20 text-[oklch(from_var(--destructive)_calc(l*0.85)_c_h)] dark:text-destructive dark:bg-destructive/20 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40;
219
+ }
220
+
221
+ .cn-badge-variant-outline {
222
+ @apply border-border text-foreground [a]:hover:bg-muted [a]:hover:text-muted-foreground;
223
+ }
224
+
225
+ .cn-badge-variant-success {
226
+ @apply bg-success/10 [a]:hover:bg-success/20 text-[oklch(from_var(--success)_calc(l*0.85)_c_h)] dark:text-success dark:bg-success/20;
227
+ }
228
+
229
+ .cn-badge-variant-warning {
230
+ @apply bg-warning/10 [a]:hover:bg-warning/20 text-[oklch(from_var(--warning)_calc(l*0.85)_c_h)] dark:text-warning dark:bg-warning/20;
231
+ }
232
+
233
+ .cn-badge-variant-info {
234
+ @apply bg-info/10 [a]:hover:bg-info/20 text-[oklch(from_var(--info)_calc(l*0.85)_c_h)] dark:text-info dark:bg-info/20;
235
+ }
236
+
237
+ /* MARK: Breadcrumb */
238
+ .cn-breadcrumb-list {
239
+ @apply text-muted-foreground gap-1.5 text-xs;
240
+ }
241
+
242
+ .cn-breadcrumb-item {
243
+ @apply gap-1;
244
+ }
245
+
246
+ .cn-breadcrumb-link {
247
+ @apply transition-colors hover:text-foreground;
248
+ }
249
+
250
+ .cn-breadcrumb-page {
251
+ @apply font-normal text-foreground;
252
+ }
253
+
254
+ .cn-breadcrumb-separator {
255
+ @apply [&>svg]:size-3.5;
256
+ }
257
+
258
+ .cn-breadcrumb-ellipsis {
259
+ @apply size-5 [&>svg]:size-4;
260
+ }
261
+
262
+ /* MARK: Bubble */
263
+ .cn-bubble {
264
+ @apply gap-1 data-[align=end]:self-end max-w-[80%] data-[variant=ghost]:max-w-full group-data-[align=end]/message:self-end;
265
+ }
266
+
267
+ .cn-bubble-group {
268
+ @apply gap-2;
269
+ }
270
+
271
+ .cn-bubble-variant-default {
272
+ @apply *:data-[slot=bubble-content]:bg-primary *:data-[slot=bubble-content]:text-primary-foreground [&>[data-slot=bubble-content]:is(button,a):hover]:bg-primary/80;
273
+ }
274
+
275
+ .cn-bubble-variant-secondary {
276
+ @apply *:data-[slot=bubble-content]:bg-secondary *:data-[slot=bubble-content]:text-secondary-foreground [&>[data-slot=bubble-content]:is(button,a):hover]:bg-[color-mix(in_oklch,var(--secondary),var(--foreground)_5%)];
277
+ }
278
+
279
+ .cn-bubble-variant-muted {
280
+ @apply *:data-[slot=bubble-content]:bg-muted [&>[data-slot=bubble-content]:is(button,a):hover]:bg-[color-mix(in_oklch,var(--muted),var(--foreground)_5%)];
281
+ }
282
+
283
+ .cn-bubble-variant-tinted {
284
+ @apply *:data-[slot=bubble-content]:bg-[oklch(from_var(--primary)_0.93_calc(c*0.4)_h)] *:data-[slot=bubble-content]:text-foreground dark:*:data-[slot=bubble-content]:bg-[oklch(from_var(--primary)_0.3_calc(c*0.4)_h)] [&>[data-slot=bubble-content]:is(button,a):hover]:bg-[oklch(from_var(--primary)_0.88_calc(c*0.5)_h)] dark:[&>[data-slot=bubble-content]:is(button,a):hover]:bg-[oklch(from_var(--primary)_0.35_calc(c*0.5)_h)];
285
+ }
286
+
287
+ .cn-bubble-variant-outline {
288
+ @apply *:data-[slot=bubble-content]:border-border *:data-[slot=bubble-content]:bg-background [&>[data-slot=bubble-content]:is(button,a):hover]:bg-muted [&>[data-slot=bubble-content]:is(button,a):hover]:text-foreground dark:[&>[data-slot=bubble-content]:is(button,a):hover]:bg-input/30;
289
+ }
290
+
291
+ .cn-bubble-variant-ghost {
292
+ @apply border-none *:data-[slot=bubble-content]:rounded-none *:data-[slot=bubble-content]:bg-transparent *:data-[slot=bubble-content]:p-0 [&>[data-slot=bubble-content]:is(button,a):hover]:bg-muted [&>[data-slot=bubble-content]:is(button,a):hover]:text-foreground dark:[&>[data-slot=bubble-content]:is(button,a):hover]:bg-muted/50;
293
+ }
294
+
295
+ .cn-bubble-variant-destructive {
296
+ @apply *:data-[slot=bubble-content]:bg-destructive/10 *:data-[slot=bubble-content]:text-destructive dark:*:data-[slot=bubble-content]:bg-destructive/20 [&>[data-slot=bubble-content]:is(button,a):hover]:bg-destructive/20 dark:[&>[data-slot=bubble-content]:is(button,a):hover]:bg-destructive/30;
297
+ }
298
+
299
+ .cn-bubble-content {
300
+ @apply rounded-none border border-transparent px-2.5 py-2 text-xs leading-relaxed [button,a]:outline-none [button,a]:focus-visible:border-ring [button,a]:focus-visible:ring-1 [button,a]:focus-visible:ring-ring/50 group-data-[align=end]/bubble:self-end;
301
+ }
302
+
303
+ .cn-bubble-reactions {
304
+ @apply rounded-none ring-2 ring-card bg-muted gap-1 px-1.5 py-0.5 has-[button]:p-0 text-xs;
305
+ }
306
+
307
+ /* MARK: Button */
308
+ .cn-button {
309
+ @apply focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 rounded-none border border-transparent bg-clip-padding text-xs font-medium focus-visible:ring-1 aria-invalid:ring-1 active:not-aria-[haspopup]:translate-y-px [&_svg:not([class*='size-'])]:size-4;
310
+ }
311
+
312
+ .cn-button-variant-default {
313
+ @apply bg-primary text-primary-foreground hover:bg-primary/80;
314
+ }
315
+
316
+ .cn-button-variant-destructive {
317
+ @apply bg-destructive/10 hover:bg-destructive/20 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/20 text-[oklch(from_var(--destructive)_calc(l*0.85)_c_h)] dark:text-destructive focus-visible:border-destructive/40 dark:hover:bg-destructive/30;
318
+ }
319
+
320
+ .cn-button-variant-outline {
321
+ @apply border-border bg-background hover:bg-muted hover:text-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50 aria-expanded:bg-muted aria-expanded:text-foreground;
322
+ }
323
+
324
+ .cn-button-variant-secondary {
325
+ @apply bg-secondary text-secondary-foreground hover:bg-[color-mix(in_oklch,var(--secondary),var(--foreground)_5%)] aria-expanded:bg-secondary aria-expanded:text-secondary-foreground;
326
+ }
327
+
328
+ .cn-button-variant-ghost {
329
+ @apply hover:bg-muted hover:text-foreground dark:hover:bg-muted/50 aria-expanded:bg-muted aria-expanded:text-foreground;
330
+ }
331
+
332
+ .cn-button-variant-link {
333
+ @apply text-primary underline-offset-4 hover:underline;
334
+ }
335
+
336
+ .cn-button-size-default {
337
+ @apply h-8 gap-1.5 px-2.5 has-data-[icon=inline-end]:pr-2 has-data-[icon=inline-start]:pl-2 has-[>svg:first-child]:pl-2 has-[>svg:last-child]:pr-2;
338
+ }
339
+
340
+ .cn-button-size-xs {
341
+ @apply h-6 gap-1 rounded-none px-2 text-xs has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 has-[>svg:first-child]:pl-1.5 has-[>svg:last-child]:pr-1.5 [&_svg:not([class*='size-'])]:size-3;
342
+ }
343
+
344
+ .cn-button-size-sm {
345
+ @apply h-7 gap-1 rounded-none px-2.5 has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 has-[>svg:first-child]:pl-1.5 has-[>svg:last-child]:pr-1.5 [&_svg:not([class*='size-'])]:size-3.5;
346
+ }
347
+
348
+ .cn-button-size-lg {
349
+ @apply h-9 gap-1.5 px-2.5 has-data-[icon=inline-end]:pr-2 has-data-[icon=inline-start]:pl-2 has-[>svg:first-child]:pl-2 has-[>svg:last-child]:pr-2;
350
+ }
351
+
352
+ .cn-button-size-icon {
353
+ @apply size-8;
354
+ }
355
+
356
+ .cn-button-size-icon-xs {
357
+ @apply size-6 rounded-none [&_svg:not([class*='size-'])]:size-3;
358
+ }
359
+
360
+ .cn-button-size-icon-sm {
361
+ @apply size-7 rounded-none;
362
+ }
363
+
364
+ .cn-button-size-icon-lg {
365
+ @apply size-9;
366
+ }
367
+
368
+ /* MARK: ButtonGroup */
369
+ .cn-button-group {
370
+ @apply rounded-none has-[>[data-slot=button-group]]:gap-2 has-[select[aria-hidden=true]:last-child]:[&>[data-slot=select-trigger]:last-of-type]:rounded-none;
371
+ }
372
+
373
+ .cn-button-group-orientation-horizontal {
374
+ @apply *:data-slot:rounded-r-none [&>[data-slot]:not(:has(~[data-slot]))]:rounded-none! [&>[data-slot]~[data-slot]]:rounded-l-none [&>[data-slot]~[data-slot]]:border-l-0 [&>:is([data-slot=select],[data-slot=dropdown-menu],[data-slot=popover]):has(~[data-slot])_:is([data-slot=select-trigger],[data-slot=dropdown-menu-trigger],[data-slot=popover-trigger])]:rounded-r-none [&>:is([data-slot=select],[data-slot=dropdown-menu],[data-slot=popover]):not(:has(~[data-slot]))_:is([data-slot=select-trigger],[data-slot=dropdown-menu-trigger],[data-slot=popover-trigger])]:rounded-none! [&>[data-slot]~:is([data-slot=select],[data-slot=dropdown-menu],[data-slot=popover])_:is([data-slot=select-trigger],[data-slot=dropdown-menu-trigger],[data-slot=popover-trigger])]:rounded-l-none [&>[data-slot]~:is([data-slot=select],[data-slot=dropdown-menu],[data-slot=popover])_:is([data-slot=select-trigger],[data-slot=dropdown-menu-trigger],[data-slot=popover-trigger])]:border-l-0;
375
+ }
376
+
377
+ .cn-button-group-orientation-vertical {
378
+ @apply flex-col *:data-slot:rounded-b-none [&>[data-slot]:not(:has(~[data-slot]))]:rounded-none! [&>[data-slot]~[data-slot]]:rounded-t-none [&>[data-slot]~[data-slot]]:border-t-0 [&>:is([data-slot=select],[data-slot=dropdown-menu],[data-slot=popover]):has(~[data-slot])_:is([data-slot=select-trigger],[data-slot=dropdown-menu-trigger],[data-slot=popover-trigger])]:rounded-b-none [&>:is([data-slot=select],[data-slot=dropdown-menu],[data-slot=popover]):not(:has(~[data-slot]))_:is([data-slot=select-trigger],[data-slot=dropdown-menu-trigger],[data-slot=popover-trigger])]:rounded-none! [&>[data-slot]~:is([data-slot=select],[data-slot=dropdown-menu],[data-slot=popover])_:is([data-slot=select-trigger],[data-slot=dropdown-menu-trigger],[data-slot=popover-trigger])]:rounded-t-none [&>[data-slot]~:is([data-slot=select],[data-slot=dropdown-menu],[data-slot=popover])_:is([data-slot=select-trigger],[data-slot=dropdown-menu-trigger],[data-slot=popover-trigger])]:border-t-0;
379
+ }
380
+
381
+ .cn-button-group-text {
382
+ @apply bg-muted gap-2 rounded-none border px-2.5 text-xs font-medium [&_svg:not([class*='size-'])]:size-4;
383
+ }
384
+
385
+ .cn-button-group-separator {
386
+ @apply bg-input!;
387
+ }
388
+
389
+ /* MARK: Calendar */
390
+ .cn-calendar {
391
+ @apply p-3;
392
+ }
393
+
394
+ .cn-calendar-caption {
395
+ @apply text-sm font-medium;
396
+ }
397
+
398
+ .cn-calendar-weekday {
399
+ @apply rounded-md text-[0.8rem] font-normal text-muted-foreground;
400
+ }
401
+
402
+ .cn-calendar-day-button {
403
+ @apply rounded-md text-sm leading-none font-normal hover:bg-accent hover:text-accent-foreground focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:text-muted-foreground disabled:opacity-50 data-today:bg-muted data-today:text-foreground data-outside:text-muted-foreground data-selected:bg-primary data-selected:text-primary-foreground data-selected:hover:bg-primary data-selected:hover:text-primary-foreground data-range-start:rounded-l-md data-range-start:bg-primary data-range-start:text-primary-foreground data-range-middle:rounded-none data-range-middle:bg-muted data-range-middle:text-foreground data-range-end:rounded-r-md data-range-end:bg-primary data-range-end:text-primary-foreground;
404
+ }
405
+
406
+ [data-slot="calendar-dropdown"] {
407
+ @apply has-focus:border-ring border-input has-focus:ring-ring/50 rounded-none border has-focus:ring-1;
408
+ }
409
+
410
+ [data-slot="calendar-caption-label"] {
411
+ @apply h-6 rounded-none pr-1 pl-1.5;
412
+ }
413
+
414
+ /* MARK: Card */
415
+ .cn-card {
416
+ @apply ring-foreground/10 bg-card text-card-foreground gap-(--card-spacing) overflow-hidden rounded-none py-(--card-spacing) text-xs/relaxed ring-1 [--card-spacing:--spacing(4)] has-data-[slot=card-footer]:pb-0 has-[>img:first-child]:pt-0 data-[size=sm]:[--card-spacing:--spacing(3)] data-[size=sm]:has-data-[slot=card-footer]:pb-0 *:[img:first-child]:rounded-none *:[img:last-child]:rounded-none;
417
+ }
418
+
419
+ .cn-card-header {
420
+ @apply gap-1 rounded-none px-(--card-spacing) [.border-b]:pb-(--card-spacing);
421
+ }
422
+
423
+ .cn-card-title {
424
+ @apply text-sm font-medium group-data-[size=sm]/card:text-sm;
425
+ }
426
+
427
+ .cn-card-description {
428
+ @apply text-muted-foreground text-xs/relaxed;
429
+ }
430
+
431
+ .cn-card-content {
432
+ @apply px-(--card-spacing);
433
+ }
434
+
435
+ .cn-card-footer {
436
+ @apply rounded-none border-t p-(--card-spacing);
437
+ }
438
+
439
+ /* MARK: Checkbox */
440
+ .cn-checkbox {
441
+ @apply border-input dark:bg-input/30 data-checked:bg-primary data-checked:text-primary-foreground dark:data-checked:bg-primary data-checked:border-primary aria-invalid:aria-checked:border-primary aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 flex size-4 items-center justify-center rounded-none border transition-colors focus-visible:ring-1 aria-invalid:ring-1 group-has-[:focus-visible]/field-label:data-checked:border-primary group-has-[:focus-visible]/field-label:not-data-checked:border-input group-has-[:focus-visible]/field-label:ring-0 group-has-disabled/field:opacity-50;
442
+ }
443
+
444
+ .cn-checkbox-indicator {
445
+ @apply [&>svg]:size-3.5;
446
+ }
447
+
448
+ /* MARK: CodeBlock */
449
+ /* The syntax palette: seven vars the dictionary's token map reads
450
+ * (GitHub light/dark is the shared v1 baseline - a theme restyles code by
451
+ * redefining the vars); .hll is highlight_lines:, .line::before the CSS
452
+ * counters (out of copied text by construction). */
453
+ .cn-code-block {
454
+ @apply bg-muted/30 rounded-lg border text-foreground [--syntax-keyword:#a40e26] [--syntax-constant:#0550ae] [--syntax-string:#0a3069] [--syntax-entity:#7f3400] [--syntax-markup:#116329] [--syntax-function:#6639ba] [--syntax-comment:#57606a] dark:[--syntax-keyword:#ff7b72] dark:[--syntax-constant:#79c0ff] dark:[--syntax-string:#a5d6ff] dark:[--syntax-entity:#ffa657] dark:[--syntax-markup:#7ee787] dark:[--syntax-function:#d2a8ff] dark:[--syntax-comment:#8b949e];
455
+ }
456
+ .cn-code-block .hll {
457
+ @apply bg-primary/10 -mx-4 w-[calc(100%+2rem)] px-4;
458
+ }
459
+ .cn-code-block[data-line-numbers] .line::before {
460
+ @apply text-muted-foreground me-4 inline-block w-6 text-right content-[counter(line)] [counter-increment:line];
461
+ }
462
+
463
+ /* MARK: Command */
464
+ .cn-command {
465
+ @apply bg-popover text-popover-foreground rounded-none;
466
+ }
467
+
468
+ .cn-input-otp-group {
469
+ @apply has-aria-invalid:ring-destructive/20 dark:has-aria-invalid:ring-destructive/40 has-aria-invalid:border-destructive rounded-none has-aria-invalid:ring-1;
470
+ }
471
+
472
+ .cn-input-otp-separator {
473
+ @apply [&_svg:not([class*='size-'])]:size-4;
474
+ }
475
+
476
+ .cn-command-input-icon {
477
+ @apply size-4 shrink-0 opacity-50;
478
+ }
479
+
480
+ .cn-command-input-wrapper {
481
+ @apply m-1 mb-0 h-8 gap-2 rounded-none border border-input/30 bg-input/30 px-2 shadow-none;
482
+ }
483
+
484
+ .cn-command-input {
485
+ @apply w-full bg-transparent text-xs placeholder:text-muted-foreground;
486
+ }
487
+
488
+ .cn-command-list {
489
+ @apply no-scrollbar max-h-72 scroll-py-0 outline-none;
490
+ }
491
+
492
+ .cn-command-empty {
493
+ @apply py-6 text-center text-xs;
494
+ }
495
+
496
+ .cn-command-group {
497
+ @apply text-foreground;
498
+ }
499
+
500
+ .cn-command-group-heading {
501
+ @apply px-2 py-1.5 text-xs font-medium text-muted-foreground;
502
+ }
503
+
504
+ .cn-command-item {
505
+ @apply data-highlighted:bg-muted data-highlighted:text-foreground data-highlighted:*:[svg]:text-foreground items-center gap-2 rounded-none px-2 py-2 text-xs outline-hidden select-none in-data-[slot=dialog-content]:rounded-none [&_svg:not([class*='size-'])]:size-4;
506
+ }
507
+
508
+ .cn-command-shortcut {
509
+ @apply text-muted-foreground group-data-highlighted/command-item:text-foreground ml-auto text-xs tracking-widest;
510
+ }
511
+
512
+ .cn-command-separator {
513
+ @apply -mx-1 h-px bg-border;
514
+ }
515
+
516
+ /* MARK: Combobox */
517
+ .cn-combobox-trigger {
518
+ @apply h-9 w-[200px] gap-2 rounded-md border bg-background px-4 py-2 text-sm font-normal shadow-xs hover:bg-accent hover:text-accent-foreground focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 data-[placeholder]:text-muted-foreground dark:aria-invalid:ring-destructive/40 dark:border-input dark:bg-input/30 dark:hover:bg-input/50 has-[>svg]:px-3 [&_svg:not([class*='size-'])]:size-4;
519
+ }
520
+
521
+ .cn-combobox-content {
522
+ @apply bg-popover text-popover-foreground ring-foreground/10 *:data-[slot=input-group]:bg-input/30 *:data-[slot=input-group]:border-input/30 *:data-[slot=input-group]:m-1 *:data-[slot=input-group]:mb-0 *:data-[slot=input-group]:h-8 *:data-[slot=input-group]:shadow-none max-h-72 min-w-36 overflow-hidden rounded-none p-0 shadow-md ring-1 duration-100 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2;
523
+ }
524
+
525
+ /* The popup's list and group label: the source's combobox rules (the
526
+ * inset rides the LIST, the group stays unpadded). */
527
+ .cn-combobox-label {
528
+ @apply text-muted-foreground px-2 py-2 text-xs;
529
+ }
530
+
531
+ .cn-combobox-list {
532
+ @apply no-scrollbar max-h-[min(calc(--spacing(72)---spacing(9)),calc(var(--available-height)---spacing(9)))] scroll-py-1 overflow-y-auto data-empty:p-0;
533
+ }
534
+
535
+ .cn-combobox-item-indicator {
536
+ @apply pointer-events-none absolute right-2 flex size-4 items-center justify-center;
537
+ }
538
+
539
+ /* The chips FIELD (multiple:) - lyra's dense square field; hairline
540
+ * focus ring, square chips. */
541
+ .cn-combobox-chips {
542
+ @apply min-h-8 gap-1.5 rounded-none border border-input px-2.5 py-1 text-xs transition-colors focus-within:border-ring focus-within:ring-1 focus-within:ring-ring/50 dark:bg-input/30 has-data-[slot=combobox-chip]:px-1.5 has-aria-invalid:border-destructive dark:has-aria-invalid:border-destructive/50 has-aria-invalid:ring-1 has-aria-invalid:ring-destructive/20 dark:has-aria-invalid:ring-destructive/40;
543
+ }
544
+
545
+ .cn-combobox-chip {
546
+ @apply h-5 gap-1 rounded-none bg-secondary px-1.5 text-xs font-medium text-secondary-foreground focus-visible:ring-1 focus-visible:ring-ring/50;
547
+ }
548
+
549
+ .cn-combobox-chip-remove {
550
+ @apply -ml-1 rounded-none opacity-50 hover:opacity-100 focus-visible:opacity-100;
551
+ }
552
+
553
+ .cn-combobox-chip-input {
554
+ @apply min-w-16 placeholder:text-muted-foreground;
555
+ }
556
+
557
+ /* MARK: ContextMenu */
558
+ .cn-context-menu-content {
559
+ @apply data-open:animate-in data-closed:animate-out data-closed:fade-out-0 data-open:fade-in-0 data-closed:zoom-out-95 data-open:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 ring-foreground/10 bg-popover text-popover-foreground min-w-36 rounded-none shadow-md ring-1 duration-100;
560
+ }
561
+
562
+ .cn-context-menu-item {
563
+ @apply focus:bg-accent focus:text-accent-foreground data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 dark:data-[variant=destructive]:focus:bg-destructive/20 data-[variant=destructive]:focus:text-destructive data-[variant=destructive]:*:[svg]:text-destructive focus:*:[svg]:text-accent-foreground gap-2 rounded-none px-2 py-2 text-xs data-inset:pl-7 [&_svg:not([class*='size-'])]:size-4;
564
+ }
565
+
566
+ .cn-context-menu-checkbox-item {
567
+ @apply focus:bg-accent focus:text-accent-foreground gap-2 rounded-none py-2 pr-8 pl-2 text-xs data-inset:pl-7 [&_svg:not([class*='size-'])]:size-4;
568
+ }
569
+
570
+ .cn-context-menu-radio-item {
571
+ @apply focus:bg-accent focus:text-accent-foreground gap-2 rounded-none py-2 pr-8 pl-2 text-xs data-inset:pl-7 [&_svg:not([class*='size-'])]:size-4;
572
+ }
573
+
574
+ .cn-context-menu-label {
575
+ @apply text-muted-foreground px-2 py-2 text-xs data-inset:pl-7;
576
+ }
577
+
578
+ .cn-context-menu-separator {
579
+ @apply bg-border -mx-1 h-px;
580
+ }
581
+
582
+ .cn-context-menu-shortcut {
583
+ @apply text-muted-foreground group-focus/context-menu-item:text-accent-foreground ml-auto text-xs tracking-widest;
584
+ }
585
+
586
+ .cn-context-menu-sub-trigger {
587
+ @apply focus:bg-accent focus:text-accent-foreground data-open:bg-accent data-open:text-accent-foreground gap-2 rounded-none px-2 py-2 text-xs data-inset:pl-7 [&_svg:not([class*='size-'])]:size-4 data-popup-open:bg-accent data-popup-open:text-accent-foreground;
588
+ }
589
+
590
+ .cn-context-menu-sub-content {
591
+ @apply data-open:animate-in data-closed:animate-out data-closed:fade-out-0 data-open:fade-in-0 data-closed:zoom-out-95 data-open:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 bg-popover text-popover-foreground min-w-32 rounded-none border shadow-lg duration-100;
592
+ }
593
+
594
+ .cn-context-menu-item-indicator {
595
+ @apply right-2;
596
+ }
597
+
598
+ /* MARK: DataTable */
599
+ .cn-data-table-toolbar {
600
+ @apply py-4;
601
+ }
602
+
603
+ .cn-data-table-container {
604
+ @apply rounded-md border;
605
+ }
606
+
607
+ .cn-data-table-footer {
608
+ @apply py-4;
609
+ }
610
+
611
+ .cn-data-table-empty {
612
+ @apply h-24 text-center;
613
+ }
614
+
615
+ /* MARK: Dialog */
616
+ .cn-dialog-content {
617
+ @apply w-full max-w-[calc(100%-2rem)] bg-popover text-popover-foreground ring-foreground/10 gap-4 rounded-none p-4 text-xs/relaxed ring-1 duration-100 sm:max-w-sm backdrop:bg-black/10 supports-backdrop-filter:backdrop:backdrop-blur-xs data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95;
618
+ }
619
+
620
+ .cn-dialog-header {
621
+ @apply gap-1 text-left;
622
+ }
623
+
624
+ .cn-dialog-title {
625
+ @apply text-sm font-medium;
626
+ }
627
+
628
+ .cn-dialog-description {
629
+ @apply text-muted-foreground *:[a]:hover:text-foreground text-xs/relaxed *:[a]:underline *:[a]:underline-offset-3;
630
+ }
631
+
632
+ /* poetry-authored: upstream ships no footer rule for this theme; gap-2
633
+ mirrors the component's own inline utilities so the hook compiles
634
+ without a visual delta (css:verify_compiled). */
635
+ .cn-dialog-footer {
636
+ @apply gap-2;
637
+ }
638
+
639
+ .cn-dialog-close {
640
+ @apply absolute top-2 right-2;
641
+ }
642
+
643
+ /* MARK: Drawer */
644
+ .cn-drawer-content {
645
+ /* Flush drawer - the explicit stance for the dictionary's
646
+ var(--drawer-inset) read (floating themes ship --spacing(2)). */
647
+ @apply bg-popover text-popover-foreground text-xs/relaxed backdrop:bg-black/10 supports-backdrop-filter:backdrop:backdrop-blur-xs [--drawer-inset:0px];
648
+ }
649
+
650
+ .cn-drawer-direction-down {
651
+ @apply rounded-none border-t;
652
+ }
653
+
654
+ .cn-drawer-direction-up {
655
+ @apply rounded-none border-b;
656
+ }
657
+
658
+ .cn-drawer-direction-left {
659
+ @apply rounded-none border-r;
660
+ }
661
+
662
+ .cn-drawer-direction-right {
663
+ @apply rounded-none border-l;
664
+ }
665
+
666
+ .cn-drawer-swipe-handle {
667
+ @apply after:h-1 after:w-12 after:rounded-none after:bg-muted;
668
+ }
669
+
670
+ .cn-drawer-header {
671
+ @apply gap-0.5 p-4 md:gap-0.5 md:text-left;
672
+ }
673
+
674
+ .cn-drawer-footer {
675
+ @apply gap-2 p-4;
676
+ }
677
+
678
+ .cn-drawer-title {
679
+ @apply text-foreground text-sm font-medium;
680
+ }
681
+
682
+ .cn-drawer-description {
683
+ @apply text-muted-foreground text-xs/relaxed;
684
+ }
685
+
686
+ .cn-drawer-body {
687
+ @apply p-4;
688
+ }
689
+
690
+ /* MARK: DropdownMenu */
691
+ .cn-dropdown-menu-content {
692
+ @apply data-open:animate-in data-closed:animate-out data-closed:fade-out-0 data-open:fade-in-0 data-closed:zoom-out-95 data-open:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 ring-foreground/10 bg-popover text-popover-foreground min-w-32 rounded-none shadow-md ring-1 duration-100;
693
+ }
694
+
695
+ .cn-dropdown-menu-item {
696
+ @apply focus:bg-accent focus:text-accent-foreground data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 dark:data-[variant=destructive]:focus:bg-destructive/20 data-[variant=destructive]:focus:text-destructive data-[variant=destructive]:*:[svg]:text-destructive not-data-[variant=destructive]:focus:**:text-accent-foreground gap-2 rounded-none px-2 py-2 text-xs data-inset:pl-7 [&_svg:not([class*='size-'])]:size-4;
697
+ }
698
+
699
+ .cn-dropdown-menu-checkbox-item {
700
+ @apply focus:bg-accent focus:text-accent-foreground focus:**:text-accent-foreground gap-2 rounded-none py-2 pr-8 pl-2 text-xs data-inset:pl-7 [&_svg:not([class*='size-'])]:size-4;
701
+ }
702
+
703
+ .cn-dropdown-menu-radio-item {
704
+ @apply focus:bg-accent focus:text-accent-foreground focus:**:text-accent-foreground gap-2 rounded-none py-2 pr-8 pl-2 text-xs data-inset:pl-7 [&_svg:not([class*='size-'])]:size-4;
705
+ }
706
+
707
+ .cn-dropdown-menu-label {
708
+ @apply text-muted-foreground px-2 py-2 text-xs data-inset:pl-7;
709
+ }
710
+
711
+ .cn-dropdown-menu-separator {
712
+ @apply bg-border -mx-1 h-px;
713
+ }
714
+
715
+ .cn-dropdown-menu-shortcut {
716
+ @apply text-muted-foreground group-focus/dropdown-menu-item:text-accent-foreground ml-auto text-xs tracking-widest;
717
+ }
718
+
719
+ .cn-dropdown-menu-sub-trigger {
720
+ @apply focus:bg-accent focus:text-accent-foreground data-open:bg-accent data-open:text-accent-foreground not-data-[variant=destructive]:focus:**:text-accent-foreground gap-2 rounded-none px-2 py-2 text-xs data-inset:pl-7 [&_svg:not([class*='size-'])]:size-4 data-popup-open:bg-accent data-popup-open:text-accent-foreground;
721
+ }
722
+
723
+ .cn-dropdown-menu-sub-content {
724
+ @apply data-open:animate-in data-closed:animate-out data-closed:fade-out-0 data-open:fade-in-0 data-closed:zoom-out-95 data-open:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 ring-foreground/10 bg-popover text-popover-foreground min-w-[96px] rounded-none shadow-lg ring-1 duration-100;
725
+ }
726
+
727
+ .cn-dropdown-menu-item-indicator {
728
+ @apply right-2 flex items-center justify-center;
729
+ }
730
+
731
+ /* MARK: Empty */
732
+ .cn-empty {
733
+ @apply gap-4 rounded-none border-dashed p-6;
734
+ }
735
+
736
+ .cn-empty-header {
737
+ @apply gap-2;
738
+ }
739
+
740
+ .cn-empty-media {
741
+ @apply mb-2;
742
+ }
743
+
744
+ .cn-empty-media-default {
745
+ @apply bg-transparent;
746
+ }
747
+
748
+ .cn-empty-media-icon {
749
+ @apply bg-muted text-foreground flex size-8 shrink-0 items-center justify-center rounded-none [&_svg:not([class*='size-'])]:size-4;
750
+ }
751
+
752
+ .cn-empty-title {
753
+ @apply text-sm font-medium;
754
+ }
755
+
756
+ .cn-empty-description {
757
+ @apply text-xs/relaxed;
758
+ }
759
+
760
+ .cn-empty-content {
761
+ @apply gap-2.5 text-xs;
762
+ }
763
+
764
+ /* MARK: Field */
765
+ .cn-field {
766
+ @apply data-[invalid=true]:text-destructive gap-2;
767
+ }
768
+
769
+ .cn-field-description {
770
+ @apply text-muted-foreground text-left text-xs/relaxed [[data-variant=legend]+&]:-mt-1.5;
771
+ }
772
+
773
+ .cn-field-error {
774
+ @apply text-destructive text-xs;
775
+ }
776
+
777
+ .cn-field-orientation-horizontal {
778
+ @apply gap-x-3;
779
+ }
780
+
781
+ /* Row layout: the label + hint pair packs at the theme's
782
+ cn-field-content rhythm; the field gap keeps the column axis. */
783
+ .cn-field-orientation-responsive {
784
+ @apply @md/field-group:gap-y-0.5;
785
+ }
786
+
787
+ .cn-field-set {
788
+ @apply gap-4 has-[>.cn-field-group-choices]:gap-3 has-[>[data-slot=radio-group]]:gap-3;
789
+ }
790
+
791
+ .cn-field-legend {
792
+ @apply mb-2.5 font-medium data-[variant=legend]:text-sm data-[variant=label]:text-xs;
793
+ }
794
+
795
+ .cn-field-group {
796
+ @apply gap-5 *:data-[slot=field-group]:gap-4;
797
+ }
798
+
799
+ .cn-field-group-choices {
800
+ @apply gap-3;
801
+ }
802
+
803
+ .cn-field-content {
804
+ @apply gap-0.5;
805
+ }
806
+
807
+ .cn-field-label {
808
+ @apply has-data-checked:bg-primary/5 has-data-checked:border-primary/30 dark:has-data-checked:border-primary/20 dark:has-data-checked:bg-primary/10 gap-2 leading-snug *:data-[slot=field]:p-2 group-data-[disabled=true]/field:opacity-50 has-[>[data-slot=field]]:border has-[>[data-slot=field]]:has-[:focus-visible]:border-ring has-[>[data-slot=field]]:has-[:focus-visible]:ring-1 has-[>[data-slot=field]]:has-[:focus-visible]:ring-ring/50 has-[>[data-slot=field]]:not-has-[:disabled,[data-disabled]]:hover:bg-muted/50 has-[>[data-slot=field]]:rounded-none;
809
+ }
810
+
811
+ .cn-field-label-card {
812
+ @apply rounded-none border p-2;
813
+ }
814
+
815
+ .cn-field-title {
816
+ @apply gap-2 text-xs/relaxed;
817
+ }
818
+
819
+ .cn-field-separator {
820
+ @apply -my-2 h-5 text-xs;
821
+ }
822
+
823
+ .cn-field-separator-content {
824
+ @apply px-2 text-muted-foreground;
825
+ }
826
+
827
+ /* MARK: HoverCard */
828
+ .cn-hover-card-content {
829
+ @apply data-open:animate-in data-closed:animate-out data-closed:fade-out-0 data-open:fade-in-0 data-closed:zoom-out-95 data-open:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 ring-foreground/10 bg-popover text-popover-foreground w-64 rounded-none p-2.5 text-xs/relaxed shadow-md ring-1 duration-100;
830
+ }
831
+
832
+ /* MARK: Input */
833
+ .cn-input {
834
+ @apply dark:bg-input/30 border-input focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 disabled:bg-input/50 dark:disabled:bg-input/80 h-8 rounded-none border bg-transparent px-2.5 py-1 text-xs transition-colors file:h-6 file:text-xs file:font-medium focus-visible:ring-1 aria-invalid:ring-1 md:text-xs placeholder:text-muted-foreground;
835
+ }
836
+
837
+ /* MARK: InputGroup */
838
+ .cn-input-group {
839
+ @apply border-input dark:bg-input/30 has-[[data-slot=input-group-control]:focus-visible]:border-ring has-[[data-slot=input-group-control]:focus-visible]:ring-ring/50 has-[[data-slot][aria-invalid=true]]:ring-destructive/20 has-[[data-slot][aria-invalid=true]]:border-destructive dark:has-[[data-slot][aria-invalid=true]]:ring-destructive/40 has-disabled:bg-input/50 dark:has-disabled:bg-input/80 h-8 rounded-none border transition-colors in-data-[slot=combobox-content]:focus-within:border-inherit in-data-[slot=combobox-content]:focus-within:ring-0 has-disabled:opacity-50 has-[[data-slot=input-group-control]:focus-visible]:ring-1 has-[[data-slot][aria-invalid=true]]:ring-1 has-[>[data-align=block-end]]:h-auto has-[>[data-align=block-end]]:flex-col has-[>[data-align=block-start]]:h-auto has-[>[data-align=block-start]]:flex-col has-[>[data-align=block-end]]:[&>input]:pt-3 has-[>[data-align=block-start]]:[&>input]:pb-3 has-[>[data-align=inline-end]]:[&>input]:pr-1.5 has-[>[data-align=inline-start]]:[&>input]:pl-1.5;
840
+ }
841
+
842
+ .cn-input-group-button-size-sm {
843
+ @apply gap-1;
844
+ }
845
+
846
+ .cn-input-group-addon {
847
+ @apply text-muted-foreground h-auto gap-2 py-1.5 text-xs font-medium group-data-[disabled=true]/input-group:opacity-50 [&>kbd]:rounded-none [&>svg:not([class*='size-'])]:size-4;
848
+ }
849
+
850
+ .cn-input-group-addon-align-inline-start {
851
+ @apply pl-2 has-[>button]:ml-[-0.3rem] has-[>kbd]:ml-[-0.15rem];
852
+ }
853
+
854
+ .cn-input-group-addon-align-inline-end {
855
+ @apply pr-2 has-[>button]:mr-[-0.3rem] has-[>kbd]:mr-[-0.15rem];
856
+ }
857
+
858
+ .cn-input-group-addon-align-block-start {
859
+ @apply px-2.5 pt-2 group-has-[>input]/input-group:pt-2 [.border-b]:pb-2;
860
+ }
861
+
862
+ .cn-input-group-addon-align-block-end {
863
+ @apply px-2.5 pb-2 group-has-[>input]/input-group:pb-2 [.border-t]:pt-2;
864
+ }
865
+
866
+ .cn-input-group-text {
867
+ @apply text-muted-foreground gap-2 text-xs [&_svg:not([class*='size-'])]:size-4;
868
+ }
869
+
870
+ /* MARK: InputOTP */
871
+ .cn-input-otp {
872
+ @apply gap-2;
873
+ }
874
+
875
+ .cn-input-otp-slot {
876
+ @apply dark:bg-input/30 border-input data-[active=true]:border-ring data-[active=true]:ring-ring/50 data-[active=true]:aria-invalid:ring-destructive/20 dark:data-[active=true]:aria-invalid:ring-destructive/40 aria-invalid:border-destructive data-[active=true]:aria-invalid:border-destructive size-8 border-y border-r text-xs transition-all outline-none first:rounded-none first:border-l last:rounded-none data-[active=true]:ring-1;
877
+ }
878
+
879
+ .cn-input-otp-caret-line {
880
+ @apply bg-foreground h-4 w-px;
881
+ }
882
+
883
+ /* MARK: Item */
884
+ .cn-item {
885
+ @apply [a]:hover:bg-muted rounded-none border text-xs;
886
+ }
887
+
888
+ .cn-item-media {
889
+ @apply gap-2 group-has-data-[slot=item-description]/item:translate-y-0.5 group-has-data-[slot=item-description]/item:self-start;
890
+ }
891
+
892
+ .cn-item-media-variant-default {
893
+ @apply bg-transparent;
894
+ }
895
+
896
+ .cn-item-media-variant-icon {
897
+ @apply [&_svg:not([class*='size-'])]:size-4;
898
+ }
899
+
900
+ .cn-item-media-variant-image {
901
+ @apply size-10 overflow-hidden rounded-none group-data-[size=sm]/item:size-8 group-data-[size=xs]/item:size-6 [&_img]:size-full [&_img]:object-cover;
902
+ }
903
+
904
+ .cn-item-content {
905
+ @apply gap-1 group-data-[size=xs]/item:gap-0;
906
+ }
907
+
908
+ .cn-item-title {
909
+ @apply gap-2 text-xs font-medium underline-offset-4;
910
+ }
911
+
912
+ .cn-item-description {
913
+ @apply text-muted-foreground text-left text-xs/relaxed group-data-[size=xs]/item:text-xs/relaxed;
914
+ }
915
+
916
+ .cn-item-actions {
917
+ @apply gap-2;
918
+ }
919
+
920
+ .cn-item-header {
921
+ @apply gap-2;
922
+ }
923
+
924
+ .cn-item-footer {
925
+ @apply gap-2;
926
+ }
927
+
928
+ .cn-item-group {
929
+ @apply gap-4 has-data-[size=sm]:gap-2.5 has-data-[size=xs]:gap-2;
930
+ }
931
+
932
+ .cn-item-separator {
933
+ @apply my-2;
934
+ }
935
+
936
+ .cn-item-variant-default {
937
+ @apply border-transparent;
938
+ }
939
+
940
+ .cn-item-variant-outline {
941
+ @apply border-border;
942
+ }
943
+
944
+ .cn-item-variant-muted {
945
+ @apply border-transparent bg-muted/50;
946
+ }
947
+
948
+ .cn-item-size-default {
949
+ @apply gap-2.5 px-3 py-2.5;
950
+ }
951
+
952
+ .cn-item-size-sm {
953
+ @apply gap-2.5 px-3 py-2.5;
954
+ }
955
+
956
+ .cn-item-size-xs {
957
+ @apply gap-2 px-2.5 py-2 in-data-[slot=dropdown-menu-content]:p-0;
958
+ }
959
+
960
+ /* MARK: Kbd */
961
+ .cn-kbd {
962
+ @apply bg-muted text-muted-foreground in-data-[slot=tooltip-content]:bg-background/20 in-data-[slot=tooltip-content]:text-background dark:in-data-[slot=tooltip-content]:bg-background/10 h-5 w-fit min-w-5 gap-1 rounded-none px-1 font-sans text-xs font-medium [&_svg:not([class*='size-'])]:size-3;
963
+ }
964
+
965
+ .cn-kbd-group {
966
+ @apply gap-1;
967
+ }
968
+
969
+ /* MARK: Label */
970
+ .cn-label {
971
+ @apply gap-2 text-xs leading-none group-data-[disabled=true]:opacity-50 peer-disabled:opacity-50;
972
+ }
973
+
974
+ /* MARK: Link */
975
+ .cn-link {
976
+ @apply gap-1 rounded-sm text-primary underline-offset-4 focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50;
977
+ }
978
+
979
+ .cn-link-underline-hover {
980
+ @apply no-underline hover:underline;
981
+ }
982
+
983
+ .cn-link-underline-always {
984
+ @apply underline;
985
+ }
986
+
987
+ .cn-link-underline-none {
988
+ @apply no-underline;
989
+ }
990
+
991
+ /* MARK: Marker */
992
+ .cn-marker {
993
+ @apply gap-2 text-xs text-muted-foreground [a]:hover:text-foreground [a]:underline-offset-3 [a]:underline [&_svg:not([class*='size-'])]:size-3.5 min-h-4 text-left;
994
+ }
995
+
996
+ .cn-marker-variant-separator {
997
+ @apply before:mr-1 before:h-px before:min-w-0 before:flex-1 before:bg-border after:ml-1 after:h-px after:min-w-0 after:flex-1 after:bg-border;
998
+ }
999
+
1000
+ .cn-marker-variant-border {
1001
+ @apply border-b border-border pb-2;
1002
+ }
1003
+
1004
+ .cn-marker-icon {
1005
+ @apply size-3.5 [&_svg:not([class*='size-'])]:size-3.5;
1006
+ }
1007
+
1008
+ .cn-marker-content {
1009
+ @apply group-data-[variant=separator]/marker:flex-none group-data-[variant=separator]/marker:text-center *:[a]:underline *:[a]:underline-offset-3 *:[a]:hover:text-foreground;
1010
+ }
1011
+
1012
+ /* MARK: Menubar */
1013
+ .cn-menubar {
1014
+ @apply h-8 gap-0.5 rounded-none border p-1;
1015
+ }
1016
+
1017
+ .cn-menubar-checkbox-item-indicator {
1018
+ @apply left-1.5 size-4 [&_svg:not([class*='size-'])]:size-4;
1019
+ }
1020
+
1021
+ .cn-menubar-radio-item-indicator {
1022
+ @apply left-1.5 size-4 [&_svg:not([class*='size-'])]:size-4;
1023
+ }
1024
+
1025
+ .cn-navigation-menu {
1026
+ @apply max-w-max;
1027
+ }
1028
+
1029
+ .cn-menubar-trigger {
1030
+ @apply hover:bg-muted aria-expanded:bg-muted rounded-none px-1.5 py-[calc(--spacing(0.8))] text-xs font-medium;
1031
+ }
1032
+
1033
+ .cn-menubar-content {
1034
+ @apply bg-popover text-popover-foreground data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 ring-foreground/10 min-w-36 rounded-none shadow-md ring-1 duration-100;
1035
+ }
1036
+
1037
+ .cn-menubar-item {
1038
+ @apply focus:bg-accent focus:text-accent-foreground data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 dark:data-[variant=destructive]:focus:bg-destructive/20 data-[variant=destructive]:focus:text-destructive data-[variant=destructive]:*:[svg]:text-destructive! not-data-[variant=destructive]:focus:**:text-accent-foreground gap-2 rounded-none px-2 py-2 text-xs data-disabled:opacity-50 data-inset:pl-8 [&_svg:not([class*='size-'])]:size-4;
1039
+ }
1040
+
1041
+ .cn-menubar-checkbox-item {
1042
+ @apply focus:bg-accent focus:text-accent-foreground focus:**:text-accent-foreground gap-2 rounded-none py-2 pr-28 pl-8 text-xs data-inset:pl-8;
1043
+ }
1044
+
1045
+ .cn-menubar-radio-item {
1046
+ @apply focus:bg-accent focus:text-accent-foreground focus:**:text-accent-foreground gap-2 rounded-none py-2 pr-2 pl-8 text-xs data-disabled:opacity-50 data-inset:pl-8 [&_svg:not([class*='size-'])]:size-4;
1047
+ }
1048
+
1049
+ .cn-menubar-label {
1050
+ @apply px-2 py-2 text-xs data-inset:pl-8;
1051
+ }
1052
+
1053
+ .cn-menubar-separator {
1054
+ @apply -mx-1 my-1 h-px bg-border;
1055
+ }
1056
+
1057
+ .cn-menubar-shortcut {
1058
+ @apply text-muted-foreground group-focus/menubar-item:text-accent-foreground text-xs tracking-widest;
1059
+ }
1060
+
1061
+ .cn-menubar-sub-trigger {
1062
+ @apply focus:bg-accent focus:text-accent-foreground data-open:bg-accent data-open:text-accent-foreground gap-2 rounded-none px-2 py-2 text-xs data-inset:pl-8 [&_svg:not([class*='size-'])]:size-4 data-popup-open:bg-accent data-popup-open:text-accent-foreground;
1063
+ }
1064
+
1065
+ .cn-menubar-sub-content {
1066
+ @apply bg-popover text-popover-foreground data-open:animate-in data-closed:animate-out data-closed:fade-out-0 data-open:fade-in-0 data-closed:zoom-out-95 data-open:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 ring-foreground/10 min-w-32 rounded-none shadow-lg ring-1 duration-100;
1067
+ }
1068
+
1069
+
1070
+ /* MARK: Message */
1071
+ .cn-message {
1072
+ @apply text-xs gap-1.5;
1073
+ }
1074
+
1075
+ .cn-message-group {
1076
+ @apply gap-1.5;
1077
+ }
1078
+
1079
+ .cn-message-avatar {
1080
+ @apply min-w-8 group-has-data-[slot=message-footer]/message:-translate-y-8;
1081
+ }
1082
+
1083
+ .cn-message-content {
1084
+ @apply gap-2 group-data-[align=end]/message:*:data-slot:self-end;
1085
+ }
1086
+
1087
+ .cn-message-header {
1088
+ @apply text-xs font-medium text-muted-foreground px-2.5 group-has-data-[variant=ghost]/message:px-0;
1089
+ }
1090
+
1091
+ .cn-message-footer {
1092
+ @apply text-xs font-medium text-muted-foreground px-2.5 group-has-data-[variant=ghost]/message:px-0;
1093
+ }
1094
+
1095
+ /* MARK: MessageScroller */
1096
+ .cn-message-scroller-content {
1097
+ @apply gap-6;
1098
+ }
1099
+
1100
+ /* MARK: NavigationMenu */
1101
+ .cn-navigation-menu-list {
1102
+ @apply gap-0;
1103
+ }
1104
+
1105
+ .cn-navigation-menu-trigger {
1106
+ @apply hover:bg-muted focus:bg-muted data-open:hover:bg-muted data-open:focus:bg-muted data-open:bg-muted/50 focus-visible:ring-ring/50 data-popup-open:bg-muted/50 data-popup-open:hover:bg-muted rounded-none px-2.5 py-1.5 text-xs font-medium transition-all focus-visible:ring-1 focus-visible:outline-1 disabled:opacity-50;
1107
+ }
1108
+
1109
+ .cn-navigation-menu-trigger-icon {
1110
+ @apply ml-1 size-3 group-data-open/navigation-menu-trigger:rotate-180 group-data-popup-open/navigation-menu-trigger:rotate-180;
1111
+ }
1112
+
1113
+ .cn-navigation-menu-content {
1114
+ @apply data-[motion^=from-]:animate-in data-[motion^=to-]:animate-out data-[motion^=from-]:fade-in data-[motion^=to-]:fade-out data-[motion=from-end]:slide-in-from-right-52 data-[motion=from-start]:slide-in-from-left-52 data-[motion=to-end]:slide-out-to-right-52 data-[motion=to-start]:slide-out-to-left-52 group-data-[viewport=false]/navigation-menu:bg-popover group-data-[viewport=false]/navigation-menu:text-popover-foreground group-data-[viewport=false]/navigation-menu:data-open:animate-in group-data-[viewport=false]/navigation-menu:data-closed:animate-out group-data-[viewport=false]/navigation-menu:data-closed:zoom-out-95 group-data-[viewport=false]/navigation-menu:data-open:zoom-in-95 group-data-[viewport=false]/navigation-menu:data-open:fade-in-0 group-data-[viewport=false]/navigation-menu:data-closed:fade-out-0 group-data-[viewport=false]/navigation-menu:ring-foreground/10 p-1 ease-[cubic-bezier(0.22,1,0.36,1)] group-data-[viewport=false]/navigation-menu:rounded-none group-data-[viewport=false]/navigation-menu:shadow group-data-[viewport=false]/navigation-menu:ring-1 group-data-[viewport=false]/navigation-menu:duration-300;
1115
+ }
1116
+
1117
+ .cn-navigation-menu-popup {
1118
+ @apply bg-popover text-popover-foreground ring-foreground/10 rounded-none shadow ring-1 transition-all ease-[cubic-bezier(0.22,1,0.36,1)] outline-none data-ending-style:scale-90 data-ending-style:opacity-0 data-ending-style:duration-150 data-starting-style:scale-90 data-starting-style:opacity-0;
1119
+ }
1120
+
1121
+ .cn-navigation-menu-link {
1122
+ @apply data-active:focus:bg-muted data-active:hover:bg-muted data-active:bg-muted/50 focus-visible:ring-ring/50 hover:bg-muted focus:bg-muted gap-2 rounded-none p-2 text-xs transition-all focus-visible:ring-1 focus-visible:outline-1 in-data-[slot=navigation-menu-content]:rounded-none [&_svg:not([class*='size-'])]:size-4;
1123
+ }
1124
+
1125
+ /* MARK: NativeSelect */
1126
+ .cn-native-select {
1127
+ @apply border-input placeholder:text-muted-foreground selection:bg-primary selection:text-primary-foreground dark:bg-input/30 dark:hover:bg-input/50 focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 h-8 min-w-0 rounded-none border bg-transparent py-1 pr-8 pl-2.5 text-xs transition-colors select-none focus-visible:ring-1 aria-invalid:ring-1 data-[size=sm]:h-7 data-[size=sm]:rounded-none data-[size=sm]:py-0.5;
1128
+ }
1129
+
1130
+ .cn-native-select-icon {
1131
+ @apply text-muted-foreground;
1132
+ }
1133
+
1134
+ /* MARK: Pagination */
1135
+ .cn-pagination-content {
1136
+ @apply gap-0.5;
1137
+ }
1138
+
1139
+ .cn-pagination-previous {
1140
+ @apply pl-1.5!;
1141
+ }
1142
+
1143
+ .cn-pagination-next {
1144
+ @apply pr-1.5!;
1145
+ }
1146
+
1147
+ .cn-pagination-ellipsis {
1148
+ @apply size-8 [&_svg:not([class*='size-'])]:size-4;
1149
+ }
1150
+
1151
+ /* MARK: Popover */
1152
+ .cn-popover-content {
1153
+ @apply bg-popover text-popover-foreground data-open:animate-in data-closed:animate-out data-closed:fade-out-0 data-open:fade-in-0 data-closed:zoom-out-95 data-open:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 ring-foreground/10 flex flex-col gap-2.5 rounded-none p-2.5 text-xs shadow-md ring-1 duration-100;
1154
+ }
1155
+
1156
+ .cn-popover-header {
1157
+ @apply gap-1 text-xs;
1158
+ }
1159
+
1160
+ .cn-popover-title {
1161
+ @apply text-sm font-medium;
1162
+ }
1163
+
1164
+ .cn-popover-description {
1165
+ @apply text-muted-foreground text-xs/relaxed;
1166
+ }
1167
+
1168
+ /* MARK: Progress */
1169
+ .cn-progress-track {
1170
+ @apply bg-muted h-1 rounded-none;
1171
+ }
1172
+
1173
+ .cn-progress-indicator {
1174
+ @apply bg-primary;
1175
+ }
1176
+
1177
+ .cn-progress-label {
1178
+ @apply text-xs;
1179
+ }
1180
+
1181
+ .cn-progress-value {
1182
+ @apply text-muted-foreground ml-auto text-xs tabular-nums;
1183
+ }
1184
+
1185
+ /* MARK: RadioGroup */
1186
+ .cn-radio-group {
1187
+ @apply grid gap-2;
1188
+ }
1189
+
1190
+ .cn-radio-group-item {
1191
+ @apply border-input dark:bg-input/30 data-checked:bg-primary data-checked:text-primary-foreground dark:data-checked:bg-primary data-checked:border-primary aria-invalid:aria-checked:border-primary aria-invalid:border-destructive focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 dark:aria-invalid:border-destructive/50 flex size-4 rounded-full focus-visible:ring-3 aria-invalid:ring-3 group-has-[:focus-visible]/field-label:data-checked:border-primary group-has-[:focus-visible]/field-label:not-data-checked:border-input group-has-[:focus-visible]/field-label:ring-0;
1192
+ }
1193
+
1194
+ .cn-radio-group-indicator {
1195
+ @apply flex size-4 items-center justify-center;
1196
+ }
1197
+
1198
+ .cn-radio-group-indicator-icon {
1199
+ @apply bg-primary-foreground absolute top-1/2 left-1/2 size-2 -translate-x-1/2 -translate-y-1/2 rounded-full;
1200
+ }
1201
+
1202
+ /* MARK: Resizable */
1203
+ .cn-resizable-handle-icon {
1204
+ @apply bg-border h-6 w-1 rounded-none;
1205
+ }
1206
+
1207
+ /* MARK: Select */
1208
+ .cn-select-trigger {
1209
+ @apply border-input data-placeholder:text-muted-foreground dark:bg-input/30 dark:hover:bg-input/50 focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 gap-1.5 rounded-none border bg-transparent py-2 pr-2 pl-2.5 text-xs transition-colors select-none focus-visible:ring-1 aria-invalid:ring-1 data-[size=default]:h-8 data-[size=sm]:h-7 data-[size=sm]:rounded-none *:data-[slot=select-value]:flex *:data-[slot=select-value]:gap-1.5 [&_svg:not([class*='size-'])]:size-4;
1210
+ }
1211
+
1212
+ .cn-select-trigger-icon {
1213
+ @apply text-muted-foreground size-4;
1214
+ }
1215
+
1216
+ .cn-select-content {
1217
+ @apply bg-popover text-popover-foreground data-open:animate-in data-closed:animate-out data-closed:fade-out-0 data-open:fade-in-0 data-closed:zoom-out-95 data-open:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 ring-foreground/10 min-w-36 rounded-none shadow-md ring-1 duration-100;
1218
+ }
1219
+
1220
+ .cn-select-group {
1221
+ @apply scroll-my-1;
1222
+ }
1223
+
1224
+ .cn-select-value {
1225
+ @apply flex flex-1 text-left;
1226
+ }
1227
+
1228
+ .cn-select-item-text {
1229
+ @apply flex flex-1 gap-2;
1230
+ }
1231
+
1232
+ .cn-select-scroll-up-button {
1233
+ @apply bg-popover z-10 flex cursor-default items-center justify-center py-1 [&_svg:not([class*='size-'])]:size-4;
1234
+ }
1235
+
1236
+ .cn-select-scroll-down-button {
1237
+ @apply bg-popover z-10 flex cursor-default items-center justify-center py-1 [&_svg:not([class*='size-'])]:size-4;
1238
+ }
1239
+
1240
+ .cn-select-viewport {
1241
+ @apply p-1 scroll-my-1;
1242
+ }
1243
+
1244
+ .cn-select-item {
1245
+ @apply focus:bg-accent focus:text-accent-foreground not-data-[variant=destructive]:focus:**:text-accent-foreground gap-2 rounded-none py-2 pr-8 pl-2 text-xs [&_svg:not([class*='size-'])]:size-4 *:[span]:last:flex *:[span]:last:items-center *:[span]:last:gap-2;
1246
+ }
1247
+
1248
+ .cn-select-label {
1249
+ @apply text-muted-foreground px-2 py-2 text-xs;
1250
+ }
1251
+
1252
+ .cn-select-separator {
1253
+ @apply bg-border -mx-1 h-px;
1254
+ }
1255
+
1256
+ .cn-select-item-indicator {
1257
+ @apply pointer-events-none absolute right-2 flex size-4 items-center justify-center;
1258
+ }
1259
+
1260
+ /* MARK: Sheet */
1261
+ /* w-full lives here so the sides' w-3/4 can beat it in-layer (split-side
1262
+ * rule) - a latent full-width regression the visual gate cannot see on a
1263
+ * closed dialog. */
1264
+ .cn-sheet-content {
1265
+ @apply m-0 w-full bg-popover text-popover-foreground text-xs/relaxed bg-clip-padding shadow-lg transition duration-200 ease-in-out data-open:animate-in data-closed:animate-out backdrop:bg-black/10 supports-backdrop-filter:backdrop:backdrop-blur-xs;
1266
+ }
1267
+
1268
+ .cn-sheet-side-top {
1269
+ @apply bottom-auto mb-auto h-auto w-full max-w-none border-b data-open:slide-in-from-top data-closed:slide-out-to-top;
1270
+ }
1271
+
1272
+ .cn-sheet-side-right {
1273
+ @apply ml-auto h-full max-h-none w-3/4 border-l data-open:slide-in-from-right data-closed:slide-out-to-right sm:max-w-sm;
1274
+ }
1275
+
1276
+ .cn-sheet-side-bottom {
1277
+ @apply top-auto mt-auto h-auto w-full max-w-none border-t data-open:slide-in-from-bottom data-closed:slide-out-to-bottom;
1278
+ }
1279
+
1280
+ .cn-sheet-side-left {
1281
+ @apply mr-auto h-full max-h-none w-3/4 border-r data-open:slide-in-from-left data-closed:slide-out-to-left sm:max-w-sm;
1282
+ }
1283
+
1284
+ .cn-sheet-header {
1285
+ @apply gap-0.5 p-4;
1286
+ }
1287
+
1288
+ .cn-sheet-title {
1289
+ @apply text-foreground text-sm font-medium;
1290
+ }
1291
+
1292
+ .cn-sheet-description {
1293
+ @apply text-muted-foreground text-xs/relaxed;
1294
+ }
1295
+
1296
+ .cn-sheet-footer {
1297
+ @apply gap-2 p-4;
1298
+ }
1299
+
1300
+ .cn-sheet-close {
1301
+ @apply absolute top-3 right-3;
1302
+ }
1303
+
1304
+ /* MARK: SensitiveInput */
1305
+ /* The masked MASK OVERLAY is the focusable reveal button (the
1306
+ * group would trip axe nested-interactive around the inert input) - the
1307
+ * bordered group wears the ring when the mask inside holds focus. */
1308
+ .cn-sensitive-input-group:has([data-slot=sensitive-input-mask]:focus-visible) {
1309
+ @apply outline-none border-ring ring-ring/50 ring-1;
1310
+ }
1311
+
1312
+ /* MARK: Sidebar */
1313
+ .cn-sidebar-mobile {
1314
+ @apply bg-sidebar p-0 text-sidebar-foreground shadow-lg transition duration-200 ease-in-out data-open:animate-in data-closed:animate-out backdrop:bg-black/10 supports-backdrop-filter:backdrop:backdrop-blur-xs;
1315
+ }
1316
+
1317
+ .cn-sidebar-mobile-left {
1318
+ @apply border-r data-open:slide-in-from-left data-closed:slide-out-to-left;
1319
+ }
1320
+
1321
+ .cn-sidebar-mobile-right {
1322
+ @apply border-l data-open:slide-in-from-right data-closed:slide-out-to-right;
1323
+ }
1324
+
1325
+ .cn-sidebar-inner {
1326
+ @apply bg-sidebar group-data-[variant=floating]:ring-sidebar-border group-data-[variant=floating]:rounded-none group-data-[variant=floating]:shadow-sm group-data-[variant=floating]:ring-1;
1327
+ }
1328
+
1329
+ .cn-sidebar-header {
1330
+ @apply gap-2 p-2;
1331
+ }
1332
+
1333
+ .cn-sidebar-footer {
1334
+ @apply gap-2 p-2;
1335
+ }
1336
+
1337
+ .cn-sidebar-separator {
1338
+ @apply mx-2 bg-sidebar-border;
1339
+ }
1340
+
1341
+ .cn-sidebar-content {
1342
+ @apply gap-0;
1343
+ }
1344
+
1345
+ .cn-sidebar-gap {
1346
+ @apply transition-[width] duration-200 ease-linear;
1347
+ }
1348
+
1349
+ .cn-sidebar-rail {
1350
+ @apply hover:after:bg-sidebar-border;
1351
+ }
1352
+
1353
+ .cn-sidebar-inset {
1354
+ @apply bg-background md:peer-data-[variant=inset]:m-2 md:peer-data-[variant=inset]:ml-0 md:peer-data-[variant=inset]:rounded-none md:peer-data-[variant=inset]:shadow-sm md:peer-data-[variant=inset]:peer-data-[state=collapsed]:ml-2;
1355
+ }
1356
+
1357
+ .cn-sidebar-group {
1358
+ @apply p-2;
1359
+ }
1360
+
1361
+ .cn-sidebar-group-label {
1362
+ @apply text-sidebar-foreground/70 ring-sidebar-ring h-8 rounded-none px-2 text-xs transition-[margin,opacity] duration-200 ease-linear group-data-[collapsible=icon]:-mt-8 group-data-[collapsible=icon]:opacity-0 focus-visible:ring-2 [&>svg]:size-4;
1363
+ }
1364
+
1365
+ .cn-sidebar-group-content {
1366
+ @apply text-xs;
1367
+ }
1368
+
1369
+ .cn-sidebar-menu {
1370
+ @apply gap-0;
1371
+ }
1372
+
1373
+ .cn-sidebar-menu-button {
1374
+ @apply ring-sidebar-ring hover:bg-sidebar-accent hover:text-sidebar-accent-foreground active:bg-sidebar-accent active:text-sidebar-accent-foreground data-active:bg-sidebar-accent data-active:text-sidebar-accent-foreground data-open:hover:bg-sidebar-accent data-open:hover:text-sidebar-accent-foreground gap-2 rounded-none p-2 text-left text-xs transition-[width,height,padding] group-has-data-[sidebar=menu-action]/menu-item:pr-8 group-data-[collapsible=icon]:size-8! group-data-[collapsible=icon]:p-2! focus-visible:ring-2 data-active:font-medium [&_svg]:size-4;
1375
+ }
1376
+
1377
+ .cn-sidebar-input {
1378
+ @apply bg-background h-8 w-full shadow-none;
1379
+ }
1380
+
1381
+ .cn-sidebar-group-action {
1382
+ @apply text-sidebar-foreground ring-sidebar-ring hover:bg-sidebar-accent hover:text-sidebar-accent-foreground absolute top-3.5 right-3 w-5 rounded-none p-0 focus-visible:ring-2 [&>svg]:size-4;
1383
+ }
1384
+
1385
+ .cn-sidebar-menu-button-variant-default {
1386
+ @apply hover:bg-sidebar-accent hover:text-sidebar-accent-foreground;
1387
+ }
1388
+
1389
+ .cn-sidebar-menu-button-variant-outline {
1390
+ @apply bg-background hover:bg-sidebar-accent hover:text-sidebar-accent-foreground shadow-[0_0_0_1px_var(--sidebar-border)] hover:shadow-[0_0_0_1px_var(--sidebar-accent)];
1391
+ }
1392
+
1393
+ .cn-sidebar-menu-skeleton {
1394
+ @apply h-8 gap-2 rounded-none px-2;
1395
+ }
1396
+
1397
+ .cn-sidebar-menu-skeleton-icon {
1398
+ @apply size-4 rounded-none;
1399
+ }
1400
+
1401
+ .cn-sidebar-menu-skeleton-text {
1402
+ @apply h-4;
1403
+ }
1404
+
1405
+ .cn-sidebar-menu-button-size-default {
1406
+ @apply h-8 text-xs;
1407
+ }
1408
+
1409
+ .cn-sidebar-menu-button-size-sm {
1410
+ @apply h-7 text-xs;
1411
+ }
1412
+
1413
+ .cn-sidebar-menu-button-size-lg {
1414
+ @apply h-12 text-xs group-data-[collapsible=icon]:p-0!;
1415
+ }
1416
+
1417
+ .cn-sidebar-menu-action {
1418
+ @apply text-sidebar-foreground ring-sidebar-ring hover:bg-sidebar-accent hover:text-sidebar-accent-foreground peer-hover/menu-button:text-sidebar-accent-foreground w-5 rounded-none p-0 peer-data-[size=default]/menu-button:top-1.5 peer-data-[size=lg]/menu-button:top-2.5 peer-data-[size=sm]/menu-button:top-1 focus-visible:ring-2 [&>svg]:size-4;
1419
+ }
1420
+
1421
+ .cn-sidebar-menu-badge {
1422
+ @apply text-sidebar-foreground peer-hover/menu-button:text-sidebar-accent-foreground peer-data-active/menu-button:text-sidebar-accent-foreground h-5 min-w-5 rounded-none px-1 text-xs font-medium peer-data-[size=default]/menu-button:top-1.5 peer-data-[size=lg]/menu-button:top-2.5 peer-data-[size=sm]/menu-button:top-1;
1423
+ }
1424
+
1425
+ .cn-sidebar-menu-sub {
1426
+ @apply border-sidebar-border gap-1 border-l px-2.5 py-0.5 group-data-[collapsible=icon]:hidden;
1427
+ }
1428
+
1429
+ .cn-sidebar-menu-sub-button {
1430
+ @apply text-sidebar-foreground ring-sidebar-ring hover:bg-sidebar-accent hover:text-sidebar-accent-foreground active:bg-sidebar-accent active:text-sidebar-accent-foreground [&>svg]:text-sidebar-accent-foreground data-active:bg-sidebar-accent data-active:text-sidebar-accent-foreground h-7 gap-2 rounded-none px-2 focus-visible:ring-2 data-[size=md]:text-xs data-[size=sm]:text-xs [&>svg]:size-4;
1431
+ }
1432
+
1433
+ /* MARK: Skeleton */
1434
+ .cn-skeleton {
1435
+ @apply bg-muted rounded-none;
1436
+ }
1437
+
1438
+ /* MARK: Slider */
1439
+ .cn-slider {
1440
+ @apply data-[orientation=vertical]:min-h-40;
1441
+ }
1442
+
1443
+ .cn-slider-track {
1444
+ @apply bg-muted rounded-none data-[orientation=horizontal]:h-1 data-[orientation=horizontal]:w-full data-[orientation=vertical]:h-full data-[orientation=vertical]:w-1;
1445
+ }
1446
+
1447
+ .cn-slider-range {
1448
+ @apply bg-primary;
1449
+ }
1450
+
1451
+ .cn-slider-thumb {
1452
+ @apply border-ring ring-ring/50 relative size-3 rounded-none border bg-white transition-[color,box-shadow] after:absolute after:-inset-2 hover:ring-1 focus-visible:ring-1 focus-visible:outline-hidden active:ring-1;
1453
+ }
1454
+
1455
+ /* MARK: Switch */
1456
+ .cn-switch {
1457
+ @apply data-checked:bg-primary data-unchecked:bg-input focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 dark:data-unchecked:bg-input/80 shrink-0 rounded-full border border-transparent focus-visible:ring-1 aria-invalid:ring-1 data-[size=default]:h-[18.4px] data-[size=default]:w-[32px] data-[size=sm]:h-[14px] data-[size=sm]:w-[24px] group-has-[:focus-visible]/field-label:border-transparent group-has-[:focus-visible]/field-label:ring-0;
1458
+ }
1459
+
1460
+ .cn-switch-thumb {
1461
+ @apply rounded-full bg-background group-data-[size=default]/switch:size-4 group-data-[size=sm]/switch:size-3 data-checked:translate-x-[calc(100%-2px)] data-unchecked:translate-x-0 rtl:data-checked:-translate-x-[calc(100%-2px)] dark:data-checked:bg-primary-foreground dark:data-unchecked:bg-foreground;
1462
+ }
1463
+
1464
+ /* MARK: Table */
1465
+ .cn-table {
1466
+ @apply w-full caption-bottom text-xs;
1467
+ }
1468
+
1469
+ .cn-table-container {
1470
+ @apply relative w-full overflow-x-auto;
1471
+ }
1472
+
1473
+ .cn-table-header {
1474
+ @apply [&_tr]:border-b;
1475
+ }
1476
+
1477
+ .cn-table-body {
1478
+ @apply [&_tr:last-child]:border-0;
1479
+ }
1480
+
1481
+ .cn-table-footer {
1482
+ @apply border-t bg-muted/50 font-medium [&>tr]:last:border-b-0;
1483
+ }
1484
+
1485
+ .cn-table-row {
1486
+ @apply border-b transition-colors hover:bg-muted/50 has-aria-expanded:bg-muted/50 data-selected:bg-muted;
1487
+ }
1488
+
1489
+ .cn-table-head {
1490
+ @apply h-10 px-2 text-left align-middle font-medium whitespace-nowrap text-foreground [&:has([role=checkbox])]:pr-0;
1491
+ }
1492
+
1493
+ .cn-table-cell {
1494
+ @apply p-2 align-middle whitespace-nowrap [&:has([role=checkbox])]:pr-0;
1495
+ }
1496
+
1497
+ .cn-table-caption {
1498
+ @apply text-muted-foreground mt-4 text-xs;
1499
+ }
1500
+
1501
+ /* MARK: Tabs */
1502
+ .cn-tabs {
1503
+ @apply gap-2;
1504
+ }
1505
+
1506
+ .cn-tabs-list {
1507
+ @apply rounded-none p-[3px] group-data-horizontal/tabs:h-8 data-[variant=line]:rounded-none;
1508
+ }
1509
+
1510
+ .cn-tabs-list-variant-default {
1511
+ @apply bg-muted;
1512
+ }
1513
+
1514
+ .cn-tabs-list-variant-line {
1515
+ @apply gap-1 bg-transparent;
1516
+ }
1517
+
1518
+ /* The whole text-color cluster lives here (split-side rule): the base
1519
+ * dims (text-foreground/60, dark:text-muted-foreground) must lose to the
1520
+ * data-active colors, which they only can in-layer. */
1521
+ .cn-tabs-trigger {
1522
+ @apply gap-1.5 rounded-none border border-transparent px-1.5 py-0.5 text-xs font-medium text-foreground/60 hover:text-foreground has-data-[icon=inline-end]:pr-1 has-data-[icon=inline-start]:pl-1 dark:text-muted-foreground dark:hover:text-foreground group-data-[variant=line]/tabs-list:data-active:shadow-none [&_svg:not([class*='size-'])]:size-4 group-data-[variant=line]/tabs-list:bg-transparent group-data-[variant=line]/tabs-list:data-active:bg-transparent dark:group-data-[variant=line]/tabs-list:data-active:border-transparent dark:group-data-[variant=line]/tabs-list:data-active:bg-transparent data-active:bg-background data-active:text-foreground dark:data-active:border-input dark:data-active:bg-input/30 dark:data-active:text-foreground after:bg-foreground group-data-horizontal/tabs:after:inset-x-0 group-data-horizontal/tabs:after:bottom-[-5px] group-data-horizontal/tabs:after:h-0.5 group-data-vertical/tabs:after:inset-y-0 group-data-vertical/tabs:after:-right-1 group-data-vertical/tabs:after:w-0.5 group-data-[variant=line]/tabs-list:data-active:after:opacity-100 group-data-vertical/tabs:py-[calc(--spacing(1.25))];
1523
+ }
1524
+
1525
+ .cn-tabs-content {
1526
+ @apply text-xs/relaxed;
1527
+ }
1528
+
1529
+ /* MARK: Textarea */
1530
+ .cn-textarea {
1531
+ @apply border-input dark:bg-input/30 focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 disabled:bg-input/50 dark:disabled:bg-input/80 rounded-none border bg-transparent px-2.5 py-2 text-xs transition-colors focus-visible:ring-1 aria-invalid:ring-1 md:text-xs placeholder:text-muted-foreground;
1532
+ }
1533
+
1534
+ /* MARK: Toast */
1535
+ .cn-toast {
1536
+ @apply gap-3 rounded-none border bg-popover p-4 text-popover-foreground shadow-lg data-open:animate-in data-open:fade-in-0 data-open:slide-in-from-bottom-2 group-data-[position^=top]/toaster:data-open:slide-in-from-top-2 data-closed:animate-out data-closed:fade-out-80 data-closed:slide-out-to-bottom-2 group-data-[position^=top]/toaster:data-closed:slide-out-to-top-2;
1537
+ }
1538
+
1539
+ .cn-toast-variant-success {
1540
+ @apply [&_[data-slot=toast-icon]]:text-primary;
1541
+ }
1542
+
1543
+ .cn-toast-variant-info {
1544
+ @apply [&_[data-slot=toast-icon]]:text-muted-foreground;
1545
+ }
1546
+
1547
+ .cn-toast-variant-warning {
1548
+ @apply [&_[data-slot=toast-icon]]:text-primary;
1549
+ }
1550
+
1551
+ .cn-toast-variant-destructive {
1552
+ @apply text-destructive [&_[data-slot=toast-icon]]:text-destructive;
1553
+ }
1554
+
1555
+ .cn-toast-icon {
1556
+ @apply mt-0.5 size-4 [&_svg]:size-4;
1557
+ }
1558
+
1559
+ .cn-toast-body {
1560
+ @apply gap-1;
1561
+ }
1562
+
1563
+ .cn-toast-title {
1564
+ @apply text-sm font-medium;
1565
+ }
1566
+
1567
+ .cn-toast-description {
1568
+ @apply text-sm text-muted-foreground;
1569
+ }
1570
+
1571
+ /* MARK: Toaster */
1572
+ /* max-w-full lives here WITH its sm: cap (the split-side rule extends to
1573
+ * responsive pairs: a bare utility would beat the themed breakpoint
1574
+ * override from the utilities layer at every width). */
1575
+ .cn-toaster {
1576
+ @apply max-w-full gap-2 p-4 sm:max-w-[420px];
1577
+ }
1578
+
1579
+ /* MARK: Toggle */
1580
+ /* hover:bg-muted lives HERE (not inline, where upstream keeps it): the
1581
+ * outline variant's hover:bg-accent must beat it, and it only can when
1582
+ * both sides share the base layer (in-layer order = the merger's old
1583
+ * last-wins). An inline utility would win the cascade unconditionally. */
1584
+ .cn-toggle {
1585
+ @apply hover:text-foreground aria-pressed:bg-muted focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive data-pressed:bg-muted gap-1 rounded-none text-xs font-medium transition-all [&_svg:not([class*='size-'])]:size-4;
1586
+ }
1587
+
1588
+ .cn-toggle-variant-default {
1589
+ @apply bg-transparent;
1590
+ }
1591
+
1592
+ .cn-toggle-variant-outline {
1593
+ @apply border-input hover:bg-muted border bg-transparent;
1594
+ }
1595
+
1596
+ .cn-toggle-size-default {
1597
+ @apply h-8 min-w-8 px-2.5 has-data-[icon=inline-end]:pr-2 has-data-[icon=inline-start]:pl-2 has-[>svg:first-child]:pl-2 has-[>svg:last-child]:pr-2;
1598
+ }
1599
+
1600
+ .cn-toggle-size-sm {
1601
+ @apply h-7 min-w-7 rounded-none px-2.5 has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 has-[>svg:first-child]:pl-1.5 has-[>svg:last-child]:pr-1.5;
1602
+ }
1603
+
1604
+ .cn-toggle-size-lg {
1605
+ @apply h-9 min-w-9 px-2.5 has-data-[icon=inline-end]:pr-2 has-data-[icon=inline-start]:pl-2 has-[>svg:first-child]:pl-2 has-[>svg:last-child]:pr-2;
1606
+ }
1607
+
1608
+ /* MARK: ToggleGroup */
1609
+ .cn-toggle-group {
1610
+ @apply rounded-none data-[size=sm]:rounded-none;
1611
+ }
1612
+
1613
+ /* Segmented edge radii live theme-side (side-move): each theme
1614
+ * rounds spacing=0 segments in its own radius language. */
1615
+ .cn-toggle-group-item {
1616
+ @apply group-data-[spacing=0]/toggle-group:rounded-none group-data-[spacing=0]/toggle-group:px-2 group-data-[spacing=0]/toggle-group:has-data-[icon=inline-end]:pr-1.5 group-data-[spacing=0]/toggle-group:has-data-[icon=inline-start]:pl-1.5 group-data-horizontal/toggle-group:data-[spacing=0]:first:rounded-none group-data-vertical/toggle-group:data-[spacing=0]:first:rounded-none group-data-horizontal/toggle-group:data-[spacing=0]:last:rounded-none group-data-vertical/toggle-group:data-[spacing=0]:last:rounded-none;
1617
+ }
1618
+
1619
+ /* MARK: Tooltip */
1620
+ .cn-tooltip-content {
1621
+ @apply data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-[state=delayed-open]:animate-in data-[state=delayed-open]:fade-in-0 data-[state=delayed-open]:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 inline-flex items-center gap-1.5 rounded-none px-3 py-1.5 text-xs has-data-[slot=kbd]:pr-1.5 **:data-[slot=kbd]:relative **:data-[slot=kbd]:isolate **:data-[slot=kbd]:z-50 **:data-[slot=kbd]:rounded-none;
1622
+ }
1623
+
1624
+ .cn-tooltip-arrow {
1625
+ @apply size-2.5 translate-y-[calc(-50%-2px)] rounded-none;
1626
+ }
1627
+
1628
+ /* MARK: Consumer utilities
1629
+ * Standalone cn-* classes templates and consumers apply directly (they
1630
+ * ride the css:verify_theme allowlist - no dictionary emits cn-rtl-flip).
1631
+ * cn-font-heading: upstream globals (@apply font-heading); poetry inlines
1632
+ * the var with a sans fallback so it is a no-op until a theme defines
1633
+ * --font-heading. cn-rtl-flip: upstream ships the NAME with no rule
1634
+ * anywhere (dead in source); poetry authors the intended RTL mirror. */
1635
+ .cn-font-heading {
1636
+ font-family: var(--font-heading, var(--font-sans));
1637
+ }
1638
+
1639
+ .cn-rtl-flip {
1640
+ @apply rtl:-scale-x-100;
1641
+ }
1642
+
1643
+ /* MARK: Cross-component overrides
1644
+ * Rules that restyle ANOTHER component's cn surface must come after every
1645
+ * rule they override - in-layer order is what lets an override win, so
1646
+ * alphabetical placement would silently lose (cn-input-group-textarea vs
1647
+ * the later cn-textarea). Keep every such rule in this closing section. */
1648
+ .cn-input-group-input {
1649
+ @apply rounded-none border-0 bg-transparent shadow-none ring-0 focus-visible:ring-0 disabled:bg-transparent aria-invalid:ring-0 dark:bg-transparent dark:disabled:bg-transparent;
1650
+ }
1651
+
1652
+ .cn-input-group-textarea {
1653
+ @apply rounded-none border-0 bg-transparent py-2 shadow-none ring-0 focus-visible:ring-0 disabled:bg-transparent aria-invalid:ring-0 dark:bg-transparent dark:disabled:bg-transparent;
1654
+ }
1655
+
1656
+ .cn-input-group-button {
1657
+ @apply gap-2 text-xs;
1658
+ }
1659
+
1660
+ .cn-input-group-button-size-xs {
1661
+ @apply h-6 gap-1 rounded-none px-1.5 [&>svg:not([class*='size-'])]:size-3.5;
1662
+ }
1663
+
1664
+ .cn-input-group-button-size-icon-xs {
1665
+ @apply size-6 rounded-none p-0 has-[>svg]:p-0;
1666
+ }
1667
+
1668
+ .cn-input-group-button-size-icon-sm {
1669
+ @apply size-7 p-0 has-[>svg]:p-0;
1670
+ }
1671
+
1672
+ /* CommandDialog re-tunes the Dialog panel (p-0 must beat cn-dialog-content's p-6). */
1673
+ .cn-command-dialog {
1674
+ @apply rounded-none;
1675
+ }
1676
+
1677
+ /* MARK: Stat */
1678
+ .cn-stat-delta-positive {
1679
+ @apply text-[oklch(from_var(--success)_calc(l*0.85)_c_h)] dark:text-success;
1680
+ }
1681
+
1682
+ /* MARK: Questionnaire */
1683
+ .cn-questionnaire {
1684
+ @apply gap-4;
1685
+ }
1686
+
1687
+ .cn-questionnaire-progress {
1688
+ @apply text-xs;
1689
+ }
1690
+
1691
+ .cn-questionnaire-item {
1692
+ @apply flex flex-col gap-4;
1693
+ }
1694
+
1695
+ .cn-questionnaire-title {
1696
+ @apply text-sm font-medium [&:not(:has(~[data-slot=questionnaire-description]))]:mb-4;
1697
+ }
1698
+
1699
+ .cn-questionnaire-description {
1700
+ @apply text-xs/relaxed;
1701
+ }
1702
+
1703
+ .cn-questionnaire-choices {
1704
+ @apply gap-2;
1705
+ }
1706
+
1707
+ .cn-questionnaire-choice {
1708
+ @apply border-input hover:bg-muted/50 data-checked:bg-muted data-checked:border-foreground/30 in-data-invalid:border-destructive has-[>input:focus-visible]:border-ring has-[>input:focus-visible]:ring-ring/50 gap-2.5 rounded-none border bg-transparent px-3 py-2.5 text-xs has-[>input:focus-visible]:ring-1;
1709
+ }
1710
+
1711
+ .cn-questionnaire-choice-indicator {
1712
+ @apply border-input group-data-checked/questionnaire-choice:bg-primary group-data-checked/questionnaire-choice:text-primary-foreground group-data-checked/questionnaire-choice:border-primary size-4 rounded-none;
1713
+ }
1714
+
1715
+ .cn-questionnaire-choice-indicator-dot {
1716
+ @apply bg-primary-foreground size-2;
1717
+ }
1718
+
1719
+ .cn-questionnaire-choice-indicator-check {
1720
+ @apply size-3.5;
1721
+ }
1722
+
1723
+ .cn-questionnaire-choice-content {
1724
+ @apply gap-0.5;
1725
+ }
1726
+
1727
+ .cn-questionnaire-choice-description {
1728
+ @apply text-muted-foreground;
1729
+ }
1730
+
1731
+ .cn-questionnaire-shortcut {
1732
+ @apply border-input bg-background text-muted-foreground size-4 translate-y-[--spacing(0.45)] group-has-data-[slot=questionnaire-choice-description]/questionnaire-choice:translate-y-0.5 items-center justify-center rounded-none border font-mono text-[0.625rem] font-medium leading-none;
1733
+ }
1734
+
1735
+ .cn-questionnaire-input-wrapper {
1736
+ @apply w-full;
1737
+ }
1738
+
1739
+ .cn-questionnaire-input {
1740
+ @apply dark:bg-input/30 border-input focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 disabled:bg-input/50 dark:disabled:bg-input/80 h-8 rounded-none border bg-transparent px-2.5 py-1 text-xs focus-visible:ring-1 aria-invalid:ring-1 md:text-xs;
1741
+ }
1742
+
1743
+ .cn-questionnaire-error {
1744
+ @apply mt-2 text-xs;
1745
+ }
1746
+
1747
+ .cn-questionnaire-actions {
1748
+ @apply gap-1.5 sm:min-h-8;
1749
+ }
1750
+
1751
+ /* MARK: WebMCP agent focus (declarative tools) - the browser marks the
1752
+ form an agent is filling and its submit; :where() keeps the rule
1753
+ forgiving in browsers that lack the pseudo-classes. */
1754
+ :where(form:tool-form-active) {
1755
+ @apply rounded-lg outline-2 outline-dashed outline-offset-4 outline-ring/60;
1756
+ }
1757
+
1758
+ :where(:tool-submit-active) {
1759
+ @apply border-ring ring-3 ring-ring/50;
1760
+ }
1761
+
1762
+ /* MARK: Menu translucent (shared, LAST - wins the content bg cascade).
1763
+ Upstream style-lyra.css:1426 ships this rule WITHOUT its trailing
1764
+ semicolon (the ledgered parse quirk) - transcribed here with the
1765
+ semicolon restored; body is byte-identical otherwise. */
1766
+ .cn-menu-translucent {
1767
+ @apply animate-none! relative bg-popover/70 before:pointer-events-none before:absolute before:inset-0 before:-z-1 before:rounded-[inherit] before:backdrop-blur-2xl before:backdrop-saturate-150 **:data-[slot$=-item]:focus:bg-foreground/10 **:data-[slot$=-item]:data-highlighted:bg-foreground/10 **:data-[slot$=-separator]:bg-foreground/5 **:data-[slot$=-trigger]:focus:bg-foreground/10 **:data-[slot$=-trigger]:aria-expanded:bg-foreground/10! **:data-[variant=destructive]:focus:bg-foreground/10! **:data-[variant=destructive]:text-accent-foreground! **:data-[variant=destructive]:**:text-accent-foreground!;
1768
+ }