@aphrody/m3-showcase 3.3.4

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 (674) hide show
  1. package/README.md +47 -0
  2. package/dist/Album-20-x0fyhqxj.png +0 -0
  3. package/dist/Album-txdjxr6p.png +0 -0
  4. package/dist/Album_Light-bnvn9x43.png +0 -0
  5. package/dist/Alias-20-jpvzp7sd.png +0 -0
  6. package/dist/Alias-fbqj79wp.png +0 -0
  7. package/dist/Alias_Light-hv5b8k7t.png +0 -0
  8. package/dist/AmazonS3-x58haer2.png +0 -0
  9. package/dist/AndroidPhotos-cj9z6mnt.png +0 -0
  10. package/dist/AppleFiles-g4g8431e.png +0 -0
  11. package/dist/ApplePhotos-f2nesvx1.png +0 -0
  12. package/dist/Application-ft1as292.png +0 -0
  13. package/dist/Application_Light-h2p2z3de.png +0 -0
  14. package/dist/Archive-20-y262mxsm.png +0 -0
  15. package/dist/Archive-vmmq3f0p.png +0 -0
  16. package/dist/Archive_Light-fqxdt82g.png +0 -0
  17. package/dist/Audio-20-345hqxr8.png +0 -0
  18. package/dist/Audio-3w697yx9.png +0 -0
  19. package/dist/Audio_Light-4pb6z10h.png +0 -0
  20. package/dist/BackBlaze-6m4qpkyc.png +0 -0
  21. package/dist/Ball-d0bcgqha.png +0 -0
  22. package/dist/Book-20-etd4fzhm.png +0 -0
  23. package/dist/Book-ekfqxh7a.png +0 -0
  24. package/dist/BookBlue-17k9z7dy.png +0 -0
  25. package/dist/Book_Light-0n5wsr76.png +0 -0
  26. package/dist/Box-rd26c0g6.png +0 -0
  27. package/dist/CloudSync-wxh5ez5h.png +0 -0
  28. package/dist/CloudSync_Light-nb09rvv4.png +0 -0
  29. package/dist/Code-20-ybgq5j59.png +0 -0
  30. package/dist/Collection-20-7g9nzzcf.png +0 -0
  31. package/dist/Collection-52f2j9wx.png +0 -0
  32. package/dist/CollectionSparkle-nj38wazp.png +0 -0
  33. package/dist/CollectionSparkle_Light-hp1jptvv.png +0 -0
  34. package/dist/Collection_Light-z7p3knd7.png +0 -0
  35. package/dist/Compute-ghst3emj.png +0 -0
  36. package/dist/Config-20-vqd0vqeb.png +0 -0
  37. package/dist/DAV-mr5nm7zs.png +0 -0
  38. package/dist/Database-20-0q97pw36.png +0 -0
  39. package/dist/Database-rcxjw7yv.png +0 -0
  40. package/dist/Database_Light-1dxfaj96.png +0 -0
  41. package/dist/DeleteLocation-3hw52syq.png +0 -0
  42. package/dist/Devices-t2f2k803.png +0 -0
  43. package/dist/Document-20-0f78jpbp.png +0 -0
  44. package/dist/Document-kgsdt3nq.png +0 -0
  45. package/dist/Document_Light-ht9avf71.png +0 -0
  46. package/dist/Document_doc-wqd2zqp2.png +0 -0
  47. package/dist/Document_doc_Light-4ppbm2he.png +0 -0
  48. package/dist/Document_memory-6vymqjra.png +0 -0
  49. package/dist/Document_pdf-7b1zt469.png +0 -0
  50. package/dist/Document_pdf_Light-42j6dt8z.png +0 -0
  51. package/dist/Document_srt-symqv91r.png +0 -0
  52. package/dist/Document_xls-j5tbzav2.png +0 -0
  53. package/dist/Document_xls_Light-w6kbrvem.png +0 -0
  54. package/dist/Document_xmp-7xqx4tm8.png +0 -0
  55. package/dist/Dotfile-20-w53rabv6.png +0 -0
  56. package/dist/Drive-7wb1bf5w.png +0 -0
  57. package/dist/Drive-AmazonS3_Light-z6j2s9xm.png +0 -0
  58. package/dist/Drive-BackBlaze_Light-tr4wfkey.png +0 -0
  59. package/dist/Drive-DAV_Light-kse85f46.png +0 -0
  60. package/dist/Drive-Darker-mss4n9ws.png +0 -0
  61. package/dist/Drive-Dropbox_Light-48naz6gc.png +0 -0
  62. package/dist/Drive-GoogleDrive_Light-t4d4180c.png +0 -0
  63. package/dist/Drive-Mega-z6k8n821.png +0 -0
  64. package/dist/Drive-Mega_Light-nk0qskfb.png +0 -0
  65. package/dist/Drive-OneDrive-sx649zqw.png +0 -0
  66. package/dist/Drive-OneDrive_Light-2n556kpe.png +0 -0
  67. package/dist/Drive-OpenStack-tcs5rge7.png +0 -0
  68. package/dist/Drive-OpenStack_Light-05qnc2gy.png +0 -0
  69. package/dist/Drive-PCloud_Light-d0h9kbwp.png +0 -0
  70. package/dist/Drive-box_Light-0cb17zc1.png +0 -0
  71. package/dist/Drive_Light-dcjdmxm9.png +0 -0
  72. package/dist/Dropbox-q4nkmy9v.png +0 -0
  73. package/dist/Encrypted-20-m8ax3zxz.png +0 -0
  74. package/dist/Encrypted-ddrf9wk4.png +0 -0
  75. package/dist/Encrypted_Light-n1mjh529.png +0 -0
  76. package/dist/Entity-a4438mse.png +0 -0
  77. package/dist/Entity_Light-acxm9r2c.png +0 -0
  78. package/dist/Executable-20-fp7e8r9j.png +0 -0
  79. package/dist/Executable_Light_old-6xd6fa1z.png +0 -0
  80. package/dist/Executable_old-cyj158kz.png +0 -0
  81. package/dist/Face_Light-pjctyrvt.png +0 -0
  82. package/dist/Folder-20-r5505wvj.png +0 -0
  83. package/dist/Folder-kc594khj.png +0 -0
  84. package/dist/Folder-tag-xmp-ff4bgkr4.png +0 -0
  85. package/dist/FolderGrey-2vy13evc.png +0 -0
  86. package/dist/FolderGrey_Light-7z31xy56.png +0 -0
  87. package/dist/FolderNoSpace-d65fr1rz.png +0 -0
  88. package/dist/FolderNoSpace_Light-r5fc4pfj.png +0 -0
  89. package/dist/Folder_Light-rrg0jy36.png +0 -0
  90. package/dist/Font-20-r5n0z7f9.png +0 -0
  91. package/dist/Game-ts1kdw4e.png +0 -0
  92. package/dist/Game_Light-4d6ty5nz.png +0 -0
  93. package/dist/Globe-b379ffpd.png +0 -0
  94. package/dist/GlobeAlt-2mjbsvpp.png +0 -0
  95. package/dist/Globe_Light-2r9sdhb0.png +0 -0
  96. package/dist/GoogleDrive-1swewbzf.png +0 -0
  97. package/dist/GoogleSansFlex-latin-23tdmmt1.woff2 +0 -0
  98. package/dist/HDD-e85re2j5.png +0 -0
  99. package/dist/HDD_Light-pfbhb5wg.png +0 -0
  100. package/dist/Heart-3nx0yjvz.png +0 -0
  101. package/dist/Heart_Light-msf9zhq6.png +0 -0
  102. package/dist/Home-waerfpg1.png +0 -0
  103. package/dist/Home_Light-mdswjrcg.png +0 -0
  104. package/dist/Image-20-7vvqrhrb.png +0 -0
  105. package/dist/Image-fz5c8462.png +0 -0
  106. package/dist/Image_Light-rp0w5n3r.png +0 -0
  107. package/dist/Indexed-nxd6ctrt.png +0 -0
  108. package/dist/Key-20-z5nhfv0c.png +0 -0
  109. package/dist/Key-4en80vnn.png +0 -0
  110. package/dist/Key_Light-h3pc5e2c.png +0 -0
  111. package/dist/Keys-9jknyggw.png +0 -0
  112. package/dist/Keys_Light-5w8kcsmz.png +0 -0
  113. package/dist/Laptop-9gwskqny.png +0 -0
  114. package/dist/Laptop_Light-pwtbqbkp.png +0 -0
  115. package/dist/Link-20-f7hh1tcv.png +0 -0
  116. package/dist/Link-w9y1yad0.png +0 -0
  117. package/dist/Link_Light-4dy9pa5j.png +0 -0
  118. package/dist/Location-7vx0yx6r.png +0 -0
  119. package/dist/LocationManaged-w1n71jx5.png +0 -0
  120. package/dist/LocationReplica-4c6ncswq.png +0 -0
  121. package/dist/Lock-mnveqyfm.png +0 -0
  122. package/dist/Lock_Light-xwnbzkjz.png +0 -0
  123. package/dist/Mega-h4j4t3sb.png +0 -0
  124. package/dist/Mesh-20-rkky209q.png +0 -0
  125. package/dist/Mesh-efjcay8j.png +0 -0
  126. package/dist/Mesh_Light-t9yyzb3y.png +0 -0
  127. package/dist/MiniSilverBox-g8dfw0cp.png +0 -0
  128. package/dist/Mobile-Android-wy5kr3bj.png +0 -0
  129. package/dist/Mobile-jpsv7vp8.png +0 -0
  130. package/dist/Mobile_Light-2rwnn5bx.png +0 -0
  131. package/dist/MoveLocation-kft0z94v.png +0 -0
  132. package/dist/MoveLocation_Light-c23j5x59.png +0 -0
  133. package/dist/Movie-nxat82kv.png +0 -0
  134. package/dist/Movie_Light-eh1hmsr5.png +0 -0
  135. package/dist/NewLocation-2hfv9dwq.png +0 -0
  136. package/dist/Node-wykht7k0.png +0 -0
  137. package/dist/Node_Light-maewxhk1.png +0 -0
  138. package/dist/OneDrive-e4jvssjp.png +0 -0
  139. package/dist/OpenStack-pqp01jfd.png +0 -0
  140. package/dist/PC-eyfa7ewm.png +0 -0
  141. package/dist/PCloud-p0n6g1hq.png +0 -0
  142. package/dist/Package-20-grg5wkse.png +0 -0
  143. package/dist/Package-d7ex1fnn.png +0 -0
  144. package/dist/Package_Light-yj2cvgyw.png +0 -0
  145. package/dist/SD-h17wvz4z.png +0 -0
  146. package/dist/SD_Light-y3mmqh6b.png +0 -0
  147. package/dist/Scrapbook-f92c8p1x.png +0 -0
  148. package/dist/Scrapbook_Light-50pjr0q7.png +0 -0
  149. package/dist/Screenshot-20-z4tfe78m.png +0 -0
  150. package/dist/Screenshot-9nd23fde.png +0 -0
  151. package/dist/ScreenshotAlt-en1yt2gv.png +0 -0
  152. package/dist/Screenshot_Light-hnbah84r.png +0 -0
  153. package/dist/Search-7x8c5z1s.png +0 -0
  154. package/dist/SearchAlt-dmxzk2jb.png +0 -0
  155. package/dist/Search_Light-n23xd2ws.png +0 -0
  156. package/dist/Server-hqsf8851.png +0 -0
  157. package/dist/Server_Light-3x01jqz4.png +0 -0
  158. package/dist/SilverBox-0mk6sxrh.png +0 -0
  159. package/dist/Spacedrop-1-d230z0az.png +0 -0
  160. package/dist/Spacedrop-r1t67bcq.png +0 -0
  161. package/dist/Spacedrop_Light-dj5tgtep.png +0 -0
  162. package/dist/Storage-4x2q4nx6.png +0 -0
  163. package/dist/Sync-531te7fq.png +0 -0
  164. package/dist/Sync_Light-754vfxyr.png +0 -0
  165. package/dist/Tablet-ze6ermb7.png +0 -0
  166. package/dist/Tablet_Light-32skyk12.png +0 -0
  167. package/dist/Tags-bfapk266.png +0 -0
  168. package/dist/Tags_Light-7s00envw.png +0 -0
  169. package/dist/Terminal-t1yjx33x.png +0 -0
  170. package/dist/Terminal_Light-4s5azdgr.png +0 -0
  171. package/dist/Text-20-pt0zjg62.png +0 -0
  172. package/dist/Text-6fgmf4b2.png +0 -0
  173. package/dist/TextAlt_Light-w9kbgvm8.png +0 -0
  174. package/dist/Text_Light-c2k3w31k.png +0 -0
  175. package/dist/Text_txt-xhvv80ys.png +0 -0
  176. package/dist/TexturedMesh-ysk831xz.png +0 -0
  177. package/dist/TexturedMesh_Light-4twy5k6k.png +0 -0
  178. package/dist/Trash-hzscccvk.png +0 -0
  179. package/dist/Trash_Light-78nc56tp.png +0 -0
  180. package/dist/Undefined-pkbecmq4.png +0 -0
  181. package/dist/Undefined_Light-jxesg2zv.png +0 -0
  182. package/dist/Unknown-20-07efh8ya.png +0 -0
  183. package/dist/Video-20-q7yg9p4w.png +0 -0
  184. package/dist/Video-370fzqyw.png +0 -0
  185. package/dist/Video_Light-00vhrp0m.png +0 -0
  186. package/dist/WebPageArchive-20-wn0v4x27.png +0 -0
  187. package/dist/Widget-20-9t860nnc.png +0 -0
  188. package/dist/Widget-k1p15mg9.png +0 -0
  189. package/dist/Widget_Light-5md790ar.png +0 -0
  190. package/dist/ace-ph0rt669.svg +1 -0
  191. package/dist/acemanifest-je939qnz.svg +1 -0
  192. package/dist/adoc-kfbf89h8.svg +1 -0
  193. package/dist/adonis-pn6tbmnq.svg +1 -0
  194. package/dist/adonisconfig-5wfnycbk.svg +1 -0
  195. package/dist/afdesign-5nzbppfa.svg +1 -0
  196. package/dist/afphoto-p941z6q7.svg +1 -0
  197. package/dist/afpub-3232tcp9.svg +1 -0
  198. package/dist/ai-vvwvj03w.svg +1 -0
  199. package/dist/air-e3h8cfx1.svg +1 -0
  200. package/dist/angular-fyg22v82.svg +1 -0
  201. package/dist/angular-kzcwnjdt.svg +1 -0
  202. package/dist/anim-15kqy432.svg +1 -0
  203. package/dist/astro-wdcxh4zx.svg +1 -0
  204. package/dist/astroconfig-73qsx73n.svg +1 -0
  205. package/dist/atomizer-42xe88w7.svg +1 -0
  206. package/dist/audio-xy5qb7t1.svg +1 -0
  207. package/dist/audiomp3-s01feh78.svg +1 -0
  208. package/dist/audioogg-bcake0v6.svg +1 -0
  209. package/dist/audiowav-px37pxve.svg +1 -0
  210. package/dist/audiowv-bq8tbfdv.svg +1 -0
  211. package/dist/azure-veqzyzqq.svg +1 -0
  212. package/dist/babel-vxcfp57a.svg +1 -0
  213. package/dist/ballerina-faxx9p3b.svg +1 -0
  214. package/dist/ballerinaconfig-tmd09kkg.svg +1 -0
  215. package/dist/bat-vjr63aqs.svg +1 -0
  216. package/dist/bazel-4e01p5gp.svg +1 -0
  217. package/dist/bazelignore-wzgc7h2d.svg +1 -0
  218. package/dist/bicep-dae0dh59.svg +1 -0
  219. package/dist/bicepconfig-v64442sp.svg +1 -0
  220. package/dist/bicepparam-ts4jjq60.svg +1 -0
  221. package/dist/binary-dz3thnjq.svg +1 -0
  222. package/dist/biome-gbahcmjy.svg +1 -0
  223. package/dist/blade-je22xc2d.svg +1 -0
  224. package/dist/brotli-1m7qfk77.svg +1 -0
  225. package/dist/browserslist-005php91.svg +1 -0
  226. package/dist/bruno-h4bh0s2c.svg +1 -0
  227. package/dist/bsconfig-gmwc0r2r.svg +1 -0
  228. package/dist/buck-gtasjqw1.svg +1 -0
  229. package/dist/bun-6y6y7t4s.svg +1 -0
  230. package/dist/bun-zxmcandz.svg +1 -0
  231. package/dist/bundler-qhs5a5xb.svg +1 -0
  232. package/dist/bunlock-74b62xbm.svg +1 -0
  233. package/dist/c-k2se7t6q.svg +1 -0
  234. package/dist/c-v9cxtxe1.svg +1 -0
  235. package/dist/cargo-ma5bwyg5.svg +1 -0
  236. package/dist/cargolock-ak0tnv5y.svg +1 -0
  237. package/dist/cert-z62mqtqq.svg +1 -0
  238. package/dist/cheader-mgw2nf38.svg +1 -0
  239. package/dist/chunk-08yjrfs5.js +2 -0
  240. package/dist/chunk-2pmrsdd5.js +2 -0
  241. package/dist/chunk-3995cv9k.js +1 -0
  242. package/dist/chunk-58a3eq49.js +2 -0
  243. package/dist/chunk-616szvb9.js +2 -0
  244. package/dist/chunk-6638b8v6.js +1 -0
  245. package/dist/chunk-6ej2n64j.js +1 -0
  246. package/dist/chunk-7tt0cawd.js +10 -0
  247. package/dist/chunk-9gxv4c5g.js +1 -0
  248. package/dist/chunk-9na12mjw.js +1 -0
  249. package/dist/chunk-b7mpjcry.js +1 -0
  250. package/dist/chunk-c1g6tshf.js +2 -0
  251. package/dist/chunk-d50zvrb1.css +1 -0
  252. package/dist/chunk-d6c35fm0.js +2 -0
  253. package/dist/chunk-ehpz56xv.js +2 -0
  254. package/dist/chunk-ewtr6sjm.js +9 -0
  255. package/dist/chunk-g9rnrhvz.js +2 -0
  256. package/dist/chunk-gv83r4qx.js +262 -0
  257. package/dist/chunk-j46wg1ym.js +156 -0
  258. package/dist/chunk-kapsksxf.js +1 -0
  259. package/dist/chunk-m98tyb4g.js +6 -0
  260. package/dist/chunk-nn0prq25.js +2 -0
  261. package/dist/chunk-nsgjb3bx.js +2 -0
  262. package/dist/chunk-p8r6wjkz.js +3 -0
  263. package/dist/chunk-rdnm87fw.js +1 -0
  264. package/dist/chunk-re36kkra.js +1 -0
  265. package/dist/chunk-vm9edd26.js +2 -0
  266. package/dist/chunk-x2hztqk0.css +1 -0
  267. package/dist/chunk-yyxb5zbq.js +2 -0
  268. package/dist/civet-5bbs33v3.svg +1 -0
  269. package/dist/claude-jscxahsf.svg +1 -0
  270. package/dist/cli-4f5nfe5s.svg +1 -0
  271. package/dist/clojure-0h7h9znc.svg +1 -0
  272. package/dist/cmake-q8ryfre0.svg +1 -0
  273. package/dist/cmake-qwe6x8nx.svg +1 -0
  274. package/dist/codeworkspace-326020b4.svg +1 -0
  275. package/dist/coffeescript-ec1bytnk.svg +1 -0
  276. package/dist/commitlint-93j0tfvp.svg +1 -0
  277. package/dist/compodoc-36b7gn70.svg +1 -0
  278. package/dist/composer-vv2tvxkr.svg +1 -0
  279. package/dist/composerlock-nf0232yh.svg +1 -0
  280. package/dist/conan-dggdfcr9.svg +1 -0
  281. package/dist/conf-5756g97p.svg +1 -0
  282. package/dist/copilot-1phy76q3.svg +1 -0
  283. package/dist/cpp-4yvddm6j.svg +1 -0
  284. package/dist/cpp-pbznrtpp.svg +1 -0
  285. package/dist/crystal-x20aj00e.svg +1 -0
  286. package/dist/csharp-0p3hstq8.svg +1 -0
  287. package/dist/csharp-cpmfe8y0.svg +1 -0
  288. package/dist/cshtml-xb5gtb0r.svg +1 -0
  289. package/dist/csproj-ftptw15a.svg +1 -0
  290. package/dist/css-tqps22nw.svg +1 -0
  291. package/dist/css-ycr1qc5f.svg +1 -0
  292. package/dist/cssmap-3gnm34f6.svg +1 -0
  293. package/dist/csv-gg0axfar.svg +1 -0
  294. package/dist/cucumber-m06dfkm5.svg +1 -0
  295. package/dist/cursor-jw7n7tpq.svg +1 -0
  296. package/dist/cypress-xsm2fq1p.svg +1 -0
  297. package/dist/cypressjs-hapzyfm1.svg +1 -0
  298. package/dist/cypressts-jey9ahc7.svg +1 -0
  299. package/dist/d-4x2njcan.svg +1 -0
  300. package/dist/dartlang-7dwdwv03.svg +1 -0
  301. package/dist/dartlang-mra7r0f8.svg +1 -0
  302. package/dist/delphiproject-7snmvsdx.svg +1 -0
  303. package/dist/diff-hekg2jpm.svg +1 -0
  304. package/dist/docker-8q58y2kc.svg +1 -0
  305. package/dist/dockerdebug-8zhgj7bd.svg +1 -0
  306. package/dist/dockerignore-488safx9.svg +1 -0
  307. package/dist/drawio-6qm0rhkv.svg +1 -0
  308. package/dist/drizzle-5bct2tg6.svg +1 -0
  309. package/dist/dsstore-pmhpmkdr.svg +1 -0
  310. package/dist/dune-r4xhac56.svg +1 -0
  311. package/dist/duneproject-3b99jndq.svg +1 -0
  312. package/dist/edge-0jwced3c.svg +1 -0
  313. package/dist/editorconfig-hee1zp1h.svg +1 -0
  314. package/dist/eex-q1bkj66x.svg +1 -0
  315. package/dist/elixir-48ge02m5.svg +1 -0
  316. package/dist/elm-97mh5wye.svg +1 -0
  317. package/dist/env-ysamxkcd.svg +1 -0
  318. package/dist/eraser-7mejjgrg.svg +1 -0
  319. package/dist/erb-f28j5x6b.svg +1 -0
  320. package/dist/erlang-3ebtbtfw.svg +1 -0
  321. package/dist/esbuild-wptxye5y.svg +1 -0
  322. package/dist/eslint-mrbexpc5.svg +1 -0
  323. package/dist/eslintignore-k65wpbsr.svg +1 -0
  324. package/dist/excalidraw-28avfa1h.svg +1 -0
  325. package/dist/exs-5w2cfpaf.svg +1 -0
  326. package/dist/exx-s897xhz3.svg +1 -0
  327. package/dist/farm-m80hxnfy.svg +1 -0
  328. package/dist/favicon-djc6sne4.svg +1 -0
  329. package/dist/figma-krwq889b.svg +1 -0
  330. package/dist/file-hetj1tjc.svg +1 -0
  331. package/dist/file_light-jx35pv2m.svg +1 -0
  332. package/dist/flakelock-2nsqn4gw.svg +1 -0
  333. package/dist/flutter-277q83en.svg +1 -0
  334. package/dist/flutterlock-h0nywsvt.svg +1 -0
  335. package/dist/flutterpackage-cpgnfwtt.svg +1 -0
  336. package/dist/folder-2xmsfyxp.svg +1 -0
  337. package/dist/folder_open-wk4ndx1f.svg +1 -0
  338. package/dist/fonteot-a8xmqj3j.svg +1 -0
  339. package/dist/fontotf-f01hg174.svg +1 -0
  340. package/dist/fontttf-pcr3rt21.svg +1 -0
  341. package/dist/fontwoff-v1gdka62.svg +1 -0
  342. package/dist/fontwoff2-1w1r47x8.svg +1 -0
  343. package/dist/freemarker-s9m714ah.svg +1 -0
  344. package/dist/fsharp-89mjndn4.svg +1 -0
  345. package/dist/gbl-v20qxsgx.svg +1 -0
  346. package/dist/git-wc9x7c5e.svg +1 -0
  347. package/dist/gitlab-bhcvbetz.svg +1 -0
  348. package/dist/gleam-h2ze8vtz.svg +1 -0
  349. package/dist/gleamconfig-6sq0xy19.svg +1 -0
  350. package/dist/go-15qaph9s.svg +1 -0
  351. package/dist/go-j2dk6r7k.svg +1 -0
  352. package/dist/go_package-5nc95prx.svg +1 -0
  353. package/dist/godot-v7nnsyvc.svg +1 -0
  354. package/dist/gradle-khh2bn3v.svg +1 -0
  355. package/dist/gradlebat-631878b0.svg +1 -0
  356. package/dist/gradlekotlin-f8netdbt.svg +1 -0
  357. package/dist/grain-tztem5b9.svg +1 -0
  358. package/dist/graphql-egmdpvzr.svg +1 -0
  359. package/dist/groovy-c0sstajm.svg +1 -0
  360. package/dist/grunt-56ssa3fr.svg +1 -0
  361. package/dist/gulp-j7wc27hd.svg +1 -0
  362. package/dist/h-4xbbejcs.svg +1 -0
  363. package/dist/haml-6pyt136a.svg +1 -0
  364. package/dist/handlebars-1v8g0n32.svg +1 -0
  365. package/dist/hardhat-1k6gym6f.svg +1 -0
  366. package/dist/hash-xd1ymkyp.svg +1 -0
  367. package/dist/hashicorp-vty9d6de.svg +1 -0
  368. package/dist/haskell-ncbxh3wk.svg +1 -0
  369. package/dist/haxe-j5nqdw5z.svg +1 -0
  370. package/dist/haxeml-bn7wtpx1.svg +1 -0
  371. package/dist/hpp-rpxcfk6j.svg +1 -0
  372. package/dist/htaccess-s4rrm1re.svg +1 -0
  373. package/dist/html-3vbw2fxn.svg +1 -0
  374. package/dist/html-v1z6sanr.svg +1 -0
  375. package/dist/http-9bfh1zqw.svg +1 -0
  376. package/dist/identifier-6gsrr6st.svg +1 -0
  377. package/dist/image-pstdg0vj.svg +1 -0
  378. package/dist/imagegif-any2rrn3.svg +1 -0
  379. package/dist/imageico-cng69rft.svg +1 -0
  380. package/dist/imagejpg-rtx9yy9y.svg +1 -0
  381. package/dist/imagepng-j6f306v1.svg +1 -0
  382. package/dist/imagewebp-q1mcm8np.svg +1 -0
  383. package/dist/imba-xxn1q1r2.svg +1 -0
  384. package/dist/index.html +16 -0
  385. package/dist/info-qssn7jw5.svg +1 -0
  386. package/dist/instructions-3068x11a.svg +1 -0
  387. package/dist/ipynb-qm8fb1p1.svg +1 -0
  388. package/dist/jar-src0eb7a.svg +1 -0
  389. package/dist/java-126v951r.svg +1 -0
  390. package/dist/java-hhh3k9xf.svg +1 -0
  391. package/dist/jenkins-ap6tzby2.svg +1 -0
  392. package/dist/jest-xrtp7hh0.svg +1 -0
  393. package/dist/jinja-v9kggcps.svg +1 -0
  394. package/dist/js-qsntbmzx.svg +1 -0
  395. package/dist/js-r0b86hmj.svg +1 -0
  396. package/dist/jsmap-1ns6yn3z.svg +1 -0
  397. package/dist/json-1jhmg3gf.svg +1 -0
  398. package/dist/jsp-7n103tna.svg +1 -0
  399. package/dist/julia-nba7etbq.svg +1 -0
  400. package/dist/karma-zcbeze4p.svg +1 -0
  401. package/dist/keep-tw8xf3gf.svg +1 -0
  402. package/dist/key-hd2nnhmr.svg +1 -0
  403. package/dist/knex-87w40q0j.svg +1 -0
  404. package/dist/knip-kzsz2w4s.svg +1 -0
  405. package/dist/kotlin-360tzrt1.svg +1 -0
  406. package/dist/kotlin-hbykz1k8.svg +1 -0
  407. package/dist/kotlins-4zz4rshm.svg +1 -0
  408. package/dist/krita-wx5qyrx7.svg +1 -0
  409. package/dist/latex-jwrpzd2b.svg +1 -0
  410. package/dist/launch-8wsjpmd3.svg +1 -0
  411. package/dist/lazarusproject-gma2fvya.svg +1 -0
  412. package/dist/less-p4zwh19p.svg +1 -0
  413. package/dist/license-qamq8mp3.svg +1 -0
  414. package/dist/light_editorconfig-k28g3f4k.svg +1 -0
  415. package/dist/liquid-wtexakya.svg +1 -0
  416. package/dist/llvm-cfgd7591.svg +1 -0
  417. package/dist/lock-wv5q3nef.svg +1 -0
  418. package/dist/log-ykdkwnpq.svg +1 -0
  419. package/dist/lua-aynthw24.svg +1 -0
  420. package/dist/m-va54fte8.svg +1 -0
  421. package/dist/m3-bun.manifest.json +3785 -0
  422. package/dist/makefile-kkcgz3sb.svg +1 -0
  423. package/dist/manifest-ede4t0vc.svg +1 -0
  424. package/dist/markdown-x7kezf76.svg +1 -0
  425. package/dist/markdownx-y5mf21hn.svg +1 -0
  426. package/dist/maven-djc7vb1b.svg +1 -0
  427. package/dist/mermaid-4bpjjghk.svg +1 -0
  428. package/dist/mesh-q798mf4t.svg +1 -0
  429. package/dist/mgcb-cfmfr63b.svg +1 -0
  430. package/dist/mint-b732cej4.svg +1 -0
  431. package/dist/mix-41smb4q2.svg +1 -0
  432. package/dist/mixlock-z0cvwpkq.svg +1 -0
  433. package/dist/mjml-4kzxtz0b.svg +1 -0
  434. package/dist/mkdocs-5t1davz8.svg +1 -0
  435. package/dist/mockoon-5pw3ckhf.svg +1 -0
  436. package/dist/motoko-yv95035d.svg +1 -0
  437. package/dist/mov-r3cjb3vr.svg +1 -0
  438. package/dist/mp4-31hded8m.svg +1 -0
  439. package/dist/mtl-01f1f06m.svg +1 -0
  440. package/dist/mustache-1s62ewsg.svg +1 -0
  441. package/dist/nelua-97199e3p.svg +1 -0
  442. package/dist/neon-gcp7rsp5.svg +1 -0
  443. package/dist/nestjs-sme3dmgk.svg +1 -0
  444. package/dist/nestjscontroller-2ceskrfc.svg +1 -0
  445. package/dist/nestjsdecorator-52k9dwm2.svg +1 -0
  446. package/dist/nestjsdto-xf36my7y.svg +1 -0
  447. package/dist/nestjsentity-q17fyvm1.svg +1 -0
  448. package/dist/nestjsfilter-qytmtqzj.svg +1 -0
  449. package/dist/nestjsguard-4pyb34xe.svg +1 -0
  450. package/dist/nestjsinterceptor-7s690j87.svg +1 -0
  451. package/dist/nestjsmodule-zeyz5633.svg +1 -0
  452. package/dist/nestjsrepository-kz26s1jf.svg +1 -0
  453. package/dist/nestjsresolver-8qdvexrk.svg +1 -0
  454. package/dist/nestjsservice-kp3b933m.svg +1 -0
  455. package/dist/nestscheduler-60p4j2tg.svg +1 -0
  456. package/dist/netlify-bbgdw42s.svg +1 -0
  457. package/dist/nextconfig-gr1sd69d.svg +1 -0
  458. package/dist/nextron-sf3ag316.svg +1 -0
  459. package/dist/nginx-73stz0yt.svg +1 -0
  460. package/dist/nim-gqnvnkc5.svg +1 -0
  461. package/dist/nix-t1m4qhc8.svg +1 -0
  462. package/dist/njk-dfv3nrxr.svg +1 -0
  463. package/dist/node-w3gp0xxn.svg +1 -0
  464. package/dist/nodemon-q41mkhvz.svg +1 -0
  465. package/dist/npm-rt8ga6qx.svg +1 -0
  466. package/dist/npmlock-8p4sp377.svg +1 -0
  467. package/dist/nuxt-13qdp31g.svg +1 -0
  468. package/dist/nvidia-fysz92ep.svg +1 -0
  469. package/dist/nvim-h3ynkfqg.svg +1 -0
  470. package/dist/nvm-ser6majj.svg +1 -0
  471. package/dist/nx-av0cw2sw.svg +1 -0
  472. package/dist/obj-thakg863.svg +1 -0
  473. package/dist/ocaml-maevkwa7.svg +1 -0
  474. package/dist/ocamli-w0gc5jq8.svg +1 -0
  475. package/dist/ocamll-h2wysvh1.svg +1 -0
  476. package/dist/ocamly-ppj6pfy3.svg +1 -0
  477. package/dist/odin-x7qb7b6x.svg +1 -0
  478. package/dist/opengl-h6pbxg3n.svg +1 -0
  479. package/dist/oxlint-7qwxtp86.svg +1 -0
  480. package/dist/panda-9qqa1nn4.svg +1 -0
  481. package/dist/parcel-gzckrwpy.svg +1 -0
  482. package/dist/pascal-kj6crs4h.svg +1 -0
  483. package/dist/pdf-wk39v1nv.svg +1 -0
  484. package/dist/perl-11dgrnh8.svg +1 -0
  485. package/dist/perlm-7xrwgd93.svg +1 -0
  486. package/dist/pfx-ggdb4v6p.svg +1 -0
  487. package/dist/photoshop-m3gw1xv7.svg +1 -0
  488. package/dist/php-jgyt96zk.svg +1 -0
  489. package/dist/php-jx84j7ns.svg +1 -0
  490. package/dist/plantuml-04ncqrmc.svg +1 -0
  491. package/dist/playright-dfc8tvme.svg +1 -0
  492. package/dist/plop-n71aee6w.svg +1 -0
  493. package/dist/pnpm-jvkts1qb.svg +1 -0
  494. package/dist/pnpmlock-2kqbdtn7.svg +1 -0
  495. package/dist/poetry-yjeeyvtr.svg +1 -0
  496. package/dist/poetrylock-da30xbws.svg +1 -0
  497. package/dist/postcssconfig-yyvnwr01.svg +1 -0
  498. package/dist/powershell-hf358xbb.svg +1 -0
  499. package/dist/powershelldata-nggemhrs.svg +1 -0
  500. package/dist/powershellmodule-v5wz6sed.svg +1 -0
  501. package/dist/precommit-wmfmt8tq.svg +1 -0
  502. package/dist/prettier-nyc1v0qk.svg +1 -0
  503. package/dist/prettierignore-hx4x759w.svg +1 -0
  504. package/dist/prisma-te242v0q.svg +1 -0
  505. package/dist/prolog-twb6h758.svg +1 -0
  506. package/dist/prompt-eg8c0gqa.svg +1 -0
  507. package/dist/properties-c39zkae1.svg +1 -0
  508. package/dist/proto-rsvsx4xb.svg +1 -0
  509. package/dist/pug-rqxd67km.svg +1 -0
  510. package/dist/pvk-bc4g1qms.svg +1 -0
  511. package/dist/py-0g79s39m.svg +1 -0
  512. package/dist/pyproject-5s59g4en.svg +1 -0
  513. package/dist/python-ds482k8k.svg +1 -0
  514. package/dist/qt-y3kxpf67.svg +1 -0
  515. package/dist/quarkus-xrq4b999.svg +1 -0
  516. package/dist/quasar-hvna6b7f.svg +1 -0
  517. package/dist/r-n1bnfab8.svg +1 -0
  518. package/dist/racket-vx5e6n1d.svg +1 -0
  519. package/dist/raku-4ydzc5wj.svg +1 -0
  520. package/dist/razor-cbqpr6vt.svg +1 -0
  521. package/dist/rb-mfkwkq7e.svg +1 -0
  522. package/dist/reactjs-qjyhk3rf.svg +1 -0
  523. package/dist/reactts-p0hf29yr.svg +1 -0
  524. package/dist/readme-3qcyy95y.svg +1 -0
  525. package/dist/redis-ya1xyn4v.svg +1 -0
  526. package/dist/rego-tr1y9cqm.svg +1 -0
  527. package/dist/remix-61pbjda4.svg +1 -0
  528. package/dist/rescript-9c3xnepn.svg +1 -0
  529. package/dist/rescriptinterface-6ne0a2rf.svg +1 -0
  530. package/dist/restructuredtext-7k21mjx4.svg +1 -0
  531. package/dist/rjson-3s2edhhr.svg +1 -0
  532. package/dist/robots-geh7c3pq.svg +1 -0
  533. package/dist/rollup-0dxydzr9.svg +1 -0
  534. package/dist/rome-1gxetp8g.svg +1 -0
  535. package/dist/ron-ft34rzr3.svg +1 -0
  536. package/dist/root_folder-rhwm7290.svg +1 -0
  537. package/dist/root_folder_light-ngkg5m4x.svg +1 -0
  538. package/dist/root_folder_light_open-c6nhg6sy.svg +1 -0
  539. package/dist/root_folder_open-genv0ps7.svg +1 -0
  540. package/dist/rs-60bcevwn.svg +1 -0
  541. package/dist/ruby-7j5zzh38.svg +1 -0
  542. package/dist/rust-a9528zdg.svg +1 -0
  543. package/dist/rustfmt-c8evpzd7.svg +1 -0
  544. package/dist/sails-5ecccxrg.svg +1 -0
  545. package/dist/salesforce-4d89045j.svg +1 -0
  546. package/dist/sass-g9qbr3x4.svg +1 -0
  547. package/dist/scala-8gnn0ekc.svg +1 -0
  548. package/dist/scss-g9qbr3x4.svg +1 -0
  549. package/dist/sentinel-g8py3peh.svg +1 -0
  550. package/dist/sequelize-qvzwnjhv.svg +1 -0
  551. package/dist/sh-bkp0n5vb.svg +1 -0
  552. package/dist/shaderlab-gkww43v2.svg +1 -0
  553. package/dist/shell-kc0a9zjq.svg +1 -0
  554. package/dist/silq-mczpsqmz.svg +1 -0
  555. package/dist/slim-8j9jf3zt.svg +1 -0
  556. package/dist/sln-nketqakm.svg +1 -0
  557. package/dist/smarty-w1zxys1s.svg +1 -0
  558. package/dist/sol-adyfjwzz.svg +1 -0
  559. package/dist/spc-kk30w5m6.svg +1 -0
  560. package/dist/sql-3c4gcy7a.svg +1 -0
  561. package/dist/sqlite-cppkxr0a.svg +1 -0
  562. package/dist/storybook-885ssp75.svg +1 -0
  563. package/dist/stylelint-z7s6yhc9.svg +1 -0
  564. package/dist/stylelintignore-xwnh8sx1.svg +1 -0
  565. package/dist/stylus-qz53ytkd.svg +1 -0
  566. package/dist/suo-3fvnz3bx.svg +1 -0
  567. package/dist/svelte-jp3x9gw7.svg +1 -0
  568. package/dist/svelteconfig-m0n00zjj.svg +1 -0
  569. package/dist/svg-8dyqf96t.svg +1 -0
  570. package/dist/swift-8g870v6j.svg +1 -0
  571. package/dist/symfony-q77kcepw.svg +1 -0
  572. package/dist/tailwind-3es9cgbd.svg +1 -0
  573. package/dist/tauri-xnj526kw.svg +1 -0
  574. package/dist/taze-e3ykqs0k.svg +1 -0
  575. package/dist/terrafile-gqn1tysh.svg +1 -0
  576. package/dist/terraform-jy4fbwsr.svg +1 -0
  577. package/dist/terraformvars-05qje1sw.svg +1 -0
  578. package/dist/terraformversion-gq2tkwmn.svg +1 -0
  579. package/dist/testjs-sqgjsb8h.svg +1 -0
  580. package/dist/testts-19m1sf26.svg +1 -0
  581. package/dist/tmpl-enggw2gc.svg +1 -0
  582. package/dist/todo-ccw0mpg2.svg +1 -0
  583. package/dist/toml-rmx5hba4.svg +1 -0
  584. package/dist/toolversions-s7fttfyp.svg +1 -0
  585. package/dist/tox-a4j4yvmb.svg +1 -0
  586. package/dist/travis-gr3jtpx2.svg +1 -0
  587. package/dist/tres-qt3kk1t0.svg +1 -0
  588. package/dist/ts-7amn21ms.svg +1 -0
  589. package/dist/tscn-g1jthb4m.svg +1 -0
  590. package/dist/tsconfig-r1s750bq.svg +1 -0
  591. package/dist/tsx-a3rsjrrz.svg +1 -0
  592. package/dist/turbo-dcmj75tc.svg +1 -0
  593. package/dist/twig-3xgrb919.svg +1 -0
  594. package/dist/txt-y0t8b72p.svg +1 -0
  595. package/dist/typescript-kd5g4jkg.svg +1 -0
  596. package/dist/typescriptdef-y43343m6.svg +1 -0
  597. package/dist/ui-pxvg5zj2.svg +1 -0
  598. package/dist/unocss-b0f5fthj.svg +1 -0
  599. package/dist/user-q7tk1k2d.svg +1 -0
  600. package/dist/v-c25jfygk.svg +1 -0
  601. package/dist/vanillaextract-3w6vds6m.svg +1 -0
  602. package/dist/vb-87ckj7t3.svg +1 -0
  603. package/dist/vercel-hfxjvaj9.svg +1 -0
  604. package/dist/version-zd7hfmf1.svg +1 -0
  605. package/dist/vhd-xaw7zbny.svg +1 -0
  606. package/dist/vhdl-s308rb5a.svg +1 -0
  607. package/dist/video-z6khth5y.svg +1 -0
  608. package/dist/vite-5g5xkmpk.svg +1 -0
  609. package/dist/viteenv-jbmx0tb0.svg +1 -0
  610. package/dist/vitest-5267dzt2.svg +1 -0
  611. package/dist/vmod-8jftapdc.svg +1 -0
  612. package/dist/vscode-8tvcs7ae.svg +1 -0
  613. package/dist/vue-j5sjdz4b.svg +1 -0
  614. package/dist/vue-x9h2d0d2.svg +1 -0
  615. package/dist/vueconfig-726zh8dd.svg +1 -0
  616. package/dist/wasm-vgmg9kv4.svg +1 -0
  617. package/dist/webpack-hfwce90m.svg +1 -0
  618. package/dist/wgsl-68923cz5.svg +1 -0
  619. package/dist/windi-c9m8en7k.svg +1 -0
  620. package/dist/wren-7ep5ph5r.svg +1 -0
  621. package/dist/xmake-mc60ax7m.svg +1 -0
  622. package/dist/xml-feq1fbt4.svg +1 -0
  623. package/dist/yaml-n43aw0fx.svg +1 -0
  624. package/dist/yang-mtcxs2mg.svg +1 -0
  625. package/dist/yarn-k4k6e35h.svg +1 -0
  626. package/dist/yarnerror-5jkesx9j.svg +1 -0
  627. package/dist/yarnignore-ryh8jd5p.svg +1 -0
  628. package/dist/yarnlock-9zvhbg04.svg +1 -0
  629. package/dist/yin-f931bzgj.svg +1 -0
  630. package/dist/zig-nx2e65ns.svg +1 -0
  631. package/dist/zip-7hqmj0b0.svg +1 -0
  632. package/m3.config.ts +32 -0
  633. package/package.json +60 -0
  634. package/scripts/browser-contract.ts +400 -0
  635. package/scripts/icons.ts +56 -0
  636. package/scripts/inventory.ts +86 -0
  637. package/scripts/shots.ts +154 -0
  638. package/scripts/tauri.ts +401 -0
  639. package/src/App.tsx +40 -0
  640. package/src/adaptive/dpad.ts +223 -0
  641. package/src/adaptive/window.ts +133 -0
  642. package/src/api/index.ts +332 -0
  643. package/src/components/ui.tsx +89 -0
  644. package/src/env.d.ts +5 -0
  645. package/src/favicon.svg +1 -0
  646. package/src/generated/inventory.json +426 -0
  647. package/src/index.html +16 -0
  648. package/src/inventory.ts +19 -0
  649. package/src/main.tsx +6 -0
  650. package/src/pages/Adaptive.tsx +128 -0
  651. package/src/pages/Ai.tsx +174 -0
  652. package/src/pages/Brands.tsx +156 -0
  653. package/src/pages/Components.tsx +91 -0
  654. package/src/pages/Design.tsx +163 -0
  655. package/src/pages/Explorer.tsx +125 -0
  656. package/src/pages/Forms.tsx +128 -0
  657. package/src/pages/Icons.tsx +138 -0
  658. package/src/pages/Motion.tsx +157 -0
  659. package/src/pages/Next.tsx +107 -0
  660. package/src/pages/Overview.tsx +105 -0
  661. package/src/pages/Primitives.tsx +138 -0
  662. package/src/pages/Reader.tsx +101 -0
  663. package/src/pages/System.tsx +283 -0
  664. package/src/pages/Theme.tsx +146 -0
  665. package/src/pages/index.ts +25 -0
  666. package/src/router.ts +22 -0
  667. package/src/shell/Shell.tsx +383 -0
  668. package/src/shell/nav.ts +198 -0
  669. package/src/styles.css +61 -0
  670. package/test/contracts.test.ts +87 -0
  671. package/test/host-contract.test.ts +183 -0
  672. package/test/runtime-api.test.ts +138 -0
  673. package/test-dom/dpad.test.ts +78 -0
  674. package/tsconfig.json +11 -0
@@ -0,0 +1,154 @@
1
+ #!/usr/bin/env bun
2
+ // SPDX-License-Identifier: Apache-2.0
3
+ // Bounded local capture: every showcase page in mobile, desktop and TV, with local assets.
4
+ import { mkdir } from "node:fs/promises";
5
+ import { join, resolve } from "node:path";
6
+ import { chromium, type Browser } from "playwright-core";
7
+ import { pool } from "../../../scripts/build.ts";
8
+ import { PAGES } from "../src/pages/index.ts";
9
+ export type Layout = "mobile" | "desktop" | "tv";
10
+ export const VIEWPORTS: Record<Layout, { width: number; height: number }> = {
11
+ mobile: { width: 390, height: 844 },
12
+ desktop: { width: 1280, height: 800 },
13
+ tv: { width: 1920, height: 1080 },
14
+ };
15
+ export interface Shot {
16
+ route: string;
17
+ layout: Layout;
18
+ scheme: "light" | "dark";
19
+ name: string;
20
+ }
21
+ export const shotName = (route: string, layout: Layout, scheme: "light" | "dark") =>
22
+ `${route}@${layout}-${scheme}`;
23
+ export function plan(
24
+ routes: readonly string[],
25
+ layouts: readonly Layout[] = ["mobile", "desktop", "tv"],
26
+ schemes: readonly ("light" | "dark")[] = ["light"],
27
+ ): Shot[] {
28
+ for (const route of routes)
29
+ if (!Object.hasOwn(PAGES, route)) throw new TypeError(`Unknown showcase route: ${route}`);
30
+ for (const layout of layouts)
31
+ if (!Object.hasOwn(VIEWPORTS, layout)) throw new TypeError(`Unknown layout: ${layout}`);
32
+ for (const scheme of schemes)
33
+ if (scheme !== "light" && scheme !== "dark") throw new TypeError(`Unknown scheme: ${scheme}`);
34
+ return routes.flatMap((route) =>
35
+ layouts.flatMap((layout) =>
36
+ schemes.map((scheme) => ({ route, layout, scheme, name: shotName(route, layout, scheme) })),
37
+ ),
38
+ );
39
+ }
40
+ export const CHROMIUM_ARGS = [
41
+ "--no-sandbox",
42
+ "--disable-gpu",
43
+ "--disable-dev-shm-usage",
44
+ "--font-render-hinting=none",
45
+ "--force-color-profile=srgb",
46
+ ];
47
+ export interface CaptureResult {
48
+ name: string;
49
+ file: string;
50
+ bytes: number;
51
+ sha256: string;
52
+ consoleErrors: string[];
53
+ }
54
+ export async function capture(
55
+ baseUrl: string,
56
+ outDir: string,
57
+ shots: readonly Shot[],
58
+ browser?: Browser,
59
+ ): Promise<CaptureResult[]> {
60
+ // Validate before creating output paths, including programmatic callers.
61
+ for (const shot of shots) {
62
+ const expected = plan([shot.route], [shot.layout], [shot.scheme])[0]!;
63
+ if (shot.name !== expected.name) throw new TypeError("Invalid capture name");
64
+ }
65
+ await mkdir(outDir, { recursive: true });
66
+ const own = !browser;
67
+ const b = browser ?? (await chromium.launch({ headless: true, args: CHROMIUM_ARGS }));
68
+ const origin = new URL(baseUrl).origin;
69
+ try {
70
+ return await pool(shots, 2, async (shot) => {
71
+ const context = await b.newContext({
72
+ viewport: VIEWPORTS[shot.layout],
73
+ deviceScaleFactor: 1,
74
+ colorScheme: shot.scheme,
75
+ reducedMotion: "reduce",
76
+ locale: "en-US",
77
+ timezoneId: "UTC",
78
+ });
79
+ try {
80
+ const page = await context.newPage();
81
+ const consoleErrors: string[] = [];
82
+ await page.route("**/*", async (route) => {
83
+ const url = new URL(route.request().url());
84
+ if (url.origin === origin || ["data:", "blob:"].includes(url.protocol))
85
+ await route.continue();
86
+ else {
87
+ consoleErrors.push(`External asset: ${url.origin}`);
88
+ await route.abort();
89
+ }
90
+ });
91
+ page.on("console", (message) => {
92
+ if (message.type() === "error") consoleErrors.push(message.text());
93
+ });
94
+ page.on("pageerror", (error) => consoleErrors.push(error.message));
95
+ await page.goto(`${baseUrl}/?layout=${shot.layout}#/${shot.route}`, {
96
+ waitUntil: "networkidle",
97
+ timeout: 30_000,
98
+ });
99
+ const main = page.locator('[data-testid="main"]');
100
+ await main.locator("h1").waitFor({ timeout: 20_000 });
101
+ if ((await main.getAttribute("data-route")) !== shot.route)
102
+ throw new Error(`Wrong destination for ${shot.route}`);
103
+ if (
104
+ (await page.locator('[data-testid="shell"]').getAttribute("data-layout")) !== shot.layout
105
+ )
106
+ throw new Error(`Wrong layout for ${shot.name}`);
107
+ if ((await main.locator("h1").textContent())?.includes("Unable to load"))
108
+ throw new Error(`Page failed: ${shot.route}`);
109
+ await page.evaluate(() => document.fonts.ready.then(() => undefined));
110
+ await page.waitForTimeout(150);
111
+ const file = join(outDir, `${shot.name}.png`);
112
+ const png = await page.screenshot({
113
+ path: file,
114
+ animations: "disabled",
115
+ caret: "hide",
116
+ type: "png",
117
+ });
118
+ return {
119
+ name: shot.name,
120
+ file,
121
+ bytes: png.length,
122
+ sha256: new Bun.CryptoHasher("sha256").update(png).digest("hex"),
123
+ consoleErrors,
124
+ };
125
+ } finally {
126
+ await context.close();
127
+ }
128
+ });
129
+ } finally {
130
+ if (own) await b.close();
131
+ }
132
+ }
133
+ if (import.meta.main) {
134
+ const args = process.argv.slice(2);
135
+ const value = (name: string) => {
136
+ const i = args.indexOf(`--${name}`);
137
+ return i < 0 ? undefined : args[i + 1];
138
+ };
139
+ const outArg = value("out");
140
+ if (!outArg) throw new Error("Give --out pointing outside the repository");
141
+ const results = await capture(
142
+ value("url") ?? "http://127.0.0.1:3300",
143
+ resolve(outArg),
144
+ plan(
145
+ value("routes")?.split(",") ?? Object.keys(PAGES),
146
+ (value("layouts")?.split(",") ?? ["mobile", "desktop", "tv"]) as Layout[],
147
+ (value("schemes")?.split(",") ?? ["light", "dark"]) as ("light" | "dark")[],
148
+ ),
149
+ );
150
+ await Bun.write(join(resolve(outArg), "capture.json"), JSON.stringify(results, null, 2) + "\n");
151
+ for (const result of results)
152
+ console.log(`${result.name}: ${result.bytes} B, ${result.consoleErrors.length} errors`);
153
+ if (results.some((result) => result.consoleErrors.length > 0)) process.exitCode = 1;
154
+ }
@@ -0,0 +1,401 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ import { existsSync } from "node:fs";
3
+ import { copyFile, mkdir } from "node:fs/promises";
4
+ import { dirname } from "node:path";
5
+ import { resolve } from "node:path";
6
+ import { tauriShell, TAURI_3, writeFiles, type FileMap } from "@aphrody/scaffold";
7
+ import {
8
+ heavyBuildStatus,
9
+ readFactoryConfig,
10
+ routeHeavyBuild,
11
+ type BuildFactoryStatus,
12
+ } from "../../../../packages/infra/workspace/src/build-factory";
13
+ import { APHRODY_ROOT, SHOWCASE_ROOT, TAURI_ROOT } from "./icons";
14
+
15
+ export const CARGO_RUNNER = resolve(APHRODY_ROOT, "scripts/build/rust/cargo-serial.sh");
16
+ const M3_BUN_CLI = resolve(SHOWCASE_ROOT, "../../packages/m3-bun/bin/m3-bun.ts");
17
+ const HEAVY_COMMANDS = new Set(["dev", "build", "bundle", "android", "ios", "sidecar"]);
18
+
19
+ export function showcaseShellFiles(): FileMap {
20
+ const files = tauriShell({
21
+ name: "Aphrody M3 Showcase",
22
+ crate: "aphrody-m3-showcase",
23
+ identifier: "com.aphrody.m3showcase",
24
+ version: "3.3.3",
25
+ mobile: true,
26
+ build: {
27
+ frontendDist: "../../../m3/apps/showcase/dist",
28
+ },
29
+ window: { mode: "runtime" },
30
+ withGlobalTauri: false,
31
+ permissions: [],
32
+ capabilityDescription: "The loopback UI uses HTTP; no host IPC is granted to its origin.",
33
+ csp: "default-src 'self'; img-src 'self' data: blob:; font-src 'self' data:; style-src 'self' 'unsafe-inline'; script-src 'self'; connect-src 'self'; object-src 'none'; base-uri 'self'; form-action 'self'",
34
+ externalBin: ["binaries/m3-showcase"],
35
+ runtimePlugin: {
36
+ crate: "aphrody-tauri-wrap",
37
+ path: "../tauri-wrap",
38
+ features: [],
39
+ init: 'aphrody_tauri_wrap::init(include_str!("../wrap.json"))',
40
+ },
41
+ });
42
+ delete files["src-tauri/icons/icon.png"];
43
+ const config = JSON.parse(String(files["src-tauri/tauri.conf.json"]));
44
+ config.bundle.icon = [
45
+ "icons/32x32.png",
46
+ "icons/128x128.png",
47
+ "icons/128x128@2x.png",
48
+ "icons/icon.icns",
49
+ "icons/icon.ico",
50
+ ];
51
+ config.build.beforeDevCommand = "bun run icons && bun scripts/tauri.ts sidecar";
52
+ config.build.beforeBuildCommand = "bun run icons && bun scripts/tauri.ts sidecar";
53
+ files["src-tauri/tauri.conf.json"] = JSON.stringify(config, null, 2) + "\n";
54
+ files["src-tauri/Cargo.toml"] = `# SPDX-License-Identifier: Apache-2.0
55
+ [package]
56
+ name = "aphrody-m3-showcase"
57
+ version = "3.3.3"
58
+ description = "Native showcase shell for the canonical Aphrody M3 frontend and API"
59
+ edition.workspace = true
60
+ rust-version.workspace = true
61
+ license.workspace = true
62
+ authors.workspace = true
63
+ homepage.workspace = true
64
+ repository.workspace = true
65
+ publish = false
66
+
67
+ [lib]
68
+ name = "aphrody_m3_showcase_lib"
69
+ crate-type = ["staticlib", "cdylib", "rlib"]
70
+
71
+ [features]
72
+ custom-protocol = ["tauri/custom-protocol"]
73
+
74
+ [build-dependencies]
75
+ tauri-build.workspace = true
76
+
77
+ [dependencies]
78
+ tauri.workspace = true
79
+ tauri-runtime-wry.workspace = true
80
+ aphrody-tauri-wrap.workspace = true
81
+
82
+ [lints]
83
+ workspace = true
84
+ `;
85
+ files["src-tauri/wrap.json"] =
86
+ JSON.stringify(
87
+ {
88
+ schema: "aphrody-web-to-tauri/1",
89
+ name: "Aphrody M3 Showcase",
90
+ identifier: "com.aphrody.m3showcase",
91
+ mode: "sidecar",
92
+ engine: "wry",
93
+ start: "/",
94
+ origins: { app: [], auth: [], embeds: [], external: "system" },
95
+ window: {
96
+ title: "Aphrody M3 Showcase",
97
+ width: 1200,
98
+ height: 800,
99
+ minWidth: 320,
100
+ minHeight: 480,
101
+ syncTitle: true,
102
+ zoomHotkeys: true,
103
+ dragDrop: false,
104
+ },
105
+ userAgent: null,
106
+ bundle: null,
107
+ sidecar: {
108
+ program: "m3-showcase",
109
+ args: [],
110
+ port: 0,
111
+ readyPath: "/healthz",
112
+ readyTimeoutSecs: 30,
113
+ env: {},
114
+ },
115
+ },
116
+ null,
117
+ 2,
118
+ ) + "\n";
119
+ files["src-tauri/.gitignore"] = "/target/\n/gen/\n/icons/\n/binaries/\n";
120
+ return Object.fromEntries(
121
+ Object.entries(files).map(([path, content]) => [path.slice("src-tauri/".length), content]),
122
+ );
123
+ }
124
+
125
+ export async function prepareShowcaseHost(root = TAURI_ROOT): Promise<void> {
126
+ const files = showcaseShellFiles();
127
+ const missing: FileMap = {};
128
+ for (const [path, content] of Object.entries(files)) {
129
+ if (!existsSync(resolve(root, path))) missing[path] = content;
130
+ }
131
+ if (Object.keys(missing).length) await writeFiles(root, missing, "merge");
132
+ }
133
+
134
+ /** The canonical compiler embeds both UI and API; the Tauri wrapper owns its child lifecycle. */
135
+ export function sidecarCommand(triple: string, root = TAURI_ROOT): string[] {
136
+ const targets: Record<string, string> = {
137
+ "x86_64-unknown-linux-gnu": "linux-x64",
138
+ "aarch64-unknown-linux-gnu": "linux-arm64",
139
+ "x86_64-unknown-linux-musl": "linux-x64-musl",
140
+ "aarch64-unknown-linux-musl": "linux-arm64-musl",
141
+ "x86_64-pc-windows-msvc": "windows-x64",
142
+ "x86_64-apple-darwin": "darwin-x64",
143
+ "aarch64-apple-darwin": "darwin-arm64",
144
+ };
145
+ const target = targets[triple];
146
+ if (!target)
147
+ throw new Error(
148
+ `No native M3 Bun API sidecar target for ${triple}; mobile requires its canonical API host adapter`,
149
+ );
150
+ const suffix = target.startsWith("windows") ? ".exe" : "";
151
+ return [
152
+ "bun",
153
+ M3_BUN_CLI,
154
+ "compile",
155
+ "--target",
156
+ target,
157
+ "--outfile",
158
+ resolve(root, `binaries/m3-showcase-${triple}${suffix}`),
159
+ ];
160
+ }
161
+
162
+ /** Tauri's desktop runner is always the existing Cargo lock/guard owner. */
163
+ export function serializedTauriCommand(args: string[], cli: string): string[] {
164
+ if (args.some((arg) => arg.startsWith("-r") || arg === "--runner" || arg.startsWith("--runner=")))
165
+ throw new Error("The Tauri Cargo runner is owned by scripts/build/rust/cargo-serial.sh");
166
+ if (args[0] === "android" || args[0] === "ios")
167
+ throw new Error(
168
+ "Mobile production requires the canonical API host adapter and serialized platform builder; no desktop Bun sidecar is available on Android/iOS",
169
+ );
170
+ if (args[0] !== "build" && args[0] !== "dev") return [cli, ...args];
171
+ if (
172
+ args.some(
173
+ (arg) =>
174
+ arg === "--manifest-path" ||
175
+ arg.startsWith("--manifest-path=") ||
176
+ arg === "-p" ||
177
+ arg === "--package" ||
178
+ arg.startsWith("--package="),
179
+ )
180
+ )
181
+ throw new Error("The Tauri manifest and Cargo package are owned by crates/ui/m3-showcase");
182
+ const separator = args.indexOf("--");
183
+ const before = separator < 0 ? args : args.slice(0, separator);
184
+ const forwarded = separator < 0 ? [] : args.slice(separator + 1);
185
+ const application = forwarded.indexOf("--");
186
+ const runnerArgs = application < 0 ? forwarded : forwarded.slice(0, application);
187
+ const appArgs = application < 0 ? [] : forwarded.slice(application);
188
+ return [
189
+ cli,
190
+ ...before,
191
+ "--runner",
192
+ CARGO_RUNNER,
193
+ "--",
194
+ ...runnerArgs,
195
+ "--manifest-path",
196
+ resolve(TAURI_ROOT, "Cargo.toml"),
197
+ "--package",
198
+ "aphrody-m3-showcase",
199
+ ...appArgs,
200
+ ];
201
+ }
202
+
203
+ export function assertFactoryHost(status: BuildFactoryStatus): void {
204
+ if (
205
+ !status.configured ||
206
+ !status.enabled ||
207
+ status.route !== "local" ||
208
+ status.host !== status.target
209
+ )
210
+ throw new Error(
211
+ "Native host compilation must execute through the configured Workspace build factory; use aphrody-ops build-factory run --repo aphrody --revision <full-sha> -- bun m3/apps/showcase/scripts/tauri.ts build. Local Cargo flags do not authorize host builds.",
212
+ );
213
+ }
214
+
215
+ export interface TauriHostPlan {
216
+ platform: string;
217
+ arch: string;
218
+ expectedCli: string;
219
+ command: string[];
220
+ execution: "workspace-build-factory" | "local";
221
+ hostOwner: string;
222
+ apiOwner: string;
223
+ missing: string[];
224
+ }
225
+
226
+ export function tauriHostPlan(
227
+ args: string[],
228
+ env: Record<string, string | undefined> = process.env,
229
+ platform: NodeJS.Platform = process.platform,
230
+ which = Bun.which,
231
+ ): TauriHostPlan {
232
+ const cli = which("tauri");
233
+ const missing: string[] = [];
234
+ if (!cli) missing.push(`Installed Tauri CLI ${TAURI_3.jsCli} is missing`);
235
+ const nativeBuild = HEAVY_COMMANDS.has(args[0] ?? "info");
236
+ if (nativeBuild && !which("cargo")) missing.push("The Rust Cargo toolchain is missing");
237
+ if (nativeBuild && !which("rustc")) missing.push("The Rust compiler is missing");
238
+ if (args[0] === "android") {
239
+ const sdk = env.ANDROID_HOME ?? env.ANDROID_SDK_ROOT;
240
+ if (!sdk || !existsSync(sdk))
241
+ missing.push("Configure an existing Android SDK with ANDROID_HOME or ANDROID_SDK_ROOT");
242
+ if (!which("java")) missing.push("The Android JDK is missing");
243
+ const ndk = env.NDK_HOME ?? env.ANDROID_NDK_HOME;
244
+ if (!(ndk && existsSync(ndk)) && !(sdk && existsSync(resolve(sdk, "ndk"))))
245
+ missing.push("The Android NDK is missing");
246
+ }
247
+ if (args[0] === "ios" && (platform !== "darwin" || !which("xcodebuild")))
248
+ missing.push("iOS requires the configured macOS/Xcode builder");
249
+ let command: string[] = [];
250
+ if (cli && args[0] !== "sidecar") {
251
+ try {
252
+ command = serializedTauriCommand(args, cli);
253
+ } catch (error) {
254
+ missing.push(error instanceof Error ? error.message : String(error));
255
+ }
256
+ }
257
+ return {
258
+ platform,
259
+ arch: process.arch,
260
+ expectedCli: TAURI_3.jsCli,
261
+ command,
262
+ execution: nativeBuild ? "workspace-build-factory" : "local",
263
+ hostOwner: TAURI_ROOT,
264
+ apiOwner: SHOWCASE_ROOT,
265
+ missing,
266
+ };
267
+ }
268
+
269
+ function explicitTarget(args: string[]): string | undefined {
270
+ const separator = args.indexOf("--");
271
+ const options = separator < 0 ? args : args.slice(0, separator);
272
+ const target = options.find((arg) => arg.startsWith("--target="));
273
+ if (target) return target.slice("--target=".length);
274
+ const short = options.find((arg) => arg.startsWith("-t") && arg.length > 2);
275
+ if (short) return short.slice(2);
276
+ const index = options.findIndex((arg) => arg === "--target" || arg === "-t");
277
+ return index >= 0 ? options[index + 1] : undefined;
278
+ }
279
+
280
+ async function runSidecar(root: string): Promise<void> {
281
+ let triple = process.env.APHRODY_M3_TAURI_TARGET;
282
+ if (!triple) {
283
+ const rust = Bun.spawn(["rustc", "-vV"], { stdout: "pipe", stderr: "inherit" });
284
+ const output = await new Response(rust.stdout).text();
285
+ if ((await rust.exited) !== 0) throw new Error("Cannot qualify the installed Rust host triple");
286
+ triple = output.match(/^host: (.+)$/m)?.[1];
287
+ }
288
+ if (!triple) throw new Error("Missing native Tauri target triple");
289
+ const child = Bun.spawn(sidecarCommand(triple, root), {
290
+ cwd: SHOWCASE_ROOT,
291
+ stdout: "inherit",
292
+ stderr: "inherit",
293
+ });
294
+ const code = await child.exited;
295
+ if (code !== 0) throw new Error(`Native API sidecar compilation failed with exit ${code}`);
296
+ // An unbundled dev/release app also resolves its sidecar beside its executable.
297
+ // Metadata runs through the same native Cargo owner, after factory admission.
298
+ const metadata = Bun.spawn(
299
+ [
300
+ CARGO_RUNNER,
301
+ "metadata",
302
+ "--format-version",
303
+ "1",
304
+ "--no-deps",
305
+ "--manifest-path",
306
+ resolve(root, "Cargo.toml"),
307
+ ],
308
+ { cwd: APHRODY_ROOT, stdout: "pipe", stderr: "inherit" },
309
+ );
310
+ const output = await new Response(metadata.stdout).text();
311
+ if ((await metadata.exited) !== 0)
312
+ throw new Error("Cannot qualify the native Tauri artifact directory");
313
+ const targetDir = (JSON.parse(output) as { target_directory: string }).target_directory;
314
+ const profile = process.env.APHRODY_M3_TAURI_PROFILE ?? "release";
315
+ if (!["debug", "release"].includes(profile))
316
+ throw new Error("Unsupported native Tauri artifact profile");
317
+ const suffix = triple.includes("windows") ? ".exe" : "";
318
+ const beside = resolve(
319
+ targetDir,
320
+ ...(process.env.APHRODY_M3_TAURI_TARGET ? [triple] : []),
321
+ profile,
322
+ `m3-showcase${suffix}`,
323
+ );
324
+ await mkdir(dirname(beside), { recursive: true });
325
+ await copyFile(sidecarCommand(triple, root).at(-1)!, beside);
326
+ }
327
+
328
+ export async function runTauri(input: string[] = [], root = TAURI_ROOT): Promise<void> {
329
+ const planOnly = input.includes("--plan");
330
+ const args = input.filter((arg) => arg !== "--plan");
331
+ if (args.length === 0) args.push("info");
332
+ if (args[0] === "prepare") {
333
+ if (planOnly)
334
+ console.log(JSON.stringify({ files: Object.keys(showcaseShellFiles()) }, null, 2));
335
+ else await prepareShowcaseHost(root);
336
+ return;
337
+ }
338
+ if (
339
+ !HEAVY_COMMANDS.has(args[0]!) &&
340
+ args[0] !== "info" &&
341
+ !(args.length === 1 && ["--help", "-h", "--version", "-V"].includes(args[0]!))
342
+ )
343
+ throw new Error(
344
+ "Use an explicit owner command: prepare, info, dev, build, bundle, sidecar, android, or ios; global options cannot bypass the build-factory gate",
345
+ );
346
+ const plan = tauriHostPlan(args);
347
+ if (planOnly) {
348
+ console.log(JSON.stringify(plan, null, 2));
349
+ return;
350
+ }
351
+ // Unsupported host APIs and toolchains are diagnosed before dispatch or source writes.
352
+ if (plan.missing.length) throw new Error(plan.missing.join("\n"));
353
+ if (HEAVY_COMMANDS.has(args[0]!)) {
354
+ const dispatched = await routeHeavyBuild(
355
+ ["bun", "m3/apps/showcase/scripts/tauri.ts", ...args],
356
+ APHRODY_ROOT,
357
+ );
358
+ if (dispatched !== undefined) {
359
+ if (dispatched !== 0) throw new Error(`Native build factory failed with exit ${dispatched}`);
360
+ return;
361
+ }
362
+ const factory = await readFactoryConfig(APHRODY_ROOT);
363
+ assertFactoryHost(heavyBuildStatus(factory, process.env, false));
364
+ }
365
+ if (args[0] === "sidecar") {
366
+ await runSidecar(root);
367
+ return;
368
+ }
369
+ const version = Bun.spawn([plan.command[0]!, "--version"], { stdout: "pipe", stderr: "pipe" });
370
+ const installed = (await new Response(version.stdout).text()).trim();
371
+ if ((await version.exited) !== 0 || !installed.endsWith(plan.expectedCli))
372
+ throw new Error(`Tauri CLI pin mismatch: expected ${plan.expectedCli}; observed ${installed}`);
373
+ await prepareShowcaseHost(root);
374
+ const target = explicitTarget(args);
375
+ const child = Bun.spawn(plan.command, {
376
+ cwd: root,
377
+ stdin: "inherit",
378
+ stdout: "inherit",
379
+ stderr: "inherit",
380
+ env: {
381
+ ...process.env,
382
+ CARGO: CARGO_RUNNER,
383
+ TAURI_APP_PATH: root,
384
+ TAURI_FRONTEND_PATH: SHOWCASE_ROOT,
385
+ ...(target ? { APHRODY_M3_TAURI_TARGET: target } : {}),
386
+ APHRODY_M3_TAURI_PROFILE:
387
+ args[0] === "dev" || args.includes("--debug") || args.includes("-d") ? "debug" : "release",
388
+ },
389
+ });
390
+ const code = await child.exited;
391
+ if (code !== 0) throw new Error(`Tauri host command failed with exit ${code}`);
392
+ }
393
+
394
+ if (import.meta.main) {
395
+ try {
396
+ await runTauri(Bun.argv.slice(2));
397
+ } catch (error) {
398
+ console.error(error instanceof Error ? error.message : error);
399
+ process.exitCode = 1;
400
+ }
401
+ }
package/src/App.tsx ADDED
@@ -0,0 +1,40 @@
1
+ import { M3ThemeProvider, useM3Theme, type ThemeMode } from "@aphrody/m3-theme/react";
2
+ import { useEffect } from "react";
3
+ import { Shell } from "./shell/Shell.tsx";
4
+
5
+ export const THEME_STORAGE_KEY = "aphrody-m3-showcase-theme";
6
+
7
+ export function savedThemeMode(): ThemeMode {
8
+ if (typeof window === "undefined") return "system";
9
+ try {
10
+ const saved = window.localStorage.getItem(THEME_STORAGE_KEY);
11
+ return saved === "light" || saved === "dark" ? saved : "system";
12
+ } catch {
13
+ return "system";
14
+ }
15
+ }
16
+
17
+ function ThemePersistence() {
18
+ const { themeMode } = useM3Theme();
19
+ useEffect(() => {
20
+ try {
21
+ window.localStorage.setItem(THEME_STORAGE_KEY, themeMode);
22
+ } catch {
23
+ // Session state still works when the host disables persistent browser storage.
24
+ }
25
+ }, [themeMode]);
26
+ return null;
27
+ }
28
+
29
+ export function App() {
30
+ return (
31
+ <M3ThemeProvider
32
+ defaultSeedColor="#6750a4"
33
+ defaultThemeMode={savedThemeMode()}
34
+ defaultVariant="tonalSpot"
35
+ >
36
+ <ThemePersistence />
37
+ <Shell />
38
+ </M3ThemeProvider>
39
+ );
40
+ }