@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.
- package/README.md +47 -0
- package/dist/Album-20-x0fyhqxj.png +0 -0
- package/dist/Album-txdjxr6p.png +0 -0
- package/dist/Album_Light-bnvn9x43.png +0 -0
- package/dist/Alias-20-jpvzp7sd.png +0 -0
- package/dist/Alias-fbqj79wp.png +0 -0
- package/dist/Alias_Light-hv5b8k7t.png +0 -0
- package/dist/AmazonS3-x58haer2.png +0 -0
- package/dist/AndroidPhotos-cj9z6mnt.png +0 -0
- package/dist/AppleFiles-g4g8431e.png +0 -0
- package/dist/ApplePhotos-f2nesvx1.png +0 -0
- package/dist/Application-ft1as292.png +0 -0
- package/dist/Application_Light-h2p2z3de.png +0 -0
- package/dist/Archive-20-y262mxsm.png +0 -0
- package/dist/Archive-vmmq3f0p.png +0 -0
- package/dist/Archive_Light-fqxdt82g.png +0 -0
- package/dist/Audio-20-345hqxr8.png +0 -0
- package/dist/Audio-3w697yx9.png +0 -0
- package/dist/Audio_Light-4pb6z10h.png +0 -0
- package/dist/BackBlaze-6m4qpkyc.png +0 -0
- package/dist/Ball-d0bcgqha.png +0 -0
- package/dist/Book-20-etd4fzhm.png +0 -0
- package/dist/Book-ekfqxh7a.png +0 -0
- package/dist/BookBlue-17k9z7dy.png +0 -0
- package/dist/Book_Light-0n5wsr76.png +0 -0
- package/dist/Box-rd26c0g6.png +0 -0
- package/dist/CloudSync-wxh5ez5h.png +0 -0
- package/dist/CloudSync_Light-nb09rvv4.png +0 -0
- package/dist/Code-20-ybgq5j59.png +0 -0
- package/dist/Collection-20-7g9nzzcf.png +0 -0
- package/dist/Collection-52f2j9wx.png +0 -0
- package/dist/CollectionSparkle-nj38wazp.png +0 -0
- package/dist/CollectionSparkle_Light-hp1jptvv.png +0 -0
- package/dist/Collection_Light-z7p3knd7.png +0 -0
- package/dist/Compute-ghst3emj.png +0 -0
- package/dist/Config-20-vqd0vqeb.png +0 -0
- package/dist/DAV-mr5nm7zs.png +0 -0
- package/dist/Database-20-0q97pw36.png +0 -0
- package/dist/Database-rcxjw7yv.png +0 -0
- package/dist/Database_Light-1dxfaj96.png +0 -0
- package/dist/DeleteLocation-3hw52syq.png +0 -0
- package/dist/Devices-t2f2k803.png +0 -0
- package/dist/Document-20-0f78jpbp.png +0 -0
- package/dist/Document-kgsdt3nq.png +0 -0
- package/dist/Document_Light-ht9avf71.png +0 -0
- package/dist/Document_doc-wqd2zqp2.png +0 -0
- package/dist/Document_doc_Light-4ppbm2he.png +0 -0
- package/dist/Document_memory-6vymqjra.png +0 -0
- package/dist/Document_pdf-7b1zt469.png +0 -0
- package/dist/Document_pdf_Light-42j6dt8z.png +0 -0
- package/dist/Document_srt-symqv91r.png +0 -0
- package/dist/Document_xls-j5tbzav2.png +0 -0
- package/dist/Document_xls_Light-w6kbrvem.png +0 -0
- package/dist/Document_xmp-7xqx4tm8.png +0 -0
- package/dist/Dotfile-20-w53rabv6.png +0 -0
- package/dist/Drive-7wb1bf5w.png +0 -0
- package/dist/Drive-AmazonS3_Light-z6j2s9xm.png +0 -0
- package/dist/Drive-BackBlaze_Light-tr4wfkey.png +0 -0
- package/dist/Drive-DAV_Light-kse85f46.png +0 -0
- package/dist/Drive-Darker-mss4n9ws.png +0 -0
- package/dist/Drive-Dropbox_Light-48naz6gc.png +0 -0
- package/dist/Drive-GoogleDrive_Light-t4d4180c.png +0 -0
- package/dist/Drive-Mega-z6k8n821.png +0 -0
- package/dist/Drive-Mega_Light-nk0qskfb.png +0 -0
- package/dist/Drive-OneDrive-sx649zqw.png +0 -0
- package/dist/Drive-OneDrive_Light-2n556kpe.png +0 -0
- package/dist/Drive-OpenStack-tcs5rge7.png +0 -0
- package/dist/Drive-OpenStack_Light-05qnc2gy.png +0 -0
- package/dist/Drive-PCloud_Light-d0h9kbwp.png +0 -0
- package/dist/Drive-box_Light-0cb17zc1.png +0 -0
- package/dist/Drive_Light-dcjdmxm9.png +0 -0
- package/dist/Dropbox-q4nkmy9v.png +0 -0
- package/dist/Encrypted-20-m8ax3zxz.png +0 -0
- package/dist/Encrypted-ddrf9wk4.png +0 -0
- package/dist/Encrypted_Light-n1mjh529.png +0 -0
- package/dist/Entity-a4438mse.png +0 -0
- package/dist/Entity_Light-acxm9r2c.png +0 -0
- package/dist/Executable-20-fp7e8r9j.png +0 -0
- package/dist/Executable_Light_old-6xd6fa1z.png +0 -0
- package/dist/Executable_old-cyj158kz.png +0 -0
- package/dist/Face_Light-pjctyrvt.png +0 -0
- package/dist/Folder-20-r5505wvj.png +0 -0
- package/dist/Folder-kc594khj.png +0 -0
- package/dist/Folder-tag-xmp-ff4bgkr4.png +0 -0
- package/dist/FolderGrey-2vy13evc.png +0 -0
- package/dist/FolderGrey_Light-7z31xy56.png +0 -0
- package/dist/FolderNoSpace-d65fr1rz.png +0 -0
- package/dist/FolderNoSpace_Light-r5fc4pfj.png +0 -0
- package/dist/Folder_Light-rrg0jy36.png +0 -0
- package/dist/Font-20-r5n0z7f9.png +0 -0
- package/dist/Game-ts1kdw4e.png +0 -0
- package/dist/Game_Light-4d6ty5nz.png +0 -0
- package/dist/Globe-b379ffpd.png +0 -0
- package/dist/GlobeAlt-2mjbsvpp.png +0 -0
- package/dist/Globe_Light-2r9sdhb0.png +0 -0
- package/dist/GoogleDrive-1swewbzf.png +0 -0
- package/dist/GoogleSansFlex-latin-23tdmmt1.woff2 +0 -0
- package/dist/HDD-e85re2j5.png +0 -0
- package/dist/HDD_Light-pfbhb5wg.png +0 -0
- package/dist/Heart-3nx0yjvz.png +0 -0
- package/dist/Heart_Light-msf9zhq6.png +0 -0
- package/dist/Home-waerfpg1.png +0 -0
- package/dist/Home_Light-mdswjrcg.png +0 -0
- package/dist/Image-20-7vvqrhrb.png +0 -0
- package/dist/Image-fz5c8462.png +0 -0
- package/dist/Image_Light-rp0w5n3r.png +0 -0
- package/dist/Indexed-nxd6ctrt.png +0 -0
- package/dist/Key-20-z5nhfv0c.png +0 -0
- package/dist/Key-4en80vnn.png +0 -0
- package/dist/Key_Light-h3pc5e2c.png +0 -0
- package/dist/Keys-9jknyggw.png +0 -0
- package/dist/Keys_Light-5w8kcsmz.png +0 -0
- package/dist/Laptop-9gwskqny.png +0 -0
- package/dist/Laptop_Light-pwtbqbkp.png +0 -0
- package/dist/Link-20-f7hh1tcv.png +0 -0
- package/dist/Link-w9y1yad0.png +0 -0
- package/dist/Link_Light-4dy9pa5j.png +0 -0
- package/dist/Location-7vx0yx6r.png +0 -0
- package/dist/LocationManaged-w1n71jx5.png +0 -0
- package/dist/LocationReplica-4c6ncswq.png +0 -0
- package/dist/Lock-mnveqyfm.png +0 -0
- package/dist/Lock_Light-xwnbzkjz.png +0 -0
- package/dist/Mega-h4j4t3sb.png +0 -0
- package/dist/Mesh-20-rkky209q.png +0 -0
- package/dist/Mesh-efjcay8j.png +0 -0
- package/dist/Mesh_Light-t9yyzb3y.png +0 -0
- package/dist/MiniSilverBox-g8dfw0cp.png +0 -0
- package/dist/Mobile-Android-wy5kr3bj.png +0 -0
- package/dist/Mobile-jpsv7vp8.png +0 -0
- package/dist/Mobile_Light-2rwnn5bx.png +0 -0
- package/dist/MoveLocation-kft0z94v.png +0 -0
- package/dist/MoveLocation_Light-c23j5x59.png +0 -0
- package/dist/Movie-nxat82kv.png +0 -0
- package/dist/Movie_Light-eh1hmsr5.png +0 -0
- package/dist/NewLocation-2hfv9dwq.png +0 -0
- package/dist/Node-wykht7k0.png +0 -0
- package/dist/Node_Light-maewxhk1.png +0 -0
- package/dist/OneDrive-e4jvssjp.png +0 -0
- package/dist/OpenStack-pqp01jfd.png +0 -0
- package/dist/PC-eyfa7ewm.png +0 -0
- package/dist/PCloud-p0n6g1hq.png +0 -0
- package/dist/Package-20-grg5wkse.png +0 -0
- package/dist/Package-d7ex1fnn.png +0 -0
- package/dist/Package_Light-yj2cvgyw.png +0 -0
- package/dist/SD-h17wvz4z.png +0 -0
- package/dist/SD_Light-y3mmqh6b.png +0 -0
- package/dist/Scrapbook-f92c8p1x.png +0 -0
- package/dist/Scrapbook_Light-50pjr0q7.png +0 -0
- package/dist/Screenshot-20-z4tfe78m.png +0 -0
- package/dist/Screenshot-9nd23fde.png +0 -0
- package/dist/ScreenshotAlt-en1yt2gv.png +0 -0
- package/dist/Screenshot_Light-hnbah84r.png +0 -0
- package/dist/Search-7x8c5z1s.png +0 -0
- package/dist/SearchAlt-dmxzk2jb.png +0 -0
- package/dist/Search_Light-n23xd2ws.png +0 -0
- package/dist/Server-hqsf8851.png +0 -0
- package/dist/Server_Light-3x01jqz4.png +0 -0
- package/dist/SilverBox-0mk6sxrh.png +0 -0
- package/dist/Spacedrop-1-d230z0az.png +0 -0
- package/dist/Spacedrop-r1t67bcq.png +0 -0
- package/dist/Spacedrop_Light-dj5tgtep.png +0 -0
- package/dist/Storage-4x2q4nx6.png +0 -0
- package/dist/Sync-531te7fq.png +0 -0
- package/dist/Sync_Light-754vfxyr.png +0 -0
- package/dist/Tablet-ze6ermb7.png +0 -0
- package/dist/Tablet_Light-32skyk12.png +0 -0
- package/dist/Tags-bfapk266.png +0 -0
- package/dist/Tags_Light-7s00envw.png +0 -0
- package/dist/Terminal-t1yjx33x.png +0 -0
- package/dist/Terminal_Light-4s5azdgr.png +0 -0
- package/dist/Text-20-pt0zjg62.png +0 -0
- package/dist/Text-6fgmf4b2.png +0 -0
- package/dist/TextAlt_Light-w9kbgvm8.png +0 -0
- package/dist/Text_Light-c2k3w31k.png +0 -0
- package/dist/Text_txt-xhvv80ys.png +0 -0
- package/dist/TexturedMesh-ysk831xz.png +0 -0
- package/dist/TexturedMesh_Light-4twy5k6k.png +0 -0
- package/dist/Trash-hzscccvk.png +0 -0
- package/dist/Trash_Light-78nc56tp.png +0 -0
- package/dist/Undefined-pkbecmq4.png +0 -0
- package/dist/Undefined_Light-jxesg2zv.png +0 -0
- package/dist/Unknown-20-07efh8ya.png +0 -0
- package/dist/Video-20-q7yg9p4w.png +0 -0
- package/dist/Video-370fzqyw.png +0 -0
- package/dist/Video_Light-00vhrp0m.png +0 -0
- package/dist/WebPageArchive-20-wn0v4x27.png +0 -0
- package/dist/Widget-20-9t860nnc.png +0 -0
- package/dist/Widget-k1p15mg9.png +0 -0
- package/dist/Widget_Light-5md790ar.png +0 -0
- package/dist/ace-ph0rt669.svg +1 -0
- package/dist/acemanifest-je939qnz.svg +1 -0
- package/dist/adoc-kfbf89h8.svg +1 -0
- package/dist/adonis-pn6tbmnq.svg +1 -0
- package/dist/adonisconfig-5wfnycbk.svg +1 -0
- package/dist/afdesign-5nzbppfa.svg +1 -0
- package/dist/afphoto-p941z6q7.svg +1 -0
- package/dist/afpub-3232tcp9.svg +1 -0
- package/dist/ai-vvwvj03w.svg +1 -0
- package/dist/air-e3h8cfx1.svg +1 -0
- package/dist/angular-fyg22v82.svg +1 -0
- package/dist/angular-kzcwnjdt.svg +1 -0
- package/dist/anim-15kqy432.svg +1 -0
- package/dist/astro-wdcxh4zx.svg +1 -0
- package/dist/astroconfig-73qsx73n.svg +1 -0
- package/dist/atomizer-42xe88w7.svg +1 -0
- package/dist/audio-xy5qb7t1.svg +1 -0
- package/dist/audiomp3-s01feh78.svg +1 -0
- package/dist/audioogg-bcake0v6.svg +1 -0
- package/dist/audiowav-px37pxve.svg +1 -0
- package/dist/audiowv-bq8tbfdv.svg +1 -0
- package/dist/azure-veqzyzqq.svg +1 -0
- package/dist/babel-vxcfp57a.svg +1 -0
- package/dist/ballerina-faxx9p3b.svg +1 -0
- package/dist/ballerinaconfig-tmd09kkg.svg +1 -0
- package/dist/bat-vjr63aqs.svg +1 -0
- package/dist/bazel-4e01p5gp.svg +1 -0
- package/dist/bazelignore-wzgc7h2d.svg +1 -0
- package/dist/bicep-dae0dh59.svg +1 -0
- package/dist/bicepconfig-v64442sp.svg +1 -0
- package/dist/bicepparam-ts4jjq60.svg +1 -0
- package/dist/binary-dz3thnjq.svg +1 -0
- package/dist/biome-gbahcmjy.svg +1 -0
- package/dist/blade-je22xc2d.svg +1 -0
- package/dist/brotli-1m7qfk77.svg +1 -0
- package/dist/browserslist-005php91.svg +1 -0
- package/dist/bruno-h4bh0s2c.svg +1 -0
- package/dist/bsconfig-gmwc0r2r.svg +1 -0
- package/dist/buck-gtasjqw1.svg +1 -0
- package/dist/bun-6y6y7t4s.svg +1 -0
- package/dist/bun-zxmcandz.svg +1 -0
- package/dist/bundler-qhs5a5xb.svg +1 -0
- package/dist/bunlock-74b62xbm.svg +1 -0
- package/dist/c-k2se7t6q.svg +1 -0
- package/dist/c-v9cxtxe1.svg +1 -0
- package/dist/cargo-ma5bwyg5.svg +1 -0
- package/dist/cargolock-ak0tnv5y.svg +1 -0
- package/dist/cert-z62mqtqq.svg +1 -0
- package/dist/cheader-mgw2nf38.svg +1 -0
- package/dist/chunk-08yjrfs5.js +2 -0
- package/dist/chunk-2pmrsdd5.js +2 -0
- package/dist/chunk-3995cv9k.js +1 -0
- package/dist/chunk-58a3eq49.js +2 -0
- package/dist/chunk-616szvb9.js +2 -0
- package/dist/chunk-6638b8v6.js +1 -0
- package/dist/chunk-6ej2n64j.js +1 -0
- package/dist/chunk-7tt0cawd.js +10 -0
- package/dist/chunk-9gxv4c5g.js +1 -0
- package/dist/chunk-9na12mjw.js +1 -0
- package/dist/chunk-b7mpjcry.js +1 -0
- package/dist/chunk-c1g6tshf.js +2 -0
- package/dist/chunk-d50zvrb1.css +1 -0
- package/dist/chunk-d6c35fm0.js +2 -0
- package/dist/chunk-ehpz56xv.js +2 -0
- package/dist/chunk-ewtr6sjm.js +9 -0
- package/dist/chunk-g9rnrhvz.js +2 -0
- package/dist/chunk-gv83r4qx.js +262 -0
- package/dist/chunk-j46wg1ym.js +156 -0
- package/dist/chunk-kapsksxf.js +1 -0
- package/dist/chunk-m98tyb4g.js +6 -0
- package/dist/chunk-nn0prq25.js +2 -0
- package/dist/chunk-nsgjb3bx.js +2 -0
- package/dist/chunk-p8r6wjkz.js +3 -0
- package/dist/chunk-rdnm87fw.js +1 -0
- package/dist/chunk-re36kkra.js +1 -0
- package/dist/chunk-vm9edd26.js +2 -0
- package/dist/chunk-x2hztqk0.css +1 -0
- package/dist/chunk-yyxb5zbq.js +2 -0
- package/dist/civet-5bbs33v3.svg +1 -0
- package/dist/claude-jscxahsf.svg +1 -0
- package/dist/cli-4f5nfe5s.svg +1 -0
- package/dist/clojure-0h7h9znc.svg +1 -0
- package/dist/cmake-q8ryfre0.svg +1 -0
- package/dist/cmake-qwe6x8nx.svg +1 -0
- package/dist/codeworkspace-326020b4.svg +1 -0
- package/dist/coffeescript-ec1bytnk.svg +1 -0
- package/dist/commitlint-93j0tfvp.svg +1 -0
- package/dist/compodoc-36b7gn70.svg +1 -0
- package/dist/composer-vv2tvxkr.svg +1 -0
- package/dist/composerlock-nf0232yh.svg +1 -0
- package/dist/conan-dggdfcr9.svg +1 -0
- package/dist/conf-5756g97p.svg +1 -0
- package/dist/copilot-1phy76q3.svg +1 -0
- package/dist/cpp-4yvddm6j.svg +1 -0
- package/dist/cpp-pbznrtpp.svg +1 -0
- package/dist/crystal-x20aj00e.svg +1 -0
- package/dist/csharp-0p3hstq8.svg +1 -0
- package/dist/csharp-cpmfe8y0.svg +1 -0
- package/dist/cshtml-xb5gtb0r.svg +1 -0
- package/dist/csproj-ftptw15a.svg +1 -0
- package/dist/css-tqps22nw.svg +1 -0
- package/dist/css-ycr1qc5f.svg +1 -0
- package/dist/cssmap-3gnm34f6.svg +1 -0
- package/dist/csv-gg0axfar.svg +1 -0
- package/dist/cucumber-m06dfkm5.svg +1 -0
- package/dist/cursor-jw7n7tpq.svg +1 -0
- package/dist/cypress-xsm2fq1p.svg +1 -0
- package/dist/cypressjs-hapzyfm1.svg +1 -0
- package/dist/cypressts-jey9ahc7.svg +1 -0
- package/dist/d-4x2njcan.svg +1 -0
- package/dist/dartlang-7dwdwv03.svg +1 -0
- package/dist/dartlang-mra7r0f8.svg +1 -0
- package/dist/delphiproject-7snmvsdx.svg +1 -0
- package/dist/diff-hekg2jpm.svg +1 -0
- package/dist/docker-8q58y2kc.svg +1 -0
- package/dist/dockerdebug-8zhgj7bd.svg +1 -0
- package/dist/dockerignore-488safx9.svg +1 -0
- package/dist/drawio-6qm0rhkv.svg +1 -0
- package/dist/drizzle-5bct2tg6.svg +1 -0
- package/dist/dsstore-pmhpmkdr.svg +1 -0
- package/dist/dune-r4xhac56.svg +1 -0
- package/dist/duneproject-3b99jndq.svg +1 -0
- package/dist/edge-0jwced3c.svg +1 -0
- package/dist/editorconfig-hee1zp1h.svg +1 -0
- package/dist/eex-q1bkj66x.svg +1 -0
- package/dist/elixir-48ge02m5.svg +1 -0
- package/dist/elm-97mh5wye.svg +1 -0
- package/dist/env-ysamxkcd.svg +1 -0
- package/dist/eraser-7mejjgrg.svg +1 -0
- package/dist/erb-f28j5x6b.svg +1 -0
- package/dist/erlang-3ebtbtfw.svg +1 -0
- package/dist/esbuild-wptxye5y.svg +1 -0
- package/dist/eslint-mrbexpc5.svg +1 -0
- package/dist/eslintignore-k65wpbsr.svg +1 -0
- package/dist/excalidraw-28avfa1h.svg +1 -0
- package/dist/exs-5w2cfpaf.svg +1 -0
- package/dist/exx-s897xhz3.svg +1 -0
- package/dist/farm-m80hxnfy.svg +1 -0
- package/dist/favicon-djc6sne4.svg +1 -0
- package/dist/figma-krwq889b.svg +1 -0
- package/dist/file-hetj1tjc.svg +1 -0
- package/dist/file_light-jx35pv2m.svg +1 -0
- package/dist/flakelock-2nsqn4gw.svg +1 -0
- package/dist/flutter-277q83en.svg +1 -0
- package/dist/flutterlock-h0nywsvt.svg +1 -0
- package/dist/flutterpackage-cpgnfwtt.svg +1 -0
- package/dist/folder-2xmsfyxp.svg +1 -0
- package/dist/folder_open-wk4ndx1f.svg +1 -0
- package/dist/fonteot-a8xmqj3j.svg +1 -0
- package/dist/fontotf-f01hg174.svg +1 -0
- package/dist/fontttf-pcr3rt21.svg +1 -0
- package/dist/fontwoff-v1gdka62.svg +1 -0
- package/dist/fontwoff2-1w1r47x8.svg +1 -0
- package/dist/freemarker-s9m714ah.svg +1 -0
- package/dist/fsharp-89mjndn4.svg +1 -0
- package/dist/gbl-v20qxsgx.svg +1 -0
- package/dist/git-wc9x7c5e.svg +1 -0
- package/dist/gitlab-bhcvbetz.svg +1 -0
- package/dist/gleam-h2ze8vtz.svg +1 -0
- package/dist/gleamconfig-6sq0xy19.svg +1 -0
- package/dist/go-15qaph9s.svg +1 -0
- package/dist/go-j2dk6r7k.svg +1 -0
- package/dist/go_package-5nc95prx.svg +1 -0
- package/dist/godot-v7nnsyvc.svg +1 -0
- package/dist/gradle-khh2bn3v.svg +1 -0
- package/dist/gradlebat-631878b0.svg +1 -0
- package/dist/gradlekotlin-f8netdbt.svg +1 -0
- package/dist/grain-tztem5b9.svg +1 -0
- package/dist/graphql-egmdpvzr.svg +1 -0
- package/dist/groovy-c0sstajm.svg +1 -0
- package/dist/grunt-56ssa3fr.svg +1 -0
- package/dist/gulp-j7wc27hd.svg +1 -0
- package/dist/h-4xbbejcs.svg +1 -0
- package/dist/haml-6pyt136a.svg +1 -0
- package/dist/handlebars-1v8g0n32.svg +1 -0
- package/dist/hardhat-1k6gym6f.svg +1 -0
- package/dist/hash-xd1ymkyp.svg +1 -0
- package/dist/hashicorp-vty9d6de.svg +1 -0
- package/dist/haskell-ncbxh3wk.svg +1 -0
- package/dist/haxe-j5nqdw5z.svg +1 -0
- package/dist/haxeml-bn7wtpx1.svg +1 -0
- package/dist/hpp-rpxcfk6j.svg +1 -0
- package/dist/htaccess-s4rrm1re.svg +1 -0
- package/dist/html-3vbw2fxn.svg +1 -0
- package/dist/html-v1z6sanr.svg +1 -0
- package/dist/http-9bfh1zqw.svg +1 -0
- package/dist/identifier-6gsrr6st.svg +1 -0
- package/dist/image-pstdg0vj.svg +1 -0
- package/dist/imagegif-any2rrn3.svg +1 -0
- package/dist/imageico-cng69rft.svg +1 -0
- package/dist/imagejpg-rtx9yy9y.svg +1 -0
- package/dist/imagepng-j6f306v1.svg +1 -0
- package/dist/imagewebp-q1mcm8np.svg +1 -0
- package/dist/imba-xxn1q1r2.svg +1 -0
- package/dist/index.html +16 -0
- package/dist/info-qssn7jw5.svg +1 -0
- package/dist/instructions-3068x11a.svg +1 -0
- package/dist/ipynb-qm8fb1p1.svg +1 -0
- package/dist/jar-src0eb7a.svg +1 -0
- package/dist/java-126v951r.svg +1 -0
- package/dist/java-hhh3k9xf.svg +1 -0
- package/dist/jenkins-ap6tzby2.svg +1 -0
- package/dist/jest-xrtp7hh0.svg +1 -0
- package/dist/jinja-v9kggcps.svg +1 -0
- package/dist/js-qsntbmzx.svg +1 -0
- package/dist/js-r0b86hmj.svg +1 -0
- package/dist/jsmap-1ns6yn3z.svg +1 -0
- package/dist/json-1jhmg3gf.svg +1 -0
- package/dist/jsp-7n103tna.svg +1 -0
- package/dist/julia-nba7etbq.svg +1 -0
- package/dist/karma-zcbeze4p.svg +1 -0
- package/dist/keep-tw8xf3gf.svg +1 -0
- package/dist/key-hd2nnhmr.svg +1 -0
- package/dist/knex-87w40q0j.svg +1 -0
- package/dist/knip-kzsz2w4s.svg +1 -0
- package/dist/kotlin-360tzrt1.svg +1 -0
- package/dist/kotlin-hbykz1k8.svg +1 -0
- package/dist/kotlins-4zz4rshm.svg +1 -0
- package/dist/krita-wx5qyrx7.svg +1 -0
- package/dist/latex-jwrpzd2b.svg +1 -0
- package/dist/launch-8wsjpmd3.svg +1 -0
- package/dist/lazarusproject-gma2fvya.svg +1 -0
- package/dist/less-p4zwh19p.svg +1 -0
- package/dist/license-qamq8mp3.svg +1 -0
- package/dist/light_editorconfig-k28g3f4k.svg +1 -0
- package/dist/liquid-wtexakya.svg +1 -0
- package/dist/llvm-cfgd7591.svg +1 -0
- package/dist/lock-wv5q3nef.svg +1 -0
- package/dist/log-ykdkwnpq.svg +1 -0
- package/dist/lua-aynthw24.svg +1 -0
- package/dist/m-va54fte8.svg +1 -0
- package/dist/m3-bun.manifest.json +3785 -0
- package/dist/makefile-kkcgz3sb.svg +1 -0
- package/dist/manifest-ede4t0vc.svg +1 -0
- package/dist/markdown-x7kezf76.svg +1 -0
- package/dist/markdownx-y5mf21hn.svg +1 -0
- package/dist/maven-djc7vb1b.svg +1 -0
- package/dist/mermaid-4bpjjghk.svg +1 -0
- package/dist/mesh-q798mf4t.svg +1 -0
- package/dist/mgcb-cfmfr63b.svg +1 -0
- package/dist/mint-b732cej4.svg +1 -0
- package/dist/mix-41smb4q2.svg +1 -0
- package/dist/mixlock-z0cvwpkq.svg +1 -0
- package/dist/mjml-4kzxtz0b.svg +1 -0
- package/dist/mkdocs-5t1davz8.svg +1 -0
- package/dist/mockoon-5pw3ckhf.svg +1 -0
- package/dist/motoko-yv95035d.svg +1 -0
- package/dist/mov-r3cjb3vr.svg +1 -0
- package/dist/mp4-31hded8m.svg +1 -0
- package/dist/mtl-01f1f06m.svg +1 -0
- package/dist/mustache-1s62ewsg.svg +1 -0
- package/dist/nelua-97199e3p.svg +1 -0
- package/dist/neon-gcp7rsp5.svg +1 -0
- package/dist/nestjs-sme3dmgk.svg +1 -0
- package/dist/nestjscontroller-2ceskrfc.svg +1 -0
- package/dist/nestjsdecorator-52k9dwm2.svg +1 -0
- package/dist/nestjsdto-xf36my7y.svg +1 -0
- package/dist/nestjsentity-q17fyvm1.svg +1 -0
- package/dist/nestjsfilter-qytmtqzj.svg +1 -0
- package/dist/nestjsguard-4pyb34xe.svg +1 -0
- package/dist/nestjsinterceptor-7s690j87.svg +1 -0
- package/dist/nestjsmodule-zeyz5633.svg +1 -0
- package/dist/nestjsrepository-kz26s1jf.svg +1 -0
- package/dist/nestjsresolver-8qdvexrk.svg +1 -0
- package/dist/nestjsservice-kp3b933m.svg +1 -0
- package/dist/nestscheduler-60p4j2tg.svg +1 -0
- package/dist/netlify-bbgdw42s.svg +1 -0
- package/dist/nextconfig-gr1sd69d.svg +1 -0
- package/dist/nextron-sf3ag316.svg +1 -0
- package/dist/nginx-73stz0yt.svg +1 -0
- package/dist/nim-gqnvnkc5.svg +1 -0
- package/dist/nix-t1m4qhc8.svg +1 -0
- package/dist/njk-dfv3nrxr.svg +1 -0
- package/dist/node-w3gp0xxn.svg +1 -0
- package/dist/nodemon-q41mkhvz.svg +1 -0
- package/dist/npm-rt8ga6qx.svg +1 -0
- package/dist/npmlock-8p4sp377.svg +1 -0
- package/dist/nuxt-13qdp31g.svg +1 -0
- package/dist/nvidia-fysz92ep.svg +1 -0
- package/dist/nvim-h3ynkfqg.svg +1 -0
- package/dist/nvm-ser6majj.svg +1 -0
- package/dist/nx-av0cw2sw.svg +1 -0
- package/dist/obj-thakg863.svg +1 -0
- package/dist/ocaml-maevkwa7.svg +1 -0
- package/dist/ocamli-w0gc5jq8.svg +1 -0
- package/dist/ocamll-h2wysvh1.svg +1 -0
- package/dist/ocamly-ppj6pfy3.svg +1 -0
- package/dist/odin-x7qb7b6x.svg +1 -0
- package/dist/opengl-h6pbxg3n.svg +1 -0
- package/dist/oxlint-7qwxtp86.svg +1 -0
- package/dist/panda-9qqa1nn4.svg +1 -0
- package/dist/parcel-gzckrwpy.svg +1 -0
- package/dist/pascal-kj6crs4h.svg +1 -0
- package/dist/pdf-wk39v1nv.svg +1 -0
- package/dist/perl-11dgrnh8.svg +1 -0
- package/dist/perlm-7xrwgd93.svg +1 -0
- package/dist/pfx-ggdb4v6p.svg +1 -0
- package/dist/photoshop-m3gw1xv7.svg +1 -0
- package/dist/php-jgyt96zk.svg +1 -0
- package/dist/php-jx84j7ns.svg +1 -0
- package/dist/plantuml-04ncqrmc.svg +1 -0
- package/dist/playright-dfc8tvme.svg +1 -0
- package/dist/plop-n71aee6w.svg +1 -0
- package/dist/pnpm-jvkts1qb.svg +1 -0
- package/dist/pnpmlock-2kqbdtn7.svg +1 -0
- package/dist/poetry-yjeeyvtr.svg +1 -0
- package/dist/poetrylock-da30xbws.svg +1 -0
- package/dist/postcssconfig-yyvnwr01.svg +1 -0
- package/dist/powershell-hf358xbb.svg +1 -0
- package/dist/powershelldata-nggemhrs.svg +1 -0
- package/dist/powershellmodule-v5wz6sed.svg +1 -0
- package/dist/precommit-wmfmt8tq.svg +1 -0
- package/dist/prettier-nyc1v0qk.svg +1 -0
- package/dist/prettierignore-hx4x759w.svg +1 -0
- package/dist/prisma-te242v0q.svg +1 -0
- package/dist/prolog-twb6h758.svg +1 -0
- package/dist/prompt-eg8c0gqa.svg +1 -0
- package/dist/properties-c39zkae1.svg +1 -0
- package/dist/proto-rsvsx4xb.svg +1 -0
- package/dist/pug-rqxd67km.svg +1 -0
- package/dist/pvk-bc4g1qms.svg +1 -0
- package/dist/py-0g79s39m.svg +1 -0
- package/dist/pyproject-5s59g4en.svg +1 -0
- package/dist/python-ds482k8k.svg +1 -0
- package/dist/qt-y3kxpf67.svg +1 -0
- package/dist/quarkus-xrq4b999.svg +1 -0
- package/dist/quasar-hvna6b7f.svg +1 -0
- package/dist/r-n1bnfab8.svg +1 -0
- package/dist/racket-vx5e6n1d.svg +1 -0
- package/dist/raku-4ydzc5wj.svg +1 -0
- package/dist/razor-cbqpr6vt.svg +1 -0
- package/dist/rb-mfkwkq7e.svg +1 -0
- package/dist/reactjs-qjyhk3rf.svg +1 -0
- package/dist/reactts-p0hf29yr.svg +1 -0
- package/dist/readme-3qcyy95y.svg +1 -0
- package/dist/redis-ya1xyn4v.svg +1 -0
- package/dist/rego-tr1y9cqm.svg +1 -0
- package/dist/remix-61pbjda4.svg +1 -0
- package/dist/rescript-9c3xnepn.svg +1 -0
- package/dist/rescriptinterface-6ne0a2rf.svg +1 -0
- package/dist/restructuredtext-7k21mjx4.svg +1 -0
- package/dist/rjson-3s2edhhr.svg +1 -0
- package/dist/robots-geh7c3pq.svg +1 -0
- package/dist/rollup-0dxydzr9.svg +1 -0
- package/dist/rome-1gxetp8g.svg +1 -0
- package/dist/ron-ft34rzr3.svg +1 -0
- package/dist/root_folder-rhwm7290.svg +1 -0
- package/dist/root_folder_light-ngkg5m4x.svg +1 -0
- package/dist/root_folder_light_open-c6nhg6sy.svg +1 -0
- package/dist/root_folder_open-genv0ps7.svg +1 -0
- package/dist/rs-60bcevwn.svg +1 -0
- package/dist/ruby-7j5zzh38.svg +1 -0
- package/dist/rust-a9528zdg.svg +1 -0
- package/dist/rustfmt-c8evpzd7.svg +1 -0
- package/dist/sails-5ecccxrg.svg +1 -0
- package/dist/salesforce-4d89045j.svg +1 -0
- package/dist/sass-g9qbr3x4.svg +1 -0
- package/dist/scala-8gnn0ekc.svg +1 -0
- package/dist/scss-g9qbr3x4.svg +1 -0
- package/dist/sentinel-g8py3peh.svg +1 -0
- package/dist/sequelize-qvzwnjhv.svg +1 -0
- package/dist/sh-bkp0n5vb.svg +1 -0
- package/dist/shaderlab-gkww43v2.svg +1 -0
- package/dist/shell-kc0a9zjq.svg +1 -0
- package/dist/silq-mczpsqmz.svg +1 -0
- package/dist/slim-8j9jf3zt.svg +1 -0
- package/dist/sln-nketqakm.svg +1 -0
- package/dist/smarty-w1zxys1s.svg +1 -0
- package/dist/sol-adyfjwzz.svg +1 -0
- package/dist/spc-kk30w5m6.svg +1 -0
- package/dist/sql-3c4gcy7a.svg +1 -0
- package/dist/sqlite-cppkxr0a.svg +1 -0
- package/dist/storybook-885ssp75.svg +1 -0
- package/dist/stylelint-z7s6yhc9.svg +1 -0
- package/dist/stylelintignore-xwnh8sx1.svg +1 -0
- package/dist/stylus-qz53ytkd.svg +1 -0
- package/dist/suo-3fvnz3bx.svg +1 -0
- package/dist/svelte-jp3x9gw7.svg +1 -0
- package/dist/svelteconfig-m0n00zjj.svg +1 -0
- package/dist/svg-8dyqf96t.svg +1 -0
- package/dist/swift-8g870v6j.svg +1 -0
- package/dist/symfony-q77kcepw.svg +1 -0
- package/dist/tailwind-3es9cgbd.svg +1 -0
- package/dist/tauri-xnj526kw.svg +1 -0
- package/dist/taze-e3ykqs0k.svg +1 -0
- package/dist/terrafile-gqn1tysh.svg +1 -0
- package/dist/terraform-jy4fbwsr.svg +1 -0
- package/dist/terraformvars-05qje1sw.svg +1 -0
- package/dist/terraformversion-gq2tkwmn.svg +1 -0
- package/dist/testjs-sqgjsb8h.svg +1 -0
- package/dist/testts-19m1sf26.svg +1 -0
- package/dist/tmpl-enggw2gc.svg +1 -0
- package/dist/todo-ccw0mpg2.svg +1 -0
- package/dist/toml-rmx5hba4.svg +1 -0
- package/dist/toolversions-s7fttfyp.svg +1 -0
- package/dist/tox-a4j4yvmb.svg +1 -0
- package/dist/travis-gr3jtpx2.svg +1 -0
- package/dist/tres-qt3kk1t0.svg +1 -0
- package/dist/ts-7amn21ms.svg +1 -0
- package/dist/tscn-g1jthb4m.svg +1 -0
- package/dist/tsconfig-r1s750bq.svg +1 -0
- package/dist/tsx-a3rsjrrz.svg +1 -0
- package/dist/turbo-dcmj75tc.svg +1 -0
- package/dist/twig-3xgrb919.svg +1 -0
- package/dist/txt-y0t8b72p.svg +1 -0
- package/dist/typescript-kd5g4jkg.svg +1 -0
- package/dist/typescriptdef-y43343m6.svg +1 -0
- package/dist/ui-pxvg5zj2.svg +1 -0
- package/dist/unocss-b0f5fthj.svg +1 -0
- package/dist/user-q7tk1k2d.svg +1 -0
- package/dist/v-c25jfygk.svg +1 -0
- package/dist/vanillaextract-3w6vds6m.svg +1 -0
- package/dist/vb-87ckj7t3.svg +1 -0
- package/dist/vercel-hfxjvaj9.svg +1 -0
- package/dist/version-zd7hfmf1.svg +1 -0
- package/dist/vhd-xaw7zbny.svg +1 -0
- package/dist/vhdl-s308rb5a.svg +1 -0
- package/dist/video-z6khth5y.svg +1 -0
- package/dist/vite-5g5xkmpk.svg +1 -0
- package/dist/viteenv-jbmx0tb0.svg +1 -0
- package/dist/vitest-5267dzt2.svg +1 -0
- package/dist/vmod-8jftapdc.svg +1 -0
- package/dist/vscode-8tvcs7ae.svg +1 -0
- package/dist/vue-j5sjdz4b.svg +1 -0
- package/dist/vue-x9h2d0d2.svg +1 -0
- package/dist/vueconfig-726zh8dd.svg +1 -0
- package/dist/wasm-vgmg9kv4.svg +1 -0
- package/dist/webpack-hfwce90m.svg +1 -0
- package/dist/wgsl-68923cz5.svg +1 -0
- package/dist/windi-c9m8en7k.svg +1 -0
- package/dist/wren-7ep5ph5r.svg +1 -0
- package/dist/xmake-mc60ax7m.svg +1 -0
- package/dist/xml-feq1fbt4.svg +1 -0
- package/dist/yaml-n43aw0fx.svg +1 -0
- package/dist/yang-mtcxs2mg.svg +1 -0
- package/dist/yarn-k4k6e35h.svg +1 -0
- package/dist/yarnerror-5jkesx9j.svg +1 -0
- package/dist/yarnignore-ryh8jd5p.svg +1 -0
- package/dist/yarnlock-9zvhbg04.svg +1 -0
- package/dist/yin-f931bzgj.svg +1 -0
- package/dist/zig-nx2e65ns.svg +1 -0
- package/dist/zip-7hqmj0b0.svg +1 -0
- package/m3.config.ts +32 -0
- package/package.json +60 -0
- package/scripts/browser-contract.ts +400 -0
- package/scripts/icons.ts +56 -0
- package/scripts/inventory.ts +86 -0
- package/scripts/shots.ts +154 -0
- package/scripts/tauri.ts +401 -0
- package/src/App.tsx +40 -0
- package/src/adaptive/dpad.ts +223 -0
- package/src/adaptive/window.ts +133 -0
- package/src/api/index.ts +332 -0
- package/src/components/ui.tsx +89 -0
- package/src/env.d.ts +5 -0
- package/src/favicon.svg +1 -0
- package/src/generated/inventory.json +426 -0
- package/src/index.html +16 -0
- package/src/inventory.ts +19 -0
- package/src/main.tsx +6 -0
- package/src/pages/Adaptive.tsx +128 -0
- package/src/pages/Ai.tsx +174 -0
- package/src/pages/Brands.tsx +156 -0
- package/src/pages/Components.tsx +91 -0
- package/src/pages/Design.tsx +163 -0
- package/src/pages/Explorer.tsx +125 -0
- package/src/pages/Forms.tsx +128 -0
- package/src/pages/Icons.tsx +138 -0
- package/src/pages/Motion.tsx +157 -0
- package/src/pages/Next.tsx +107 -0
- package/src/pages/Overview.tsx +105 -0
- package/src/pages/Primitives.tsx +138 -0
- package/src/pages/Reader.tsx +101 -0
- package/src/pages/System.tsx +283 -0
- package/src/pages/Theme.tsx +146 -0
- package/src/pages/index.ts +25 -0
- package/src/router.ts +22 -0
- package/src/shell/Shell.tsx +383 -0
- package/src/shell/nav.ts +198 -0
- package/src/styles.css +61 -0
- package/test/contracts.test.ts +87 -0
- package/test/host-contract.test.ts +183 -0
- package/test/runtime-api.test.ts +138 -0
- package/test-dom/dpad.test.ts +78 -0
- package/tsconfig.json +11 -0
|
@@ -0,0 +1,383 @@
|
|
|
1
|
+
// The adaptive shell. One component tree, three layouts chosen from the window size class and the layout mode:
|
|
2
|
+
// mobile (compact) top app bar, content, bottom navigation bar, "More" sheet for the other destinations
|
|
3
|
+
// desktop (medium and up) navigation rail (medium, expanded) or standard drawer (large, extra large) beside the content
|
|
4
|
+
// tv 10-foot drawer, large type, focus ring, D-pad (arrow keys + Enter + Back) navigation
|
|
5
|
+
import { useM3Theme } from "@aphrody/m3-theme/react";
|
|
6
|
+
import { Component, Suspense, useEffect, useRef, useState, type ReactNode } from "react";
|
|
7
|
+
import closeIcon from "m3:icons/close";
|
|
8
|
+
import contrastIcon from "m3:icons/contrast";
|
|
9
|
+
import darkIcon from "m3:icons/dark_mode";
|
|
10
|
+
import lightIcon from "m3:icons/light_mode";
|
|
11
|
+
import { attachDpad } from "../adaptive/dpad.ts";
|
|
12
|
+
import { useAdaptive, type AdaptiveState } from "../adaptive/window.ts";
|
|
13
|
+
import { Svg } from "../components/ui.tsx";
|
|
14
|
+
import { PAGES } from "../pages/index.ts";
|
|
15
|
+
import { useRoute } from "../router.ts";
|
|
16
|
+
import {
|
|
17
|
+
DESTINATIONS,
|
|
18
|
+
MORE_ICON,
|
|
19
|
+
MORE_ICON_FILLED,
|
|
20
|
+
PRIMARY_IDS,
|
|
21
|
+
findDestination,
|
|
22
|
+
type Destination,
|
|
23
|
+
} from "./nav.ts";
|
|
24
|
+
|
|
25
|
+
const MODE_LABEL = { light: "Light", dark: "Dark", system: "System" } as const;
|
|
26
|
+
|
|
27
|
+
function ThemeModeButton() {
|
|
28
|
+
const { themeMode, setThemeMode } = useM3Theme();
|
|
29
|
+
const next = themeMode === "system" ? "light" : themeMode === "light" ? "dark" : "system";
|
|
30
|
+
const icon = themeMode === "light" ? lightIcon : themeMode === "dark" ? darkIcon : contrastIcon;
|
|
31
|
+
return (
|
|
32
|
+
<button
|
|
33
|
+
type="button"
|
|
34
|
+
className="state-layer inline-flex size-12 items-center justify-center rounded-full text-on-surface-variant"
|
|
35
|
+
aria-label={`Colour scheme: ${MODE_LABEL[themeMode]}. Switch to ${MODE_LABEL[next]}`}
|
|
36
|
+
title={`Colour scheme: ${MODE_LABEL[themeMode]}`}
|
|
37
|
+
onClick={() => setThemeMode(next)}
|
|
38
|
+
>
|
|
39
|
+
<Svg html={icon} />
|
|
40
|
+
</button>
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function TopBar({ a, current }: { a: AdaptiveState; current: Destination }) {
|
|
45
|
+
return (
|
|
46
|
+
<header
|
|
47
|
+
className="flex h-16 shrink-0 items-center gap-2 bg-surface px-(--m3-gutter) text-on-surface"
|
|
48
|
+
role="banner"
|
|
49
|
+
>
|
|
50
|
+
<div
|
|
51
|
+
className={`${a.mode === "tv" ? "text-headline-medium" : "text-title-large"} flex-1 truncate`}
|
|
52
|
+
data-testid="top-title"
|
|
53
|
+
>
|
|
54
|
+
{a.mode === "mobile" ? current.label : `Aphrody M3 / ${current.label}`}
|
|
55
|
+
</div>
|
|
56
|
+
<span
|
|
57
|
+
className="hidden rounded-full bg-secondary-container px-3 py-1 text-label-medium text-on-secondary-container expanded:inline"
|
|
58
|
+
data-testid="window-class"
|
|
59
|
+
title="Window size class, M3 breakpoints"
|
|
60
|
+
>
|
|
61
|
+
{a.width} · {a.mode}
|
|
62
|
+
</span>
|
|
63
|
+
<ThemeModeButton />
|
|
64
|
+
</header>
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function NavItem({
|
|
69
|
+
item,
|
|
70
|
+
selected,
|
|
71
|
+
variant,
|
|
72
|
+
onSelect,
|
|
73
|
+
}: {
|
|
74
|
+
item: Destination;
|
|
75
|
+
selected: boolean;
|
|
76
|
+
variant: "bar" | "rail" | "drawer";
|
|
77
|
+
onSelect: (id: string) => void;
|
|
78
|
+
}) {
|
|
79
|
+
const icon = <Svg html={selected ? item.iconFilled : item.icon} />;
|
|
80
|
+
if (variant === "drawer") {
|
|
81
|
+
return (
|
|
82
|
+
<a
|
|
83
|
+
href={`#/${item.id}`}
|
|
84
|
+
data-dpad
|
|
85
|
+
data-testid={`nav-${item.id}`}
|
|
86
|
+
aria-current={selected ? "page" : undefined}
|
|
87
|
+
className={`state-layer flex h-14 w-full items-center gap-3 rounded-full px-4 text-label-large ${selected ? "bg-secondary-container text-on-secondary-container" : "text-on-surface-variant"}`}
|
|
88
|
+
onClick={(event) => {
|
|
89
|
+
if (
|
|
90
|
+
event.button === 0 &&
|
|
91
|
+
!event.metaKey &&
|
|
92
|
+
!event.ctrlKey &&
|
|
93
|
+
!event.shiftKey &&
|
|
94
|
+
!event.altKey
|
|
95
|
+
) {
|
|
96
|
+
event.preventDefault();
|
|
97
|
+
onSelect(item.id);
|
|
98
|
+
}
|
|
99
|
+
}}
|
|
100
|
+
>
|
|
101
|
+
{icon}
|
|
102
|
+
<span className="truncate">{item.label}</span>
|
|
103
|
+
</a>
|
|
104
|
+
);
|
|
105
|
+
}
|
|
106
|
+
return (
|
|
107
|
+
<a
|
|
108
|
+
href={`#/${item.id}`}
|
|
109
|
+
data-dpad
|
|
110
|
+
data-testid={`nav-${item.id}`}
|
|
111
|
+
aria-current={selected ? "page" : undefined}
|
|
112
|
+
className={`state-layer group flex ${variant === "bar" ? "flex-1 py-3" : "w-full py-1.5"} flex-col items-center gap-1 text-label-medium ${selected ? "text-on-surface" : "text-on-surface-variant"}`}
|
|
113
|
+
onClick={() => onSelect(item.id)}
|
|
114
|
+
>
|
|
115
|
+
<span
|
|
116
|
+
className={`flex h-8 w-16 items-center justify-center rounded-full ${selected ? "bg-secondary-container text-on-secondary-container" : ""}`}
|
|
117
|
+
>
|
|
118
|
+
{icon}
|
|
119
|
+
</span>
|
|
120
|
+
<span className="max-w-full truncate px-1">{item.label}</span>
|
|
121
|
+
</a>
|
|
122
|
+
);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
function SideNav({
|
|
126
|
+
a,
|
|
127
|
+
route,
|
|
128
|
+
navigate,
|
|
129
|
+
}: {
|
|
130
|
+
a: AdaptiveState;
|
|
131
|
+
route: string;
|
|
132
|
+
navigate: (id: string) => void;
|
|
133
|
+
}) {
|
|
134
|
+
const drawer = a.mode === "tv" || a.navigation === "rail-expanded";
|
|
135
|
+
return (
|
|
136
|
+
<nav
|
|
137
|
+
aria-label="Destinations"
|
|
138
|
+
className={`m3-scroll flex shrink-0 flex-col gap-1 overflow-y-auto bg-surface p-3 ${drawer ? (a.mode === "tv" ? "w-[19rem]" : "w-[22.5rem]") : "w-24"}`}
|
|
139
|
+
data-testid={drawer ? "drawer" : "rail"}
|
|
140
|
+
>
|
|
141
|
+
{DESTINATIONS.map((item) => (
|
|
142
|
+
<NavItem
|
|
143
|
+
key={item.id}
|
|
144
|
+
item={item}
|
|
145
|
+
selected={route === item.id}
|
|
146
|
+
variant={drawer ? "drawer" : "rail"}
|
|
147
|
+
onSelect={navigate}
|
|
148
|
+
/>
|
|
149
|
+
))}
|
|
150
|
+
</nav>
|
|
151
|
+
);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
function BottomBar({
|
|
155
|
+
route,
|
|
156
|
+
navigate,
|
|
157
|
+
onMore,
|
|
158
|
+
}: {
|
|
159
|
+
route: string;
|
|
160
|
+
navigate: (id: string) => void;
|
|
161
|
+
onMore: () => void;
|
|
162
|
+
}) {
|
|
163
|
+
const primary = PRIMARY_IDS.map(findDestination);
|
|
164
|
+
const moreSelected = !PRIMARY_IDS.includes(route as (typeof PRIMARY_IDS)[number]);
|
|
165
|
+
return (
|
|
166
|
+
<nav
|
|
167
|
+
aria-label="Destinations"
|
|
168
|
+
className="flex h-20 shrink-0 items-stretch bg-surface-container px-2 pb-[env(safe-area-inset-bottom)]"
|
|
169
|
+
data-testid="bottom-bar"
|
|
170
|
+
>
|
|
171
|
+
{primary.map((item) => (
|
|
172
|
+
<NavItem
|
|
173
|
+
key={item.id}
|
|
174
|
+
item={item}
|
|
175
|
+
selected={route === item.id}
|
|
176
|
+
variant="bar"
|
|
177
|
+
onSelect={navigate}
|
|
178
|
+
/>
|
|
179
|
+
))}
|
|
180
|
+
<button
|
|
181
|
+
type="button"
|
|
182
|
+
data-testid="nav-more"
|
|
183
|
+
aria-haspopup="dialog"
|
|
184
|
+
className={`state-layer flex flex-1 flex-col items-center gap-1 py-3 text-label-medium ${moreSelected ? "text-on-surface" : "text-on-surface-variant"}`}
|
|
185
|
+
onClick={onMore}
|
|
186
|
+
>
|
|
187
|
+
<span
|
|
188
|
+
className={`flex h-8 w-16 items-center justify-center rounded-full ${moreSelected ? "bg-secondary-container text-on-secondary-container" : ""}`}
|
|
189
|
+
>
|
|
190
|
+
<Svg html={moreSelected ? MORE_ICON_FILLED : MORE_ICON} />
|
|
191
|
+
</span>
|
|
192
|
+
<span>More</span>
|
|
193
|
+
</button>
|
|
194
|
+
</nav>
|
|
195
|
+
);
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
/** The destinations behind "More", as a modal bottom sheet on a native <dialog> (focus trap and Escape for free). */
|
|
199
|
+
function MoreSheet({
|
|
200
|
+
open,
|
|
201
|
+
route,
|
|
202
|
+
navigate,
|
|
203
|
+
onClose,
|
|
204
|
+
}: {
|
|
205
|
+
open: boolean;
|
|
206
|
+
route: string;
|
|
207
|
+
navigate: (id: string) => void;
|
|
208
|
+
onClose: () => void;
|
|
209
|
+
}) {
|
|
210
|
+
const ref = useRef<HTMLDialogElement>(null);
|
|
211
|
+
useEffect(() => {
|
|
212
|
+
const dialog = ref.current;
|
|
213
|
+
if (!dialog) return;
|
|
214
|
+
if (open && !dialog.open) dialog.showModal();
|
|
215
|
+
if (!open && dialog.open) dialog.close();
|
|
216
|
+
}, [open]);
|
|
217
|
+
return (
|
|
218
|
+
<dialog
|
|
219
|
+
ref={ref}
|
|
220
|
+
onClose={onClose}
|
|
221
|
+
onClick={(event) => event.target === ref.current && onClose()}
|
|
222
|
+
className="m-0 mt-auto w-full max-w-none rounded-t-extra-large bg-surface-container-low p-4 text-on-surface backdrop:bg-scrim/32"
|
|
223
|
+
data-testid="more-sheet"
|
|
224
|
+
aria-label="All destinations"
|
|
225
|
+
>
|
|
226
|
+
<div className="mb-2 flex items-center justify-between">
|
|
227
|
+
<h2 className="text-title-large">All destinations</h2>
|
|
228
|
+
<button
|
|
229
|
+
type="button"
|
|
230
|
+
className="state-layer inline-flex size-12 items-center justify-center rounded-full"
|
|
231
|
+
aria-label="Close"
|
|
232
|
+
onClick={onClose}
|
|
233
|
+
>
|
|
234
|
+
<Svg html={closeIcon} />
|
|
235
|
+
</button>
|
|
236
|
+
</div>
|
|
237
|
+
<div className="grid grid-cols-3 gap-2">
|
|
238
|
+
{DESTINATIONS.map((item) => (
|
|
239
|
+
<a
|
|
240
|
+
key={item.id}
|
|
241
|
+
href={`#/${item.id}`}
|
|
242
|
+
data-testid={`more-${item.id}`}
|
|
243
|
+
aria-current={route === item.id ? "page" : undefined}
|
|
244
|
+
className={`state-layer flex flex-col items-center gap-1 rounded-large p-3 text-label-medium ${route === item.id ? "bg-secondary-container text-on-secondary-container" : "text-on-surface-variant"}`}
|
|
245
|
+
onClick={(event) => {
|
|
246
|
+
if (
|
|
247
|
+
event.button === 0 &&
|
|
248
|
+
!event.metaKey &&
|
|
249
|
+
!event.ctrlKey &&
|
|
250
|
+
!event.shiftKey &&
|
|
251
|
+
!event.altKey
|
|
252
|
+
) {
|
|
253
|
+
event.preventDefault();
|
|
254
|
+
navigate(item.id);
|
|
255
|
+
onClose();
|
|
256
|
+
}
|
|
257
|
+
}}
|
|
258
|
+
>
|
|
259
|
+
<Svg html={route === item.id ? item.iconFilled : item.icon} />
|
|
260
|
+
<span className="truncate">{item.label}</span>
|
|
261
|
+
</a>
|
|
262
|
+
))}
|
|
263
|
+
</div>
|
|
264
|
+
</dialog>
|
|
265
|
+
);
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
function PageSlot({
|
|
269
|
+
a,
|
|
270
|
+
route,
|
|
271
|
+
children,
|
|
272
|
+
}: {
|
|
273
|
+
a: AdaptiveState;
|
|
274
|
+
route: string;
|
|
275
|
+
children: ReactNode;
|
|
276
|
+
}) {
|
|
277
|
+
const heading = useRef<HTMLDivElement>(null);
|
|
278
|
+
useEffect(() => {
|
|
279
|
+
// After a route change the page, not the nav, takes focus: screen readers announce the new title. TV keeps the nav focused.
|
|
280
|
+
if (a.mode !== "tv") heading.current?.focus({ preventScroll: true });
|
|
281
|
+
}, [route, a.mode]);
|
|
282
|
+
return (
|
|
283
|
+
<main
|
|
284
|
+
id="main"
|
|
285
|
+
ref={heading}
|
|
286
|
+
tabIndex={-1}
|
|
287
|
+
className="m3-scroll min-w-0 flex-1 overflow-y-auto rounded-tl-extra-large bg-surface-container-lowest outline-none"
|
|
288
|
+
data-testid="main"
|
|
289
|
+
data-route={route}
|
|
290
|
+
aria-labelledby="page-title"
|
|
291
|
+
>
|
|
292
|
+
{children}
|
|
293
|
+
</main>
|
|
294
|
+
);
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
class PageBoundary extends Component<{ children: ReactNode }, { failed: boolean }> {
|
|
298
|
+
override state = { failed: false };
|
|
299
|
+
static getDerivedStateFromError() {
|
|
300
|
+
return { failed: true };
|
|
301
|
+
}
|
|
302
|
+
override render() {
|
|
303
|
+
if (this.state.failed)
|
|
304
|
+
return (
|
|
305
|
+
<div className="p-6" role="alert">
|
|
306
|
+
<h1 id="page-title" className="text-headline-medium">
|
|
307
|
+
Unable to load this page
|
|
308
|
+
</h1>
|
|
309
|
+
<p>Reload to try again.</p>
|
|
310
|
+
<button
|
|
311
|
+
type="button"
|
|
312
|
+
className="state-layer rounded-full bg-primary px-6 py-3 text-on-primary"
|
|
313
|
+
onClick={() => location.reload()}
|
|
314
|
+
>
|
|
315
|
+
Reload
|
|
316
|
+
</button>
|
|
317
|
+
</div>
|
|
318
|
+
);
|
|
319
|
+
return this.props.children;
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
export function Shell() {
|
|
324
|
+
const a = useAdaptive();
|
|
325
|
+
const { route, navigate } = useRoute();
|
|
326
|
+
const [more, setMore] = useState(false);
|
|
327
|
+
const current = findDestination(route);
|
|
328
|
+
const Page = PAGES[current.id];
|
|
329
|
+
|
|
330
|
+
useEffect(
|
|
331
|
+
() =>
|
|
332
|
+
a.mode === "tv" || document.documentElement.dataset["dpad"] === "on"
|
|
333
|
+
? attachDpad({ onBack: () => history.back() })
|
|
334
|
+
: undefined,
|
|
335
|
+
[a.mode],
|
|
336
|
+
);
|
|
337
|
+
useEffect(() => {
|
|
338
|
+
document.title = `${current.label} · Aphrody M3 Showcase`;
|
|
339
|
+
}, [current.label]);
|
|
340
|
+
|
|
341
|
+
return (
|
|
342
|
+
<div className="flex h-full flex-col bg-surface" data-testid="shell" data-layout={a.mode}>
|
|
343
|
+
<a
|
|
344
|
+
href="#main"
|
|
345
|
+
onClick={(event) => {
|
|
346
|
+
event.preventDefault();
|
|
347
|
+
document.getElementById("main")?.focus();
|
|
348
|
+
}}
|
|
349
|
+
className="sr-only focus:not-sr-only focus:absolute focus:left-2 focus:top-2 focus:z-50 focus:rounded-full focus:bg-primary focus:px-4 focus:py-2 focus:text-on-primary"
|
|
350
|
+
>
|
|
351
|
+
Skip to content
|
|
352
|
+
</a>
|
|
353
|
+
<TopBar a={a} current={current} />
|
|
354
|
+
<div className="flex min-h-0 flex-1">
|
|
355
|
+
{a.mode !== "mobile" ? <SideNav a={a} route={current.id} navigate={navigate} /> : null}
|
|
356
|
+
<PageSlot a={a} route={current.id}>
|
|
357
|
+
<PageBoundary key={current.id}>
|
|
358
|
+
<Suspense
|
|
359
|
+
fallback={
|
|
360
|
+
<div className="p-6 text-body-medium text-on-surface-variant" role="status">
|
|
361
|
+
Loading {current.label}…
|
|
362
|
+
</div>
|
|
363
|
+
}
|
|
364
|
+
>
|
|
365
|
+
<Page adaptive={a} />
|
|
366
|
+
</Suspense>
|
|
367
|
+
</PageBoundary>
|
|
368
|
+
</PageSlot>
|
|
369
|
+
</div>
|
|
370
|
+
{a.mode === "mobile" ? (
|
|
371
|
+
<BottomBar route={current.id} navigate={navigate} onMore={() => setMore(true)} />
|
|
372
|
+
) : null}
|
|
373
|
+
{a.mode === "mobile" ? (
|
|
374
|
+
<MoreSheet
|
|
375
|
+
open={more}
|
|
376
|
+
route={current.id}
|
|
377
|
+
navigate={navigate}
|
|
378
|
+
onClose={() => setMore(false)}
|
|
379
|
+
/>
|
|
380
|
+
) : null}
|
|
381
|
+
</div>
|
|
382
|
+
);
|
|
383
|
+
}
|
package/src/shell/nav.ts
ADDED
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
// Destinations of the showcase: one per group of packages, each with the packages it demonstrates.
|
|
2
|
+
import appsIcon from "m3:icons/apps";
|
|
3
|
+
import appsFilled from "m3:icons/apps?fill=1";
|
|
4
|
+
import badgeIcon from "m3:icons/badge";
|
|
5
|
+
import badgeFilled from "m3:icons/badge?fill=1";
|
|
6
|
+
import designIcon from "m3:icons/design_services";
|
|
7
|
+
import designFilled from "m3:icons/design_services?fill=1";
|
|
8
|
+
import devicesIcon from "m3:icons/devices";
|
|
9
|
+
import devicesFilled from "m3:icons/devices?fill=1";
|
|
10
|
+
import editIcon from "m3:icons/edit_note";
|
|
11
|
+
import editFilled from "m3:icons/edit_note?fill=1";
|
|
12
|
+
import folderIcon from "m3:icons/folder";
|
|
13
|
+
import folderFilled from "m3:icons/folder?fill=1";
|
|
14
|
+
import homeIcon from "m3:icons/home";
|
|
15
|
+
import homeFilled from "m3:icons/home?fill=1";
|
|
16
|
+
import motionIcon from "m3:icons/animation";
|
|
17
|
+
import motionFilled from "m3:icons/animation?fill=1";
|
|
18
|
+
import paletteIcon from "m3:icons/palette";
|
|
19
|
+
import paletteFilled from "m3:icons/palette?fill=1";
|
|
20
|
+
import readerIcon from "m3:icons/menu_book";
|
|
21
|
+
import readerFilled from "m3:icons/menu_book?fill=1";
|
|
22
|
+
import smartIcon from "m3:icons/smart_toy";
|
|
23
|
+
import smartFilled from "m3:icons/smart_toy?fill=1";
|
|
24
|
+
import symbolsIcon from "m3:icons/interests";
|
|
25
|
+
import symbolsFilled from "m3:icons/interests?fill=1";
|
|
26
|
+
import terminalIcon from "m3:icons/terminal";
|
|
27
|
+
import terminalFilled from "m3:icons/terminal?fill=1";
|
|
28
|
+
import webIcon from "m3:icons/web";
|
|
29
|
+
import webFilled from "m3:icons/web?fill=1";
|
|
30
|
+
import widgetsIcon from "m3:icons/widgets";
|
|
31
|
+
import widgetsFilled from "m3:icons/widgets?fill=1";
|
|
32
|
+
import extensionIcon from "m3:icons/extension";
|
|
33
|
+
import extensionFilled from "m3:icons/extension?fill=1";
|
|
34
|
+
|
|
35
|
+
import type { PageId } from "../pages/index.ts";
|
|
36
|
+
|
|
37
|
+
export interface Destination {
|
|
38
|
+
id: PageId;
|
|
39
|
+
label: string;
|
|
40
|
+
/** Outlined and filled (selected) Material Symbols SVG markup. */
|
|
41
|
+
icon: string;
|
|
42
|
+
iconFilled: string;
|
|
43
|
+
/** What the page shows, one sentence. */
|
|
44
|
+
summary: string;
|
|
45
|
+
/** The workspace packages the page imports and exercises. */
|
|
46
|
+
packages: readonly string[];
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export const DESTINATIONS: readonly Destination[] = [
|
|
50
|
+
{
|
|
51
|
+
id: "overview",
|
|
52
|
+
label: "Overview",
|
|
53
|
+
icon: homeIcon,
|
|
54
|
+
iconFilled: homeFilled,
|
|
55
|
+
summary: "Every package of the monorepo, served by this app's own API.",
|
|
56
|
+
packages: ["@aphrody/m3", "@aphrody/m3-bun", "@aphrody/m3-config"],
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
id: "theme",
|
|
60
|
+
label: "Theme",
|
|
61
|
+
icon: paletteIcon,
|
|
62
|
+
iconFilled: paletteFilled,
|
|
63
|
+
summary: "Material You roles from a seed: tokens, Tailwind preset, fonts, a scoped <m3-theme>.",
|
|
64
|
+
packages: [
|
|
65
|
+
"@aphrody/m3-theme",
|
|
66
|
+
"@aphrody/m3-tokens",
|
|
67
|
+
"@aphrody/m3-front",
|
|
68
|
+
"@aphrody/m3-tailwind",
|
|
69
|
+
"@aphrody/m3-fonts",
|
|
70
|
+
],
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
id: "components",
|
|
74
|
+
label: "Components",
|
|
75
|
+
icon: widgetsIcon,
|
|
76
|
+
iconFilled: widgetsFilled,
|
|
77
|
+
summary: "The Material Web components through their React wrappers.",
|
|
78
|
+
packages: ["@aphrody/m3-react"],
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
id: "primitives",
|
|
82
|
+
label: "Primitives",
|
|
83
|
+
icon: extensionIcon,
|
|
84
|
+
iconFilled: extensionFilled,
|
|
85
|
+
summary: "Accessible parts on Base UI, styled with M3 tokens.",
|
|
86
|
+
packages: ["@aphrody/m3-primitives", "@aphrody/m3-baseui"],
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
id: "forms",
|
|
90
|
+
label: "Forms",
|
|
91
|
+
icon: editIcon,
|
|
92
|
+
iconFilled: editFilled,
|
|
93
|
+
summary: "react-hook-form fields with M3 inputs, validation and descriptions.",
|
|
94
|
+
packages: ["@aphrody/m3-forms"],
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
id: "explorer",
|
|
98
|
+
label: "Explorer",
|
|
99
|
+
icon: folderIcon,
|
|
100
|
+
iconFilled: folderFilled,
|
|
101
|
+
summary: "A file explorer: list and grid views, thumbnails, tags, rename.",
|
|
102
|
+
packages: ["@aphrody/m3-explorer"],
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
id: "motion",
|
|
106
|
+
label: "Motion",
|
|
107
|
+
icon: motionIcon,
|
|
108
|
+
iconFilled: motionFilled,
|
|
109
|
+
summary: "Springs, easings, shared axis, container transform, list stagger.",
|
|
110
|
+
packages: ["@aphrody/m3-motion", "@aphrody/m3-react"],
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
id: "icons",
|
|
114
|
+
label: "Icons & fonts",
|
|
115
|
+
icon: symbolsIcon,
|
|
116
|
+
iconFilled: symbolsFilled,
|
|
117
|
+
summary: "Material Symbols from the forked catalogue, inlined at build time.",
|
|
118
|
+
packages: ["@aphrody/m3-icons", "@aphrody/material-design-icons", "@aphrody/m3-fonts"],
|
|
119
|
+
},
|
|
120
|
+
{
|
|
121
|
+
id: "ai",
|
|
122
|
+
label: "AI",
|
|
123
|
+
icon: smartIcon,
|
|
124
|
+
iconFilled: smartFilled,
|
|
125
|
+
summary: "A chat transcript, tool calls, markdown and an AG-UI stream from the API.",
|
|
126
|
+
packages: ["@aphrody/m3-ai", "@aphrody/ag-ui"],
|
|
127
|
+
},
|
|
128
|
+
{
|
|
129
|
+
id: "reader",
|
|
130
|
+
label: "Reader",
|
|
131
|
+
icon: readerIcon,
|
|
132
|
+
iconFilled: readerFilled,
|
|
133
|
+
summary: "Manga and databook readers with paging, vertical scroll and RTL.",
|
|
134
|
+
packages: ["@aphrody/m3-reader"],
|
|
135
|
+
},
|
|
136
|
+
{
|
|
137
|
+
id: "design",
|
|
138
|
+
label: "Design",
|
|
139
|
+
icon: designIcon,
|
|
140
|
+
iconFilled: designFilled,
|
|
141
|
+
summary: "A design brief parsed and turned into an M3 theme by the design engine.",
|
|
142
|
+
packages: ["@aphrody/m3-design"],
|
|
143
|
+
},
|
|
144
|
+
{
|
|
145
|
+
id: "next",
|
|
146
|
+
label: "Next",
|
|
147
|
+
icon: webIcon,
|
|
148
|
+
iconFilled: webFilled,
|
|
149
|
+
summary: "Metadata, scheme CSS, robots, sitemap and JSON-LD from the Next integration.",
|
|
150
|
+
packages: ["@aphrody/m3-next", "@aphrody/m3-next-migrate"],
|
|
151
|
+
},
|
|
152
|
+
{
|
|
153
|
+
id: "system",
|
|
154
|
+
label: "System",
|
|
155
|
+
icon: terminalIcon,
|
|
156
|
+
iconFilled: terminalFilled,
|
|
157
|
+
summary: "OS themes, scaffolds, MCP tools, codemods and lint rules, computed by the API.",
|
|
158
|
+
packages: [
|
|
159
|
+
"@aphrody/m3-os-themes",
|
|
160
|
+
"@aphrody/scaffold",
|
|
161
|
+
"@aphrody/m3-mcp",
|
|
162
|
+
"@aphrody/m3-codemods",
|
|
163
|
+
"@aphrody/eslint-plugin-m3",
|
|
164
|
+
],
|
|
165
|
+
},
|
|
166
|
+
{
|
|
167
|
+
id: "brands",
|
|
168
|
+
label: "Brands",
|
|
169
|
+
icon: badgeIcon,
|
|
170
|
+
iconFilled: badgeFilled,
|
|
171
|
+
summary: "Host-bound UI kits where they resolve, the identity set, canvas and assets.",
|
|
172
|
+
packages: [
|
|
173
|
+
"@rosegriffon/ui",
|
|
174
|
+
"@shenron/ui",
|
|
175
|
+
"@aphrody/nie-ui",
|
|
176
|
+
"@aphrody/identity",
|
|
177
|
+
"@aphrody/canvas",
|
|
178
|
+
"@aphrody/assets",
|
|
179
|
+
],
|
|
180
|
+
},
|
|
181
|
+
{
|
|
182
|
+
id: "adaptive",
|
|
183
|
+
label: "Adaptive",
|
|
184
|
+
icon: devicesIcon,
|
|
185
|
+
iconFilled: devicesFilled,
|
|
186
|
+
summary: "Window size classes, layout modes and the TV D-pad lab.",
|
|
187
|
+
packages: ["@aphrody/m3-tokens", "@aphrody/m3-front"],
|
|
188
|
+
},
|
|
189
|
+
];
|
|
190
|
+
|
|
191
|
+
/** The destinations the mobile bottom bar shows; the rest sit behind "More". */
|
|
192
|
+
export const PRIMARY_IDS = ["overview", "theme", "components", "adaptive"] as const;
|
|
193
|
+
|
|
194
|
+
export const MORE_ICON = appsIcon;
|
|
195
|
+
export const MORE_ICON_FILLED = appsFilled;
|
|
196
|
+
|
|
197
|
+
export const findDestination = (id: string): Destination =>
|
|
198
|
+
DESTINATIONS.find((d) => d.id === id) ?? DESTINATIONS[0]!;
|
package/src/styles.css
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
@import "tailwindcss";
|
|
2
|
+
@import "@aphrody/m3-tokens/m3-tokens.css";
|
|
3
|
+
@import "@aphrody/m3-tokens/expressive.css";
|
|
4
|
+
@import "@aphrody/m3-tailwind/preset.css";
|
|
5
|
+
|
|
6
|
+
/*
|
|
7
|
+
* Google Sans Flex (latin subset) from @aphrody/m3-fonts. The package's own fonts.css also declares Google Sans Code and
|
|
8
|
+
* Roboto Mono: Bun inlines CSS url() assets under ~128 KB as base64 (neither a loader nor a plugin changes that), which
|
|
9
|
+
* would put ~290 KB of data URLs into the render-blocking stylesheet. The Icons & fonts page loads the other families itself.
|
|
10
|
+
*/
|
|
11
|
+
@font-face {
|
|
12
|
+
font-family: "Google Sans Flex";
|
|
13
|
+
src: url("../../../packages/m3-fonts/fonts/web/GoogleSansFlex-latin.woff2") format("woff2");
|
|
14
|
+
font-weight: 1 1000;
|
|
15
|
+
font-stretch: 25% 151%;
|
|
16
|
+
font-style: oblique -10deg 0deg;
|
|
17
|
+
font-display: swap;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/* The showcase sets colour roles at runtime (M3ThemeProvider); everything else comes from the token sheets. */
|
|
21
|
+
:root {
|
|
22
|
+
--m3-nav-width: 0px;
|
|
23
|
+
--m3-gutter: 16px;
|
|
24
|
+
color-scheme: light dark;
|
|
25
|
+
}
|
|
26
|
+
html[data-m3-width="medium"], html[data-m3-width="expanded"], html[data-m3-width="large"], html[data-m3-width="extra-large"] { --m3-gutter: 24px; }
|
|
27
|
+
|
|
28
|
+
html, body, #root { height: 100%; }
|
|
29
|
+
body {
|
|
30
|
+
margin: 0;
|
|
31
|
+
background: var(--md-sys-color-background);
|
|
32
|
+
color: var(--md-sys-color-on-background);
|
|
33
|
+
font-family: var(--md-ref-typeface-plain);
|
|
34
|
+
font-size: var(--md-sys-typescale-body-large-size);
|
|
35
|
+
line-height: var(--md-sys-typescale-body-large-line-height);
|
|
36
|
+
-webkit-font-smoothing: antialiased;
|
|
37
|
+
overscroll-behavior: none;
|
|
38
|
+
}
|
|
39
|
+
* { box-sizing: border-box; }
|
|
40
|
+
a { color: inherit; }
|
|
41
|
+
|
|
42
|
+
/* TV: 10-foot type scale, safe area, obvious focus. */
|
|
43
|
+
html[data-layout="tv"] { font-size: 150%; }
|
|
44
|
+
html[data-layout="tv"] body { padding: 2.5vh 2.5vw; }
|
|
45
|
+
html[data-layout="tv"] :focus-visible,
|
|
46
|
+
html[data-layout="tv"] [data-dpad-focus] {
|
|
47
|
+
outline: 4px solid var(--md-sys-color-primary);
|
|
48
|
+
outline-offset: 4px;
|
|
49
|
+
border-radius: var(--md-sys-shape-corner-medium);
|
|
50
|
+
}
|
|
51
|
+
:focus-visible { outline: 2px solid var(--md-sys-color-primary); outline-offset: 2px; }
|
|
52
|
+
|
|
53
|
+
.m3-scroll { scrollbar-width: thin; scrollbar-color: var(--md-sys-color-outline-variant) transparent; }
|
|
54
|
+
.m3-card { background: var(--md-sys-color-surface-container); border-radius: var(--md-sys-shape-corner-large); padding: 16px; }
|
|
55
|
+
.m3-code { font-family: var(--md-ref-typeface-code, ui-monospace, monospace); font-size: 0.8125rem; background: var(--md-sys-color-surface-container-highest); border-radius: var(--md-sys-shape-corner-small); padding: 12px; overflow: auto; white-space: pre; }
|
|
56
|
+
.m3-icon svg { width: 1.5rem; height: 1.5rem; fill: currentColor; display: block; }
|
|
57
|
+
.m3-icon-sm svg { width: 1.125rem; height: 1.125rem; fill: currentColor; display: block; }
|
|
58
|
+
|
|
59
|
+
@media (prefers-reduced-motion: reduce) {
|
|
60
|
+
* { animation-duration: 0.01ms !important; transition-duration: 0.01ms !important; }
|
|
61
|
+
}
|