@sableui/react 0.6.2 → 0.7.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 (642) hide show
  1. package/AGENTS.md +2 -2
  2. package/CHANGELOG.md +315 -0
  3. package/CONTRIBUTING.md +16 -10
  4. package/DESIGN.md +3 -3
  5. package/README.md +3 -3
  6. package/bin/sable-lint.mjs +18 -0
  7. package/bin/sable.mjs +470 -62
  8. package/dist/blocks/api-keys-block.js +44 -0
  9. package/dist/blocks/api-keys-block.meta.js +21 -0
  10. package/dist/blocks/chat-thread-block.js +17 -0
  11. package/dist/blocks/chat-thread-block.meta.js +20 -0
  12. package/dist/blocks/command-palette-block.js +24 -0
  13. package/dist/blocks/command-palette-block.meta.js +21 -0
  14. package/dist/blocks/cta-band-block.js +27 -0
  15. package/dist/blocks/cta-band-block.meta.js +20 -0
  16. package/dist/blocks/danger-zone-block.js +39 -0
  17. package/dist/blocks/danger-zone-block.meta.js +21 -0
  18. package/dist/blocks/device-comparison-block.js +69 -0
  19. package/dist/blocks/device-comparison-block.meta.js +21 -0
  20. package/dist/blocks/event-card-block.js +40 -0
  21. package/dist/blocks/event-card-block.meta.js +21 -0
  22. package/dist/blocks/faq-block.js +38 -0
  23. package/dist/blocks/faq-block.meta.js +20 -0
  24. package/dist/blocks/feature-grid-block.js +38 -0
  25. package/dist/blocks/feature-grid-block.meta.js +21 -0
  26. package/dist/blocks/feedback-form-block.js +30 -0
  27. package/dist/blocks/feedback-form-block.meta.js +21 -0
  28. package/dist/blocks/goal-progress-block.js +24 -0
  29. package/dist/blocks/goal-progress-block.meta.js +21 -0
  30. package/dist/blocks/hero-block.js +33 -0
  31. package/dist/blocks/hero-block.meta.js +21 -0
  32. package/dist/blocks/index.js +162 -1964
  33. package/dist/blocks/invite-team-block.js +36 -0
  34. package/dist/blocks/invite-team-block.meta.js +20 -0
  35. package/dist/blocks/invoice-history-block.js +41 -0
  36. package/dist/blocks/invoice-history-block.meta.js +21 -0
  37. package/dist/blocks/kpi-sparkline-block.js +29 -0
  38. package/dist/blocks/kpi-sparkline-block.meta.js +20 -0
  39. package/dist/blocks/media-player-block.js +68 -0
  40. package/dist/blocks/media-player-block.meta.js +21 -0
  41. package/dist/blocks/newsletter-block.js +35 -0
  42. package/dist/blocks/newsletter-block.meta.js +21 -0
  43. package/dist/blocks/not-found-block.js +27 -0
  44. package/dist/blocks/not-found-block.meta.js +20 -0
  45. package/dist/blocks/notification-list-block.js +32 -0
  46. package/dist/blocks/notification-list-block.meta.js +21 -0
  47. package/dist/blocks/notification-settings-block.js +25 -0
  48. package/dist/blocks/notification-settings-block.meta.js +20 -0
  49. package/dist/blocks/order-tracking-block.js +26 -0
  50. package/dist/blocks/order-tracking-block.meta.js +20 -0
  51. package/dist/blocks/pricing-card-block.js +46 -0
  52. package/dist/blocks/pricing-card-block.meta.js +21 -0
  53. package/dist/blocks/pricing-table-block.js +88 -0
  54. package/dist/blocks/pricing-table-block.meta.js +20 -0
  55. package/dist/blocks/product-card-block.js +26 -0
  56. package/dist/blocks/product-card-block.meta.js +21 -0
  57. package/dist/blocks/profile-card-block.js +58 -0
  58. package/dist/blocks/profile-card-block.meta.js +21 -0
  59. package/dist/blocks/profile-form-block.js +70 -0
  60. package/dist/blocks/profile-form-block.meta.js +21 -0
  61. package/dist/blocks/revenue-breakdown-block.js +38 -0
  62. package/dist/blocks/revenue-breakdown-block.meta.js +21 -0
  63. package/dist/blocks/sign-in-block.js +38 -0
  64. package/dist/blocks/sign-in-block.meta.js +21 -0
  65. package/dist/blocks/sign-up-block.js +48 -0
  66. package/dist/blocks/sign-up-block.meta.js +21 -0
  67. package/dist/blocks/site-footer-block.js +54 -0
  68. package/dist/blocks/site-footer-block.meta.js +20 -0
  69. package/dist/blocks/stat-row-block.js +28 -0
  70. package/dist/blocks/stat-row-block.meta.js +21 -0
  71. package/dist/blocks/steps-block.js +37 -0
  72. package/dist/blocks/steps-block.meta.js +20 -0
  73. package/dist/blocks/task-list-block.js +52 -0
  74. package/dist/blocks/task-list-block.meta.js +21 -0
  75. package/dist/blocks/team-members-block.js +49 -0
  76. package/dist/blocks/team-members-block.meta.js +21 -0
  77. package/dist/blocks/testimonial-block.js +49 -0
  78. package/dist/blocks/testimonial-block.meta.js +20 -0
  79. package/dist/blocks/traffic-sources-block.js +39 -0
  80. package/dist/blocks/traffic-sources-block.meta.js +21 -0
  81. package/dist/blocks/traffic-trend-block.js +61 -0
  82. package/dist/blocks/traffic-trend-block.meta.js +21 -0
  83. package/dist/blocks/upload-list-block.js +39 -0
  84. package/dist/blocks/upload-list-block.meta.js +21 -0
  85. package/dist/blocks/verify-code-block.js +28 -0
  86. package/dist/blocks/verify-code-block.meta.js +21 -0
  87. package/dist/blocks/wallet-block.js +48 -0
  88. package/dist/blocks/wallet-block.meta.js +21 -0
  89. package/dist/components/accordion/accordion.js +63 -0
  90. package/dist/components/accordion/accordion.meta.js +155 -0
  91. package/dist/components/accordion/index.js +15 -0
  92. package/dist/components/app-header/app-header.js +30 -0
  93. package/dist/components/app-header/app-header.meta.js +88 -0
  94. package/dist/components/app-header/index.js +7 -0
  95. package/dist/components/app-shell/app-shell-dock.js +37 -0
  96. package/dist/components/app-shell/app-shell.js +67 -0
  97. package/dist/components/app-shell/app-shell.meta.js +176 -0
  98. package/dist/components/app-shell/index.js +7 -0
  99. package/dist/components/area-chart/area-chart.js +10 -0
  100. package/dist/components/area-chart/area-chart.meta.js +218 -0
  101. package/dist/components/area-chart/index.js +7 -0
  102. package/dist/components/attachment/attachment.js +176 -0
  103. package/dist/components/attachment/attachment.meta.js +179 -0
  104. package/dist/components/attachment/attachment.variants.js +47 -0
  105. package/dist/components/attachment/index.js +7 -0
  106. package/dist/components/avatar/avatar.js +192 -0
  107. package/dist/components/avatar/avatar.meta.js +233 -0
  108. package/dist/components/avatar/avatar.variants.js +44 -0
  109. package/dist/components/avatar/index.js +22 -0
  110. package/dist/components/badge/badge.js +26 -0
  111. package/dist/components/badge/badge.meta.js +171 -0
  112. package/dist/components/badge/badge.variants.js +103 -0
  113. package/dist/components/badge/index.js +11 -0
  114. package/dist/components/banner/banner.js +76 -0
  115. package/dist/components/banner/banner.meta.js +172 -0
  116. package/dist/components/banner/banner.variants.js +44 -0
  117. package/dist/components/banner/index.js +9 -0
  118. package/dist/components/bar-chart/bar-chart.js +10 -0
  119. package/dist/components/bar-chart/bar-chart.meta.js +245 -0
  120. package/dist/components/bar-chart/index.js +7 -0
  121. package/dist/components/bottom-nav/bottom-nav.js +63 -0
  122. package/dist/components/bottom-nav/bottom-nav.meta.js +95 -0
  123. package/dist/components/bottom-nav/index.js +11 -0
  124. package/dist/components/breadcrumbs/breadcrumbs.js +90 -0
  125. package/dist/components/breadcrumbs/breadcrumbs.meta.js +111 -0
  126. package/dist/components/breadcrumbs/index.js +17 -0
  127. package/dist/components/browser/browser.js +39 -0
  128. package/dist/components/browser/browser.meta.js +80 -0
  129. package/dist/components/browser/index.js +7 -0
  130. package/dist/components/bubble/bubble.js +110 -0
  131. package/dist/components/bubble/bubble.meta.js +158 -0
  132. package/dist/components/bubble/bubble.variants.js +90 -0
  133. package/dist/components/bubble/index.js +13 -0
  134. package/dist/components/button/button.js +87 -0
  135. package/dist/components/button/button.meta.js +302 -0
  136. package/dist/components/button/button.variants.js +137 -0
  137. package/dist/components/button/index.js +9 -0
  138. package/dist/components/calendar/calendar.js +89 -0
  139. package/dist/components/calendar/calendar.meta.js +136 -0
  140. package/dist/components/calendar/index.js +7 -0
  141. package/dist/components/card/card.js +203 -0
  142. package/dist/components/card/card.meta.js +212 -0
  143. package/dist/components/card/index.js +23 -0
  144. package/dist/components/carousel/carousel.js +428 -0
  145. package/dist/components/carousel/carousel.meta.js +100 -0
  146. package/dist/components/carousel/index.js +7 -0
  147. package/dist/components/chat-composer/chat-composer.js +174 -0
  148. package/dist/components/chat-composer/chat-composer.meta.js +241 -0
  149. package/dist/components/chat-composer/chat-composer.variants.js +17 -0
  150. package/dist/components/chat-composer/index.js +7 -0
  151. package/dist/components/checkbox/checkbox-mark.js +28 -0
  152. package/dist/components/checkbox/checkbox.js +30 -0
  153. package/dist/components/checkbox/checkbox.meta.js +127 -0
  154. package/dist/components/checkbox/index.js +7 -0
  155. package/dist/components/checkbox-card/checkbox-card.js +94 -0
  156. package/dist/components/checkbox-card/checkbox-card.meta.js +154 -0
  157. package/dist/components/checkbox-card/checkbox-card.variants.js +43 -0
  158. package/dist/components/checkbox-card/index.js +11 -0
  159. package/dist/components/code/code.js +19 -0
  160. package/dist/components/code/code.meta.js +71 -0
  161. package/dist/components/code/index.js +7 -0
  162. package/dist/components/code-block/code-block.js +84 -0
  163. package/dist/components/code-block/code-block.meta.js +103 -0
  164. package/dist/components/code-block/index.js +8 -0
  165. package/dist/components/collapsible/collapsible.js +38 -0
  166. package/dist/components/collapsible/collapsible.meta.js +117 -0
  167. package/dist/components/collapsible/index.js +15 -0
  168. package/dist/components/color-field/color-field.js +293 -0
  169. package/dist/components/color-field/color-field.meta.js +142 -0
  170. package/dist/components/color-field/color.js +69 -0
  171. package/dist/components/color-field/index.js +15 -0
  172. package/dist/components/combobox/combobox.js +486 -0
  173. package/dist/components/combobox/combobox.meta.js +217 -0
  174. package/dist/components/combobox/index.js +37 -0
  175. package/dist/components/command-menu/command-menu-trigger.js +122 -0
  176. package/dist/components/command-menu/command-menu.js +433 -0
  177. package/dist/components/command-menu/command-menu.meta.js +279 -0
  178. package/dist/components/command-menu/index.js +21 -0
  179. package/dist/components/context-card/context-card.js +62 -0
  180. package/dist/components/context-card/context-card.meta.js +106 -0
  181. package/dist/components/context-card/index.js +17 -0
  182. package/dist/components/context-menu/context-menu.js +92 -0
  183. package/dist/components/context-menu/context-menu.meta.js +138 -0
  184. package/dist/components/context-menu/index.js +23 -0
  185. package/dist/components/data-table/data-table.js +142 -0
  186. package/dist/components/data-table/data-table.meta.js +146 -0
  187. package/dist/components/data-table/index.js +9 -0
  188. package/dist/components/date-picker/date-picker.js +196 -0
  189. package/dist/components/date-picker/date-picker.meta.js +164 -0
  190. package/dist/components/date-picker/index.js +7 -0
  191. package/dist/components/date-tile/date-tile.js +29 -0
  192. package/dist/components/date-tile/date-tile.meta.js +72 -0
  193. package/dist/components/date-tile/index.js +7 -0
  194. package/dist/components/destructive-action-modal/destructive-action-modal.js +130 -0
  195. package/dist/components/destructive-action-modal/destructive-action-modal.meta.js +136 -0
  196. package/dist/components/destructive-action-modal/index.js +9 -0
  197. package/dist/components/dialog/dialog.js +207 -0
  198. package/dist/components/dialog/dialog.meta.js +239 -0
  199. package/dist/components/dialog/index.js +45 -0
  200. package/dist/components/disclosure-picker/disclosure-picker.js +417 -0
  201. package/dist/components/disclosure-picker/disclosure-picker.meta.js +213 -0
  202. package/dist/components/disclosure-picker/index.js +21 -0
  203. package/dist/components/empty-state/empty-state.js +52 -0
  204. package/dist/components/empty-state/empty-state.meta.js +158 -0
  205. package/dist/components/empty-state/index.js +7 -0
  206. package/dist/components/entity/entity.js +70 -0
  207. package/dist/components/entity/entity.meta.js +108 -0
  208. package/dist/components/entity/entity.variants.js +16 -0
  209. package/dist/components/entity/index.js +7 -0
  210. package/dist/components/feedback/feedback.js +93 -0
  211. package/dist/components/feedback/feedback.meta.js +109 -0
  212. package/dist/components/feedback/index.js +7 -0
  213. package/dist/components/fieldset/fieldset.js +80 -0
  214. package/dist/components/fieldset/fieldset.meta.js +160 -0
  215. package/dist/components/fieldset/index.js +17 -0
  216. package/dist/components/file-dropzone/file-dropzone.js +193 -0
  217. package/dist/components/file-dropzone/file-dropzone.meta.js +210 -0
  218. package/dist/components/file-dropzone/file-dropzone.variants.js +26 -0
  219. package/dist/components/file-dropzone/index.js +13 -0
  220. package/dist/components/font-picker/font-picker.js +77 -0
  221. package/dist/components/font-picker/font-picker.meta.js +119 -0
  222. package/dist/components/font-picker/index.js +7 -0
  223. package/dist/components/form/form.js +145 -0
  224. package/dist/components/form/form.meta.js +142 -0
  225. package/dist/components/form/index.js +11 -0
  226. package/dist/components/gliding-highlight/gliding-highlight.js +50 -0
  227. package/dist/components/gliding-highlight/gliding-highlight.meta.js +135 -0
  228. package/dist/components/gliding-highlight/index.js +9 -0
  229. package/dist/components/gradient-art/gradient-art.js +168 -0
  230. package/dist/components/gradient-art/gradient-art.meta.js +81 -0
  231. package/dist/components/gradient-art/index.js +7 -0
  232. package/dist/components/gradient-art/renderer.js +336 -0
  233. package/dist/components/inline-status/index.js +7 -0
  234. package/dist/components/inline-status/inline-status.js +33 -0
  235. package/dist/components/inline-status/inline-status.meta.js +83 -0
  236. package/dist/components/inline-status/inline-status.variants.js +18 -0
  237. package/dist/components/input/index.js +7 -0
  238. package/dist/components/input/input.js +33 -0
  239. package/dist/components/input/input.meta.js +155 -0
  240. package/dist/components/kbd/index.js +8 -0
  241. package/dist/components/kbd/kbd.js +54 -0
  242. package/dist/components/kbd/kbd.meta.js +95 -0
  243. package/dist/components/label/index.js +7 -0
  244. package/dist/components/label/label.js +51 -0
  245. package/dist/components/label/label.meta.js +98 -0
  246. package/dist/components/line-chart/index.js +7 -0
  247. package/dist/components/line-chart/line-chart.js +10 -0
  248. package/dist/components/line-chart/line-chart.meta.js +222 -0
  249. package/dist/components/marker/index.js +7 -0
  250. package/dist/components/marker/marker.js +39 -0
  251. package/dist/components/marker/marker.meta.js +132 -0
  252. package/dist/components/marker/marker.variants.js +25 -0
  253. package/dist/components/marquee/index.js +7 -0
  254. package/dist/components/marquee/marquee.js +146 -0
  255. package/dist/components/marquee/marquee.meta.js +106 -0
  256. package/dist/components/media-image/index.js +7 -0
  257. package/dist/components/media-image/media-image.js +56 -0
  258. package/dist/components/media-image/media-image.meta.js +92 -0
  259. package/dist/components/media-tile/index.js +7 -0
  260. package/dist/components/media-tile/media-tile.js +135 -0
  261. package/dist/components/media-tile/media-tile.meta.js +133 -0
  262. package/dist/components/media-tile/media-tile.variants.js +48 -0
  263. package/dist/components/menu/index.js +33 -0
  264. package/dist/components/menu/menu.js +168 -0
  265. package/dist/components/menu/menu.meta.js +176 -0
  266. package/dist/components/message/index.js +7 -0
  267. package/dist/components/message/message.js +83 -0
  268. package/dist/components/message/message.meta.js +150 -0
  269. package/dist/components/message/message.variants.js +41 -0
  270. package/dist/components/message-scroller/index.js +9 -0
  271. package/dist/components/message-scroller/message-scroller.js +300 -0
  272. package/dist/components/message-scroller/message-scroller.meta.js +172 -0
  273. package/dist/components/meter/index.js +20 -0
  274. package/dist/components/meter/meter.js +112 -0
  275. package/dist/components/meter/meter.meta.js +227 -0
  276. package/dist/components/meter/meter.variants.js +61 -0
  277. package/dist/components/middle-truncate/index.js +7 -0
  278. package/dist/components/middle-truncate/middle-truncate.js +28 -0
  279. package/dist/components/middle-truncate/middle-truncate.meta.js +77 -0
  280. package/dist/components/note/index.js +9 -0
  281. package/dist/components/note/note.js +73 -0
  282. package/dist/components/note/note.meta.js +112 -0
  283. package/dist/components/note/note.variants.js +22 -0
  284. package/dist/components/notification-badge/index.js +15 -0
  285. package/dist/components/notification-badge/notification-badge.js +48 -0
  286. package/dist/components/notification-badge/notification-badge.meta.js +107 -0
  287. package/dist/components/notification-badge/notification-badge.variants.js +57 -0
  288. package/dist/components/number-field/index.js +7 -0
  289. package/dist/components/number-field/number-field.js +70 -0
  290. package/dist/components/number-field/number-field.meta.js +109 -0
  291. package/dist/components/otp-field/index.js +7 -0
  292. package/dist/components/otp-field/otp-field.js +70 -0
  293. package/dist/components/otp-field/otp-field.meta.js +197 -0
  294. package/dist/components/overflow-menu/index.js +7 -0
  295. package/dist/components/overflow-menu/overflow-menu.js +26 -0
  296. package/dist/components/overflow-menu/overflow-menu.meta.js +100 -0
  297. package/dist/components/page-header/index.js +7 -0
  298. package/dist/components/page-header/page-header.js +34 -0
  299. package/dist/components/page-header/page-header.meta.js +104 -0
  300. package/dist/components/page-loader/index.js +7 -0
  301. package/dist/components/page-loader/page-loader.js +37 -0
  302. package/dist/components/page-loader/page-loader.meta.js +85 -0
  303. package/dist/components/pagination/index.js +7 -0
  304. package/dist/components/pagination/pagination.js +105 -0
  305. package/dist/components/pagination/pagination.meta.js +141 -0
  306. package/dist/components/panel-group/index.js +10 -0
  307. package/dist/components/panel-group/panel-group.js +168 -0
  308. package/dist/components/panel-group/panel-group.meta.js +153 -0
  309. package/dist/components/panel-section/index.js +9 -0
  310. package/dist/components/panel-section/panel-section.js +115 -0
  311. package/dist/components/panel-section/panel-section.meta.js +156 -0
  312. package/dist/components/phone/index.js +7 -0
  313. package/dist/components/phone/phone.js +50 -0
  314. package/dist/{chunk-KFZ43RKU.js → components/phone/phone.meta.js} +3 -50
  315. package/dist/{chunk-NEQNXI2G.js → components/phone/status-icons.js} +4 -4
  316. package/dist/components/pie-chart/index.js +7 -0
  317. package/dist/components/pie-chart/pie-chart.js +191 -0
  318. package/dist/components/pie-chart/pie-chart.meta.js +210 -0
  319. package/dist/components/pill/index.js +9 -0
  320. package/dist/components/pill/pill.js +24 -0
  321. package/dist/components/pill/pill.meta.js +108 -0
  322. package/dist/components/pill/pill.variants.js +65 -0
  323. package/dist/components/popover/index.js +23 -0
  324. package/dist/components/popover/popover.js +100 -0
  325. package/dist/components/popover/popover.meta.js +136 -0
  326. package/dist/components/progress/index.js +19 -0
  327. package/dist/components/progress/progress.js +70 -0
  328. package/dist/components/progress/progress.meta.js +171 -0
  329. package/dist/components/progress/progress.variants.js +17 -0
  330. package/dist/components/radar-chart/index.js +7 -0
  331. package/dist/components/radar-chart/radar-chart.js +161 -0
  332. package/dist/components/radar-chart/radar-chart.meta.js +204 -0
  333. package/dist/components/radial-chart/index.js +7 -0
  334. package/dist/components/radial-chart/radial-chart.js +175 -0
  335. package/dist/components/radial-chart/radial-chart.meta.js +216 -0
  336. package/dist/components/radio/index.js +8 -0
  337. package/dist/components/radio/radio.js +39 -0
  338. package/dist/components/radio/radio.meta.js +104 -0
  339. package/dist/components/radio-card/index.js +7 -0
  340. package/dist/components/radio-card/radio-card.js +81 -0
  341. package/dist/components/radio-card/radio-card.meta.js +144 -0
  342. package/dist/components/radio-card/radio-card.variants.js +43 -0
  343. package/dist/components/relative-time/index.js +7 -0
  344. package/dist/components/relative-time/relative-time.js +47 -0
  345. package/dist/components/relative-time/relative-time.meta.js +77 -0
  346. package/dist/components/scroller/index.js +7 -0
  347. package/dist/components/scroller/scroller.js +111 -0
  348. package/dist/components/scroller/scroller.meta.js +118 -0
  349. package/dist/components/scrub-field/index.js +7 -0
  350. package/dist/components/scrub-field/scrub-field.js +124 -0
  351. package/dist/components/scrub-field/scrub-field.meta.js +139 -0
  352. package/dist/components/search-input/index.js +7 -0
  353. package/dist/components/search-input/search-input.js +91 -0
  354. package/dist/components/search-input/search-input.meta.js +129 -0
  355. package/dist/components/section-header/index.js +7 -0
  356. package/dist/components/section-header/section-header.js +39 -0
  357. package/dist/components/section-header/section-header.meta.js +174 -0
  358. package/dist/components/segmented-bar/index.js +14 -0
  359. package/dist/components/segmented-bar/segmented-bar.js +26 -0
  360. package/dist/components/segmented-bar/segmented-bar.meta.js +108 -0
  361. package/dist/components/segmented-bar/segmented-bar.variants.js +39 -0
  362. package/dist/components/select/index.js +25 -0
  363. package/dist/components/select/select.js +191 -0
  364. package/dist/components/select/select.meta.js +189 -0
  365. package/dist/components/separator/index.js +7 -0
  366. package/dist/components/separator/separator.js +42 -0
  367. package/dist/components/separator/separator.meta.js +84 -0
  368. package/dist/components/settings-menu/index.js +11 -0
  369. package/dist/components/settings-menu/settings-menu.js +101 -0
  370. package/dist/components/settings-menu/settings-menu.meta.js +177 -0
  371. package/dist/components/settings-menu/settings-menu.variants.js +15 -0
  372. package/dist/components/sheet/index.js +29 -0
  373. package/dist/components/sheet/sheet.js +121 -0
  374. package/dist/components/sheet/sheet.meta.js +167 -0
  375. package/dist/components/sheet/sheet.variants.js +21 -0
  376. package/dist/components/show-more/index.js +7 -0
  377. package/dist/components/show-more/show-more.js +87 -0
  378. package/dist/components/show-more/show-more.meta.js +79 -0
  379. package/dist/components/side-nav/index.js +13 -0
  380. package/dist/components/side-nav/side-nav.js +75 -0
  381. package/dist/components/side-nav/side-nav.meta.js +139 -0
  382. package/dist/components/side-nav/side-nav.variants.js +34 -0
  383. package/dist/components/sidebar/index.js +21 -0
  384. package/dist/components/sidebar/sidebar.js +196 -0
  385. package/dist/components/sidebar/sidebar.meta.js +118 -0
  386. package/dist/components/skeleton/index.js +7 -0
  387. package/dist/components/skeleton/skeleton.js +16 -0
  388. package/dist/components/skeleton/skeleton.meta.js +90 -0
  389. package/dist/components/slider/index.js +21 -0
  390. package/dist/components/slider/slider.js +115 -0
  391. package/dist/components/slider/slider.meta.js +214 -0
  392. package/dist/components/sparkline/index.js +7 -0
  393. package/dist/components/sparkline/sparkline.js +84 -0
  394. package/dist/components/sparkline/sparkline.meta.js +147 -0
  395. package/dist/components/spinner/index.js +7 -0
  396. package/dist/components/spinner/spinner.js +59 -0
  397. package/dist/components/spinner/spinner.meta.js +118 -0
  398. package/dist/components/status-bar/index.js +9 -0
  399. package/dist/components/status-bar/status-bar.js +40 -0
  400. package/dist/components/status-bar/status-bar.meta.js +117 -0
  401. package/dist/components/status-dot/index.js +9 -0
  402. package/dist/components/status-dot/status-dot.js +40 -0
  403. package/dist/components/status-dot/status-dot.meta.js +113 -0
  404. package/dist/components/status-dot/status-dot.variants.js +28 -0
  405. package/dist/components/stepper/index.js +17 -0
  406. package/dist/components/stepper/stepper.js +161 -0
  407. package/dist/components/stepper/stepper.meta.js +190 -0
  408. package/dist/components/stepper/stepper.variants.js +72 -0
  409. package/dist/components/streaming-text/index.js +7 -0
  410. package/dist/components/streaming-text/streaming-text.js +55 -0
  411. package/dist/components/streaming-text/streaming-text.meta.js +147 -0
  412. package/dist/components/switch/index.js +7 -0
  413. package/dist/components/switch/switch.js +26 -0
  414. package/dist/components/switch/switch.meta.js +133 -0
  415. package/dist/components/table/index.js +23 -0
  416. package/dist/components/table/table.js +117 -0
  417. package/dist/components/table/table.meta.js +143 -0
  418. package/dist/components/tabs/index.js +17 -0
  419. package/dist/components/tabs/tabs.js +58 -0
  420. package/dist/components/tabs/tabs.meta.js +120 -0
  421. package/dist/components/textarea/index.js +7 -0
  422. package/dist/components/textarea/textarea.js +38 -0
  423. package/dist/components/textarea/textarea.meta.js +117 -0
  424. package/dist/components/theme-selector/index.js +11 -0
  425. package/dist/components/theme-selector/theme-selector.js +145 -0
  426. package/dist/components/theme-selector/theme-selector.meta.js +181 -0
  427. package/dist/components/theme-switcher/index.js +7 -0
  428. package/dist/components/theme-switcher/theme-switcher.js +106 -0
  429. package/dist/components/theme-switcher/theme-switcher.meta.js +99 -0
  430. package/dist/components/thinking-orb/index.js +9 -0
  431. package/dist/components/thinking-orb/thinking-orb.js +126 -0
  432. package/dist/components/thinking-orb/thinking-orb.meta.js +142 -0
  433. package/dist/components/thinking-orb/thinking-orb.render.js +252 -0
  434. package/dist/components/toast/index.js +29 -0
  435. package/dist/components/toast/toast.js +254 -0
  436. package/dist/components/toast/toast.meta.js +261 -0
  437. package/dist/components/toggle/index.js +13 -0
  438. package/dist/components/toggle/toggle.js +51 -0
  439. package/dist/components/toggle/toggle.meta.js +129 -0
  440. package/dist/components/toolbar/index.js +27 -0
  441. package/dist/components/toolbar/toolbar.js +80 -0
  442. package/dist/components/toolbar/toolbar.meta.js +272 -0
  443. package/dist/components/toolbar/toolbar.variants.js +16 -0
  444. package/dist/components/tooltip/index.js +21 -0
  445. package/dist/components/tooltip/tooltip.js +74 -0
  446. package/dist/components/tooltip/tooltip.meta.js +156 -0
  447. package/dist/components/tree/index.js +12 -0
  448. package/dist/components/tree/tree.js +364 -0
  449. package/dist/components/tree/tree.meta.js +334 -0
  450. package/dist/components/video/index.js +7 -0
  451. package/dist/components/video/video.js +59 -0
  452. package/dist/components/video/video.meta.js +81 -0
  453. package/dist/components/workspace/index.js +9 -0
  454. package/dist/components/workspace/workspace.js +79 -0
  455. package/dist/components/workspace/workspace.meta.js +183 -0
  456. package/dist/foundations/accessibility.js +107 -0
  457. package/dist/foundations/index.js +25 -792
  458. package/dist/foundations/motion.js +135 -0
  459. package/dist/foundations/scrolling.js +62 -0
  460. package/dist/foundations/shape.js +113 -0
  461. package/dist/foundations/spacing.js +121 -0
  462. package/dist/foundations/surfaces.js +107 -0
  463. package/dist/foundations/types.js +0 -0
  464. package/dist/foundations/typography.js +152 -0
  465. package/dist/icon/Icon.js +30 -0
  466. package/dist/icon/IconProvider.js +27 -0
  467. package/dist/icon/compose.js +13 -0
  468. package/dist/icon/index.d.ts +13 -5
  469. package/dist/icon/index.js +13 -2
  470. package/dist/icon/registry.js +0 -0
  471. package/dist/icon-sets/brands.generated.js +123 -0
  472. package/dist/icon-sets/brands.js +10 -123
  473. package/dist/icon-sets/reicon.d.ts +3 -1
  474. package/dist/icon-sets/reicon.js +209 -1
  475. package/dist/index.d.ts +618 -34
  476. package/dist/index.js +211 -11351
  477. package/dist/ios/chrome.js +36 -0
  478. package/dist/ios/index.js +19 -315
  479. package/dist/ios/liquid-glass.js +103 -0
  480. package/dist/ios/native-app.js +46 -0
  481. package/dist/ios/navigation.js +63 -0
  482. package/dist/ios/phone-frame.js +64 -0
  483. package/dist/ios/preview-theme.js +83 -0
  484. package/dist/ios/preview.js +10 -137
  485. package/dist/ios/sheet.js +85 -0
  486. package/dist/ios/theme.js +19 -0
  487. package/dist/layout/AspectBox.js +27 -0
  488. package/dist/layout/Bleed.js +15 -0
  489. package/dist/layout/Center.js +21 -0
  490. package/dist/layout/Columns.js +70 -0
  491. package/dist/layout/Grid.js +50 -0
  492. package/dist/layout/GridOverlay.js +41 -0
  493. package/dist/layout/Page.js +11 -0
  494. package/dist/layout/Region.js +39 -0
  495. package/dist/layout/Row.js +45 -0
  496. package/dist/layout/SafeArea.js +26 -0
  497. package/dist/layout/Spacer.js +9 -0
  498. package/dist/layout/SplitPane.js +55 -0
  499. package/dist/layout/Stack.js +42 -0
  500. package/dist/layout/_responsive.js +16 -0
  501. package/dist/layout/_safeArea.js +18 -0
  502. package/dist/layout/index.d.ts +30 -8
  503. package/dist/layout/index.js +14 -2
  504. package/dist/lib/anchored-scroll.js +7 -0
  505. package/dist/lib/bleed.js +7 -0
  506. package/dist/lib/chart/cartesian.js +365 -0
  507. package/dist/lib/chart/chart-frame.js +163 -0
  508. package/dist/lib/chart/chart-legend.js +13 -0
  509. package/dist/lib/chart/chart-tooltip.js +38 -0
  510. package/dist/lib/chart/format.js +24 -0
  511. package/dist/lib/chart/geometry.js +114 -0
  512. package/dist/lib/chart/motion.js +34 -0
  513. package/dist/lib/chart/scale.js +72 -0
  514. package/dist/lib/chart/types.js +45 -0
  515. package/dist/lib/chart/use-arrival.js +41 -0
  516. package/dist/{chunk-SRQWQUTW.js → lib/cn.js} +5 -5
  517. package/dist/lib/component-guidance.js +215 -0
  518. package/dist/lib/density.js +54 -0
  519. package/dist/lib/field-shell.js +11 -0
  520. package/dist/lib/glyphs.js +9 -0
  521. package/dist/lib/heading-row.js +36 -0
  522. package/dist/lib/highlight-glide.js +84 -0
  523. package/dist/lib/hit-target.js +5 -0
  524. package/dist/lib/meta.js +0 -0
  525. package/dist/lib/portal-theme-scope.js +74 -0
  526. package/dist/{chunk-FKZXAFIY.js → lib/presentation.js} +8 -3
  527. package/dist/lib/refs.js +14 -0
  528. package/dist/lib/scrub-gesture.js +50 -0
  529. package/dist/lib/segmented.js +13 -0
  530. package/dist/lib/selection-card.js +41 -0
  531. package/dist/lib/status-tone.js +13 -0
  532. package/dist/lib/taxonomy.js +214 -0
  533. package/dist/lib/trim-label.js +20 -0
  534. package/dist/lib/use-copy.js +27 -0
  535. package/dist/lib/use-edge-fade.js +32 -0
  536. package/dist/lib/use-isomorphic-layout-effect.js +8 -0
  537. package/dist/lib/use-resize-observer.js +18 -0
  538. package/dist/lib/use-scroll-activity.js +52 -0
  539. package/dist/lib/use-wheel-to-horizontal.js +65 -0
  540. package/dist/motion/MotionProvider.js +75 -0
  541. package/dist/motion/Presence.js +112 -0
  542. package/dist/motion/Reveal.js +42 -0
  543. package/dist/motion/TextReveal.js +61 -0
  544. package/dist/motion/index.js +24 -0
  545. package/dist/motion/useInView.js +36 -0
  546. package/dist/motion/useReducedMotion.js +25 -0
  547. package/dist/motion/viewTransition.js +47 -0
  548. package/dist/patterns/auth-page.js +90 -0
  549. package/dist/patterns/auth-page.meta.js +27 -0
  550. package/dist/patterns/brand-landing-page.js +341 -0
  551. package/dist/patterns/brand-landing-page.meta.js +28 -0
  552. package/dist/patterns/chat-panel.js +185 -0
  553. package/dist/patterns/chat-panel.meta.js +31 -0
  554. package/dist/patterns/dashboard-page.js +332 -0
  555. package/dist/patterns/dashboard-page.meta.js +29 -0
  556. package/dist/patterns/feed-page.js +205 -0
  557. package/dist/patterns/feed-page.meta.js +25 -0
  558. package/dist/patterns/index.js +34 -2140
  559. package/dist/patterns/landing-page.js +356 -0
  560. package/dist/patterns/landing-page.meta.js +26 -0
  561. package/dist/patterns/list-detail-page.js +373 -0
  562. package/dist/patterns/list-detail-page.meta.js +24 -0
  563. package/dist/patterns/settings-page.js +268 -0
  564. package/dist/patterns/settings-page.meta.js +27 -0
  565. package/dist/presets/index.d.ts +7 -1
  566. package/dist/presets/index.js +53 -185
  567. package/dist/styles.css +118 -3
  568. package/dist/{theme-provider-kQszHYji.d.ts → theme-provider-S0NVJs2Y.d.ts} +6 -1
  569. package/dist/{chunk-NETUFI34.js → themes/_contract.js} +14 -2
  570. package/dist/themes/atelier/index.js +17 -1
  571. package/dist/themes/contrast.js +288 -0
  572. package/dist/themes/ember/ember.css +6 -6
  573. package/dist/themes/ember/index.js +16 -1
  574. package/dist/themes/index.d.ts +1 -1
  575. package/dist/themes/index.js +3 -8
  576. package/dist/themes/meridian/index.js +16 -1
  577. package/dist/themes/poppy/index.js +17 -1
  578. package/dist/themes/prism/index.js +17 -1
  579. package/dist/themes/prism/prism.css +2 -2
  580. package/dist/themes/registry.js +59 -0
  581. package/dist/themes/sable/index.js +16 -1
  582. package/dist/{chunk-EFLC4NA3.js → themes/theme-provider.js} +38 -54
  583. package/dist/themes/verdant/index.js +17 -1
  584. package/llms/blocks/media-player-block.md +20 -7
  585. package/llms/blocks/product-card-block.md +6 -4
  586. package/llms/blocks/task-list-block.md +1 -1
  587. package/llms/blocks/traffic-sources-block.md +1 -1
  588. package/llms/blocks/traffic-trend-block.md +5 -3
  589. package/llms/blocks/verify-code-block.md +1 -1
  590. package/llms/components/app-shell.md +5 -2
  591. package/llms/components/avatar.md +25 -3
  592. package/llms/components/button.md +20 -1
  593. package/llms/components/card.md +1 -1
  594. package/llms/components/disclosure-picker.md +168 -0
  595. package/llms/components/font-picker.md +104 -0
  596. package/llms/components/media-image.md +98 -0
  597. package/llms/components/media-tile.md +143 -0
  598. package/llms/components/page-header.md +6 -5
  599. package/llms/components/pie-chart.md +2 -2
  600. package/llms/components/radial-chart.md +1 -1
  601. package/llms/components/section-header.md +144 -0
  602. package/llms/components/sheet.md +10 -0
  603. package/llms/components/sidebar.md +4 -3
  604. package/llms/components/slider.md +14 -2
  605. package/llms/components/theme-selector.md +44 -4
  606. package/llms/components/tree.md +3 -3
  607. package/llms/layout/grid.md +24 -3
  608. package/llms/layout/region.md +16 -3
  609. package/llms/patterns/dashboard-page.md +3 -6
  610. package/llms/patterns/feed-page.md +4 -4
  611. package/llms/patterns/list-detail-page.md +1 -0
  612. package/llms/patterns/settings-page.md +2 -5
  613. package/llms/reference/utilities.md +84 -4
  614. package/llms/tasks/building-a-page.md +34 -3
  615. package/llms/tasks/converting-an-app.md +14 -4
  616. package/llms/tasks/creating-a-preset.md +4 -1
  617. package/llms/tasks/reviewing-a-design.md +19 -0
  618. package/llms/tasks/using-presets.md +19 -0
  619. package/llms-full.txt +1066 -78
  620. package/llms.txt +26 -9
  621. package/package.json +1 -1
  622. package/registry.json +2342 -164
  623. package/scripts/agent-setup.mjs +90 -0
  624. package/scripts/design-presets.mjs +59 -6
  625. package/scripts/grade.mjs +195 -29
  626. package/scripts/lint-rules.mjs +486 -10
  627. package/scripts/review-evidence.mjs +28 -1
  628. package/skills/sable/SKILL.md +67 -24
  629. package/targets/ios.json +45 -0
  630. package/dist/chunk-3IWZYBGH.js +0 -398
  631. package/dist/chunk-7MG4SHYX.js +0 -15
  632. package/dist/chunk-7QSDYBXO.js +0 -7421
  633. package/dist/chunk-ADLLDWLW.js +0 -15
  634. package/dist/chunk-C4Z3CF54.js +0 -15
  635. package/dist/chunk-EDXLM7YL.js +0 -5078
  636. package/dist/chunk-EHH4MHO6.js +0 -14
  637. package/dist/chunk-K7RUHUGC.js +0 -14
  638. package/dist/chunk-KO3NAEBF.js +0 -15
  639. package/dist/chunk-L4IEIQQA.js +0 -14
  640. package/dist/chunk-QJ6FWTUG.js +0 -40
  641. package/dist/chunk-VVW4UCDI.js +0 -4908
  642. package/dist/chunk-XAZGMY73.js +0 -187
@@ -0,0 +1,88 @@
1
+ // src/blocks/pricing-table-block.tsx
2
+ import { useId, useState } from "react";
3
+ import { Badge } from "../components/badge/index.js";
4
+ import { Button } from "../components/button/index.js";
5
+ import { Card, CardAction, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from "../components/card/index.js";
6
+ import { Toggle, ToggleGroup } from "../components/toggle/index.js";
7
+ import { Icon } from "../icon/index.js";
8
+ import { cn } from "../lib/cn.js";
9
+ import { Grid, Region, Stack } from "../layout/index.js";
10
+ import { jsx, jsxs } from "react/jsx-runtime";
11
+ var tiers = [
12
+ {
13
+ id: "starter",
14
+ name: "Starter",
15
+ blurb: "For one person shipping their first editions.",
16
+ monthly: 0,
17
+ yearly: 0,
18
+ cta: "Start for free",
19
+ featured: false,
20
+ features: ["3 live editions", "Collector profiles", "Community support"]
21
+ },
22
+ {
23
+ id: "studio",
24
+ name: "Studio",
25
+ blurb: "For working artists with a steady release schedule.",
26
+ monthly: 20,
27
+ yearly: 16,
28
+ cta: "Start free trial",
29
+ featured: true,
30
+ features: ["Unlimited editions", "Scheduled drops", "Sales analytics", "Priority support"]
31
+ },
32
+ {
33
+ id: "collective",
34
+ name: "Collective",
35
+ blurb: "For galleries and teams releasing together.",
36
+ monthly: 48,
37
+ yearly: 40,
38
+ cta: "Talk to sales",
39
+ featured: false,
40
+ features: ["Everything in Studio", "Up to 10 seats", "Shared payouts", "Roles and approvals"]
41
+ }
42
+ ];
43
+ function PricingTableBlock({ className, onChoose }) {
44
+ const [period, setPeriod] = useState("yearly");
45
+ const titleId = useId();
46
+ return /* @__PURE__ */ jsx(Region, { as: "section", "aria-labelledby": titleId, max: "wide", className: cn("w-full py-16", className), children: /* @__PURE__ */ jsxs(Stack, { gap: 10, children: [
47
+ /* @__PURE__ */ jsxs(Stack, { gap: 4, align: "center", className: "text-center", children: [
48
+ /* @__PURE__ */ jsx("h2", { id: titleId, className: "text-balance text-heading-1", children: "Pricing that grows with your practice" }),
49
+ /* @__PURE__ */ jsx("p", { className: "max-w-(--measure-prose) text-body-lg text-muted-foreground", children: "Every plan includes unlimited collectors and no fees on your first $1,000 in sales." }),
50
+ /* @__PURE__ */ jsxs(ToggleGroup, { value: [period], onValueChange: (v) => v[0] && setPeriod(v[0]), "aria-label": "Billing period", children: [
51
+ /* @__PURE__ */ jsx(Toggle, { value: "monthly", children: "Monthly" }),
52
+ /* @__PURE__ */ jsx(Toggle, { value: "yearly", children: "Yearly \xB7 save 20%" })
53
+ ] })
54
+ ] }),
55
+ /* @__PURE__ */ jsx(Grid, { cols: { base: 1, md: 3 }, gap: 4, className: "items-stretch", children: tiers.map((tier) => /* @__PURE__ */ jsxs(
56
+ Card,
57
+ {
58
+ render: /* @__PURE__ */ jsx("article", {}),
59
+ className: cn("flex flex-col", tier.featured && "border-primary ring-1 ring-primary"),
60
+ children: [
61
+ /* @__PURE__ */ jsxs(CardHeader, { children: [
62
+ /* @__PURE__ */ jsx(CardTitle, { render: /* @__PURE__ */ jsx("h3", {}), children: tier.name }),
63
+ /* @__PURE__ */ jsx(CardDescription, { children: tier.blurb }),
64
+ tier.featured ? /* @__PURE__ */ jsx(CardAction, { children: /* @__PURE__ */ jsx(Badge, { tone: "edition", size: "sm", children: "Most popular" }) }) : null
65
+ ] }),
66
+ /* @__PURE__ */ jsxs(CardContent, { className: "flex flex-1 flex-col gap-5", children: [
67
+ /* @__PURE__ */ jsxs("div", { className: "flex items-baseline gap-1.5", children: [
68
+ /* @__PURE__ */ jsxs("span", { className: "text-heading-2", children: [
69
+ "$",
70
+ tier[period]
71
+ ] }),
72
+ /* @__PURE__ */ jsx("span", { className: "text-body-sm text-muted-foreground", children: "per seat / month" })
73
+ ] }),
74
+ /* @__PURE__ */ jsx("ul", { className: "flex flex-col gap-2 text-body-sm", children: tier.features.map((feature) => /* @__PURE__ */ jsxs("li", { className: "flex items-center gap-2", children: [
75
+ /* @__PURE__ */ jsx(Icon, { name: "check", className: "text-success" }),
76
+ feature
77
+ ] }, feature)) })
78
+ ] }),
79
+ /* @__PURE__ */ jsx(CardFooter, { children: /* @__PURE__ */ jsx(Button, { className: "w-full", variant: tier.featured ? "primary" : "outline", onClick: () => onChoose?.(tier.id, period), children: tier.cta }) })
80
+ ]
81
+ },
82
+ tier.id
83
+ )) })
84
+ ] }) });
85
+ }
86
+ export {
87
+ PricingTableBlock
88
+ };
@@ -0,0 +1,20 @@
1
+ // src/blocks/pricing-table-block.meta.ts
2
+ var pricingTableBlockMeta = {
3
+ name: "PricingTableBlock",
4
+ family: "Commerce",
5
+ kind: "section",
6
+ summary: 'A three-tier pricing section: heading, a Monthly/Yearly ToggleGroup, and three equal-height plan cards with the recommended one outlined in primary and badged "Most popular".',
7
+ intent: "Reach for this on a pricing page or the pricing band of a landing page, to compare plans side by side. A single plan on offer (an upgrade prompt, a paywall) is PricingCardBlock.",
8
+ notes: [
9
+ "One featured tier at most: it takes the primary button and a primary outline; the others take outline buttons so the recommendation is unmistakable.",
10
+ "Cards stretch to the tallest one and push their buttons to the bottom, so the calls to action line up across the row.",
11
+ "The yearly saving is stated in the toggle itself, where the choice is made. `onChoose` receives the tier id and the period showing."
12
+ ],
13
+ a11y: [
14
+ "Each plan is an <article> with an h3 under the section's h2, so the tiers are navigable by heading.",
15
+ 'The ToggleGroup is labelled "Billing period"; prices update in place and stay in the reading order of each card.'
16
+ ]
17
+ };
18
+ export {
19
+ pricingTableBlockMeta
20
+ };
@@ -0,0 +1,26 @@
1
+ // src/blocks/product-card-block.tsx
2
+ import { Badge } from "../components/badge/index.js";
3
+ import { Button } from "../components/button/index.js";
4
+ import { Card, CardAction, CardDescription, CardFooter, CardHeader, CardTitle } from "../components/card/index.js";
5
+ import { MediaImage } from "../components/media-image/index.js";
6
+ import { AspectBox } from "../layout/AspectBox.js";
7
+ import { cn } from "../lib/cn.js";
8
+ import { jsx, jsxs } from "react/jsx-runtime";
9
+ var product = { title: "Untitled (gold rush)", maker: "Mara Okafor", image: "", edition: "12 of 50", price: "0.42 SOL" };
10
+ function ProductCardBlock({ className, framed = true, onCollect }) {
11
+ return /* @__PURE__ */ jsxs(Card, { variant: framed ? "default" : "flat", className: cn("w-full max-w-xs overflow-hidden", className), children: [
12
+ /* @__PURE__ */ jsx(AspectBox, { ratio: 4 / 3, children: /* @__PURE__ */ jsx(MediaImage, { src: product.image, seed: product.title }) }),
13
+ /* @__PURE__ */ jsxs(CardHeader, { children: [
14
+ /* @__PURE__ */ jsx(CardTitle, { children: product.title }),
15
+ /* @__PURE__ */ jsx(CardDescription, { children: product.maker }),
16
+ /* @__PURE__ */ jsx(CardAction, { children: /* @__PURE__ */ jsx(Badge, { tone: "edition", children: product.edition }) })
17
+ ] }),
18
+ /* @__PURE__ */ jsxs(CardFooter, { className: "justify-between pt-4", children: [
19
+ /* @__PURE__ */ jsx("span", { className: "text-mono-lg", children: product.price }),
20
+ /* @__PURE__ */ jsx(Button, { onClick: onCollect, children: "Collect" })
21
+ ] })
22
+ ] });
23
+ }
24
+ export {
25
+ ProductCardBlock
26
+ };
@@ -0,0 +1,21 @@
1
+ // src/blocks/product-card-block.meta.ts
2
+ var productCardBlockMeta = {
3
+ name: "ProductCardBlock",
4
+ family: "Commerce",
5
+ kind: "card",
6
+ width: { min: "16rem", max: "20rem" },
7
+ summary: "A product card: edge-to-edge artwork, title and maker, an edition Badge, and the price beside a single buy action.",
8
+ intent: "Reach for this for a product, edition or listing in a grid or a featured slot. For a row in a dense list, use an Entity with the image as `leading` instead.",
9
+ notes: [
10
+ "The artwork runs to the card's edges; the card clips it to its own corners (overflow-hidden).",
11
+ "Prices are `text-mono-lg` \u2014 the metric mono tier with tabular figures \u2014 never a heading tier.",
12
+ "The placeholder art is painted from the palette's decorative tones so it follows the theme; swap it for the product image with real alt text."
13
+ ],
14
+ a11y: [
15
+ "The placeholder art is aria-hidden. A real product image needs alt text naming the product.",
16
+ "The card is not a link: it holds its own button. To make the whole card navigate, move the action to the detail page and render the Card as an <a>."
17
+ ]
18
+ };
19
+ export {
20
+ productCardBlockMeta
21
+ };
@@ -0,0 +1,58 @@
1
+ // src/blocks/profile-card-block.tsx
2
+ import { useState } from "react";
3
+ import { Avatar } from "../components/avatar/index.js";
4
+ import { Button } from "../components/button/index.js";
5
+ import { Card, CardContent, CardDescription, CardTitle } from "../components/card/index.js";
6
+ import { GradientArt } from "../components/gradient-art/index.js";
7
+ import { Icon } from "../icon/index.js";
8
+ import { cn } from "../lib/cn.js";
9
+ import { jsx, jsxs } from "react/jsx-runtime";
10
+ var profile = {
11
+ name: "Juno Avery",
12
+ initials: "JA",
13
+ handle: "@juno \xB7 Sound and light",
14
+ bio: "Field recordings, slowed down. New edition every full moon.",
15
+ stats: [
16
+ { value: "128", label: "posts" },
17
+ { value: "4.2k", label: "followers" }
18
+ ]
19
+ };
20
+ function ProfileCardBlock({ className, framed = true, onFollowChange, onShare }) {
21
+ const [following, setFollowing] = useState(false);
22
+ return /* @__PURE__ */ jsxs(Card, { variant: framed ? "default" : "flat", className: cn("w-full max-w-xs overflow-hidden", className), children: [
23
+ /* @__PURE__ */ jsx(GradientArt, { "aria-hidden": true, seed: profile.handle, className: "h-20" }),
24
+ /* @__PURE__ */ jsxs(CardContent, { className: "flex flex-col gap-3 pt-0", children: [
25
+ /* @__PURE__ */ jsxs("div", { className: "flex items-start justify-between", children: [
26
+ /* @__PURE__ */ jsx(Avatar, { variant: "art", size: "lg", fallback: profile.initials, alt: profile.name, className: "-mt-6 ring-4 ring-card" }),
27
+ /* @__PURE__ */ jsxs("div", { className: "flex gap-1.5 pt-3", children: [
28
+ /* @__PURE__ */ jsx(Button, { variant: "ghost", size: "icon-sm", "aria-label": "Share profile", onClick: onShare, children: /* @__PURE__ */ jsx(Icon, { name: "share" }) }),
29
+ /* @__PURE__ */ jsx(
30
+ Button,
31
+ {
32
+ size: "sm",
33
+ variant: following ? "secondary" : "primary",
34
+ onClick: () => {
35
+ setFollowing(!following);
36
+ onFollowChange?.(!following);
37
+ },
38
+ children: following ? "Following" : "Follow"
39
+ }
40
+ )
41
+ ] })
42
+ ] }),
43
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-0.5", children: [
44
+ /* @__PURE__ */ jsx(CardTitle, { children: profile.name }),
45
+ /* @__PURE__ */ jsx(CardDescription, { children: profile.handle })
46
+ ] }),
47
+ /* @__PURE__ */ jsx("p", { className: "text-body-sm", children: profile.bio }),
48
+ /* @__PURE__ */ jsx("div", { className: "flex gap-4 text-body-sm", children: profile.stats.map((s) => /* @__PURE__ */ jsxs("span", { children: [
49
+ /* @__PURE__ */ jsx("span", { className: "text-label-lg", children: s.value }),
50
+ " ",
51
+ /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: s.label })
52
+ ] }, s.label)) })
53
+ ] })
54
+ ] });
55
+ }
56
+ export {
57
+ ProfileCardBlock
58
+ };
@@ -0,0 +1,21 @@
1
+ // src/blocks/profile-card-block.meta.ts
2
+ var profileCardBlockMeta = {
3
+ name: "ProfileCardBlock",
4
+ family: "Social & messaging",
5
+ kind: "card",
6
+ width: { min: "18rem", max: "20rem" },
7
+ summary: "A profile card: a cover banner, an avatar rising into it, Share and Follow, the name and handle, a one-line bio and two counts.",
8
+ intent: "Reach for this for a person or creator summary \u2014 a suggested-follow card, a hover target's full view, the top of a profile sidebar. For a small inline preview on hover, use ContextCard; for a row in a list of people, use Entity.",
9
+ notes: [
10
+ "The avatar overlaps the banner by half its height with a ring in the card colour, so it reads as sitting on the card, not pasted over the art.",
11
+ "Follow is the one primary action and flips to a secondary Following once pressed; Share is an icon-only ghost Button beside it.",
12
+ "Counts pair a label-tier number with muted body text, so the numbers scan as a row."
13
+ ],
14
+ a11y: [
15
+ "The Share button carries aria-label; Follow's visible text changes with its state.",
16
+ "The banner is decorative (aria-hidden); the Avatar's alt is the person's name."
17
+ ]
18
+ };
19
+ export {
20
+ profileCardBlockMeta
21
+ };
@@ -0,0 +1,70 @@
1
+ // src/blocks/profile-form-block.tsx
2
+ import { Avatar } from "../components/avatar/index.js";
3
+ import { Button } from "../components/button/index.js";
4
+ import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from "../components/card/index.js";
5
+ import { Field, Form } from "../components/form/index.js";
6
+ import { Input } from "../components/input/index.js";
7
+ import { Select, SelectContent, SelectItem, SelectTrigger } from "../components/select/index.js";
8
+ import { Textarea } from "../components/textarea/index.js";
9
+ import { cn } from "../lib/cn.js";
10
+ import { Grid, Row, Stack } from "../layout/index.js";
11
+ import { jsx, jsxs } from "react/jsx-runtime";
12
+ var profile = {
13
+ name: "Ada Lovelace",
14
+ initials: "AL",
15
+ handle: "ada",
16
+ bio: "Generative artist working in plotted ink and code. New editions of 25 to 100 every month.",
17
+ timezone: "europe-london"
18
+ };
19
+ var timezones = [
20
+ { value: "europe-london", label: "London (GMT+1)" },
21
+ { value: "europe-paris", label: "Paris (GMT+2)" },
22
+ { value: "america-new-york", label: "New York (GMT\u22124)" },
23
+ { value: "america-los-angeles", label: "Los Angeles (GMT\u22127)" },
24
+ { value: "asia-tokyo", label: "Tokyo (GMT+9)" }
25
+ ];
26
+ function ProfileFormBlock({ className, framed = true, onSave }) {
27
+ return /* @__PURE__ */ jsxs(Card, { variant: framed ? "default" : "flat", className: cn("w-full max-w-2xl", className), children: [
28
+ /* @__PURE__ */ jsxs(CardHeader, { children: [
29
+ /* @__PURE__ */ jsx(CardTitle, { render: /* @__PURE__ */ jsx("h2", {}), children: "Profile" }),
30
+ /* @__PURE__ */ jsx(CardDescription, { children: "How collectors see you." })
31
+ ] }),
32
+ /* @__PURE__ */ jsxs(
33
+ Form,
34
+ {
35
+ className: "gap-0",
36
+ onSubmit: (event) => {
37
+ event.preventDefault();
38
+ onSave?.(new FormData(event.currentTarget));
39
+ },
40
+ children: [
41
+ /* @__PURE__ */ jsx(CardContent, { children: /* @__PURE__ */ jsxs(Stack, { gap: 3, children: [
42
+ /* @__PURE__ */ jsxs(Row, { gap: 2, children: [
43
+ /* @__PURE__ */ jsx(Avatar, { variant: "art", size: "lg", fallback: profile.initials, alt: profile.name }),
44
+ /* @__PURE__ */ jsxs(Stack, { gap: 0.5, align: "start", children: [
45
+ /* @__PURE__ */ jsxs(Row, { gap: 1, children: [
46
+ /* @__PURE__ */ jsx(Button, { type: "button", variant: "outline", size: "sm", children: "Upload photo" }),
47
+ /* @__PURE__ */ jsx(Button, { type: "button", variant: "ghost", size: "sm", children: "Remove" })
48
+ ] }),
49
+ /* @__PURE__ */ jsx("p", { className: "text-caption text-muted-foreground", children: "Square PNG or JPG, at least 400 px." })
50
+ ] })
51
+ ] }),
52
+ /* @__PURE__ */ jsxs(Grid, { cols: { base: 1, sm: 2 }, gap: 3, children: [
53
+ /* @__PURE__ */ jsx(Field, { label: "Display name", name: "displayName", required: true, children: /* @__PURE__ */ jsx(Input, { defaultValue: profile.name, autoComplete: "name" }) }),
54
+ /* @__PURE__ */ jsx(Field, { label: "Handle", name: "handle", description: `atelier.com/@${profile.handle}`, required: true, children: /* @__PURE__ */ jsx(Input, { defaultValue: profile.handle, autoComplete: "username", spellCheck: false }) })
55
+ ] }),
56
+ /* @__PURE__ */ jsx(Field, { label: "Bio", name: "bio", description: "Shown on your profile and edition pages.", children: /* @__PURE__ */ jsx(Textarea, { rows: 3, defaultValue: profile.bio }) }),
57
+ /* @__PURE__ */ jsx(Grid, { cols: { base: 1, sm: 2 }, gap: 3, children: /* @__PURE__ */ jsx(Field, { label: "Timezone", name: "timezone", description: "Release times use this zone.", children: /* @__PURE__ */ jsxs(Select, { defaultValue: profile.timezone, items: timezones, children: [
58
+ /* @__PURE__ */ jsx(SelectTrigger, {}),
59
+ /* @__PURE__ */ jsx(SelectContent, { children: timezones.map((zone) => /* @__PURE__ */ jsx(SelectItem, { value: zone.value, children: zone.label }, zone.value)) })
60
+ ] }) }) })
61
+ ] }) }),
62
+ /* @__PURE__ */ jsx(CardFooter, { actions: true, className: "justify-end", children: /* @__PURE__ */ jsx(Button, { type: "submit", children: "Save profile" }) })
63
+ ]
64
+ }
65
+ )
66
+ ] });
67
+ }
68
+ export {
69
+ ProfileFormBlock
70
+ };
@@ -0,0 +1,21 @@
1
+ // src/blocks/profile-form-block.meta.ts
2
+ var profileFormBlockMeta = {
3
+ name: "ProfileFormBlock",
4
+ family: "Settings & team",
5
+ kind: "card",
6
+ width: { min: "20rem", max: "42rem" },
7
+ summary: "A profile settings card: avatar with upload/remove, name and handle side by side, a bio, a timezone Select, and one Save profile in the footer.",
8
+ intent: "Reach for this for the profile or account section of settings, or any form of drafted text that is committed together. Toggles that apply instantly belong in NotificationSettingsBlock, never behind this Save.",
9
+ notes: [
10
+ "Copied from the SettingsPage page shell's Profile section; the shell keeps its own copy so it stays one self-contained file.",
11
+ "One explicit save for the whole card. Short pairs (name + handle) sit side by side from sm up with Grid cols={{ base: 1, sm: 2 }}.",
12
+ "The CardTitle renders an h2, so the section joins the page outline under its h1."
13
+ ],
14
+ a11y: [
15
+ "Field wires label, description and error to each control; the handle's URL preview is its description.",
16
+ 'The photo actions are type="button", so neither one submits the form.'
17
+ ]
18
+ };
19
+ export {
20
+ profileFormBlockMeta
21
+ };
@@ -0,0 +1,38 @@
1
+ // src/blocks/revenue-breakdown-block.tsx
2
+ import { Badge } from "../components/badge/index.js";
3
+ import { Card, CardAction, CardContent, CardDescription, CardHeader } from "../components/card/index.js";
4
+ import { SegmentedBar } from "../components/segmented-bar/index.js";
5
+ import { StatusDot } from "../components/status-dot/index.js";
6
+ import { cn } from "../lib/cn.js";
7
+ import { Grid } from "../layout/index.js";
8
+ import { jsx, jsxs } from "react/jsx-runtime";
9
+ var revenue = { label: "Revenue this month", total: "$12,480", change: "+8.2%" };
10
+ var segments = [
11
+ { label: "Editions", value: 42, tone: "edition" },
12
+ { label: "Collectibles", value: 27, tone: "collectible" },
13
+ { label: "Standard", value: 19, tone: "standard" },
14
+ { label: "Commissions", value: 12, tone: "info" }
15
+ ];
16
+ function RevenueBreakdownBlock({ className, framed = true }) {
17
+ return /* @__PURE__ */ jsxs(Card, { variant: framed ? "default" : "flat", className: cn("w-full max-w-xs", className), children: [
18
+ /* @__PURE__ */ jsxs(CardHeader, { children: [
19
+ /* @__PURE__ */ jsx(CardDescription, { children: revenue.label }),
20
+ /* @__PURE__ */ jsx(CardAction, { children: /* @__PURE__ */ jsx(Badge, { tone: "success", size: "sm", children: revenue.change }) })
21
+ ] }),
22
+ /* @__PURE__ */ jsxs(CardContent, { className: "flex flex-col gap-4 pt-2", children: [
23
+ /* @__PURE__ */ jsx("span", { className: "text-mono-xl", children: revenue.total }),
24
+ /* @__PURE__ */ jsx(SegmentedBar, { label: "Revenue by type", segments: [...segments], size: "lg" }),
25
+ /* @__PURE__ */ jsx(Grid, { "aria-hidden": true, minItemWidth: "9.5em", gap: "calc(var(--spacing) * 1.5) calc(var(--spacing) * 4)", children: segments.map((s) => /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 text-body-sm", children: [
26
+ /* @__PURE__ */ jsx(StatusDot, { tone: s.tone }),
27
+ /* @__PURE__ */ jsx("span", { className: "flex-1 text-muted-foreground", children: s.label }),
28
+ /* @__PURE__ */ jsxs("span", { className: "text-mono-caption", children: [
29
+ s.value,
30
+ "%"
31
+ ] })
32
+ ] }, s.label)) })
33
+ ] })
34
+ ] });
35
+ }
36
+ export {
37
+ RevenueBreakdownBlock
38
+ };
@@ -0,0 +1,21 @@
1
+ // src/blocks/revenue-breakdown-block.meta.ts
2
+ var revenueBreakdownBlockMeta = {
3
+ name: "RevenueBreakdownBlock",
4
+ family: "Dashboard",
5
+ kind: "card",
6
+ width: { min: "18rem", max: "20rem" },
7
+ summary: "A stat card with a breakdown: the KPI in the metric mono tier, its trend Badge, a SegmentedBar of how the total divides, and a StatusDot legend.",
8
+ intent: "Reach for this when a headline number is worth splitting into a few categories \u2014 revenue by product, storage by type, tickets by priority. A plain KPI with no split is a smaller stat card (see DashboardPage's stat row).",
9
+ notes: [
10
+ "The value is `text-mono-xl` \u2014 tabular figures, never a heading tier \u2014 and the label above it is CardDescription.",
11
+ "The legend reflows from two columns to one by measuring in em, so larger type or a narrower card never truncates a label.",
12
+ "Each category keeps the same tone in the bar and its legend dot; reuse those tones wherever the category appears."
13
+ ],
14
+ a11y: [
15
+ "The SegmentedBar is one image whose name reads every share; the legend repeats it visually and is aria-hidden so it is not announced twice.",
16
+ "The trend Badge states the change as text (+8.2%), not by colour."
17
+ ]
18
+ };
19
+ export {
20
+ revenueBreakdownBlockMeta
21
+ };
@@ -0,0 +1,38 @@
1
+ // src/blocks/sign-in-block.tsx
2
+ import { Button } from "../components/button/index.js";
3
+ import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "../components/card/index.js";
4
+ import { Input } from "../components/input/index.js";
5
+ import { Separator } from "../components/separator/index.js";
6
+ import { Icon } from "../icon/index.js";
7
+ import { cn } from "../lib/cn.js";
8
+ import { jsx, jsxs } from "react/jsx-runtime";
9
+ function SignInBlock({ className, framed = true, onSignIn }) {
10
+ return /* @__PURE__ */ jsxs(Card, { variant: framed ? "default" : "flat", className: cn("w-full max-w-xs", className), children: [
11
+ /* @__PURE__ */ jsxs(CardHeader, { children: [
12
+ /* @__PURE__ */ jsx(CardTitle, { children: "Welcome back" }),
13
+ /* @__PURE__ */ jsx(CardDescription, { children: "Sign in to pick up where you left off." })
14
+ ] }),
15
+ /* @__PURE__ */ jsx(CardContent, { children: /* @__PURE__ */ jsxs(
16
+ "form",
17
+ {
18
+ className: "flex flex-col gap-4",
19
+ onSubmit: (event) => {
20
+ event.preventDefault();
21
+ onSignIn?.("password");
22
+ },
23
+ children: [
24
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2", children: [
25
+ /* @__PURE__ */ jsx(Input, { name: "email", type: "email", autoComplete: "email", placeholder: "you@studio.com", "aria-label": "Email" }),
26
+ /* @__PURE__ */ jsx(Input, { name: "password", type: "password", autoComplete: "current-password", placeholder: "Password", "aria-label": "Password" })
27
+ ] }),
28
+ /* @__PURE__ */ jsx(Button, { type: "submit", className: "w-full", children: "Sign in" }),
29
+ /* @__PURE__ */ jsx(Separator, { label: "or" }),
30
+ /* @__PURE__ */ jsx(Button, { variant: "outline", className: "w-full", iconStart: /* @__PURE__ */ jsx(Icon, { name: "lock" }), onClick: () => onSignIn?.("passkey"), children: "Use a passkey" })
31
+ ]
32
+ }
33
+ ) })
34
+ ] });
35
+ }
36
+ export {
37
+ SignInBlock
38
+ };
@@ -0,0 +1,21 @@
1
+ // src/blocks/sign-in-block.meta.ts
2
+ var signInBlockMeta = {
3
+ name: "SignInBlock",
4
+ family: "Auth",
5
+ kind: "card",
6
+ width: { min: "18rem", max: "20rem" },
7
+ summary: 'A sign-in card: email and password, a primary Sign in, and a passkey alternative under an "or" separator.',
8
+ intent: "Reach for this wherever someone signs in inside a surface you already have \u2014 a Sheet, a Dialog, a gated panel. For a whole sign-in route with brand art beside the form, start from the AuthPage page shell instead.",
9
+ notes: [
10
+ "One primary action. The passkey is an outline Button under a labelled Separator, so it reads as an alternative, not a second submit.",
11
+ "The fields are a real <form>: Enter submits, and the browser's password manager recognises the autocomplete hints.",
12
+ "framed={false} keeps the padding and drops the surface, for a Sheet or Dialog that is already the frame."
13
+ ],
14
+ a11y: [
15
+ "Inputs carry aria-label because the design shows placeholders, not visible labels; add Field labels if your brief wants them visible.",
16
+ '`onSignIn` receives "password" or "passkey", so focus and error handling stay with the caller\'s auth flow.'
17
+ ]
18
+ };
19
+ export {
20
+ signInBlockMeta
21
+ };
@@ -0,0 +1,48 @@
1
+ // src/blocks/sign-up-block.tsx
2
+ import { Button } from "../components/button/index.js";
3
+ import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from "../components/card/index.js";
4
+ import { Field, Form } from "../components/form/index.js";
5
+ import { Input } from "../components/input/index.js";
6
+ import { cn } from "../lib/cn.js";
7
+ import { jsx, jsxs } from "react/jsx-runtime";
8
+ function SignUpBlock({ className, framed = true, onSignUp }) {
9
+ return /* @__PURE__ */ jsxs(Card, { variant: framed ? "default" : "flat", className: cn("w-full max-w-sm", className), children: [
10
+ /* @__PURE__ */ jsxs(CardHeader, { children: [
11
+ /* @__PURE__ */ jsx(CardTitle, { children: "Create your account" }),
12
+ /* @__PURE__ */ jsx(CardDescription, { children: "Free for 14 days. No card needed." })
13
+ ] }),
14
+ /* @__PURE__ */ jsxs(
15
+ Form,
16
+ {
17
+ className: "gap-0",
18
+ onSubmit: (event) => {
19
+ event.preventDefault();
20
+ const data = new FormData(event.currentTarget);
21
+ onSignUp?.({
22
+ name: String(data.get("name") ?? ""),
23
+ email: String(data.get("email") ?? ""),
24
+ password: String(data.get("password") ?? "")
25
+ });
26
+ },
27
+ children: [
28
+ /* @__PURE__ */ jsxs(CardContent, { className: "flex flex-col gap-3", children: [
29
+ /* @__PURE__ */ jsx(Field, { label: "Name", name: "name", required: true, children: /* @__PURE__ */ jsx(Input, { autoComplete: "name" }) }),
30
+ /* @__PURE__ */ jsx(Field, { label: "Work email", name: "email", required: true, children: /* @__PURE__ */ jsx(Input, { type: "email", autoComplete: "email", placeholder: "you@studio.com" }) }),
31
+ /* @__PURE__ */ jsx(Field, { label: "Password", name: "password", description: "At least 12 characters.", required: true, children: /* @__PURE__ */ jsx(Input, { type: "password", autoComplete: "new-password", minLength: 12 }) })
32
+ ] }),
33
+ /* @__PURE__ */ jsxs(CardFooter, { className: "flex-col items-stretch gap-3", children: [
34
+ /* @__PURE__ */ jsx(Button, { type: "submit", className: "w-full", children: "Create account" }),
35
+ /* @__PURE__ */ jsxs("p", { className: "text-center text-caption text-muted-foreground", children: [
36
+ "Already have an account?",
37
+ " ",
38
+ /* @__PURE__ */ jsx("a", { href: "/sign-in", className: "text-foreground underline underline-offset-4 motion-interactive hover:text-muted-foreground", children: "Sign in" })
39
+ ] })
40
+ ] })
41
+ ]
42
+ }
43
+ )
44
+ ] });
45
+ }
46
+ export {
47
+ SignUpBlock
48
+ };
@@ -0,0 +1,21 @@
1
+ // src/blocks/sign-up-block.meta.ts
2
+ var signUpBlockMeta = {
3
+ name: "SignUpBlock",
4
+ family: "Auth",
5
+ kind: "card",
6
+ width: { min: "18rem", max: "24rem" },
7
+ summary: "A sign-up card: name, work email and password as labelled Fields, one full-width Create account, and a link to sign in instead.",
8
+ intent: "Reach for this to create an account inside a surface you already have, or as the form of a sign-up route. For the whole route with brand art beside it, start from the AuthPage page shell and drop this card in.",
9
+ notes: [
10
+ "Visible labels, not placeholders: someone filling a new form needs to see what each field is after typing in it.",
11
+ "The password rule is stated up front in the Field description, before anyone fails it.",
12
+ "`onSignUp` receives the fields only after the browser's own validation (required, type=email, minLength) passes."
13
+ ],
14
+ a11y: [
15
+ "Field wires each label, description and error to its input; never hand-roll <label> + <input> pairs.",
16
+ "autoComplete hints (name, email, new-password) let password managers offer to generate and save the password."
17
+ ]
18
+ };
19
+ export {
20
+ signUpBlockMeta
21
+ };
@@ -0,0 +1,54 @@
1
+ // src/blocks/site-footer-block.tsx
2
+ import { cn } from "../lib/cn.js";
3
+ import { Region, Stack } from "../layout/index.js";
4
+ import { jsx, jsxs } from "react/jsx-runtime";
5
+ var brand = { name: "Sable", tagline: "React components, patterns, and tokens for products built with AI agents." };
6
+ var groups = [
7
+ {
8
+ title: "Product",
9
+ links: [
10
+ { label: "Components", href: "/components" },
11
+ { label: "Patterns", href: "/patterns" },
12
+ { label: "Themes", href: "/themes" },
13
+ { label: "Canvas", href: "/canvas" }
14
+ ]
15
+ },
16
+ {
17
+ title: "Resources",
18
+ links: [
19
+ { label: "Documentation", href: "/docs" },
20
+ { label: "Changelog", href: "/changelog" },
21
+ { label: "llms.txt", href: "/llms.txt" }
22
+ ]
23
+ },
24
+ {
25
+ title: "Community",
26
+ links: [
27
+ { label: "GitHub", href: "/github" },
28
+ { label: "npm", href: "/npm" },
29
+ { label: "Discussions", href: "/discussions" }
30
+ ]
31
+ }
32
+ ];
33
+ function SiteFooterBlock({ className }) {
34
+ return /* @__PURE__ */ jsx("footer", { className: cn("w-full border-t border-border", className), children: /* @__PURE__ */ jsxs(Region, { max: "wide", className: "py-12", children: [
35
+ /* @__PURE__ */ jsxs("div", { className: "grid gap-10 md:grid-cols-[minmax(0,2fr)_minmax(0,3fr)]", children: [
36
+ /* @__PURE__ */ jsxs(Stack, { gap: 3, className: "max-w-xs", children: [
37
+ /* @__PURE__ */ jsx("a", { href: "/", className: "w-fit text-title-lg motion-interactive hover:text-muted-foreground", children: brand.name }),
38
+ /* @__PURE__ */ jsx("p", { className: "text-body-sm text-muted-foreground", children: brand.tagline })
39
+ ] }),
40
+ /* @__PURE__ */ jsx("nav", { "aria-label": "Footer", className: "grid grid-cols-2 gap-8 sm:grid-cols-3", children: groups.map((group) => /* @__PURE__ */ jsxs("div", { children: [
41
+ /* @__PURE__ */ jsx("h2", { className: "text-label-md text-muted-foreground", children: group.title }),
42
+ /* @__PURE__ */ jsx("ul", { className: "mt-3 flex flex-col gap-1", children: group.links.map((link) => /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsx("a", { href: link.href, className: "flex min-h-9 items-center text-body-sm motion-interactive hover:text-muted-foreground", children: link.label }) }, link.label)) })
43
+ ] }, group.title)) })
44
+ ] }),
45
+ /* @__PURE__ */ jsx("div", { className: "mt-12 border-t border-border pt-6", children: /* @__PURE__ */ jsxs("p", { className: "text-caption text-muted-foreground", children: [
46
+ "\xA9 2026 ",
47
+ brand.name,
48
+ ". Released under the MIT license."
49
+ ] }) })
50
+ ] }) });
51
+ }
52
+ export {
53
+ SiteFooterBlock
54
+ };
@@ -0,0 +1,20 @@
1
+ // src/blocks/site-footer-block.meta.ts
2
+ var siteFooterBlockMeta = {
3
+ name: "SiteFooterBlock",
4
+ family: "Marketing",
5
+ kind: "section",
6
+ summary: "A site footer: the brand and a one-line tagline beside link groups in a labelled Footer nav, over a copyright line.",
7
+ intent: "Reach for this at the foot of a marketing or docs site. App screens inside an AppShell take no footer; their navigation lives in the sidebar.",
8
+ notes: [
9
+ "Copied from the LandingPage page shell's footer.",
10
+ "Every link is at least 36px tall (min-h-9), so the dense list is still an easy touch target.",
11
+ "Groups go two up on a phone and three up from sm; add a group only if it has three links or more."
12
+ ],
13
+ a11y: [
14
+ `Renders <footer> with a <nav aria-label="Footer">, distinct from the page's main navigation.`,
15
+ "Group titles are h2s, so the footer's structure is navigable by heading."
16
+ ]
17
+ };
18
+ export {
19
+ siteFooterBlockMeta
20
+ };
@@ -0,0 +1,28 @@
1
+ // src/blocks/stat-row-block.tsx
2
+ import { Badge } from "../components/badge/index.js";
3
+ import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "../components/card/index.js";
4
+ import { Icon } from "../icon/index.js";
5
+ import { cn } from "../lib/cn.js";
6
+ import { Grid, Row } from "../layout/index.js";
7
+ import { jsx, jsxs } from "react/jsx-runtime";
8
+ var stats = [
9
+ { label: "Revenue", value: "$18,240", delta: "+8.2%", up: true, note: "vs. $16,857" },
10
+ { label: "Collects", value: "1,284", delta: "+3.1%", up: true, note: "182 first-time" },
11
+ { label: "Collectors", value: "312", delta: "+12.4%", up: true, note: "Best month yet" },
12
+ { label: "Sell-through", value: "64%", delta: "\u22121.8%", up: false, note: "6 open editions" }
13
+ ];
14
+ function StatRowBlock({ className }) {
15
+ return /* @__PURE__ */ jsx(Grid, { cols: { base: 2, xl: 4 }, gap: 3, className: cn("w-full", className), children: stats.map((stat) => /* @__PURE__ */ jsxs(Card, { children: [
16
+ /* @__PURE__ */ jsxs(CardHeader, { children: [
17
+ /* @__PURE__ */ jsx(CardDescription, { children: stat.label }),
18
+ /* @__PURE__ */ jsx(CardTitle, { className: "text-mono-xl", children: stat.value })
19
+ ] }),
20
+ /* @__PURE__ */ jsx(CardContent, { children: /* @__PURE__ */ jsxs(Row, { gap: 1, wrap: true, children: [
21
+ /* @__PURE__ */ jsx(Badge, { tone: stat.up ? "success" : "warning", size: "sm", icon: /* @__PURE__ */ jsx(Icon, { name: stat.up ? "arrow-up" : "arrow-down" }), children: stat.delta }),
22
+ /* @__PURE__ */ jsx("span", { className: "text-caption text-muted-foreground", children: stat.note })
23
+ ] }) })
24
+ ] }, stat.label)) });
25
+ }
26
+ export {
27
+ StatRowBlock
28
+ };