defuss-shadcn 0.7.19 → 0.8.1

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 (386) hide show
  1. package/AGENTS.md +18 -0
  2. package/ARCH.md +22 -6
  3. package/README.md +3 -1
  4. package/bun.lock +3 -0
  5. package/dist/SKILL.md +117 -0
  6. package/dist/architecture_tpl.html +154 -0
  7. package/dist/components/blog/blog.css +122 -0
  8. package/dist/components/blog/component-skill.md +85 -0
  9. package/dist/components/brand-logos/brand-logos.css +74 -0
  10. package/dist/components/brand-logos/component-skill.md +58 -0
  11. package/dist/components/checkbox/checkbox.css +9 -0
  12. package/dist/components/faq/component-skill.md +67 -0
  13. package/dist/components/faq/faq.css +88 -0
  14. package/dist/components/feature-details/component-skill.md +83 -0
  15. package/dist/components/feature-details/feature-details.css +130 -0
  16. package/dist/components/get-in-touch/component-skill.md +63 -0
  17. package/dist/components/get-in-touch/get-in-touch.css +74 -0
  18. package/dist/components/hero/component-skill.md +55 -0
  19. package/dist/components/hero/hero.css +63 -0
  20. package/dist/components/navigation-menu/navigation-menu.js +22 -20
  21. package/dist/components/newsletter/component-skill.md +62 -0
  22. package/dist/components/newsletter/newsletter.css +65 -0
  23. package/dist/components/popover/popover.js +6 -1
  24. package/dist/components/pricing/component-skill.md +107 -0
  25. package/dist/components/pricing/pricing.css +171 -0
  26. package/dist/components/product-showcase/component-skill.md +89 -0
  27. package/dist/components/product-showcase/product-showcase.css +79 -0
  28. package/dist/components/product-showcase/product-showcase.js +127 -0
  29. package/dist/components/site-footer/component-skill.md +80 -0
  30. package/dist/components/site-footer/site-footer.css +104 -0
  31. package/dist/components/site-header/component-skill.md +96 -0
  32. package/dist/components/site-header/site-header.css +73 -0
  33. package/dist/components/stats/component-skill.md +68 -0
  34. package/dist/components/stats/stats.css +88 -0
  35. package/dist/components/testimonials/component-skill.md +79 -0
  36. package/dist/components/testimonials/testimonials.css +129 -0
  37. package/dist/documentation/accessibility.html +14 -0
  38. package/dist/documentation/accordion.html +14 -0
  39. package/dist/documentation/alert-dialog.html +14 -0
  40. package/dist/documentation/alert.html +14 -0
  41. package/dist/documentation/animations.html +14 -0
  42. package/dist/documentation/architecture.html +216 -0
  43. package/dist/documentation/avatar.html +14 -0
  44. package/dist/documentation/badge.html +14 -0
  45. package/dist/documentation/blog.html +517 -0
  46. package/dist/documentation/brand-logos.html +355 -0
  47. package/dist/documentation/breadcrumb.html +14 -0
  48. package/dist/documentation/button-group.html +14 -0
  49. package/dist/documentation/button.html +14 -0
  50. package/dist/documentation/calendar.html +14 -0
  51. package/dist/documentation/card.html +14 -0
  52. package/dist/documentation/carousel.html +14 -0
  53. package/dist/documentation/cascade-layers.html +14 -0
  54. package/dist/documentation/changelog.html +43 -0
  55. package/dist/documentation/checkbox.html +23 -0
  56. package/dist/documentation/collapsible.html +14 -0
  57. package/dist/documentation/color-picker.html +14 -0
  58. package/dist/documentation/combobox.html +14 -0
  59. package/dist/documentation/command.html +14 -0
  60. package/dist/documentation/component-skills.html +14 -0
  61. package/dist/documentation/context-menu.html +14 -0
  62. package/dist/documentation/css/docs-utilities.css +1 -0
  63. package/dist/documentation/css/layout.css +52 -3
  64. package/dist/documentation/dark-mode.html +14 -0
  65. package/dist/documentation/data-attribute-api.html +14 -0
  66. package/dist/documentation/date-picker.html +14 -0
  67. package/dist/documentation/dialog.html +14 -0
  68. package/dist/documentation/dropdown.html +14 -0
  69. package/dist/documentation/es-modules.html +14 -0
  70. package/dist/documentation/faq.html +429 -0
  71. package/dist/documentation/feature-details.html +514 -0
  72. package/dist/documentation/file-input.html +14 -0
  73. package/dist/documentation/form.html +14 -0
  74. package/dist/documentation/get-in-touch.html +358 -0
  75. package/dist/documentation/hero.html +339 -0
  76. package/dist/documentation/icon.html +14 -0
  77. package/dist/documentation/image.html +14 -0
  78. package/dist/documentation/images/mk-portrait.png +0 -0
  79. package/dist/documentation/images/mk-portrait2.png +0 -0
  80. package/dist/documentation/images/mk-square.png +0 -0
  81. package/dist/documentation/images/mk-wide.png +0 -0
  82. package/dist/documentation/images/mk-wide2.png +0 -0
  83. package/dist/documentation/images/mk-wide3.png +0 -0
  84. package/dist/documentation/index.html +15 -1
  85. package/dist/documentation/input.html +14 -0
  86. package/dist/documentation/installation.html +14 -0
  87. package/dist/documentation/js/layout.js +112 -8
  88. package/dist/documentation/js/search-index.js +1 -1
  89. package/dist/documentation/label.html +14 -0
  90. package/dist/documentation/native-web-apis.html +14 -0
  91. package/dist/documentation/navigation-menu.html +23 -7
  92. package/dist/documentation/newsletter.html +368 -0
  93. package/dist/documentation/number-input.html +14 -0
  94. package/dist/documentation/pagination.html +14 -0
  95. package/dist/documentation/popover.html +20 -1
  96. package/dist/documentation/pricing.html +658 -0
  97. package/dist/documentation/product-showcase.html +500 -0
  98. package/dist/documentation/progress.html +14 -0
  99. package/dist/documentation/radio.html +14 -0
  100. package/dist/documentation/scroll-area.html +14 -0
  101. package/dist/documentation/select.html +14 -0
  102. package/dist/documentation/separator.html +14 -0
  103. package/dist/documentation/sheet.html +14 -0
  104. package/dist/documentation/sidebar.html +14 -0
  105. package/dist/documentation/site-footer.html +503 -0
  106. package/dist/documentation/site-header.html +479 -0
  107. package/dist/documentation/skeleton.html +14 -0
  108. package/dist/documentation/slider.html +14 -0
  109. package/dist/documentation/sortable.html +14 -0
  110. package/dist/documentation/spinner.html +14 -0
  111. package/dist/documentation/statistic.html +14 -0
  112. package/dist/documentation/stats.html +433 -0
  113. package/dist/documentation/steps.html +14 -0
  114. package/dist/documentation/switch.html +14 -0
  115. package/dist/documentation/table.html +14 -0
  116. package/dist/documentation/tabs.html +14 -0
  117. package/dist/documentation/testimonials.html +497 -0
  118. package/dist/documentation/textarea.html +14 -0
  119. package/dist/documentation/theming.html +14 -0
  120. package/dist/documentation/timeline.html +14 -0
  121. package/dist/documentation/toast.html +14 -0
  122. package/dist/documentation/toggle-group.html +14 -0
  123. package/dist/documentation/toggle.html +14 -0
  124. package/dist/documentation/toolbar.html +14 -0
  125. package/dist/documentation/tooltip.html +14 -0
  126. package/dist/documentation/tree-view.html +14 -0
  127. package/dist/documentation/typography.html +14 -0
  128. package/dist/documentation/videos/demo.mp4 +0 -0
  129. package/dist/documentation/videos/demo.webm +0 -0
  130. package/dist/sitemap.xml +1 -0
  131. package/docs/accessibility.html +14 -0
  132. package/docs/accordion.html +14 -0
  133. package/docs/alert-dialog.html +14 -0
  134. package/docs/alert.html +14 -0
  135. package/docs/animations.html +14 -0
  136. package/docs/architecture.html +216 -0
  137. package/docs/avatar.html +14 -0
  138. package/docs/badge.html +14 -0
  139. package/docs/blog.html +517 -0
  140. package/docs/brand-logos.html +355 -0
  141. package/docs/breadcrumb.html +14 -0
  142. package/docs/button-group.html +14 -0
  143. package/docs/button.html +14 -0
  144. package/docs/calendar.html +14 -0
  145. package/docs/card.html +14 -0
  146. package/docs/carousel.html +14 -0
  147. package/docs/cascade-layers.html +14 -0
  148. package/docs/changelog.html +43 -0
  149. package/docs/checkbox.html +23 -0
  150. package/docs/collapsible.html +14 -0
  151. package/docs/color-picker.html +14 -0
  152. package/docs/combobox.html +14 -0
  153. package/docs/command.html +14 -0
  154. package/docs/component-skills.html +14 -0
  155. package/docs/context-menu.html +14 -0
  156. package/docs/css/docs-utilities.css +1 -0
  157. package/docs/css/layout.css +52 -3
  158. package/docs/dark-mode.html +14 -0
  159. package/docs/data-attribute-api.html +14 -0
  160. package/docs/date-picker.html +14 -0
  161. package/docs/dialog.html +14 -0
  162. package/docs/dropdown.html +14 -0
  163. package/docs/es-modules.html +14 -0
  164. package/docs/faq.html +429 -0
  165. package/docs/feature-details.html +514 -0
  166. package/docs/file-input.html +14 -0
  167. package/docs/form.html +14 -0
  168. package/docs/get-in-touch.html +358 -0
  169. package/docs/hero.html +339 -0
  170. package/docs/icon.html +14 -0
  171. package/docs/image.html +14 -0
  172. package/docs/images/mk-portrait.png +0 -0
  173. package/docs/images/mk-portrait2.png +0 -0
  174. package/docs/images/mk-square.png +0 -0
  175. package/docs/images/mk-wide.png +0 -0
  176. package/docs/images/mk-wide2.png +0 -0
  177. package/docs/images/mk-wide3.png +0 -0
  178. package/docs/index.html +15 -1
  179. package/docs/input.html +14 -0
  180. package/docs/installation.html +14 -0
  181. package/docs/js/layout.js +112 -8
  182. package/docs/js/search-index.js +1 -1
  183. package/docs/label.html +14 -0
  184. package/docs/native-web-apis.html +14 -0
  185. package/docs/navigation-menu.html +23 -7
  186. package/docs/newsletter.html +368 -0
  187. package/docs/number-input.html +14 -0
  188. package/docs/pagination.html +14 -0
  189. package/docs/popover.html +20 -1
  190. package/docs/pricing.html +658 -0
  191. package/docs/product-showcase.html +500 -0
  192. package/docs/progress.html +14 -0
  193. package/docs/radio.html +14 -0
  194. package/docs/scroll-area.html +14 -0
  195. package/docs/select.html +14 -0
  196. package/docs/separator.html +14 -0
  197. package/docs/sheet.html +14 -0
  198. package/docs/sidebar.html +14 -0
  199. package/docs/site-footer.html +503 -0
  200. package/docs/site-header.html +479 -0
  201. package/docs/sitemap.xml +1 -0
  202. package/docs/skeleton.html +14 -0
  203. package/docs/slider.html +14 -0
  204. package/docs/sortable.html +14 -0
  205. package/docs/spinner.html +14 -0
  206. package/docs/statistic.html +14 -0
  207. package/docs/stats.html +433 -0
  208. package/docs/steps.html +14 -0
  209. package/docs/switch.html +14 -0
  210. package/docs/table.html +14 -0
  211. package/docs/tabs.html +14 -0
  212. package/docs/testimonials.html +497 -0
  213. package/docs/textarea.html +14 -0
  214. package/docs/theming.html +14 -0
  215. package/docs/timeline.html +14 -0
  216. package/docs/toast.html +14 -0
  217. package/docs/toggle-group.html +14 -0
  218. package/docs/toggle.html +14 -0
  219. package/docs/toolbar.html +14 -0
  220. package/docs/tooltip.html +14 -0
  221. package/docs/tree-view.html +14 -0
  222. package/docs/typography.html +14 -0
  223. package/docs/videos/demo.mp4 +0 -0
  224. package/docs/videos/demo.webm +0 -0
  225. package/package.json +2 -1
  226. package/scripts/build.ts +6 -0
  227. package/scripts/lib/arch-page.ts +130 -0
  228. package/scripts/lib/changelog.ts +32 -0
  229. package/scripts/verify.ts +32 -1
  230. package/src/SKILL.md +117 -0
  231. package/src/architecture_tpl.html +154 -0
  232. package/src/components/blog/blog.css +122 -0
  233. package/src/components/blog/component-skill.md +85 -0
  234. package/src/components/brand-logos/brand-logos.css +74 -0
  235. package/src/components/brand-logos/component-skill.md +58 -0
  236. package/src/components/checkbox/checkbox.css +9 -0
  237. package/src/components/faq/component-skill.md +67 -0
  238. package/src/components/faq/faq.css +88 -0
  239. package/src/components/feature-details/component-skill.md +83 -0
  240. package/src/components/feature-details/feature-details.css +130 -0
  241. package/src/components/get-in-touch/component-skill.md +63 -0
  242. package/src/components/get-in-touch/get-in-touch.css +74 -0
  243. package/src/components/hero/component-skill.md +55 -0
  244. package/src/components/hero/hero.css +63 -0
  245. package/src/components/navigation-menu/navigation-menu.ts +9 -7
  246. package/src/components/newsletter/component-skill.md +62 -0
  247. package/src/components/newsletter/newsletter.css +65 -0
  248. package/src/components/popover/popover.ts +6 -1
  249. package/src/components/pricing/component-skill.md +107 -0
  250. package/src/components/pricing/pricing.css +171 -0
  251. package/src/components/product-showcase/component-skill.md +89 -0
  252. package/src/components/product-showcase/product-showcase.css +79 -0
  253. package/src/components/product-showcase/product-showcase.ts +89 -0
  254. package/src/components/site-footer/component-skill.md +80 -0
  255. package/src/components/site-footer/site-footer.css +104 -0
  256. package/src/components/site-header/component-skill.md +96 -0
  257. package/src/components/site-header/site-header.css +73 -0
  258. package/src/components/stats/component-skill.md +68 -0
  259. package/src/components/stats/stats.css +88 -0
  260. package/src/components/testimonials/component-skill.md +79 -0
  261. package/src/components/testimonials/testimonials.css +129 -0
  262. package/src/documentation/accessibility.html +14 -0
  263. package/src/documentation/accordion.html +14 -0
  264. package/src/documentation/alert-dialog.html +14 -0
  265. package/src/documentation/alert.html +14 -0
  266. package/src/documentation/animations.html +14 -0
  267. package/src/documentation/architecture.html +216 -0
  268. package/src/documentation/avatar.html +14 -0
  269. package/src/documentation/badge.html +14 -0
  270. package/src/documentation/blog.html +517 -0
  271. package/src/documentation/brand-logos.html +355 -0
  272. package/src/documentation/breadcrumb.html +14 -0
  273. package/src/documentation/button-group.html +14 -0
  274. package/src/documentation/button.html +14 -0
  275. package/src/documentation/calendar.html +14 -0
  276. package/src/documentation/card.html +14 -0
  277. package/src/documentation/carousel.html +14 -0
  278. package/src/documentation/cascade-layers.html +14 -0
  279. package/src/documentation/changelog.html +43 -0
  280. package/src/documentation/checkbox.html +23 -0
  281. package/src/documentation/collapsible.html +14 -0
  282. package/src/documentation/color-picker.html +14 -0
  283. package/src/documentation/combobox.html +14 -0
  284. package/src/documentation/command.html +14 -0
  285. package/src/documentation/component-skills.html +14 -0
  286. package/src/documentation/context-menu.html +14 -0
  287. package/src/documentation/css/docs-utilities.css +1 -0
  288. package/src/documentation/css/layout.css +52 -3
  289. package/src/documentation/dark-mode.html +14 -0
  290. package/src/documentation/data-attribute-api.html +14 -0
  291. package/src/documentation/date-picker.html +14 -0
  292. package/src/documentation/dialog.html +14 -0
  293. package/src/documentation/dropdown.html +14 -0
  294. package/src/documentation/es-modules.html +14 -0
  295. package/src/documentation/faq.html +429 -0
  296. package/src/documentation/feature-details.html +514 -0
  297. package/src/documentation/file-input.html +14 -0
  298. package/src/documentation/form.html +14 -0
  299. package/src/documentation/get-in-touch.html +358 -0
  300. package/src/documentation/hero.html +339 -0
  301. package/src/documentation/icon.html +14 -0
  302. package/src/documentation/image.html +14 -0
  303. package/src/documentation/images/mk-portrait.png +0 -0
  304. package/src/documentation/images/mk-portrait2.png +0 -0
  305. package/src/documentation/images/mk-square.png +0 -0
  306. package/src/documentation/images/mk-wide.png +0 -0
  307. package/src/documentation/images/mk-wide2.png +0 -0
  308. package/src/documentation/images/mk-wide3.png +0 -0
  309. package/src/documentation/index.html +15 -1
  310. package/src/documentation/input.html +14 -0
  311. package/src/documentation/installation.html +14 -0
  312. package/src/documentation/js/layout.ts +102 -8
  313. package/src/documentation/js/search-index.js +1 -1
  314. package/src/documentation/label.html +14 -0
  315. package/src/documentation/native-web-apis.html +14 -0
  316. package/src/documentation/navigation-menu.html +23 -7
  317. package/src/documentation/newsletter.html +368 -0
  318. package/src/documentation/number-input.html +14 -0
  319. package/src/documentation/pagination.html +14 -0
  320. package/src/documentation/popover.html +20 -1
  321. package/src/documentation/pricing.html +658 -0
  322. package/src/documentation/product-showcase.html +500 -0
  323. package/src/documentation/progress.html +14 -0
  324. package/src/documentation/radio.html +14 -0
  325. package/src/documentation/scroll-area.html +14 -0
  326. package/src/documentation/select.html +14 -0
  327. package/src/documentation/separator.html +14 -0
  328. package/src/documentation/sheet.html +14 -0
  329. package/src/documentation/sidebar.html +14 -0
  330. package/src/documentation/site-footer.html +503 -0
  331. package/src/documentation/site-header.html +479 -0
  332. package/src/documentation/skeleton.html +14 -0
  333. package/src/documentation/slider.html +14 -0
  334. package/src/documentation/sortable.html +14 -0
  335. package/src/documentation/spinner.html +14 -0
  336. package/src/documentation/statistic.html +14 -0
  337. package/src/documentation/stats.html +433 -0
  338. package/src/documentation/steps.html +14 -0
  339. package/src/documentation/switch.html +14 -0
  340. package/src/documentation/table.html +14 -0
  341. package/src/documentation/tabs.html +14 -0
  342. package/src/documentation/testimonials.html +497 -0
  343. package/src/documentation/textarea.html +14 -0
  344. package/src/documentation/theming.html +14 -0
  345. package/src/documentation/timeline.html +14 -0
  346. package/src/documentation/toast.html +14 -0
  347. package/src/documentation/toggle-group.html +14 -0
  348. package/src/documentation/toggle.html +14 -0
  349. package/src/documentation/toolbar.html +14 -0
  350. package/src/documentation/tooltip.html +14 -0
  351. package/src/documentation/tree-view.html +14 -0
  352. package/src/documentation/typography.html +14 -0
  353. package/src/documentation/videos/demo.mp4 +0 -0
  354. package/src/documentation/videos/demo.webm +0 -0
  355. package/src/sitemap.xml +1 -0
  356. package/tests/changelog.test.ts +34 -0
  357. package/tests/e2e/blog.e2e-fixture.html +67 -0
  358. package/tests/e2e/blog.e2e.ts +45 -0
  359. package/tests/e2e/brand-logos.e2e-fixture.html +31 -0
  360. package/tests/e2e/brand-logos.e2e.ts +82 -0
  361. package/tests/e2e/documentation.e2e.ts +44 -0
  362. package/tests/e2e/faq.e2e-fixture.html +54 -0
  363. package/tests/e2e/faq.e2e.ts +43 -0
  364. package/tests/e2e/feature-details.e2e-fixture.html +64 -0
  365. package/tests/e2e/feature-details.e2e.ts +46 -0
  366. package/tests/e2e/get-in-touch.e2e-fixture.html +30 -0
  367. package/tests/e2e/get-in-touch.e2e.ts +42 -0
  368. package/tests/e2e/hero.e2e-fixture.html +30 -0
  369. package/tests/e2e/hero.e2e.ts +34 -0
  370. package/tests/e2e/navigation-menu.e2e.ts +4 -2
  371. package/tests/e2e/newsletter.e2e-fixture.html +38 -0
  372. package/tests/e2e/newsletter.e2e.ts +41 -0
  373. package/tests/e2e/pricing.e2e-fixture.html +101 -0
  374. package/tests/e2e/pricing.e2e.ts +68 -0
  375. package/tests/e2e/product-showcase.e2e-fixture.html +32 -0
  376. package/tests/e2e/product-showcase.e2e.ts +165 -0
  377. package/tests/e2e/site-footer.e2e-fixture.html +75 -0
  378. package/tests/e2e/site-footer.e2e.ts +60 -0
  379. package/tests/e2e/site-header.e2e-fixture.html +68 -0
  380. package/tests/e2e/site-header.e2e.ts +97 -0
  381. package/tests/e2e/stats.e2e-fixture.html +55 -0
  382. package/tests/e2e/stats.e2e.ts +46 -0
  383. package/tests/e2e/testimonials.e2e-fixture.html +58 -0
  384. package/tests/e2e/testimonials.e2e.ts +58 -0
  385. package/tests/readme.test.ts +4 -4
  386. package/tests/ui.test.ts +33 -0
package/AGENTS.md CHANGED
@@ -171,6 +171,23 @@ its `fix:` line states the two-commit instruction. `scripts/deploy.sh`
171
171
  automates the whole flow. Legacy entries (v0.7.13-alpha and earlier) keep
172
172
  date-only badges — the hash requirement applies from this rule onward.
173
173
 
174
+ ### ARCH.md ↔ architecture page sync (REQUIRED)
175
+
176
+ [`ARCH.md`](ARCH.md) is the repo's design manifesto (why the verifier is the
177
+ authority, how the proof loop works, where the human review sits). The docs
178
+ site publishes it as an Overview page,
179
+ [`src/documentation/architecture.html`](src/documentation/architecture.html) —
180
+ a **generated** render of ARCH.md via `src/architecture_tpl.html`
181
+ (`scripts/lib/arch-page.ts`, regenerated by `build.ts`, mirrored to the docs
182
+ site like every other page).
183
+
184
+ - **When you edit ARCH.md, run `bun run build` in the same commit** — the page
185
+ is rebuilt from it. `verify`'s `architecture ↔ ARCH.md` gate fails when the
186
+ two diverge, exactly like the SKILL.md index.
187
+ - **Never hand-edit `architecture.html`** (or its `dist/` / `docs/` copies):
188
+ like all generated files it is deleted and rebuilt; the generator would
189
+ silently revert your edit, and the gate would fail anyway.
190
+
174
191
  ### Native web platform first
175
192
 
176
193
  Every component starts from a native HTML element or browser API. If the browser
@@ -958,6 +975,7 @@ The sidebar is ordered by dependency (primitives first):
958
975
  8. Overlays (Popover, Tooltip, Context Menu, Dialog, Sheet, Accordion, Command)
959
976
  9. Navigation (Breadcrumb, Pagination, Steps, Tabs, Dropdown Menu, Navigation Menu)
960
977
  10. Application (Sidebar)
978
+ 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
979
 
962
980
  To reorder, edit the `NAV` array in `layout.js`.
963
981
 
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/README.md CHANGED
@@ -11,7 +11,9 @@
11
11
 
12
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.
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
 
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
@@ -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.
@@ -0,0 +1,154 @@
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
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/marked/15.0.7/marked.min.js" defer integrity="sha384-H+hy9ULve6xfxRkWIh/YOtvDdpXgV2fmAGQkIDTxIgZwNoaoBal14Di2YTMR6MzR" crossorigin="anonymous"></script>
27
+ <link rel="stylesheet" href="../components/button/button.css">
28
+ <link rel="stylesheet" href="../components/card/card.css">
29
+ <link rel="stylesheet" href="../components/dialog/dialog.css">
30
+ <link rel="stylesheet" href="../components/badge/badge.css">
31
+ <link rel="stylesheet" href="../components/input/input.css">
32
+ <link rel="stylesheet" href="../components/accordion/accordion.css">
33
+ <link rel="stylesheet" href="../components/tabs/tabs.css">
34
+ <link rel="stylesheet" href="../components/dropdown/dropdown.css">
35
+ <link rel="stylesheet" href="../components/toast/toast.css">
36
+ <link rel="stylesheet" href="../components/combobox/combobox.css">
37
+ <link rel="stylesheet" href="../components/sheet/sheet.css">
38
+ <link rel="stylesheet" href="../components/toggle/toggle.css">
39
+ <link rel="stylesheet" href="../components/icon/icon.css">
40
+ <link rel="stylesheet" href="../components/typography/typography.css">
41
+ <link rel="stylesheet" href="../components/separator/separator.css">
42
+ <link rel="stylesheet" href="../components/label/label.css">
43
+ <link rel="stylesheet" href="../components/toggle-group/toggle-group.css">
44
+ <link rel="stylesheet" href="../components/button-group/button-group.css">
45
+ <link rel="stylesheet" href="../components/toolbar/toolbar.css">
46
+ <link rel="stylesheet" href="../components/textarea/textarea.css">
47
+ <link rel="stylesheet" href="../components/checkbox/checkbox.css">
48
+ <link rel="stylesheet" href="../components/radio/radio.css">
49
+ <link rel="stylesheet" href="../components/switch/switch.css">
50
+ <link rel="stylesheet" href="../components/slider/slider.css">
51
+ <link rel="stylesheet" href="../components/select/select.css">
52
+ <link rel="stylesheet" href="../components/number-input/number-input.css">
53
+ <link rel="stylesheet" href="../components/file-input/file-input.css">
54
+ <link rel="stylesheet" href="../components/color-picker/color-picker.css">
55
+ <link rel="stylesheet" href="../components/date-picker/date-picker.css">
56
+ <link rel="stylesheet" href="../components/form/form.css">
57
+ <link rel="stylesheet" href="../components/avatar/avatar.css">
58
+ <link rel="stylesheet" href="../components/image/image.css">
59
+ <link rel="stylesheet" href="../components/statistic/statistic.css">
60
+ <link rel="stylesheet" href="../components/table/table.css">
61
+ <link rel="stylesheet" href="../components/collapsible/collapsible.css">
62
+ <link rel="stylesheet" href="../components/timeline/timeline.css">
63
+ <link rel="stylesheet" href="../components/tree-view/tree-view.css">
64
+ <link rel="stylesheet" href="../components/calendar/calendar.css">
65
+ <link rel="stylesheet" href="../components/spinner/spinner.css">
66
+ <link rel="stylesheet" href="../components/skeleton/skeleton.css">
67
+ <link rel="stylesheet" href="../components/progress/progress.css">
68
+ <link rel="stylesheet" href="../components/alert/alert.css">
69
+ <link rel="stylesheet" href="../components/alert-dialog/alert-dialog.css">
70
+ <link rel="stylesheet" href="../components/popover/popover.css">
71
+ <link rel="stylesheet" href="../components/tooltip/tooltip.css">
72
+ <link rel="stylesheet" href="../components/context-menu/context-menu.css">
73
+ <link rel="stylesheet" href="../components/command/command.css">
74
+ <link rel="stylesheet" href="../components/breadcrumb/breadcrumb.css">
75
+ <link rel="stylesheet" href="../components/pagination/pagination.css">
76
+ <link rel="stylesheet" href="../components/steps/steps.css">
77
+ <link rel="stylesheet" href="../components/navigation-menu/navigation-menu.css">
78
+ <link rel="stylesheet" href="../components/scroll-area/scroll-area.css">
79
+ <link rel="stylesheet" href="../components/carousel/carousel.css">
80
+ <link rel="stylesheet" href="../components/sidebar/sidebar.css">
81
+ <link rel="stylesheet" href="../components/sortable/sortable.css">
82
+ <link rel="stylesheet" href="../components/site-header/site-header.css">
83
+ <link rel="stylesheet" href="../components/hero/hero.css">
84
+ <link rel="stylesheet" href="../components/product-showcase/product-showcase.css">
85
+ <link rel="stylesheet" href="../components/brand-logos/brand-logos.css">
86
+ <link rel="stylesheet" href="../components/feature-details/feature-details.css">
87
+ <link rel="stylesheet" href="../components/testimonials/testimonials.css">
88
+ <link rel="stylesheet" href="../components/stats/stats.css">
89
+ <link rel="stylesheet" href="../components/pricing/pricing.css">
90
+ <link rel="stylesheet" href="../components/blog/blog.css">
91
+ <link rel="stylesheet" href="../components/faq/faq.css">
92
+ <link rel="stylesheet" href="../components/get-in-touch/get-in-touch.css">
93
+ <link rel="stylesheet" href="../components/newsletter/newsletter.css">
94
+ <link rel="stylesheet" href="../components/site-footer/site-footer.css">
95
+ </head>
96
+ <body>
97
+ <site-header></site-header>
98
+
99
+ <div class="flex" style="margin-top: 3.5rem; min-height: calc(100vh - 3.5rem);">
100
+ <site-nav></site-nav>
101
+
102
+ <main style="flex: 1; min-width: 0; max-width: 44rem; padding: 2rem 3.5rem 8rem;">
103
+ <div class="page-header">
104
+ <p class="text-sm text-muted-foreground mb-3" style="font-family:var(--font-mono);">defuss-shadcn / architecture</p>
105
+ <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>
106
+ <p class="text-muted-foreground leading-relaxed mb-10" style="max-width:38rem;">
107
+ How defuss-shadcn scales with AI:
108
+ <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>
109
+ teaches,
110
+ <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>
111
+ enforces, screenshots prove, and a human reviews before every release. This page is generated from
112
+ <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>
113
+ on every build — a verify gate fails if the two ever diverge.
114
+ </p>
115
+ </div>
116
+
117
+ <!-- ARCH_BODY -->
118
+
119
+ </main>
120
+ </div>
121
+
122
+ <script src="js/site.js" defer></script>
123
+ <script type="module" src="js/shiki-highlight.js"></script>
124
+ <script type="module" src="../components/accordion/accordion.js"></script>
125
+ <script type="module" src="../components/combobox/combobox.js"></script>
126
+ <script type="module" src="../components/dialog/dialog.js"></script>
127
+ <script type="module" src="../components/dropdown/dropdown.js"></script>
128
+ <script type="module" src="../components/sheet/sheet.js"></script>
129
+ <script type="module" src="../components/tabs/tabs.js"></script>
130
+ <script type="module" src="../components/toast/toast.js"></script>
131
+ <script type="module" src="../components/toggle/toggle.js"></script>
132
+ <script type="module" src="../components/toggle-group/toggle-group.js"></script>
133
+ <script type="module" src="../components/toolbar/toolbar.js"></script>
134
+ <script type="module" src="../components/number-input/number-input.js"></script>
135
+ <script type="module" src="../components/color-picker/color-picker.js"></script>
136
+ <script type="module" src="../components/avatar/avatar.js"></script>
137
+ <script type="module" src="../components/image/image.js"></script>
138
+ <script type="module" src="../components/tree-view/tree-view.js"></script>
139
+ <script type="module" src="../components/calendar/calendar.js"></script>
140
+ <script type="module" src="../components/alert-dialog/alert-dialog.js"></script>
141
+ <script type="module" src="../components/popover/popover.js"></script>
142
+ <script type="module" src="../components/tooltip/tooltip.js"></script>
143
+ <script type="module" src="../components/context-menu/context-menu.js"></script>
144
+ <script type="module" src="../components/command/command.js"></script>
145
+ <script type="module" src="../components/navigation-menu/navigation-menu.js"></script>
146
+ <script type="module" src="../components/sidebar/sidebar.js"></script>
147
+ <script type="module" src="../components/carousel/carousel.js"></script>
148
+ <script type="module" src="../components/slider/slider.js"></script>
149
+ <script type="module" src="../components/sortable/sortable.js"></script>
150
+ <script type="module" src="../components/product-showcase/product-showcase.js"></script>
151
+ <script src="https://unpkg.com/lucide@1.8.0" integrity="sha384-+8nbzwDAyu5kAjqtR/XKxIgPHQD2TflvbZgeDZn5t3JP+OOogNH1jXnfel8ZAgzS" crossorigin="anonymous"></script>
152
+ <script>globalThis.lucide?.createIcons();</script>
153
+ </body>
154
+ </html>
@@ -0,0 +1,122 @@
1
+ /* -- Blog (marketing) ----------------------------------------------
2
+ Insights grid: media card with category/read-time meta, line-clamped
3
+ excerpt, and author row composed from the avatar component. */
4
+
5
+ @layer components {
6
+ .mk-blog {
7
+ container: mk-blog / inline-size;
8
+ display: flex;
9
+ flex-direction: column;
10
+ gap: 3rem;
11
+ width: 100%;
12
+ max-width: 80rem;
13
+ margin-inline: auto;
14
+ padding-inline: 1.25rem;
15
+ }
16
+
17
+ .mk-blog-head { display: flex; gap: 1.25rem; align-items: flex-start; }
18
+
19
+ .mk-blog-head-copy {
20
+ display: flex;
21
+ flex: 1;
22
+ flex-direction: column;
23
+ align-items: flex-start;
24
+ gap: 0.75rem;
25
+ width: 100%;
26
+ max-width: 48rem;
27
+ text-align: left;
28
+ }
29
+
30
+ .mk-blog-eyebrow { color: var(--primary); font-size: 1rem; font-weight: 500; }
31
+
32
+ .mk-blog-title {
33
+ margin: 0;
34
+ font-size: 1.875rem;
35
+ font-weight: 500;
36
+ letter-spacing: -0.025em;
37
+ text-wrap: balance;
38
+ }
39
+
40
+ .mk-blog-desc { margin: 0; max-width: 42rem; color: var(--muted-foreground); font-size: 1rem; text-wrap: pretty; }
41
+
42
+ .mk-blog-see-all { display: none; margin-inline-start: auto; align-self: flex-end; flex-shrink: 0; }
43
+
44
+ .mk-blog-grid { display: grid; gap: 1.25rem; width: 100%; }
45
+
46
+ .mk-blog-card { display: flex; flex-direction: column; color: inherit; text-decoration: none; }
47
+
48
+ .mk-blog-media {
49
+ position: relative;
50
+ aspect-ratio: 3 / 2;
51
+ width: 100%;
52
+ margin: 0;
53
+ overflow: hidden;
54
+ border-radius: var(--radius-lg);
55
+ background: var(--muted);
56
+
57
+ & img {
58
+ width: 100%;
59
+ height: 100%;
60
+ object-fit: cover;
61
+ display: block;
62
+ transition: opacity 150ms ease;
63
+ }
64
+ }
65
+
66
+ .mk-blog-card:hover .mk-blog-media img { opacity: 0.9; }
67
+
68
+ .mk-blog-body { display: flex; flex: 1; flex-direction: column; gap: 0.75rem; padding-block: 0.875rem; }
69
+
70
+ .mk-blog-meta { display: flex; align-items: center; justify-content: space-between; gap: 0.75rem; }
71
+
72
+ .mk-blog-category { color: var(--primary); font-size: 0.875rem; font-weight: 500; }
73
+
74
+ .mk-blog-read { color: var(--muted-foreground); font-size: 0.875rem; }
75
+
76
+ .mk-blog-copy { display: grid; gap: 0.25rem; }
77
+
78
+ .mk-blog-card-title {
79
+ margin: 0;
80
+ font-size: 1.125rem;
81
+ font-weight: 500;
82
+ letter-spacing: -0.025em;
83
+ text-wrap: balance;
84
+ }
85
+
86
+ /* excerpt clamp: exactly 3 lines (source: line-clamp-3) */
87
+ .mk-blog-excerpt {
88
+ margin: 0;
89
+ color: var(--muted-foreground);
90
+ font-size: 0.875rem;
91
+ text-wrap: pretty;
92
+ display: -webkit-box;
93
+ -webkit-line-clamp: 3;
94
+ -webkit-box-orient: vertical;
95
+ overflow: hidden;
96
+ }
97
+
98
+ .mk-blog-author { display: flex; align-items: center; gap: 0.5rem; margin-block-start: auto; }
99
+
100
+ .mk-blog-author-name { font-size: 0.875rem; font-weight: 500; }
101
+
102
+ .mk-blog-author-date { color: var(--muted-foreground); font-size: 0.75rem; }
103
+
104
+ @container mk-blog (min-width: 30rem) {
105
+ .mk-blog-grid { grid-template-columns: 1fr 1fr; }
106
+ }
107
+
108
+ @container mk-blog (min-width: 52rem) {
109
+ .mk-blog-title { font-size: 2.25rem; }
110
+ .mk-blog-see-all { display: inline-flex; }
111
+ .mk-blog-grid { grid-template-columns: repeat(3, 1fr); gap: 2.25rem; }
112
+ }
113
+
114
+ /* -- Accessibility ------------------------------------------- */
115
+ @media (prefers-reduced-motion: reduce) {
116
+ .mk-blog-media img { transition: none; }
117
+ }
118
+
119
+ @media (forced-colors: active) {
120
+ .mk-blog-card { color: LinkText; }
121
+ }
122
+ }
@@ -0,0 +1,85 @@
1
+ ---
2
+ name: Blog
3
+ why: Post cards are `<a>` + `<img>` + clamped text — line-clamp and aspect-ratio give the editorial layout for free.
4
+ when: Insights/news teasers on a marketing page; the full article list is a table or card grid instead.
5
+ where: dist/components/blog/blog.css
6
+ supportedStates: default
7
+ ---
8
+
9
+ # Pattern: Blog
10
+
11
+ ## Native basis
12
+ The whole card is a single `<a>` wrapping the preview — one tab stop,
13
+ one click target. Excerpt clamping uses `-webkit-line-clamp` (shipped
14
+ everywhere), media uses `aspect-ratio`; authors compose the
15
+ [Avatar](../avatar/component-skill.md) component.
16
+
17
+ ---
18
+
19
+ ## Native Web APIs
20
+ - [`line-clamp`](https://developer.mozilla.org/en-US/docs/Web/CSS/-webkit-line-clamp) — 3-line excerpt cut with ellipsis
21
+ - [`aspect-ratio`](https://developer.mozilla.org/en-US/docs/Web/CSS/aspect-ratio) — 3:2 preview frames
22
+ - [Avatar](../avatar/component-skill.md) — author identity row
23
+ - [Container queries](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_containment/Container_queries) — 1 → 2 → 3 columns
24
+
25
+ ---
26
+
27
+ ## Structure
28
+
29
+ ```html
30
+ <section class="mk-blog">
31
+ <div class="mk-blog-head">
32
+ <div class="mk-blog-head-copy">
33
+ <span class="mk-blog-eyebrow">Blog</span>
34
+ <h2 class="mk-blog-title">Acme Inc. Insights</h2>
35
+ <p class="mk-blog-desc">Tips to work smarter and finish faster.</p>
36
+ </div>
37
+ <a href="#" class="btn mk-blog-see-all" data-variant="secondary">See all</a>
38
+ </div>
39
+ <div class="mk-blog-grid">
40
+ <a href="#" class="mk-blog-card">
41
+ <figure class="mk-blog-media">
42
+ <img src="images/mk-wide.png" alt="Team in flow at a whiteboard" />
43
+ </figure>
44
+ <div class="mk-blog-body">
45
+ <div class="mk-blog-meta">
46
+ <span class="mk-blog-category">Productivity</span>
47
+ <span class="mk-blog-read">8 min read</span>
48
+ </div>
49
+ <div class="mk-blog-copy">
50
+ <h3 class="mk-blog-card-title">5 Ways AI Helps Teams Stay in Flow</h3>
51
+ <p class="mk-blog-excerpt">Simple ways to cut distractions and keep your team focused.</p>
52
+ </div>
53
+ <div class="mk-blog-author">
54
+ <span class="avatar" data-size="sm">
55
+ <img class="avatar-image" src="images/mk-portrait.png" alt="" />
56
+ </span>
57
+ <div class="flex flex-col">
58
+ <span class="mk-blog-author-name">Sophie Tan</span>
59
+ <time class="mk-blog-author-date" datetime="2025-09-04">4 Sept, 2025</time>
60
+ </div>
61
+ </div>
62
+ </div>
63
+ </a>
64
+ </div>
65
+ </section>
66
+ ```
67
+
68
+ The author avatar is decorative next to the visible name → `alt=""` on the author image.
69
+
70
+ ---
71
+
72
+ ## ARIA
73
+
74
+ | Attribute | Element | Purpose |
75
+ |-------------|------------------|----------------------------------------|
76
+ | `<time>` | date | Machine-readable date, human format |
77
+ | `alt=""` | author photo | Redundant beside the name text |
78
+ | one `<h3>` | card title | Headings stay navigable across cards |
79
+
80
+ ---
81
+
82
+ ## Notes
83
+ - Card links need distinct accessible names — the `<h3>` title provides it; don't duplicate the title in `alt` AND `aria-label`.
84
+ - "See all" sits `margin-inline-start: auto` and only shows ≥ 48rem container width (source's `hidden lg:flex`).
85
+ - Hover only dims the image (`opacity .9`) — never transform-lift whole cards; motion-sensitive users get none of it under reduced-motion.