@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,128 @@
1
+ import { BREAKPOINTS, HEIGHT_BREAKPOINTS, marginFor, navigationFor, panesFor, WINDOW_SIZE_CLASSES } from "@aphrody/m3-tokens/breakpoints";
2
+ import { useEffect, useRef, useState } from "react";
3
+ import { attachDpad } from "../adaptive/dpad.ts";
4
+ import { LAYOUT_MODES, setLayoutOverride, type LayoutMode } from "../adaptive/window.ts";
5
+ import { Card, Page, Section } from "../components/ui.tsx";
6
+ import type { PageProps } from "./index.ts";
7
+
8
+ const FRAMES: ReadonlyArray<{ mode: LayoutMode; width: number; height: number; label: string }> = [
9
+ { mode: "mobile", width: 390, height: 844, label: "Mobile · 390 × 844" },
10
+ { mode: "desktop", width: 1280, height: 800, label: "Desktop · 1280 × 800" },
11
+ { mode: "tv", width: 1920, height: 1080, label: "TV · 1920 × 1080" },
12
+ ];
13
+
14
+ function Frame({ mode, width, height, label, scale }: { mode: LayoutMode; width: number; height: number; label: string; scale: number }) {
15
+ return (
16
+ <figure className="flex flex-col gap-2" data-testid={`frame-${mode}`}>
17
+ <div className="overflow-hidden rounded-large border border-outline-variant" style={{ width: width * scale, height: height * scale }}>
18
+ <iframe title={`${label} preview`} src={`${location.pathname}?layout=${mode}#/overview`} loading="lazy" className="origin-top-left border-0" style={{ width, height, transform: `scale(${scale})` }} />
19
+ </div>
20
+ <figcaption className="text-label-medium text-on-surface-variant">{label}</figcaption>
21
+ </figure>
22
+ );
23
+ }
24
+
25
+ export default function Adaptive({ adaptive: a }: PageProps) {
26
+ const [dpad, setDpad] = useState(false);
27
+ const [focused, setFocused] = useState("none");
28
+ const grid = useRef<HTMLDivElement>(null);
29
+ const framed = window.self !== window.top;
30
+
31
+ useEffect(() => {
32
+ if (!dpad || a.mode === "tv") return;
33
+ document.documentElement.dataset["dpad"] = "on";
34
+ const detach = attachDpad({ onBack: () => history.back() });
35
+ return () => {
36
+ detach();
37
+ delete document.documentElement.dataset["dpad"];
38
+ };
39
+ }, [dpad, a.mode]);
40
+
41
+ return (
42
+ <Page title="Adaptive" summary="One app, three layouts. The window size class (M3 breakpoints at 600, 840, 1200 and 1600 dp) picks the navigation and the panes; the TV layout adds a 10-foot type scale and D-pad focus navigation." packages={["@aphrody/m3-tokens", "@aphrody/m3-front"]} panes={a.panes}>
43
+ <Section title="This window" description="Live from @aphrody/m3-front (observeWindowClass) and @aphrody/m3-tokens.">
44
+ <dl className="grid grid-cols-2 gap-3 expanded:grid-cols-4" data-testid="window-state">
45
+ {[
46
+ ["Width class", `${a.width} (${a.widthPx} px)`],
47
+ ["Height class", `${a.height} (${a.heightPx} px)`],
48
+ ["Navigation", a.navigation],
49
+ ["Panes", String(a.panes)],
50
+ ["Layout mode", `${a.mode} (${a.source})`],
51
+ ["Margin", `${marginFor(a.width)} dp`],
52
+ ["Orientation", a.landscape ? "landscape" : "portrait"],
53
+ ["Pointer", a.touch ? "coarse (touch)" : "fine"],
54
+ ].map(([term, value]) => (
55
+ <Card key={term}>
56
+ <dt className="text-label-medium text-on-surface-variant">{term}</dt>
57
+ <dd className="text-title-medium text-on-surface">{value}</dd>
58
+ </Card>
59
+ ))}
60
+ </dl>
61
+ </Section>
62
+
63
+ <Section title="Layout mode" description="TV is chosen by user agent (Tizen, webOS, Android TV, Fire TV, Chromecast, consoles), by ?layout=tv, or here.">
64
+ <div role="radiogroup" aria-label="Layout mode" className="inline-flex flex-wrap gap-2">
65
+ {[...LAYOUT_MODES, null].map((mode) => (
66
+ <button key={mode ?? "auto"} type="button" role="radio" aria-checked={(mode ?? "auto") === (a.source === "override" ? a.mode : "auto")} data-dpad data-testid={`layout-${mode ?? "auto"}`} className={`state-layer rounded-full border px-4 py-2 text-label-large ${(mode ?? "auto") === (a.source === "override" ? a.mode : "auto") ? "border-transparent bg-secondary-container text-on-secondary-container" : "border-outline text-on-surface-variant"}`} onClick={() => setLayoutOverride(mode)}>
67
+ {mode ?? "auto"}
68
+ </button>
69
+ ))}
70
+ </div>
71
+ </Section>
72
+
73
+ <Section title="Window size classes" description="Lower bounds in dp from @aphrody/m3-tokens/breakpoints; navigation and panes per class.">
74
+ <div className="m3-scroll overflow-x-auto rounded-large bg-surface-container">
75
+ <table className="w-full text-left text-body-medium" data-testid="breakpoints">
76
+ <thead className="text-label-large text-on-surface-variant">
77
+ <tr>
78
+ <th className="p-3">Class</th>
79
+ <th className="p-3">From</th>
80
+ <th className="p-3">Navigation</th>
81
+ <th className="p-3">Panes</th>
82
+ <th className="p-3">Margin</th>
83
+ </tr>
84
+ </thead>
85
+ <tbody>
86
+ {WINDOW_SIZE_CLASSES.map((c) => (
87
+ <tr key={c} className={c === a.width ? "bg-secondary-container text-on-secondary-container" : ""} aria-current={c === a.width ? "true" : undefined}>
88
+ <td className="p-3 font-medium">{c}</td>
89
+ <td className="p-3">{BREAKPOINTS[c]} dp</td>
90
+ <td className="p-3">{navigationFor(c)}</td>
91
+ <td className="p-3">{panesFor(c)}</td>
92
+ <td className="p-3">{marginFor(c)} dp</td>
93
+ </tr>
94
+ ))}
95
+ </tbody>
96
+ </table>
97
+ </div>
98
+ <p className="text-body-small text-on-surface-variant">Height classes: compact &lt; {HEIGHT_BREAKPOINTS.medium}, medium &lt; {HEIGHT_BREAKPOINTS.expanded}, expanded from {HEIGHT_BREAKPOINTS.expanded} dp.</p>
99
+ </Section>
100
+
101
+ <Section title="D-pad lab" description="Arrow keys move focus to the nearest control in that direction, Enter activates, Back (Escape, Backspace, TV Back keys) leaves. It is always on in the TV layout; switch it on here to try it with a keyboard.">
102
+ <div className="flex items-center gap-3">
103
+ <button type="button" role="switch" aria-checked={dpad || a.mode === "tv"} data-dpad data-testid="dpad-toggle" disabled={a.mode === "tv"} className="state-layer rounded-full border border-outline px-4 py-2 text-label-large" onClick={() => setDpad((v) => !v)}>
104
+ D-pad navigation: {dpad || a.mode === "tv" ? "on" : "off"}
105
+ </button>
106
+ <span className="text-body-medium text-on-surface-variant" data-testid="dpad-focus">Focused: {focused}</span>
107
+ </div>
108
+ <div ref={grid} className="grid grid-cols-3 gap-3 expanded:grid-cols-6" onFocusCapture={(event) => setFocused((event.target as HTMLElement).dataset["tile"] ?? "none")}>
109
+ {Array.from({ length: 12 }, (_, i) => (
110
+ <button key={i} type="button" data-dpad data-tile={`tile ${i + 1}`} className="state-layer flex h-24 items-center justify-center rounded-large bg-surface-container-high text-title-medium text-on-surface" onClick={() => setFocused(`tile ${i + 1} (activated)`)}>
111
+ {i + 1}
112
+ </button>
113
+ ))}
114
+ </div>
115
+ </Section>
116
+
117
+ {framed ? null : (
118
+ <Section title="Three layouts, side by side" description="The same app in three frames: the iframes load this page with ?layout=mobile, desktop and tv.">
119
+ <div className="flex flex-wrap items-start gap-6" data-testid="frames">
120
+ {FRAMES.map((f) => (
121
+ <Frame key={f.mode} {...f} scale={f.mode === "mobile" ? 0.6 : f.mode === "desktop" ? 0.4 : 0.3} />
122
+ ))}
123
+ </div>
124
+ </Section>
125
+ )}
126
+ </Page>
127
+ );
128
+ }
@@ -0,0 +1,174 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ import { useEffect, useRef, useState } from "react";
3
+ import {
4
+ AgUiEventAccumulator,
5
+ ChatComposer,
6
+ MessageBubble,
7
+ ToolCall,
8
+ type AgUiStreamState,
9
+ } from "@aphrody/m3-ai";
10
+ import type { BaseEvent } from "@aphrody/ag-ui";
11
+ import { Button } from "@aphrody/m3-primitives";
12
+ import { Card, Code, Page, Section } from "../components/ui.tsx";
13
+ import type { PageProps } from "./index.ts";
14
+
15
+ const initial = (): AgUiStreamState => new AgUiEventAccumulator().snapshot();
16
+ export default function Ai({ adaptive }: PageProps) {
17
+ const [draft, setDraft] = useState("Show the Material 3 package inventory.");
18
+ const [prompt, setPrompt] = useState("");
19
+ const [state, setState] = useState(initial);
20
+ const [running, setRunning] = useState(false);
21
+ const [notice, setNotice] = useState("");
22
+ const active = useRef<AbortController | null>(null);
23
+ useEffect(() => () => active.current?.abort(), []);
24
+
25
+ async function send() {
26
+ if (active.current || !draft.trim()) return;
27
+ const controller = new AbortController();
28
+ active.current = controller;
29
+ const accumulator = new AgUiEventAccumulator();
30
+ setPrompt(draft.trim());
31
+ setState(initial());
32
+ setNotice("");
33
+ setRunning(true);
34
+ try {
35
+ const response = await fetch("/api/ai/stream", {
36
+ method: "POST",
37
+ headers: { "Content-Type": "application/json" },
38
+ body: JSON.stringify({ prompt: draft.trim() }),
39
+ signal: controller.signal,
40
+ });
41
+ if (!response.ok || !response.body)
42
+ throw new Error("The local fixture stream is unavailable.");
43
+ const reader = response.body.getReader();
44
+ const decoder = new TextDecoder();
45
+ let pending = "";
46
+ const consume = () => {
47
+ const packets = pending.split(/\r?\n\r?\n/);
48
+ pending = packets.pop() ?? "";
49
+ for (const packet of packets) {
50
+ const data = packet
51
+ .split(/\r?\n/)
52
+ .filter((line) => line.startsWith("data:"))
53
+ .map((line) => line.slice(5).trimStart())
54
+ .join("\n");
55
+ if (data) accumulator.push(JSON.parse(data) as BaseEvent);
56
+ }
57
+ if (!controller.signal.aborted) setState(accumulator.snapshot());
58
+ };
59
+ try {
60
+ // eslint-disable-next-line no-await-in-loop -- Each SSE read extends the pending event frame from the previous chunk.
61
+ for (let chunk = await reader.read(); !chunk.done; chunk = await reader.read()) {
62
+ pending += decoder.decode(chunk.value, { stream: true });
63
+ consume();
64
+ }
65
+ pending += decoder.decode();
66
+ consume();
67
+ } finally {
68
+ reader.releaseLock();
69
+ }
70
+ } catch (error) {
71
+ if (!controller.signal.aborted)
72
+ setNotice(error instanceof Error ? error.message : "The fixture stream failed.");
73
+ } finally {
74
+ if (active.current === controller) {
75
+ active.current = null;
76
+ setRunning(false);
77
+ }
78
+ }
79
+ }
80
+ const stop = () => {
81
+ active.current?.abort();
82
+ active.current = null;
83
+ setRunning(false);
84
+ setNotice("Stream stopped.");
85
+ };
86
+ return (
87
+ <Page
88
+ title="AI"
89
+ summary="Inspect a real AG-UI event stream through the Material 3 transcript, tool-call and composer components."
90
+ packages={["@aphrody/m3-ai", "@aphrody/ag-ui"]}
91
+ panes={adaptive.panes}
92
+ aside={
93
+ <Card>
94
+ <h3 className="text-title-medium">Stream state</h3>
95
+ <Code>
96
+ {JSON.stringify(
97
+ {
98
+ status: state.status,
99
+ items: state.items.length,
100
+ subagents: state.subagents,
101
+ fixture: true,
102
+ },
103
+ null,
104
+ 2,
105
+ )}
106
+ </Code>
107
+ </Card>
108
+ }
109
+ >
110
+ <Section
111
+ title="Local protocol fixture"
112
+ description="This app streams its package inventory as labelled AG-UI events."
113
+ >
114
+ <Card className="flex flex-col gap-4">
115
+ <div aria-live="polite" aria-busy={running} className="flex flex-col gap-3">
116
+ {prompt ? (
117
+ <MessageBubble content={prompt} isUser />
118
+ ) : (
119
+ <p className="text-body-large text-on-surface-variant">
120
+ Send a draft to inspect the local event fixture.
121
+ </p>
122
+ )}
123
+ {state.items.map((item, index) =>
124
+ item.kind === "tool" ? (
125
+ <ToolCall key={item.pair.id} pair={item.pair} defaultExpanded />
126
+ ) : (
127
+ <MessageBubble
128
+ key={index}
129
+ content={item.text}
130
+ isUser={false}
131
+ isStreaming={running}
132
+ onCopy={(content) => {
133
+ if (!navigator.clipboard) {
134
+ setNotice("Clipboard access is unavailable.");
135
+ return;
136
+ }
137
+ void navigator.clipboard.writeText(content).then(
138
+ () => setNotice("Message copied."),
139
+ () => setNotice("Clipboard access is unavailable."),
140
+ );
141
+ }}
142
+ />
143
+ ),
144
+ )}
145
+ </div>
146
+ <ChatComposer
147
+ draft={draft}
148
+ onDraftChange={setDraft}
149
+ onSend={() => {
150
+ void send();
151
+ }}
152
+ isSending={running}
153
+ onStop={stop}
154
+ placeholder="Draft for the local protocol fixture"
155
+ />
156
+ <p role="status" className="text-body-medium text-on-surface-variant">
157
+ {notice || (running ? "Receiving AG-UI events…" : "Ready")}
158
+ </p>
159
+ <Button
160
+ variant="outlined"
161
+ onClick={() => {
162
+ stop();
163
+ setPrompt("");
164
+ setState(initial());
165
+ setNotice("");
166
+ }}
167
+ >
168
+ Reset transcript
169
+ </Button>
170
+ </Card>
171
+ </Section>
172
+ </Page>
173
+ );
174
+ }
@@ -0,0 +1,156 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ import { useEffect, useRef, useState } from "react";
3
+ import { AphrodyAvatar, AphrodyPet, PET, type PetAnimation } from "@aphrody/identity";
4
+ import { PET_ATLAS_URL } from "@aphrody/identity/atlas";
5
+ import {
6
+ configureBrowserCanvas,
7
+ createM3CanvasSurface,
8
+ selectCanvasBackend,
9
+ } from "@aphrody/canvas/browser";
10
+ import { getIcon } from "@aphrody/assets/util";
11
+ import { useM3Theme } from "@aphrody/m3-theme/react";
12
+ import rgTokens, { resolved as rgResolved } from "m3:optional/@rosegriffon/ui/tokens";
13
+ import shenronTokens, { resolved as shenronResolved } from "m3:optional/@shenron/ui/tokens";
14
+ import nieKit, { resolved as nieResolved } from "m3:optional/@aphrody/nie-ui";
15
+ import { Card, Code, Page, Section } from "../components/ui.tsx";
16
+ import type { PageProps } from "./index.ts";
17
+
18
+ const kits = [
19
+ { name: "@rosegriffon/ui/tokens", resolved: rgResolved, namespace: rgTokens },
20
+ { name: "@shenron/ui/tokens", resolved: shenronResolved, namespace: shenronTokens },
21
+ { name: "@aphrody/nie-ui", resolved: nieResolved, namespace: nieKit },
22
+ ];
23
+ export default function Brands({ adaptive }: PageProps) {
24
+ const theme = useM3Theme();
25
+ const [animation, setAnimation] = useState<PetAnimation>("idle");
26
+ const canvas = useRef<HTMLCanvasElement | null>(null);
27
+ useEffect(() => {
28
+ const element = canvas.current;
29
+ if (!element) return;
30
+ configureBrowserCanvas(element, {
31
+ width: 420,
32
+ height: 180,
33
+ m3: createM3CanvasSurface({ colorScheme: theme.resolvedTheme }),
34
+ });
35
+ const context = element.getContext("2d");
36
+ if (!context) return;
37
+ const style = getComputedStyle(element);
38
+ const ratio = devicePixelRatio || 1;
39
+ context.setTransform(ratio, 0, 0, ratio, 0, 0);
40
+ context.fillStyle = style.getPropertyValue("--md-sys-color-surface-container").trim();
41
+ context.fillRect(0, 0, 420, 180);
42
+ context.fillStyle = style.getPropertyValue("--md-sys-color-primary").trim();
43
+ context.fillRect(20, 20, 380, 140);
44
+ context.fillStyle = style.getPropertyValue("--md-sys-color-on-primary").trim();
45
+ context.font = "500 24px " + style.fontFamily;
46
+ context.fillText("Aphrody M3", 40, 82);
47
+ context.font = "400 16px " + style.fontFamily;
48
+ context.fillText("Canvas follows the live theme", 40, 114);
49
+ }, [theme.seedColor, theme.resolvedTheme, theme.variant, theme.contrastLevel]);
50
+ return (
51
+ <Page
52
+ title="Brands"
53
+ summary="Explore Aphrody's canonical identity, animated pet, adaptive canvas surface and shared file assets."
54
+ packages={["@aphrody/identity", "@aphrody/canvas", "@aphrody/assets"]}
55
+ panes={adaptive.panes}
56
+ aside={
57
+ <Card>
58
+ <h3 className="text-title-medium">Host kits</h3>
59
+ <p className="text-body-medium text-on-surface-variant">
60
+ Optional modules report their actual resolution in this workspace.
61
+ </p>
62
+ {kits.map((kit) => (
63
+ <div key={kit.name} className="mt-3">
64
+ <p className="text-label-large">{kit.name}</p>
65
+ <p className="text-body-medium">
66
+ {kit.resolved ? "Resolved" : "External host package"}
67
+ </p>
68
+ {kit.namespace ? <Code>{Object.keys(kit.namespace).join("\n")}</Code> : null}
69
+ </div>
70
+ ))}
71
+ </Card>
72
+ }
73
+ >
74
+ <Section title="Aphrody identity">
75
+ <Card className="flex flex-wrap items-center gap-5">
76
+ {[32, 64, 96].map((size) => (
77
+ <AphrodyAvatar key={size} size={size} label={"Aphrody emblem at " + size + " pixels"} />
78
+ ))}
79
+ <div>
80
+ <h3 className="text-title-large">Aphrody</h3>
81
+ <p className="text-body-medium text-on-surface-variant">
82
+ One brand asset source, with adaptive pixel density.
83
+ </p>
84
+ </div>
85
+ </Card>
86
+ </Section>
87
+ <Section
88
+ title="Animated pet"
89
+ description="The canonical atlas and timed tracks honour reduced-motion preferences."
90
+ >
91
+ <Card className="flex flex-col gap-4">
92
+ <label className="flex flex-col gap-2 text-label-large">
93
+ Animation
94
+ <select
95
+ className="h-12 rounded-small border border-outline bg-surface px-3"
96
+ value={animation}
97
+ onChange={(event) => setAnimation(event.target.value as PetAnimation)}
98
+ >
99
+ {Object.keys(PET.tracks).map((name) => (
100
+ <option key={name}>{name}</option>
101
+ ))}
102
+ </select>
103
+ </label>
104
+ <AphrodyPet
105
+ atlasUrl={PET_ATLAS_URL}
106
+ animation={animation}
107
+ height={160}
108
+ label="Aphrody animated pet"
109
+ />
110
+ </Card>
111
+ </Section>
112
+ <Section
113
+ title="Canvas surface"
114
+ description="The browser canvas adapter sizes the backing surface for the display's pixel ratio."
115
+ >
116
+ <Card>
117
+ <canvas
118
+ ref={canvas}
119
+ width={420}
120
+ height={180}
121
+ style={{ width: "100%", maxWidth: 420, height: "auto" }}
122
+ role="img"
123
+ aria-label="Aphrody Material 3 canvas using the current theme"
124
+ >
125
+ Aphrody M3 canvas.
126
+ </canvas>
127
+ <Code>
128
+ {JSON.stringify(
129
+ {
130
+ backend: selectCanvasBackend("browser"),
131
+ surface: createM3CanvasSurface({ colorScheme: theme.resolvedTheme }),
132
+ },
133
+ null,
134
+ 2,
135
+ )}
136
+ </Code>
137
+ </Card>
138
+ </Section>
139
+ <Section title="Shared file assets">
140
+ <div className="grid grid-cols-3 gap-3 expanded:grid-cols-6">
141
+ {["Document", "Image", "Audio", "Video", "Code", "Archive"].map((kind) => (
142
+ <Card key={kind} className="flex flex-col items-center gap-2">
143
+ <img
144
+ src={String(getIcon(kind, theme.resolvedTheme === "dark"))}
145
+ width={48}
146
+ height={48}
147
+ alt={kind + " file icon"}
148
+ />
149
+ <span className="text-label-large">{kind}</span>
150
+ </Card>
151
+ ))}
152
+ </div>
153
+ </Section>
154
+ </Page>
155
+ );
156
+ }
@@ -0,0 +1,91 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ import { useState } from "react";
3
+ import {
4
+ MdElevatedButton,
5
+ MdFilledButton,
6
+ MdFilledTonalButton,
7
+ MdOutlinedButton,
8
+ MdTextButton,
9
+ } from "@aphrody/m3-react/button";
10
+ import { MdOutlinedTextField, MdFilledTextField } from "@aphrody/m3-react/textfield";
11
+ import { MdSwitch } from "@aphrody/m3-react/switch";
12
+ import { MdSlider } from "@aphrody/m3-react/slider";
13
+ import { Card, Page, Section } from "../components/ui.tsx";
14
+ import type { PageProps } from "./index.ts";
15
+
16
+ export default function Components({ adaptive }: PageProps) {
17
+ const [clicks, setClicks] = useState(0);
18
+ const [name, setName] = useState("Aphrody");
19
+ const [enabled, setEnabled] = useState(true);
20
+ const [volume, setVolume] = useState(50);
21
+ return (
22
+ <Page
23
+ title="Web components"
24
+ summary="Material Web custom elements rendered through the React adapters. The shared theme reaches their shadow roots; native events update React state."
25
+ packages={["@aphrody/material-web", "@aphrody/m3-react"]}
26
+ panes={adaptive.panes}
27
+ >
28
+ <Section
29
+ title="Button family"
30
+ description="All five Material 3 emphasis levels trigger the same local counter."
31
+ >
32
+ <Card className="flex flex-wrap items-center gap-3">
33
+ <MdElevatedButton onClick={() => setClicks((value) => value + 1)}>
34
+ Elevated
35
+ </MdElevatedButton>
36
+ <MdFilledButton onClick={() => setClicks((value) => value + 1)}>Filled</MdFilledButton>
37
+ <MdFilledTonalButton onClick={() => setClicks((value) => value + 1)}>
38
+ Tonal
39
+ </MdFilledTonalButton>
40
+ <MdOutlinedButton onClick={() => setClicks((value) => value + 1)}>
41
+ Outlined
42
+ </MdOutlinedButton>
43
+ <MdTextButton onClick={() => setClicks((value) => value + 1)}>Text</MdTextButton>
44
+ <output className="text-body-large" aria-live="polite">
45
+ Activations: {clicks}
46
+ </output>
47
+ </Card>
48
+ </Section>
49
+ <Section
50
+ title="Text fields"
51
+ description="Input events keep outlined and filled fields in sync."
52
+ >
53
+ <Card className="flex flex-wrap items-start gap-4">
54
+ <MdOutlinedTextField
55
+ label="Outlined name"
56
+ value={name}
57
+ onInput={(event) => setName((event.currentTarget as HTMLInputElement).value)}
58
+ />
59
+ <MdFilledTextField
60
+ label="Filled name"
61
+ value={name}
62
+ onInput={(event) => setName((event.currentTarget as HTMLInputElement).value)}
63
+ />
64
+ <p className="text-body-large">Hello, {name || "visitor"}.</p>
65
+ </Card>
66
+ </Section>
67
+ <Section title="Selection and range">
68
+ <Card className="flex flex-col gap-4">
69
+ <label className="flex items-center gap-3">
70
+ <MdSwitch
71
+ selected={enabled}
72
+ onChange={(event) =>
73
+ setEnabled((event.currentTarget as unknown as { selected: boolean }).selected)
74
+ }
75
+ aria-label="Enable notifications"
76
+ />
77
+ Enable notifications: {enabled ? "on" : "off"}
78
+ </label>
79
+ <MdSlider
80
+ min={0}
81
+ max={100}
82
+ value={volume}
83
+ aria-label="Volume"
84
+ onInput={(event) => setVolume(Number((event.currentTarget as HTMLInputElement).value))}
85
+ />
86
+ <output className="text-body-large">Volume: {volume}%</output>
87
+ </Card>
88
+ </Section>
89
+ </Page>
90
+ );
91
+ }