defuss-shadcn 0.7.19 → 0.8.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 (458) hide show
  1. package/AGENTS.md +28 -3
  2. package/ARCH.md +22 -6
  3. package/Makefile +4 -1
  4. package/README.md +6 -3
  5. package/bun.lock +3 -0
  6. package/dist/SKILL.md +118 -1
  7. package/dist/SKILL_tpl.md +1 -1
  8. package/dist/architecture_tpl.html +153 -0
  9. package/dist/components/accordion/accordion.css +12 -5
  10. package/dist/components/accordion/accordion.js +16 -0
  11. package/dist/components/accordion/component-skill.md +1 -0
  12. package/dist/components/alert-dialog/alert-dialog.css +8 -0
  13. package/dist/components/alert-dialog/component-skill.md +1 -0
  14. package/dist/components/blog/blog.css +122 -0
  15. package/dist/components/blog/component-skill.md +85 -0
  16. package/dist/components/brand-logos/brand-logos.css +74 -0
  17. package/dist/components/brand-logos/component-skill.md +58 -0
  18. package/dist/components/checkbox/checkbox.css +9 -0
  19. package/dist/components/collapsible/collapsible.css +11 -3
  20. package/dist/components/combobox/combobox.css +40 -0
  21. package/dist/components/combobox/combobox.js +24 -0
  22. package/dist/components/combobox/component-skill.md +2 -0
  23. package/dist/components/command/command.css +11 -0
  24. package/dist/components/command/component-skill.md +1 -0
  25. package/dist/components/dialog/component-skill.md +1 -0
  26. package/dist/components/dialog/dialog.css +12 -0
  27. package/dist/components/faq/component-skill.md +67 -0
  28. package/dist/components/faq/faq.css +88 -0
  29. package/dist/components/feature-details/component-skill.md +83 -0
  30. package/dist/components/feature-details/feature-details.css +130 -0
  31. package/dist/components/get-in-touch/component-skill.md +63 -0
  32. package/dist/components/get-in-touch/get-in-touch.css +74 -0
  33. package/dist/components/hero/component-skill.md +55 -0
  34. package/dist/components/hero/hero.css +63 -0
  35. package/dist/components/image/component-skill.md +1 -0
  36. package/dist/components/image/image.css +8 -0
  37. package/dist/components/navigation-menu/navigation-menu.js +22 -20
  38. package/dist/components/newsletter/component-skill.md +62 -0
  39. package/dist/components/newsletter/newsletter.css +65 -0
  40. package/dist/components/popover/popover.js +6 -1
  41. package/dist/components/pricing/component-skill.md +107 -0
  42. package/dist/components/pricing/pricing.css +171 -0
  43. package/dist/components/product-showcase/component-skill.md +89 -0
  44. package/dist/components/product-showcase/product-showcase.css +79 -0
  45. package/dist/components/product-showcase/product-showcase.js +127 -0
  46. package/dist/components/sheet/component-skill.md +1 -0
  47. package/dist/components/sheet/sheet.css +8 -0
  48. package/dist/components/sidebar/component-skill.md +1 -1
  49. package/dist/components/sidebar/sidebar.css +8 -0
  50. package/dist/components/site-footer/component-skill.md +80 -0
  51. package/dist/components/site-footer/site-footer.css +104 -0
  52. package/dist/components/site-header/component-skill.md +96 -0
  53. package/dist/components/site-header/site-header.css +73 -0
  54. package/dist/components/stats/component-skill.md +68 -0
  55. package/dist/components/stats/stats.css +88 -0
  56. package/dist/components/testimonials/component-skill.md +79 -0
  57. package/dist/components/testimonials/testimonials.css +129 -0
  58. package/dist/components/tree-view/tree-view.css +11 -3
  59. package/dist/components/typography/component-skill.md +2 -2
  60. package/dist/components/typography/typography.css +3 -3
  61. package/dist/documentation/accessibility.html +15 -2
  62. package/dist/documentation/accordion.html +42 -163
  63. package/dist/documentation/alert-dialog.html +25 -48
  64. package/dist/documentation/alert.html +15 -59
  65. package/dist/documentation/animations.html +15 -2
  66. package/dist/documentation/architecture.html +210 -0
  67. package/dist/documentation/avatar.html +15 -62
  68. package/dist/documentation/badge.html +15 -43
  69. package/dist/documentation/blog.html +431 -0
  70. package/dist/documentation/brand-logos.html +296 -0
  71. package/dist/documentation/breadcrumb.html +15 -114
  72. package/dist/documentation/button-group.html +15 -70
  73. package/dist/documentation/button.html +16 -86
  74. package/dist/documentation/calendar.html +15 -63
  75. package/dist/documentation/card.html +15 -124
  76. package/dist/documentation/carousel.html +15 -156
  77. package/dist/documentation/cascade-layers.html +15 -2
  78. package/dist/documentation/changelog.html +63 -2
  79. package/dist/documentation/checkbox.html +24 -103
  80. package/dist/documentation/collapsible.html +26 -38
  81. package/dist/documentation/color-picker.html +15 -32
  82. package/dist/documentation/combobox.html +83 -158
  83. package/dist/documentation/command.html +30 -95
  84. package/dist/documentation/component-skills.html +15 -2
  85. package/dist/documentation/context-menu.html +15 -24
  86. package/dist/documentation/css/docs-utilities.css +1 -0
  87. package/dist/documentation/css/layout.css +75 -36
  88. package/dist/documentation/dark-mode.html +15 -2
  89. package/dist/documentation/data-attribute-api.html +15 -2
  90. package/dist/documentation/date-picker.html +15 -43
  91. package/dist/documentation/dialog.html +28 -102
  92. package/dist/documentation/dropdown.html +15 -153
  93. package/dist/documentation/es-modules.html +15 -2
  94. package/dist/documentation/faq.html +361 -0
  95. package/dist/documentation/feature-details.html +430 -0
  96. package/dist/documentation/file-input.html +15 -40
  97. package/dist/documentation/form.html +15 -137
  98. package/dist/documentation/get-in-touch.html +294 -0
  99. package/dist/documentation/hero.html +283 -0
  100. package/dist/documentation/icon.html +15 -162
  101. package/dist/documentation/image.html +27 -175
  102. package/dist/documentation/images/mk-portrait.png +0 -0
  103. package/dist/documentation/images/mk-portrait2.png +0 -0
  104. package/dist/documentation/images/mk-square.png +0 -0
  105. package/dist/documentation/images/mk-wide.png +0 -0
  106. package/dist/documentation/images/mk-wide2.png +0 -0
  107. package/dist/documentation/images/mk-wide3.png +0 -0
  108. package/dist/documentation/index.html +17 -4
  109. package/dist/documentation/input.html +15 -140
  110. package/dist/documentation/installation.html +15 -2
  111. package/dist/documentation/js/layout.js +157 -10
  112. package/dist/documentation/js/search-index.js +1 -1
  113. package/dist/documentation/js/site.js +74 -72
  114. package/dist/documentation/label.html +15 -101
  115. package/dist/documentation/native-web-apis.html +15 -2
  116. package/dist/documentation/navigation-menu.html +24 -86
  117. package/dist/documentation/newsletter.html +305 -0
  118. package/dist/documentation/number-input.html +15 -30
  119. package/dist/documentation/pagination.html +15 -112
  120. package/dist/documentation/popover.html +21 -82
  121. package/dist/documentation/pricing.html +550 -0
  122. package/dist/documentation/product-showcase.html +410 -0
  123. package/dist/documentation/progress.html +15 -31
  124. package/dist/documentation/radio.html +15 -143
  125. package/dist/documentation/scroll-area.html +15 -47
  126. package/dist/documentation/select.html +15 -58
  127. package/dist/documentation/separator.html +15 -96
  128. package/dist/documentation/sheet.html +24 -112
  129. package/dist/documentation/sidebar.html +26 -177
  130. package/dist/documentation/site-footer.html +422 -0
  131. package/dist/documentation/site-header.html +382 -0
  132. package/dist/documentation/skeleton.html +15 -37
  133. package/dist/documentation/slider.html +15 -112
  134. package/dist/documentation/sortable.html +15 -126
  135. package/dist/documentation/spinner.html +15 -37
  136. package/dist/documentation/statistic.html +15 -48
  137. package/dist/documentation/stats.html +364 -0
  138. package/dist/documentation/steps.html +15 -186
  139. package/dist/documentation/switch.html +15 -80
  140. package/dist/documentation/table.html +15 -54
  141. package/dist/documentation/tabs.html +15 -143
  142. package/dist/documentation/testimonials.html +417 -0
  143. package/dist/documentation/textarea.html +15 -44
  144. package/dist/documentation/theming.html +15 -2
  145. package/dist/documentation/timeline.html +15 -48
  146. package/dist/documentation/toast.html +15 -114
  147. package/dist/documentation/toggle-group.html +15 -154
  148. package/dist/documentation/toggle.html +15 -90
  149. package/dist/documentation/toolbar.html +15 -71
  150. package/dist/documentation/tooltip.html +15 -99
  151. package/dist/documentation/tree-view.html +26 -55
  152. package/dist/documentation/typography.html +21 -120
  153. package/dist/documentation/videos/demo.mp4 +0 -0
  154. package/dist/documentation/videos/demo.webm +0 -0
  155. package/dist/sitemap.xml +1 -0
  156. package/docs/404.html +340 -0
  157. package/docs/accessibility.html +15 -2
  158. package/docs/accordion.html +42 -163
  159. package/docs/alert-dialog.html +25 -48
  160. package/docs/alert.html +15 -59
  161. package/docs/animations.html +15 -2
  162. package/docs/architecture.html +210 -0
  163. package/docs/avatar.html +15 -62
  164. package/docs/badge.html +15 -43
  165. package/docs/blog.html +431 -0
  166. package/docs/brand-logos.html +296 -0
  167. package/docs/breadcrumb.html +15 -114
  168. package/docs/button-group.html +15 -70
  169. package/docs/button.html +16 -86
  170. package/docs/calendar.html +15 -63
  171. package/docs/card.html +15 -124
  172. package/docs/carousel.html +15 -156
  173. package/docs/cascade-layers.html +15 -2
  174. package/docs/changelog.html +63 -2
  175. package/docs/checkbox.html +24 -103
  176. package/docs/collapsible.html +26 -38
  177. package/docs/color-picker.html +15 -32
  178. package/docs/combobox.html +83 -158
  179. package/docs/command.html +30 -95
  180. package/docs/component-skills.html +15 -2
  181. package/docs/context-menu.html +15 -24
  182. package/docs/css/docs-utilities.css +1 -0
  183. package/docs/css/layout.css +75 -36
  184. package/docs/dark-mode.html +15 -2
  185. package/docs/data-attribute-api.html +15 -2
  186. package/docs/date-picker.html +15 -43
  187. package/docs/dialog.html +28 -102
  188. package/docs/dropdown.html +15 -153
  189. package/docs/es-modules.html +15 -2
  190. package/docs/faq.html +361 -0
  191. package/docs/feature-details.html +430 -0
  192. package/docs/file-input.html +15 -40
  193. package/docs/form.html +15 -137
  194. package/docs/get-in-touch.html +294 -0
  195. package/docs/hero.html +283 -0
  196. package/docs/icon.html +15 -162
  197. package/docs/image.html +27 -175
  198. package/docs/images/mk-portrait.png +0 -0
  199. package/docs/images/mk-portrait2.png +0 -0
  200. package/docs/images/mk-square.png +0 -0
  201. package/docs/images/mk-wide.png +0 -0
  202. package/docs/images/mk-wide2.png +0 -0
  203. package/docs/images/mk-wide3.png +0 -0
  204. package/docs/index.html +17 -4
  205. package/docs/input.html +15 -140
  206. package/docs/installation.html +15 -2
  207. package/docs/js/layout.js +157 -10
  208. package/docs/js/search-index.js +1 -1
  209. package/docs/js/site.js +74 -72
  210. package/docs/label.html +15 -101
  211. package/docs/native-web-apis.html +15 -2
  212. package/docs/navigation-menu.html +24 -86
  213. package/docs/newsletter.html +305 -0
  214. package/docs/number-input.html +15 -30
  215. package/docs/pagination.html +15 -112
  216. package/docs/popover.html +21 -82
  217. package/docs/pricing.html +550 -0
  218. package/docs/product-showcase.html +410 -0
  219. package/docs/progress.html +15 -31
  220. package/docs/radio.html +15 -143
  221. package/docs/scroll-area.html +15 -47
  222. package/docs/select.html +15 -58
  223. package/docs/separator.html +15 -96
  224. package/docs/sheet.html +24 -112
  225. package/docs/sidebar.html +26 -177
  226. package/docs/site-footer.html +422 -0
  227. package/docs/site-header.html +382 -0
  228. package/docs/sitemap.xml +1 -0
  229. package/docs/skeleton.html +15 -37
  230. package/docs/slider.html +15 -112
  231. package/docs/sortable.html +15 -126
  232. package/docs/spinner.html +15 -37
  233. package/docs/statistic.html +15 -48
  234. package/docs/stats.html +364 -0
  235. package/docs/steps.html +15 -186
  236. package/docs/switch.html +15 -80
  237. package/docs/table.html +15 -54
  238. package/docs/tabs.html +15 -143
  239. package/docs/testimonials.html +417 -0
  240. package/docs/textarea.html +15 -44
  241. package/docs/theming.html +15 -2
  242. package/docs/timeline.html +15 -48
  243. package/docs/toast.html +15 -114
  244. package/docs/toggle-group.html +15 -154
  245. package/docs/toggle.html +15 -90
  246. package/docs/toolbar.html +15 -71
  247. package/docs/tooltip.html +15 -99
  248. package/docs/tree-view.html +26 -55
  249. package/docs/typography.html +21 -120
  250. package/docs/videos/demo.mp4 +0 -0
  251. package/docs/videos/demo.webm +0 -0
  252. package/package.json +3 -1
  253. package/scripts/build.ts +6 -0
  254. package/scripts/lib/arch-page.ts +153 -0
  255. package/scripts/lib/changelog.ts +32 -0
  256. package/scripts/lib/mirror.ts +8 -0
  257. package/scripts/purge-cdn.ts +71 -0
  258. package/scripts/sync-docs.ts +1 -2
  259. package/scripts/verify.ts +36 -4
  260. package/src/SKILL.md +118 -1
  261. package/src/SKILL_tpl.md +1 -1
  262. package/src/architecture_tpl.html +153 -0
  263. package/src/components/accordion/accordion.css +12 -5
  264. package/src/components/accordion/accordion.ts +13 -0
  265. package/src/components/accordion/component-skill.md +1 -0
  266. package/src/components/alert-dialog/alert-dialog.css +8 -0
  267. package/src/components/alert-dialog/component-skill.md +1 -0
  268. package/src/components/blog/blog.css +122 -0
  269. package/src/components/blog/component-skill.md +85 -0
  270. package/src/components/brand-logos/brand-logos.css +74 -0
  271. package/src/components/brand-logos/component-skill.md +58 -0
  272. package/src/components/checkbox/checkbox.css +9 -0
  273. package/src/components/collapsible/collapsible.css +11 -3
  274. package/src/components/combobox/combobox.css +40 -0
  275. package/src/components/combobox/combobox.ts +25 -0
  276. package/src/components/combobox/component-skill.md +2 -0
  277. package/src/components/command/command.css +11 -0
  278. package/src/components/command/component-skill.md +1 -0
  279. package/src/components/dialog/component-skill.md +1 -0
  280. package/src/components/dialog/dialog.css +12 -0
  281. package/src/components/faq/component-skill.md +67 -0
  282. package/src/components/faq/faq.css +88 -0
  283. package/src/components/feature-details/component-skill.md +83 -0
  284. package/src/components/feature-details/feature-details.css +130 -0
  285. package/src/components/get-in-touch/component-skill.md +63 -0
  286. package/src/components/get-in-touch/get-in-touch.css +74 -0
  287. package/src/components/hero/component-skill.md +55 -0
  288. package/src/components/hero/hero.css +63 -0
  289. package/src/components/image/component-skill.md +1 -0
  290. package/src/components/image/image.css +8 -0
  291. package/src/components/navigation-menu/navigation-menu.ts +9 -7
  292. package/src/components/newsletter/component-skill.md +62 -0
  293. package/src/components/newsletter/newsletter.css +65 -0
  294. package/src/components/popover/popover.ts +6 -1
  295. package/src/components/pricing/component-skill.md +107 -0
  296. package/src/components/pricing/pricing.css +171 -0
  297. package/src/components/product-showcase/component-skill.md +89 -0
  298. package/src/components/product-showcase/product-showcase.css +79 -0
  299. package/src/components/product-showcase/product-showcase.ts +89 -0
  300. package/src/components/sheet/component-skill.md +1 -0
  301. package/src/components/sheet/sheet.css +8 -0
  302. package/src/components/sidebar/component-skill.md +1 -1
  303. package/src/components/sidebar/sidebar.css +8 -0
  304. package/src/components/site-footer/component-skill.md +80 -0
  305. package/src/components/site-footer/site-footer.css +104 -0
  306. package/src/components/site-header/component-skill.md +96 -0
  307. package/src/components/site-header/site-header.css +73 -0
  308. package/src/components/stats/component-skill.md +68 -0
  309. package/src/components/stats/stats.css +88 -0
  310. package/src/components/testimonials/component-skill.md +79 -0
  311. package/src/components/testimonials/testimonials.css +129 -0
  312. package/src/components/tree-view/tree-view.css +11 -3
  313. package/src/components/typography/component-skill.md +2 -2
  314. package/src/components/typography/typography.css +3 -3
  315. package/src/documentation/accessibility.html +15 -2
  316. package/src/documentation/accordion.html +42 -163
  317. package/src/documentation/alert-dialog.html +25 -48
  318. package/src/documentation/alert.html +15 -59
  319. package/src/documentation/animations.html +15 -2
  320. package/src/documentation/architecture.html +210 -0
  321. package/src/documentation/avatar.html +15 -62
  322. package/src/documentation/badge.html +15 -43
  323. package/src/documentation/blog.html +431 -0
  324. package/src/documentation/brand-logos.html +296 -0
  325. package/src/documentation/breadcrumb.html +15 -114
  326. package/src/documentation/button-group.html +15 -70
  327. package/src/documentation/button.html +16 -86
  328. package/src/documentation/calendar.html +15 -63
  329. package/src/documentation/card.html +15 -124
  330. package/src/documentation/carousel.html +15 -156
  331. package/src/documentation/cascade-layers.html +15 -2
  332. package/src/documentation/changelog.html +63 -2
  333. package/src/documentation/checkbox.html +24 -103
  334. package/src/documentation/collapsible.html +26 -38
  335. package/src/documentation/color-picker.html +15 -32
  336. package/src/documentation/combobox.html +83 -158
  337. package/src/documentation/command.html +30 -95
  338. package/src/documentation/component-skills.html +15 -2
  339. package/src/documentation/context-menu.html +15 -24
  340. package/src/documentation/css/docs-utilities.css +1 -0
  341. package/src/documentation/css/layout.css +75 -36
  342. package/src/documentation/dark-mode.html +15 -2
  343. package/src/documentation/data-attribute-api.html +15 -2
  344. package/src/documentation/date-picker.html +15 -43
  345. package/src/documentation/dialog.html +28 -102
  346. package/src/documentation/dropdown.html +15 -153
  347. package/src/documentation/es-modules.html +15 -2
  348. package/src/documentation/faq.html +361 -0
  349. package/src/documentation/feature-details.html +430 -0
  350. package/src/documentation/file-input.html +15 -40
  351. package/src/documentation/form.html +15 -137
  352. package/src/documentation/get-in-touch.html +294 -0
  353. package/src/documentation/hero.html +283 -0
  354. package/src/documentation/icon.html +15 -162
  355. package/src/documentation/image.html +27 -175
  356. package/src/documentation/images/mk-portrait.png +0 -0
  357. package/src/documentation/images/mk-portrait2.png +0 -0
  358. package/src/documentation/images/mk-square.png +0 -0
  359. package/src/documentation/images/mk-wide.png +0 -0
  360. package/src/documentation/images/mk-wide2.png +0 -0
  361. package/src/documentation/images/mk-wide3.png +0 -0
  362. package/src/documentation/index.html +17 -4
  363. package/src/documentation/input.html +15 -140
  364. package/src/documentation/installation.html +15 -2
  365. package/src/documentation/js/layout.ts +149 -11
  366. package/src/documentation/js/search-index.js +1 -1
  367. package/src/documentation/js/site.ts +70 -75
  368. package/src/documentation/label.html +15 -101
  369. package/src/documentation/native-web-apis.html +15 -2
  370. package/src/documentation/navigation-menu.html +24 -86
  371. package/src/documentation/newsletter.html +305 -0
  372. package/src/documentation/number-input.html +15 -30
  373. package/src/documentation/pagination.html +15 -112
  374. package/src/documentation/popover.html +21 -82
  375. package/src/documentation/pricing.html +550 -0
  376. package/src/documentation/product-showcase.html +410 -0
  377. package/src/documentation/progress.html +15 -31
  378. package/src/documentation/radio.html +15 -143
  379. package/src/documentation/scroll-area.html +15 -47
  380. package/src/documentation/select.html +15 -58
  381. package/src/documentation/separator.html +15 -96
  382. package/src/documentation/sheet.html +24 -112
  383. package/src/documentation/sidebar.html +26 -177
  384. package/src/documentation/site-footer.html +422 -0
  385. package/src/documentation/site-header.html +382 -0
  386. package/src/documentation/skeleton.html +15 -37
  387. package/src/documentation/slider.html +15 -112
  388. package/src/documentation/sortable.html +15 -126
  389. package/src/documentation/spinner.html +15 -37
  390. package/src/documentation/statistic.html +15 -48
  391. package/src/documentation/stats.html +364 -0
  392. package/src/documentation/steps.html +15 -186
  393. package/src/documentation/switch.html +15 -80
  394. package/src/documentation/table.html +15 -54
  395. package/src/documentation/tabs.html +15 -143
  396. package/src/documentation/testimonials.html +417 -0
  397. package/src/documentation/textarea.html +15 -44
  398. package/src/documentation/theming.html +15 -2
  399. package/src/documentation/timeline.html +15 -48
  400. package/src/documentation/toast.html +15 -114
  401. package/src/documentation/toggle-group.html +15 -154
  402. package/src/documentation/toggle.html +15 -90
  403. package/src/documentation/toolbar.html +15 -71
  404. package/src/documentation/tooltip.html +15 -99
  405. package/src/documentation/tree-view.html +26 -55
  406. package/src/documentation/typography.html +21 -120
  407. package/src/documentation/videos/demo.mp4 +0 -0
  408. package/src/documentation/videos/demo.webm +0 -0
  409. package/src/sitemap.xml +1 -0
  410. package/tests/changelog.test.ts +34 -0
  411. package/tests/e2e/accordion.e2e.ts +47 -3
  412. package/tests/e2e/alert-dialog.e2e-fixture.html +6 -1
  413. package/tests/e2e/alert-dialog.e2e.ts +28 -0
  414. package/tests/e2e/blog.e2e-fixture.html +67 -0
  415. package/tests/e2e/blog.e2e.ts +45 -0
  416. package/tests/e2e/brand-logos.e2e-fixture.html +31 -0
  417. package/tests/e2e/brand-logos.e2e.ts +82 -0
  418. package/tests/e2e/combobox.e2e.ts +54 -0
  419. package/tests/e2e/command.e2e-fixture.html +3 -1
  420. package/tests/e2e/command.e2e.ts +24 -0
  421. package/tests/e2e/dialog.e2e-fixture.html +6 -1
  422. package/tests/e2e/dialog.e2e.ts +25 -0
  423. package/tests/e2e/documentation.e2e.ts +44 -0
  424. package/tests/e2e/faq.e2e-fixture.html +54 -0
  425. package/tests/e2e/faq.e2e.ts +43 -0
  426. package/tests/e2e/feature-details.e2e-fixture.html +64 -0
  427. package/tests/e2e/feature-details.e2e.ts +46 -0
  428. package/tests/e2e/get-in-touch.e2e-fixture.html +30 -0
  429. package/tests/e2e/get-in-touch.e2e.ts +42 -0
  430. package/tests/e2e/hero.e2e-fixture.html +30 -0
  431. package/tests/e2e/hero.e2e.ts +34 -0
  432. package/tests/e2e/image.e2e-fixture.html +3 -1
  433. package/tests/e2e/image.e2e.ts +27 -0
  434. package/tests/e2e/navigation-menu.e2e.ts +4 -2
  435. package/tests/e2e/newsletter.e2e-fixture.html +38 -0
  436. package/tests/e2e/newsletter.e2e.ts +41 -0
  437. package/tests/e2e/pricing.e2e-fixture.html +101 -0
  438. package/tests/e2e/pricing.e2e.ts +68 -0
  439. package/tests/e2e/product-showcase.e2e-fixture.html +32 -0
  440. package/tests/e2e/product-showcase.e2e.ts +165 -0
  441. package/tests/e2e/sheet.e2e-fixture.html +6 -1
  442. package/tests/e2e/sheet.e2e.ts +34 -0
  443. package/tests/e2e/sidebar.e2e-fixture.html +3 -0
  444. package/tests/e2e/sidebar.e2e.ts +31 -0
  445. package/tests/e2e/site-footer.e2e-fixture.html +75 -0
  446. package/tests/e2e/site-footer.e2e.ts +60 -0
  447. package/tests/e2e/site-header.e2e-fixture.html +68 -0
  448. package/tests/e2e/site-header.e2e.ts +97 -0
  449. package/tests/e2e/spinner.e2e.ts +5 -1
  450. package/tests/e2e/stats.e2e-fixture.html +55 -0
  451. package/tests/e2e/stats.e2e.ts +46 -0
  452. package/tests/e2e/tabs.e2e.ts +5 -0
  453. package/tests/e2e/testimonials.e2e-fixture.html +58 -0
  454. package/tests/e2e/testimonials.e2e.ts +58 -0
  455. package/tests/e2e/typography.e2e-fixture.html +1 -1
  456. package/tests/e2e/typography.e2e.ts +1 -1
  457. package/tests/readme.test.ts +4 -4
  458. package/tests/ui.test.ts +117 -0
package/AGENTS.md CHANGED
@@ -17,12 +17,18 @@ You are working on the **defuss-shadcn** design system repo.
17
17
  The consumer-facing system lives in `dist/` — **it is generated**: edit sources in
18
18
  `src/` (`bun run build` compiles `.ts` → `.js` and copies everything else 1:1).
19
19
  `docs/` is also generated: **only the documentation site** (`dist/documentation/*` +
20
- `robots.txt`/`sitemap.xml`) published by GitHub Pages — its pages' `../components/…` and
20
+ `robots.txt`/`sitemap.xml` + a `404.html` copy of `index.html` so GitHub Pages never
21
+ serves an empty page for dead links) published by GitHub Pages — its pages' `../components/…` and
21
22
  `../theme/…` references are rewritten to the jsDelivr GitHub CDN (shared transform in
22
23
  `scripts/lib/mirror.ts`), so the mirror carries no copies of the component assets.
23
24
  Refresh it with `bun run docs` (`make build` does this automatically and `verify`
24
25
  fails if the mirror drifts). Never edit `docs/` directly — like `dist/`, it is
25
26
  deleted and rebuilt on every `bun run docs`.
27
+ Because the docs pages load their assets from jsDelivr `@latest` (newest git tag),
28
+ a fresh release keeps serving the **previous** release's CSS/JS until jsDelivr's
29
+ cache expires (12h edge, 7d browser). After `bun run deploy`, run
30
+ `bun run purge-cdn` (`make purge-cdn`) to force `@latest` to re-resolve to the
31
+ new tag immediately.
26
32
  Never edit `dist/` directly; it is deleted and rebuilt on every build.
27
33
 
28
34
  ---
@@ -45,7 +51,7 @@ defuss-shadcn/
45
51
  │ ├── css/docs-theme.css ← doc-site font overrides (not part of the system)
46
52
  │ ├── css/layout.css ← doc-site layout (not part of the system)
47
53
  │ ├── js/layout.js ← SPA router, <site-header>/<site-nav> web components
48
- │ ├── js/site.js ← doc-site-only JS (tabs, copy buttons, skill modal, code collapse)
54
+ │ ├── js/site.js ← doc-site-only JS (tabs, copy buttons, code collapse)
49
55
  │ ├── js/shiki-highlight.js ← Shiki-based syntax highlighting (ES module, CDN)
50
56
  │ ├── js/themes.js ← tweakcn color theme presets (global THEMES array)
51
57
  │ └── js/theme-switcher.js ← applies theme overrides to CSS custom properties
@@ -73,7 +79,8 @@ defuss-shadcn/
73
79
  │ ├── sync-css-snippets.ts ← re-embed component CSS into doc pages after edits
74
80
  │ ├── sync-js-snippets.ts ← re-embed component JS into doc pages after edits
75
81
  │ ├── push.sh ← commit + push dev → main (non-release)
76
- │ └── deploy.sh ← release: version bump, changelog, tag, GitHub release
82
+ │ ├── deploy.sh ← release: version bump, changelog, tag, GitHub release
83
+ │ └── purge-cdn.ts ← purge jsDelivr @latest cache for all dist assets (run after deploy)
77
84
  ├── tests/ ← UI tests (Vitest browser mode + Playwright)
78
85
  │ ├── helpers.ts ← loads real doc pages in a same-origin iframe
79
86
  │ ├── ui.test.ts ← end-to-end tests of the actual site UI
@@ -171,6 +178,23 @@ its `fix:` line states the two-commit instruction. `scripts/deploy.sh`
171
178
  automates the whole flow. Legacy entries (v0.7.13-alpha and earlier) keep
172
179
  date-only badges — the hash requirement applies from this rule onward.
173
180
 
181
+ ### ARCH.md ↔ architecture page sync (REQUIRED)
182
+
183
+ [`ARCH.md`](ARCH.md) is the repo's design manifesto (why the verifier is the
184
+ authority, how the proof loop works, where the human review sits). The docs
185
+ site publishes it as an Overview page,
186
+ [`src/documentation/architecture.html`](src/documentation/architecture.html) —
187
+ a **generated** render of ARCH.md via `src/architecture_tpl.html`
188
+ (`scripts/lib/arch-page.ts`, regenerated by `build.ts`, mirrored to the docs
189
+ site like every other page).
190
+
191
+ - **When you edit ARCH.md, run `bun run build` in the same commit** — the page
192
+ is rebuilt from it. `verify`'s `architecture ↔ ARCH.md` gate fails when the
193
+ two diverge, exactly like the SKILL.md index.
194
+ - **Never hand-edit `architecture.html`** (or its `dist/` / `docs/` copies):
195
+ like all generated files it is deleted and rebuilt; the generator would
196
+ silently revert your edit, and the gate would fail anyway.
197
+
174
198
  ### Native web platform first
175
199
 
176
200
  Every component starts from a native HTML element or browser API. If the browser
@@ -958,6 +982,7 @@ The sidebar is ordered by dependency (primitives first):
958
982
  8. Overlays (Popover, Tooltip, Context Menu, Dialog, Sheet, Accordion, Command)
959
983
  9. Navigation (Breadcrumb, Pagination, Steps, Tabs, Dropdown Menu, Navigation Menu)
960
984
  10. Application (Sidebar)
985
+ 11. Marketing (Site Header, Hero, Product Showcase, Brand Logos, Feature Details, Testimonials, Stats, Pricing, Blog, FAQ, Get In Touch, Newsletter, Site Footer) — CSS-only page sections composed from the same tokens + primitives
961
986
 
962
987
  To reorder, edit the `NAV` array in `layout.js`.
963
988
 
package/ARCH.md CHANGED
@@ -1,13 +1,13 @@
1
- # ARCH — How this framework scales without a human reviewer
1
+ # ARCH — How this framework scales with AI
2
2
 
3
- defuss-shadcn is built for an era where **coding agents do the work**. The
3
+ `defuss-shadcn` is built for an era where **coding agents do the work**. The
4
4
  scaling bottleneck is no longer writing components — it is *trusting* them.
5
5
  This repo solves trust with a closed loop: every artifact an agent produces
6
6
  passes through mechanical quality gates designed by a human senior software engineer, and the gates talk back to the AI agent in the form of executable instructions. An agent can reach "done" only by satisfying every gate; the goal is unreachable any other way.
7
7
 
8
- The method has four parts.
8
+ The method has five parts.
9
9
 
10
- ## 1. AGENTS.md — the philosophy layer
10
+ ## 1. AGENTS.md — the philosophy/instruction layer
11
11
 
12
12
  [`AGENTS.md`](AGENTS.md) tells a coding agent **how to work, what to
13
13
  implement where, and why**: the native-web-platform-first rules (`<dialog>`,
@@ -18,7 +18,7 @@ model reads before and while it works. Prose, however, is advisory: an agent
18
18
  can misread it, skip it, or claim compliance. That is exactly what the next
19
19
  layer is for.
20
20
 
21
- ## 2. The verifier — the authority layer
21
+ ## 2. The deterministic verifier — an authority layer
22
22
 
23
23
  [`scripts/verify.ts`](scripts/verify.ts) is a custom, code-implemented audit
24
24
  of everything prose cannot guarantee: **41 check groups** over the shipped
@@ -68,7 +68,7 @@ to ignore it. The two files are one system: prose explains the *why*, the
68
68
  verifier enforces the *what*, and prose points at the verifier as the final
69
69
  word (`bun run verify` is the single "am I done?" question).
70
70
 
71
- ## 4. The surrounding gates — verification is not enough by itself
71
+ ## 4. The surrounding gates — suppressing hallucination, AI slop and overstating claims
72
72
 
73
73
  The verifier checks *consistency*. The loop wraps it with gates that check
74
74
  *behavior, quality, and appearance*:
@@ -131,3 +131,19 @@ the loop until the work is actually good* — which is precisely the point:
131
131
  human review does not scale to an army of agents, but a verifier that
132
132
  audits every byte, speaks repair instructions, and is the only door out
133
133
  does.
134
+
135
+ ## 5. Human expert final review before release
136
+
137
+ The human expert only reviews the code, documentation and visual representation after all quality gates have passed and the visual evidence has been captured - right before a new version is released.
138
+
139
+ Should the human expert find any issues during this final review, the feedback is fed back into the loop, and the agents must address it before a new version can be released. If a regression or a new "unknown unknown" fail case is discovered, the human expert will either instruct the agent to add this to the AGENTS.md or let the agent implement yet another verifier logic to add a new static and deterministic quality gate, preventing the same issue from slipping through in future iterations.
140
+
141
+ As for the Agent Harness, this method has a huge advantage compared to more automated or harness-native solutions:
142
+
143
+ 1. It doesn't matter what VLM model is used. As long as the model is capable enough, it can handle the task including multimodal reasoning and visual inspection of the screenshots.
144
+
145
+ 2. AGENTS.md and the verifier logic are decoupled from the specific VLM model. This means that improvements or changes to the VLM model do not require modifications to the agent's instructions or the verifier, ensuring long-term maintainability and flexibility.
146
+
147
+ 3. The human still has oversight over both the development process (and thus can intercept in case of errors or unexpected behavior) and the release process, ensuring that the quality gates are meaningful, implemented changes are safe and correct, and that the released version meets all of the desired standards, set by the human expert.
148
+
149
+ 4. Spec-driven development is absolutely possible by simply creating plans or bug reports in the ./issues folder - decoupling the agentic engineering process from any 3rd party project management tool, while still maintaining a clear and structured workflow for the agents to follow - even in case the harness fails right in the middle of an implementation loop.
package/Makefile CHANGED
@@ -2,7 +2,7 @@
2
2
  # KISS: every target delegates to package.json so there is one source of truth.
3
3
 
4
4
  .DEFAULT_GOAL := help
5
- .PHONY: help setup dev test test-run coverage e2e lint verify screenshots build docs
5
+ .PHONY: help setup dev test test-run coverage e2e lint verify screenshots build docs purge-cdn
6
6
 
7
7
  help: ## Show available targets
8
8
  @grep -E '^[a-zA-Z0-9_-]+:.*## ' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*## "}; {printf " \033[36m%-12s\033[0m %s\n", $$1, $$2}'
@@ -35,6 +35,9 @@ typecheck: ## Strict tsc type-check of tests/ and scripts/ (no emit)
35
35
  docs: ## Build, then mirror dist/ → docs/ for GitHub Pages
36
36
  bun run docs
37
37
 
38
+ purge-cdn: ## Purge jsDelivr @latest cache for all dist assets (run after deploy)
39
+ bun run purge-cdn
40
+
38
41
  # Full pipeline: fast checks first, compile, refresh screenshots (the verify
39
42
  # gate requires them fresh vs. the new dist/), then gate + tests. Calls
40
43
  # scripts/build.ts directly because `bun run build` would run verify BEFORE
package/README.md CHANGED
@@ -9,9 +9,11 @@
9
9
  [![TypeScript definitions](https://img.shields.io/npm/types/defuss-shadcn.svg)](https://www.npmjs.com/package/defuss-shadcn)
10
10
  [![Socket Badge](https://badge.socket.dev/npm/package/defuss-shadcn/latest)](https://socket.dev/npm/package/defuss-shadcn)
11
11
 
12
- **A UI component system that scales with AI.** Themeable components built on semantic HTML, modern CSS, and vanilla JavaScript. No framework. No build step for consumers — `dist/` is committed and ready to use as-is. The simplest possible foundation for AI-driven prototyping.
12
+ **A UI component system that scales with _local_ AI.** Themeable components built on semantic HTML, modern CSS, and vanilla JavaScript. No framework. No build step for consumers — `dist/` is committed and ready to use as-is. The simplest possible foundation for AI-driven prototyping.
13
13
 
14
- 29 of 55 components need no JavaScript — native HTML and modern CSS cover them entirely.
14
+ 41 of 68 components need no JavaScript — native HTML and modern CSS cover them entirely.
15
+
16
+ The set includes 13 marketing blocks (Site Header, Hero, Pricing, Testimonials, Blog, Footer, …) — full-page sections composed from the same tokens and primitives, all CSS-only.
15
17
 
16
18
  **[Documentation & Live Demos →](https://kyr0.github.io/defuss-shadcn/)** · [Architecture (ARCH.md)](ARCH.md) · [Agent integration guide (dist/SKILL.md)](dist/SKILL.md)
17
19
 
@@ -139,7 +141,8 @@ bun run test:run # run the UI test suite (headless Chromium)
139
141
 
140
142
  `src/` is the authoring tree (`.ts` + html/css/md/fonts); `dist/` is its compiled, 1:1
141
143
  mirror, committed and the only thing that ships. `docs/` is the generated **documentation
142
- site** (only `dist/documentation/` + the SEO files) that GitHub Pages publishes — the
144
+ site** (only `dist/documentation/` + the SEO files + a `404.html` copy of `index.html` so
145
+ GitHub Pages never serves an empty page for dead links) that GitHub Pages publishes — the
143
146
  pages' `../components/…` / `../theme/…` references are rewritten to the jsDelivr GitHub
144
147
  CDN by the mirror ([scripts/lib/mirror.ts](scripts/lib/mirror.ts)), so docs/ carries no
145
148
  copies of the component assets. Refresh with `bun run docs`, never edit it directly.
package/bun.lock CHANGED
@@ -12,6 +12,7 @@
12
12
  "linkedom": "^0.18.13",
13
13
  "oxlint": "^1.81.0",
14
14
  "playwright": "^1.63.0",
15
+ "simple-icons": "^16.30.0",
15
16
  "typescript": "^7.0.2",
16
17
  "vite": "^8.2.2",
17
18
  "vitest": "^5.0.0",
@@ -289,6 +290,8 @@
289
290
 
290
291
  "siginfo": ["siginfo@2.0.0", "", {}, "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g=="],
291
292
 
293
+ "simple-icons": ["simple-icons@16.30.0", "", {}, "sha512-YX/HmgEqjpn5Zs3myzKp8ek5Ti+TdrkvNWn9skGLetg9tOg0cTjYizj9ESAYJn4xwc0GQYVGzQxBELDfbxq7WQ=="],
294
+
292
295
  "sirv": ["sirv@3.0.2", "", { "dependencies": { "@polka/url": "^1.0.0-next.24", "mrmime": "^2.0.0", "totalist": "^3.0.0" } }, "sha512-2wcC/oGxHis/BoHkkPwldgiPSYcpZK3JU28WoMVv55yHJgcZ8rlXvuG9iZggz+sU1d4bRgIGASwyWqjxu3FM0g=="],
293
296
 
294
297
  "source-map-js": ["source-map-js@1.2.1", "", {}, "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA=="],
package/dist/SKILL.md CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  # defuss-shadcn — Agent Skill
6
6
 
7
- **A UI component system that scales with AI.** Themeable components built on semantic HTML, modern CSS, and vanilla JavaScript. No framework, zero dependencies — `dist/` is committed and ready to use as-is. This file is the entry point for an AI agent integrating the library: read it once, then read only the component skills you need.
7
+ **A UI component system that scales with _local_ AI.** Themeable components built on semantic HTML, modern CSS, and vanilla JavaScript. No framework, zero dependencies — `dist/` is committed and ready to use as-is. This file is the entry point for an AI agent integrating the library: read it once, then read only the component skills you need.
8
8
 
9
9
  ## Integrate
10
10
 
@@ -108,6 +108,24 @@ In the **source repository** additionally: `screenshots/{light,dark}/{name}.png`
108
108
  **Screenshots:** screenshots/{light,dark}/badge.png
109
109
  **Skill:** [components/badge/component-skill.md](components/badge/component-skill.md)
110
110
 
111
+ ## Blog
112
+
113
+ **Why:** Post cards are `<a>` + `<img>` + clamped text — line-clamp and aspect-ratio give the editorial layout for free.
114
+ **When:** Insights/news teasers on a marketing page; the full article list is a table or card grid instead.
115
+ **Files:** dist/components/blog/blog.css
116
+ **Supported states:** default
117
+ **Screenshots:** screenshots/{light,dark}/blog.png
118
+ **Skill:** [components/blog/component-skill.md](components/blog/component-skill.md)
119
+
120
+ ## Brand Logos
121
+
122
+ **Why:** Logos as currentColor SVGs recolor with the theme automatically — a row of marks needs zero behavior.
123
+ **When:** "Trusted by" social proof band under a Hero — not for user-uploaded arbitrary images.
124
+ **Files:** dist/components/brand-logos/brand-logos.css
125
+ **Supported states:** default
126
+ **Screenshots:** screenshots/{light,dark}/brand-logos.png
127
+ **Skill:** [components/brand-logos/component-skill.md](components/brand-logos/component-skill.md)
128
+
111
129
  ## Breadcrumb
112
130
 
113
131
  **Why:** nav > ol markup with aria-current="page" — the accessibility comes free with the markup, not from JS.
@@ -243,6 +261,24 @@ In the **source repository** additionally: `screenshots/{light,dark}/{name}.png`
243
261
  **Screenshots:** screenshots/{light,dark}/dropdown.png, screenshots/{light,dark}/dropdown-open.png
244
262
  **Skill:** [components/dropdown/component-skill.md](components/dropdown/component-skill.md)
245
263
 
264
+ ## FAQ
265
+
266
+ **Why:** Icon-card answers stay visible — no disclosure widget to wire, so screen readers and crawlers see every answer.
267
+ **When:** Support section on a marketing page; for many long Q&As use the Accordion (native <details>) instead.
268
+ **Files:** dist/components/faq/faq.css
269
+ **Supported states:** default
270
+ **Screenshots:** screenshots/{light,dark}/faq.png
271
+ **Skill:** [components/faq/component-skill.md](components/faq/component-skill.md)
272
+
273
+ ## Feature Details
274
+
275
+ **Why:** Two-image feature split with a rule between — a grid with an auto-stretched divider column, no JS.
276
+ **When:** "Benefits" section of a marketing page; for a feature list without imagery use cards instead.
277
+ **Files:** dist/components/feature-details/feature-details.css
278
+ **Supported states:** default
279
+ **Screenshots:** screenshots/{light,dark}/feature-details.png
280
+ **Skill:** [components/feature-details/component-skill.md](components/feature-details/component-skill.md)
281
+
246
282
  ## File Input
247
283
 
248
284
  **Why:** A <label> wrapping the native file input with styled drag-over and filled states.
@@ -261,6 +297,24 @@ In the **source repository** additionally: `screenshots/{light,dark}/{name}.png`
261
297
  **Screenshots:** screenshots/{light,dark}/form.png
262
298
  **Skill:** [components/form/component-skill.md](components/form/component-skill.md)
263
299
 
300
+ ## Get In Touch
301
+
302
+ **Why:** A bordered contact CTA card — avatar overlap is negative margins + outline, not positioning math.
303
+ **When:** End-of-page "want to know more?" band; for an actual contact form use Form + Input components.
304
+ **Files:** dist/components/get-in-touch/get-in-touch.css
305
+ **Supported states:** default
306
+ **Screenshots:** screenshots/{light,dark}/get-in-touch.png
307
+ **Skill:** [components/get-in-touch/component-skill.md](components/get-in-touch/component-skill.md)
308
+
309
+ ## Hero
310
+
311
+ **Why:** Headline, description and CTAs in one centered copy block — native flow layout and container queries, nothing to script.
312
+ **When:** First section of a marketing page; pair with the Product Showcase block when you need a video.
313
+ **Files:** dist/components/hero/hero.css
314
+ **Supported states:** default
315
+ **Screenshots:** screenshots/{light,dark}/hero.png
316
+ **Skill:** [components/hero/component-skill.md](components/hero/component-skill.md)
317
+
264
318
  ## Icon
265
319
 
266
320
  **Why:** Consistent 24px stroke wrappers around lucide icons, sized via data-size.
@@ -306,6 +360,15 @@ In the **source repository** additionally: `screenshots/{light,dark}/{name}.png`
306
360
  **Screenshots:** screenshots/{light,dark}/navigation-menu.png, screenshots/{light,dark}/navigation-menu-open.png
307
361
  **Skill:** [components/navigation-menu/component-skill.md](components/navigation-menu/component-skill.md)
308
362
 
363
+ ## Newsletter
364
+
365
+ **Why:** A real <form> with <input type="email"> — native validation, keyboard, and autofill come free.
366
+ **When:** Sign-up band on a marketing page; for multi-field sign-up use the Form component.
367
+ **Files:** dist/components/newsletter/newsletter.css
368
+ **Supported states:** default
369
+ **Screenshots:** screenshots/{light,dark}/newsletter.png
370
+ **Skill:** [components/newsletter/component-skill.md](components/newsletter/component-skill.md)
371
+
309
372
  ## Number Input
310
373
 
311
374
  **Why:** Input plus stepper buttons bound to native min/max/step and arrow-key behavior.
@@ -333,6 +396,24 @@ In the **source repository** additionally: `screenshots/{light,dark}/{name}.png`
333
396
  **Screenshots:** screenshots/{light,dark}/popover.png, screenshots/{light,dark}/popover-open.png
334
397
  **Skill:** [components/popover/component-skill.md](components/popover/component-skill.md)
335
398
 
399
+ ## Pricing
400
+
401
+ **Why:** Plan cards are a stretch-aligned grid; the billing toggle is native radios plus :has(), so one checked input flips every plan with zero JS.
402
+ **When:** Plans/tiers section of a marketing page; a single plan needs no grid — one card suffices.
403
+ **Files:** dist/components/pricing/pricing.css
404
+ **Supported states:** default
405
+ **Screenshots:** screenshots/{light,dark}/pricing.png
406
+ **Skill:** [components/pricing/component-skill.md](components/pricing/component-skill.md)
407
+
408
+ ## Product Showcase
409
+
410
+ **Why:** A poster frame + one real <button> starts a native <video controls> — the browser draws every playback affordance once the video is visible.
411
+ **When:** Hero pairing or standalone product video; a static screenshot needs only the poster <img> (drop the video and button).
412
+ **Files:** dist/components/product-showcase/product-showcase.css + dist/components/product-showcase/product-showcase.js
413
+ **Supported states:** default, playing
414
+ **Screenshots:** screenshots/{light,dark}/product-showcase.png, screenshots/{light,dark}/product-showcase-playing.png
415
+ **Skill:** [components/product-showcase/component-skill.md](components/product-showcase/component-skill.md)
416
+
336
417
  ## Progress
337
418
 
338
419
  **Why:** Native <progress value max> — semantics and rendering come free.
@@ -396,6 +477,24 @@ In the **source repository** additionally: `screenshots/{light,dark}/{name}.png`
396
477
  **Screenshots:** screenshots/{light,dark}/sidebar.png, screenshots/{light,dark}/sidebar-collapsed.png
397
478
  **Skill:** [components/sidebar/component-skill.md](components/sidebar/component-skill.md)
398
479
 
480
+ ## Site Footer
481
+
482
+ **Why:** Link columns + social row is pure grid/flex markup in a <footer> landmark — no behavior to script.
483
+ **When:** Bottom of marketing pages; the doc site's own footer is separate chrome (<footer> in layout.js).
484
+ **Files:** dist/components/site-footer/site-footer.css
485
+ **Supported states:** default
486
+ **Screenshots:** screenshots/{light,dark}/site-footer.png
487
+ **Skill:** [components/site-footer/component-skill.md](components/site-footer/component-skill.md)
488
+
489
+ ## Site Header
490
+
491
+ **Why:** A marketing page header is pure layout — flexbox + a container query replace any JS show/hide of the nav.
492
+ **When:** Top of a marketing/landing page — for the doc site's own chrome use <site-header> instead.
493
+ **Files:** dist/components/site-header/site-header.css
494
+ **Supported states:** default
495
+ **Screenshots:** screenshots/{light,dark}/site-header.png
496
+ **Skill:** [components/site-header/component-skill.md](components/site-header/component-skill.md)
497
+
399
498
  ## Skeleton
400
499
 
401
500
  **Why:** Shimmering placeholder blocks shaped like the content that will arrive.
@@ -441,6 +540,15 @@ In the **source repository** additionally: `screenshots/{light,dark}/{name}.png`
441
540
  **Screenshots:** screenshots/{light,dark}/statistic.png
442
541
  **Skill:** [components/statistic/component-skill.md](components/statistic/component-skill.md)
443
542
 
543
+ ## Stats
544
+
545
+ **Why:** Metric band = a grid of rule-led numbers; text alignment and tabular-nums do what a chart library would.
546
+ **When:** "Trusted by teams everywhere" social proof with hard numbers; not a data dashboard.
547
+ **Files:** dist/components/stats/stats.css
548
+ **Supported states:** default
549
+ **Screenshots:** screenshots/{light,dark}/stats.png
550
+ **Skill:** [components/stats/component-skill.md](components/stats/component-skill.md)
551
+
444
552
  ## Steps
445
553
 
446
554
  **Why:** Ordered list of process steps with aria-current="step" on the active one.
@@ -477,6 +585,15 @@ In the **source repository** additionally: `screenshots/{light,dark}/{name}.png`
477
585
  **Screenshots:** screenshots/{light,dark}/tabs.png, screenshots/{light,dark}/tabs-active.png
478
586
  **Skill:** [components/tabs/component-skill.md](components/tabs/component-skill.md)
479
587
 
588
+ ## Testimonials
589
+
590
+ **Why:** A pull-quote plus photo cards with floating review overlays — backdrop-filter and stacking replace any JS layering.
591
+ **When:** Social-proof band on a marketing page; for short quotes without photos a plain blockquote is enough.
592
+ **Files:** dist/components/testimonials/testimonials.css
593
+ **Supported states:** default
594
+ **Screenshots:** screenshots/{light,dark}/testimonials.png
595
+ **Skill:** [components/testimonials/component-skill.md](components/testimonials/component-skill.md)
596
+
480
597
  ## Textarea
481
598
 
482
599
  **Why:** Native textarea with field-sizing: content — auto-grows with zero JavaScript.
package/dist/SKILL_tpl.md CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  # defuss-shadcn — Agent Skill
6
6
 
7
- **A UI component system that scales with AI.** Themeable components built on semantic HTML, modern CSS, and vanilla JavaScript. No framework, zero dependencies — `dist/` is committed and ready to use as-is. This file is the entry point for an AI agent integrating the library: read it once, then read only the component skills you need.
7
+ **A UI component system that scales with _local_ AI.** Themeable components built on semantic HTML, modern CSS, and vanilla JavaScript. No framework, zero dependencies — `dist/` is committed and ready to use as-is. This file is the entry point for an AI agent integrating the library: read it once, then read only the component skills you need.
8
8
 
9
9
  ## Integrate
10
10
 
@@ -0,0 +1,153 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <meta name="color-scheme" content="light dark">
7
+ <link rel="icon" href="images/favicon.webp" type="image/webp">
8
+ <meta name="description" content="How defuss-shadcn scales with AI: AGENTS.md teaches, a deterministic verifier enforces, screenshots prove, humans review before release.">
9
+ <meta property="og:title" content="Architecture — defuss-shadcn">
10
+ <meta property="og:description" content="How defuss-shadcn scales with AI: AGENTS.md teaches, a deterministic verifier enforces, screenshots prove, humans review before release.">
11
+ <meta property="og:type" content="website">
12
+ <meta property="og:url" content="https://kyr0.github.io/defuss-shadcn/documentation/architecture.html">
13
+ <meta property="og:site_name" content="defuss-shadcn">
14
+ <meta name="twitter:card" content="summary">
15
+ <meta name="twitter:title" content="Architecture — defuss-shadcn">
16
+ <meta name="twitter:description" content="How defuss-shadcn scales with AI: AGENTS.md teaches, a deterministic verifier enforces, screenshots prove, humans review before release.">
17
+ <title>Architecture — defuss-shadcn</title>
18
+ <script src="js/themes.js"></script>
19
+ <script src="js/theme-switcher.js"></script>
20
+ <script src="js/layout.js"></script>
21
+ <script src="js/search-index.js"></script>
22
+ <link rel="stylesheet" href="../theme/default-semantic-tokens.css">
23
+ <link rel="stylesheet" href="css/docs-theme.css">
24
+ <link rel="stylesheet" href="css/docs-utilities.css">
25
+ <link rel="stylesheet" href="css/layout.css">
26
+ <link rel="stylesheet" href="../components/button/button.css">
27
+ <link rel="stylesheet" href="../components/card/card.css">
28
+ <link rel="stylesheet" href="../components/dialog/dialog.css">
29
+ <link rel="stylesheet" href="../components/badge/badge.css">
30
+ <link rel="stylesheet" href="../components/input/input.css">
31
+ <link rel="stylesheet" href="../components/accordion/accordion.css">
32
+ <link rel="stylesheet" href="../components/tabs/tabs.css">
33
+ <link rel="stylesheet" href="../components/dropdown/dropdown.css">
34
+ <link rel="stylesheet" href="../components/toast/toast.css">
35
+ <link rel="stylesheet" href="../components/combobox/combobox.css">
36
+ <link rel="stylesheet" href="../components/sheet/sheet.css">
37
+ <link rel="stylesheet" href="../components/toggle/toggle.css">
38
+ <link rel="stylesheet" href="../components/icon/icon.css">
39
+ <link rel="stylesheet" href="../components/typography/typography.css">
40
+ <link rel="stylesheet" href="../components/separator/separator.css">
41
+ <link rel="stylesheet" href="../components/label/label.css">
42
+ <link rel="stylesheet" href="../components/toggle-group/toggle-group.css">
43
+ <link rel="stylesheet" href="../components/button-group/button-group.css">
44
+ <link rel="stylesheet" href="../components/toolbar/toolbar.css">
45
+ <link rel="stylesheet" href="../components/textarea/textarea.css">
46
+ <link rel="stylesheet" href="../components/checkbox/checkbox.css">
47
+ <link rel="stylesheet" href="../components/radio/radio.css">
48
+ <link rel="stylesheet" href="../components/switch/switch.css">
49
+ <link rel="stylesheet" href="../components/slider/slider.css">
50
+ <link rel="stylesheet" href="../components/select/select.css">
51
+ <link rel="stylesheet" href="../components/number-input/number-input.css">
52
+ <link rel="stylesheet" href="../components/file-input/file-input.css">
53
+ <link rel="stylesheet" href="../components/color-picker/color-picker.css">
54
+ <link rel="stylesheet" href="../components/date-picker/date-picker.css">
55
+ <link rel="stylesheet" href="../components/form/form.css">
56
+ <link rel="stylesheet" href="../components/avatar/avatar.css">
57
+ <link rel="stylesheet" href="../components/image/image.css">
58
+ <link rel="stylesheet" href="../components/statistic/statistic.css">
59
+ <link rel="stylesheet" href="../components/table/table.css">
60
+ <link rel="stylesheet" href="../components/collapsible/collapsible.css">
61
+ <link rel="stylesheet" href="../components/timeline/timeline.css">
62
+ <link rel="stylesheet" href="../components/tree-view/tree-view.css">
63
+ <link rel="stylesheet" href="../components/calendar/calendar.css">
64
+ <link rel="stylesheet" href="../components/spinner/spinner.css">
65
+ <link rel="stylesheet" href="../components/skeleton/skeleton.css">
66
+ <link rel="stylesheet" href="../components/progress/progress.css">
67
+ <link rel="stylesheet" href="../components/alert/alert.css">
68
+ <link rel="stylesheet" href="../components/alert-dialog/alert-dialog.css">
69
+ <link rel="stylesheet" href="../components/popover/popover.css">
70
+ <link rel="stylesheet" href="../components/tooltip/tooltip.css">
71
+ <link rel="stylesheet" href="../components/context-menu/context-menu.css">
72
+ <link rel="stylesheet" href="../components/command/command.css">
73
+ <link rel="stylesheet" href="../components/breadcrumb/breadcrumb.css">
74
+ <link rel="stylesheet" href="../components/pagination/pagination.css">
75
+ <link rel="stylesheet" href="../components/steps/steps.css">
76
+ <link rel="stylesheet" href="../components/navigation-menu/navigation-menu.css">
77
+ <link rel="stylesheet" href="../components/scroll-area/scroll-area.css">
78
+ <link rel="stylesheet" href="../components/carousel/carousel.css">
79
+ <link rel="stylesheet" href="../components/sidebar/sidebar.css">
80
+ <link rel="stylesheet" href="../components/sortable/sortable.css">
81
+ <link rel="stylesheet" href="../components/site-header/site-header.css">
82
+ <link rel="stylesheet" href="../components/hero/hero.css">
83
+ <link rel="stylesheet" href="../components/product-showcase/product-showcase.css">
84
+ <link rel="stylesheet" href="../components/brand-logos/brand-logos.css">
85
+ <link rel="stylesheet" href="../components/feature-details/feature-details.css">
86
+ <link rel="stylesheet" href="../components/testimonials/testimonials.css">
87
+ <link rel="stylesheet" href="../components/stats/stats.css">
88
+ <link rel="stylesheet" href="../components/pricing/pricing.css">
89
+ <link rel="stylesheet" href="../components/blog/blog.css">
90
+ <link rel="stylesheet" href="../components/faq/faq.css">
91
+ <link rel="stylesheet" href="../components/get-in-touch/get-in-touch.css">
92
+ <link rel="stylesheet" href="../components/newsletter/newsletter.css">
93
+ <link rel="stylesheet" href="../components/site-footer/site-footer.css">
94
+ </head>
95
+ <body>
96
+ <site-header></site-header>
97
+
98
+ <div class="flex" style="margin-top: 3.5rem; min-height: calc(100vh - 3.5rem);">
99
+ <site-nav></site-nav>
100
+
101
+ <main style="flex: 1; min-width: 0; max-width: 44rem; padding: 2rem 3.5rem 8rem;">
102
+ <div class="page-header">
103
+ <p class="text-sm text-muted-foreground mb-3" style="font-family:var(--font-mono);">defuss-shadcn / architecture</p>
104
+ <h1 style="font-family:var(--font-display);font-size:2.5rem;font-weight:400;letter-spacing:-0.035em;margin:0 0 0.75rem;">Architecture</h1>
105
+ <p class="text-muted-foreground leading-relaxed mb-10" style="max-width:38rem;">
106
+ How defuss-shadcn scales with AI:
107
+ <a href="https://github.com/kyr0/defuss-shadcn/blob/main/AGENTS.md" style="color:var(--primary);text-decoration:underline;text-underline-offset:4px;">AGENTS.md</a>
108
+ teaches,
109
+ <a href="https://github.com/kyr0/defuss-shadcn/blob/main/scripts/verify.ts" style="color:var(--primary);text-decoration:underline;text-underline-offset:4px;">a deterministic verifier</a>
110
+ enforces, screenshots prove, and a human reviews before every release. This page is generated from
111
+ <a href="https://github.com/kyr0/defuss-shadcn/blob/main/ARCH.md" style="color:var(--primary);text-decoration:underline;text-underline-offset:4px;">ARCH.md</a>
112
+ on every build — a verify gate fails if the two ever diverge.
113
+ </p>
114
+ </div>
115
+
116
+ <!-- ARCH_BODY -->
117
+
118
+ </main>
119
+ </div>
120
+
121
+ <script src="js/site.js" defer></script>
122
+ <script type="module" src="js/shiki-highlight.js"></script>
123
+ <script type="module" src="../components/accordion/accordion.js"></script>
124
+ <script type="module" src="../components/combobox/combobox.js"></script>
125
+ <script type="module" src="../components/dialog/dialog.js"></script>
126
+ <script type="module" src="../components/dropdown/dropdown.js"></script>
127
+ <script type="module" src="../components/sheet/sheet.js"></script>
128
+ <script type="module" src="../components/tabs/tabs.js"></script>
129
+ <script type="module" src="../components/toast/toast.js"></script>
130
+ <script type="module" src="../components/toggle/toggle.js"></script>
131
+ <script type="module" src="../components/toggle-group/toggle-group.js"></script>
132
+ <script type="module" src="../components/toolbar/toolbar.js"></script>
133
+ <script type="module" src="../components/number-input/number-input.js"></script>
134
+ <script type="module" src="../components/color-picker/color-picker.js"></script>
135
+ <script type="module" src="../components/avatar/avatar.js"></script>
136
+ <script type="module" src="../components/image/image.js"></script>
137
+ <script type="module" src="../components/tree-view/tree-view.js"></script>
138
+ <script type="module" src="../components/calendar/calendar.js"></script>
139
+ <script type="module" src="../components/alert-dialog/alert-dialog.js"></script>
140
+ <script type="module" src="../components/popover/popover.js"></script>
141
+ <script type="module" src="../components/tooltip/tooltip.js"></script>
142
+ <script type="module" src="../components/context-menu/context-menu.js"></script>
143
+ <script type="module" src="../components/command/command.js"></script>
144
+ <script type="module" src="../components/navigation-menu/navigation-menu.js"></script>
145
+ <script type="module" src="../components/sidebar/sidebar.js"></script>
146
+ <script type="module" src="../components/carousel/carousel.js"></script>
147
+ <script type="module" src="../components/slider/slider.js"></script>
148
+ <script type="module" src="../components/sortable/sortable.js"></script>
149
+ <script type="module" src="../components/product-showcase/product-showcase.js"></script>
150
+ <script src="https://unpkg.com/lucide@1.8.0" integrity="sha384-+8nbzwDAyu5kAjqtR/XKxIgPHQD2TflvbZgeDZn5t3JP+OOogNH1jXnfel8ZAgzS" crossorigin="anonymous"></script>
151
+ <script>globalThis.lucide?.createIcons();</script>
152
+ </body>
153
+ </html>
@@ -11,20 +11,27 @@
11
11
 
12
12
  &:last-child { border-bottom: none; }
13
13
 
14
- /* -- Content animation (CSS-only) ------------------------- */
15
- & ::details-content {
14
+ /* -- Content animation (CSS-only) -------------------------
15
+ Two gotchas, both required for the panel to glide:
16
+ 1. `::details-content` must attach to the compound (`&::details-content`,
17
+ NOT `& ::details-content` — the descendant form never matches, the
18
+ pseudo's originating element is the subject itself).
19
+ 2. `block-size: auto` is a keyword — without interpolate-size the
20
+ 0→auto pair is non-interpolable and the transition silently snaps. */
21
+ &::details-content {
16
22
  block-size: 0;
17
23
  overflow-y: clip;
24
+ interpolate-size: allow-keywords;
18
25
  transition: block-size 200ms ease, content-visibility 200ms allow-discrete;
19
26
  }
20
27
 
21
- &[open] ::details-content {
28
+ &[open]::details-content {
22
29
  block-size: auto;
23
30
  }
24
31
  }
25
32
 
26
33
  @starting-style {
27
- .accordion-item[open] ::details-content {
34
+ .accordion-item[open]::details-content {
28
35
  block-size: 0;
29
36
  }
30
37
  }
@@ -76,7 +83,7 @@
76
83
  (REQUIRED for all components — AGENTS.md "Accessibility CSS"). */
77
84
  @media (prefers-reduced-motion: reduce) {
78
85
  @layer components {
79
- .accordion-item ::details-content { transition: none; }
86
+ .accordion-item::details-content { transition: none; }
80
87
  .accordion-trigger { transition: none; }
81
88
  }
82
89
  }
@@ -116,6 +116,18 @@ function init() {
116
116
  getState: () => accordionApi.getState(accordion),
117
117
  };
118
118
  items.forEach((item) => {
119
+ // Cancellable pre-event: closing the LAST open item of a non-collapsible
120
+ // single accordion is denied here, before the DOM changes. Reopening it
121
+ // in the `toggle` handler instead would visibly flicker close→open now
122
+ // that the ::details-content height transition animates.
123
+ item.addEventListener('beforetoggle', (e) => {
124
+ if (accordion._applying)
125
+ return; // programmatic state change in progress
126
+ if (e.newState !== 'closed' || collapsible)
127
+ return;
128
+ if (!Array.from(items).some((i) => i !== item && i.open))
129
+ e.preventDefault();
130
+ });
119
131
  item.addEventListener('toggle', () => {
120
132
  if (accordion._applying)
121
133
  return; // programmatic state change in progress
@@ -126,6 +138,10 @@ function init() {
126
138
  });
127
139
  }
128
140
  else if (!collapsible) {
141
+ // fallback for browsers without beforetoggle (which the deny above
142
+ // needs): reopen, accepting the flicker — better than losing the
143
+ // single-open guarantee. Modern browsers never reach this branch
144
+ // because a denied beforetoggle fires no toggle event at all.
129
145
  const anyOpen = Array.from(items).some((i) => i.open);
130
146
  if (!anyOpen)
131
147
  item.open = true;
@@ -171,3 +171,4 @@ These are all browser-native — no JS needed.
171
171
  - Content height animation uses `::details-content` pseudo-element with `block-size` transition and `@starting-style` for the enter animation — fully CSS-only, no JS measurement needed
172
172
  - Set `data-type="single"` for accordion behavior (only one open); omit for disclosure list (any number open)
173
173
  - Set `data-collapsible` alongside `data-type="single"` to allow all items to be closed
174
+ - A non-collapsible single accordion never closes its last open item: the attempt is denied in the cancellable `beforetoggle` event (`preventDefault()`), so the click is a silent no-op. Reopening in `toggle` instead would visibly flicker close-then-open
@@ -50,6 +50,14 @@
50
50
  }
51
51
  }
52
52
 
53
+ /* -- Scroll lock ------------------------------------------- */
54
+ /* Page behind stays put while the alert is modal (see dialog.css):
55
+ `:modal` + overflow:hidden freezes the viewport at its current offset. */
56
+ html:has(dialog.alert-dialog:modal) {
57
+ overflow: hidden;
58
+ scrollbar-gutter: stable;
59
+ }
60
+
53
61
  .alert-dialog-content {
54
62
  padding: 1.5rem;
55
63
  }