From 85ac12e5c7bda975e4b4b8408e0395c88a46bd88 Mon Sep 17 00:00:00 2001 From: Tsiry Sandratraina Date: Sun, 1 Feb 2026 21:50:45 +0300 Subject: [PATCH] Add embed pages, components, types, and fetchers --- apps/embed/bun.lock | 88 + apps/embed/package.json | 6 + apps/embed/public/styles.css | 2845 ++++++++++++++++- apps/embed/src/components/Header/Header.tsx | 55 + apps/embed/src/components/Header/index.tsx | 3 + apps/embed/src/components/Icons/Artist.tsx | 23 + apps/embed/src/embeds/ProfileEmbedPage.tsx | 7 +- .../src/embeds/RecentScrobblesEmbedPage.tsx | 16 +- apps/embed/src/embeds/TopAlbumsEmbedPage.tsx | 16 +- apps/embed/src/embeds/TopArtistsEmbedPage.tsx | 57 +- apps/embed/src/embeds/TopTracksEmbedPage.tsx | 16 +- apps/embed/src/index.tsx | 57 +- apps/embed/src/styles.css | 7 + apps/embed/src/types/album.ts | 11 + apps/embed/src/types/artist.ts | 6 +- apps/embed/src/types/scrobble.ts | 16 + apps/embed/src/types/track.ts | 13 +- apps/embed/src/xrpc/getRecentScrobbles.ts | 18 + apps/embed/src/xrpc/getTopAlbums.ts | 18 + apps/embed/src/xrpc/getTopArtists.ts | 23 + apps/embed/src/xrpc/getTopTracks.ts | 19 + 21 files changed, 3263 insertions(+), 57 deletions(-) create mode 100644 apps/embed/src/components/Header/Header.tsx create mode 100644 apps/embed/src/components/Header/index.tsx create mode 100644 apps/embed/src/components/Icons/Artist.tsx create mode 100644 apps/embed/src/types/album.ts create mode 100644 apps/embed/src/types/scrobble.ts create mode 100644 apps/embed/src/xrpc/getRecentScrobbles.ts create mode 100644 apps/embed/src/xrpc/getTopAlbums.ts create mode 100644 apps/embed/src/xrpc/getTopArtists.ts create mode 100644 apps/embed/src/xrpc/getTopTracks.ts diff --git a/apps/embed/bun.lock b/apps/embed/bun.lock index 56520605..0ec213b7 100644 --- a/apps/embed/bun.lock +++ b/apps/embed/bun.lock @@ -6,10 +6,16 @@ "name": "embed", "dependencies": { "@hono/react-renderer": "^1.0.1", + "@iconify-json/tabler": "^1.2.26", + "@iconify/tailwind4": "^1.2.1", + "@logtape/logtape": "^2.0.2", "dayjs": "^1.11.19", + "flyonui": "^2.4.1", "hono": "^4.11.7", "honox": "^0.1.53", + "lodash": "^4.17.23", "numeral": "^2.0.6", + "ramda": "^0.32.0", "react": "^19.2.4", "react-dom": "^19.2.4", "uuid": "^13.0.0", @@ -30,6 +36,8 @@ }, }, "packages": { + "@antfu/install-pkg": ["@antfu/install-pkg@1.1.0", "", { "dependencies": { "package-manager-detector": "^1.3.0", "tinyexec": "^1.0.1" } }, "sha512-MGQsmw10ZyI+EJo45CdSER4zEb+p31LpDAFp2Z3gkSd1yqVZGi0Ebx++YTEMonJy4oChEMLsxZ64j8FH6sSqtQ=="], + "@babel/code-frame": ["@babel/code-frame@7.29.0", "", { "dependencies": { "@babel/helper-validator-identifier": "^7.28.5", "js-tokens": "^4.0.0", "picocolors": "^1.1.1" } }, "sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw=="], "@babel/generator": ["@babel/generator@7.25.6", "", { "dependencies": { "@babel/types": "^7.25.6", "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.25", "jsesc": "^2.5.1" } }, "sha512-VPC82gr1seXOpkjAAKoLhP50vx4vGNlF4msF64dSFq1P8RfB+QAuJWGHPXXPc8QyfVWwwB/TNNU4+ayZmHNbZw=="], @@ -46,6 +54,8 @@ "@babel/types": ["@babel/types@7.25.6", "", { "dependencies": { "@babel/helper-string-parser": "^7.24.8", "@babel/helper-validator-identifier": "^7.24.7", "to-fast-properties": "^2.0.0" } }, "sha512-/l42B1qxpG6RdfYf343Uw1vmDjeNhneUXtzhojE7pDgfpEypmRhI6j1kr17XCVv4Cgl9HdAiQY2x0GwKm7rWCw=="], + "@cyberalien/svg-utils": ["@cyberalien/svg-utils@1.1.1", "", { "dependencies": { "@iconify/types": "^2.0.0" } }, "sha512-i05Cnpzeezf3eJAXLx7aFirTYYoq5D1XUItp1XsjqkerNJh//6BG9sOYHbiO7v0KYMvJAx3kosrZaRcNlQPdsA=="], + "@dependents/detective-less": ["@dependents/detective-less@5.0.1", "", { "dependencies": { "gonzales-pe": "^4.3.0", "node-source-walk": "^7.0.1" } }, "sha512-Y6+WUMsTFWE5jb20IFP4YGa5IrGY/+a/FbOSjDF/wz9gepU2hwCYSXRHP/vPwBvwcY3SVMASt4yXxbXNXigmZQ=="], "@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.27.2", "", { "os": "aix", "cpu": "ppc64" }, "sha512-GZMB+a0mOMZs4MpDbj8RJp4cw+w1WV5NYD6xzgvzUJ5Ek2jerwfO2eADyI6ExDSUED+1X8aMbegahsJi+8mgpw=="], @@ -100,12 +110,28 @@ "@esbuild/win32-x64": ["@esbuild/win32-x64@0.27.2", "", { "os": "win32", "cpu": "x64" }, "sha512-sRdU18mcKf7F+YgheI/zGf5alZatMUTKj/jNS6l744f9u3WFu4v7twcUI9vu4mknF4Y9aDlblIie0IM+5xxaqQ=="], + "@floating-ui/core": ["@floating-ui/core@1.7.4", "", { "dependencies": { "@floating-ui/utils": "^0.2.10" } }, "sha512-C3HlIdsBxszvm5McXlB8PeOEWfBhcGBTZGkGlWc2U0KFY5IwG5OQEuQ8rq52DZmcHDlPLd+YFBK+cZcytwIFWg=="], + + "@floating-ui/dom": ["@floating-ui/dom@1.7.5", "", { "dependencies": { "@floating-ui/core": "^1.7.4", "@floating-ui/utils": "^0.2.10" } }, "sha512-N0bD2kIPInNHUHehXhMke1rBGs1dwqvC9O9KYMyyjK7iXt7GAhnro7UlcuYcGdS/yYOlq0MAVgrow8IbWJwyqg=="], + + "@floating-ui/utils": ["@floating-ui/utils@0.2.10", "", {}, "sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ=="], + "@hono/node-server": ["@hono/node-server@1.19.9", "", { "peerDependencies": { "hono": "^4" } }, "sha512-vHL6w3ecZsky+8P5MD+eFfaGTyCeOHUIFYMGpQGbrBTSmNNoxv0if69rEZ5giu36weC5saFuznL411gRX7bJDw=="], "@hono/react-renderer": ["@hono/react-renderer@1.0.1", "", { "peerDependencies": { "hono": "*", "react": "^19.0.0", "react-dom": "^19.0.0" } }, "sha512-vjQ/70hVrbgsi2O44N7w5sO0v51lRcuXau/4caVzw0A1hje+U2zAnuhiBC3JhX56gGfhGT4kO5B0di4SROx0Lg=="], "@hono/vite-dev-server": ["@hono/vite-dev-server@0.23.0", "", { "dependencies": { "@hono/node-server": "^1.14.2", "minimatch": "^9.0.3" }, "peerDependencies": { "hono": "*", "miniflare": "*", "wrangler": "*" }, "optionalPeers": ["miniflare", "wrangler"] }, "sha512-tHV86xToed9Up0j/dubQW2PDP4aYNFDSfQrjcV6Ra7bqCGrxhtg/zZBmbgSco3aTxKOEPzDXKK+6seAAfsbIXw=="], + "@iconify-json/tabler": ["@iconify-json/tabler@1.2.26", "", { "dependencies": { "@iconify/types": "*" } }, "sha512-92G+ZD70AZgeJf07JfQzH+isnai6DwPcMBuF/qL1F+xAxdXCJzGd3w2RmsRvOmB+w1ImmWEEDms50QivQIjd6g=="], + + "@iconify/tailwind4": ["@iconify/tailwind4@1.2.1", "", { "dependencies": { "@iconify/tools": "^5.0.2", "@iconify/types": "^2.0.0", "@iconify/utils": "^3.1.0" }, "peerDependencies": { "tailwindcss": ">= 4.0.0" } }, "sha512-Hd7k8y7uzT3hk8ltw0jGku0r0wA8sc3d2iMvVTYv/9tMxBb+frZtWZGD9hDMU3EYuE+lMn58wi2lS8R2ZbwFcQ=="], + + "@iconify/tools": ["@iconify/tools@5.0.3", "", { "dependencies": { "@cyberalien/svg-utils": "^1.1.1", "@iconify/types": "^2.0.0", "@iconify/utils": "^3.1.0", "fflate": "^0.8.2", "modern-tar": "^0.7.3", "pathe": "^2.0.3", "svgo": "^4.0.0" } }, "sha512-W5nbH5fNv20TvU49Al19Foos/ViAnmppbCNV9ieGl6/dRMDRzxeFol6peXX/NAgaOytQwZZxTTJRq/Kxd4eWsA=="], + + "@iconify/types": ["@iconify/types@2.0.0", "", {}, "sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg=="], + + "@iconify/utils": ["@iconify/utils@3.1.0", "", { "dependencies": { "@antfu/install-pkg": "^1.1.0", "@iconify/types": "^2.0.0", "mlly": "^1.8.0" } }, "sha512-Zlzem1ZXhI1iHeeERabLNzBHdOa4VhQbqAcOQaMKuTuyZCpwKbC2R4Dd0Zo3g9EAc+Y4fiarO8HIHRAth7+skw=="], + "@jridgewell/gen-mapping": ["@jridgewell/gen-mapping@0.3.13", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.0", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA=="], "@jridgewell/remapping": ["@jridgewell/remapping@2.3.5", "", { "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ=="], @@ -116,6 +142,8 @@ "@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.31", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw=="], + "@logtape/logtape": ["@logtape/logtape@2.0.2", "", {}, "sha512-cveUBLbCMFkvkLycP/2vNWvywl47JcJbazHIju94/QNGboZ/jyYAgZIm0ZXezAOx3eIz8OG1EOZ5CuQP3+2FQg=="], + "@rollup/rollup-android-arm-eabi": ["@rollup/rollup-android-arm-eabi@4.57.1", "", { "os": "android", "cpu": "arm" }, "sha512-A6ehUVSiSaaliTxai040ZpZ2zTevHYbvu/lDoeAteHI8QnaosIzm4qwtezfRg1jOYaUmnzLX1AOD6Z+UJjtifg=="], "@rollup/rollup-android-arm64": ["@rollup/rollup-android-arm64@4.57.1", "", { "os": "android", "cpu": "arm64" }, "sha512-dQaAddCY9YgkFHZcFNS/606Exo8vcLHwArFZ7vxXq4rigo2bb494/xKMMwRRQW6ug7Js6yXmBZhSBRuBvCCQ3w=="], @@ -226,6 +254,8 @@ "@vue/shared": ["@vue/shared@3.5.27", "", {}, "sha512-dXr/3CgqXsJkZ0n9F3I4elY8wM9jMJpP3pvRG52r6m0tu/MsAFIe6JpXVGeNMd/D9F4hQynWT8Rfuj0bdm9kFQ=="], + "acorn": ["acorn@8.15.0", "", { "bin": { "acorn": "bin/acorn" } }, "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg=="], + "ast-module-types": ["ast-module-types@6.0.1", "", {}, "sha512-WHw67kLXYbZuHTmcdbIrVArCq5wxo6NEuj3hiYAWr8mwJeC+C2mMCIBIWCiDoCye/OF/xelc+teJ1ERoWmnEIA=="], "autoprefixer": ["autoprefixer@10.4.24", "", { "dependencies": { "browserslist": "^4.28.1", "caniuse-lite": "^1.0.30001766", "fraction.js": "^5.3.4", "picocolors": "^1.1.1", "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.1.0" }, "bin": { "autoprefixer": "bin/autoprefixer" } }, "sha512-uHZg7N9ULTVbutaIsDRoUkoS8/h3bdsmVJYZ5l3wv8Cp/6UIIoRDm90hZ+BwxUj/hGBEzLxdHNSKuFpn8WOyZw=="], @@ -234,6 +264,8 @@ "baseline-browser-mapping": ["baseline-browser-mapping@2.9.19", "", { "bin": { "baseline-browser-mapping": "dist/cli.js" } }, "sha512-ipDqC8FrAl/76p2SSWKSI+H9tFwm7vYqXQrItCuiVPt26Km0jS+NzSsBWAaBusvSbQcfJG+JitdMm+wZAgTYqg=="], + "boolbase": ["boolbase@1.0.0", "", {}, "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww=="], + "brace-expansion": ["brace-expansion@2.0.2", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ=="], "browserslist": ["browserslist@4.28.1", "", { "dependencies": { "baseline-browser-mapping": "^2.9.0", "caniuse-lite": "^1.0.30001759", "electron-to-chromium": "^1.5.263", "node-releases": "^2.0.27", "update-browserslist-db": "^1.2.0" }, "bin": { "browserslist": "cli.js" } }, "sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA=="], @@ -246,6 +278,16 @@ "commander": ["commander@12.1.0", "", {}, "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA=="], + "confbox": ["confbox@0.1.8", "", {}, "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w=="], + + "css-select": ["css-select@5.2.2", "", { "dependencies": { "boolbase": "^1.0.0", "css-what": "^6.1.0", "domhandler": "^5.0.2", "domutils": "^3.0.1", "nth-check": "^2.0.1" } }, "sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw=="], + + "css-tree": ["css-tree@3.1.0", "", { "dependencies": { "mdn-data": "2.12.2", "source-map-js": "^1.0.1" } }, "sha512-0eW44TGN5SQXU1mWSkKwFstI/22X2bG1nYzZTYMAWjylYURhse752YgbE4Cx46AC+bAvI+/dYTPRk1LqSUnu6w=="], + + "css-what": ["css-what@6.2.2", "", {}, "sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA=="], + + "csso": ["csso@5.0.5", "", { "dependencies": { "css-tree": "~2.2.0" } }, "sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ=="], + "csstype": ["csstype@3.2.3", "", {}, "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ=="], "dayjs": ["dayjs@1.11.19", "", {}, "sha512-t5EcLVS6QPBNqM2z8fakk/NKel+Xzshgt8FFKAn+qwlD1pzZWxh0nVCrvFK7ZDb6XucZeF9z8C7CBWTRIVApAw=="], @@ -272,6 +314,14 @@ "detective-vue2": ["detective-vue2@2.2.0", "", { "dependencies": { "@dependents/detective-less": "^5.0.1", "@vue/compiler-sfc": "^3.5.13", "detective-es6": "^5.0.1", "detective-sass": "^6.0.1", "detective-scss": "^5.0.1", "detective-stylus": "^5.0.1", "detective-typescript": "^14.0.0" }, "peerDependencies": { "typescript": "^5.4.4" } }, "sha512-sVg/t6O2z1zna8a/UIV6xL5KUa2cMTQbdTIIvqNM0NIPswp52fe43Nwmbahzj3ww4D844u/vC2PYfiGLvD3zFA=="], + "dom-serializer": ["dom-serializer@2.0.0", "", { "dependencies": { "domelementtype": "^2.3.0", "domhandler": "^5.0.2", "entities": "^4.2.0" } }, "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg=="], + + "domelementtype": ["domelementtype@2.3.0", "", {}, "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw=="], + + "domhandler": ["domhandler@5.0.3", "", { "dependencies": { "domelementtype": "^2.3.0" } }, "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w=="], + + "domutils": ["domutils@3.2.2", "", { "dependencies": { "dom-serializer": "^2.0.0", "domelementtype": "^2.3.0", "domhandler": "^5.0.3" } }, "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw=="], + "electron-to-chromium": ["electron-to-chromium@1.5.283", "", {}, "sha512-3vifjt1HgrGW/h76UEeny+adYApveS9dH2h3p57JYzBSXJIKUJAvtmIytDKjcSCt9xHfrNCFJ7gts6vkhuq++w=="], "enhanced-resolve": ["enhanced-resolve@5.18.4", "", { "dependencies": { "graceful-fs": "^4.2.4", "tapable": "^2.2.0" } }, "sha512-LgQMM4WXU3QI+SYgEc2liRgznaD5ojbmY3sb8LxyguVkIg5FxdpTkvk72te2R38/TGKxH634oLxXRGY6d7AP+Q=="], @@ -296,6 +346,10 @@ "fdir": ["fdir@6.5.0", "", { "peerDependencies": { "picomatch": "^3 || ^4" }, "optionalPeers": ["picomatch"] }, "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg=="], + "fflate": ["fflate@0.8.2", "", {}, "sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A=="], + + "flyonui": ["flyonui@2.4.1", "", { "dependencies": { "@floating-ui/dom": "^1.7.1" } }, "sha512-WgP/YP1nZXbEtRkl3ThJIcIaisXOyON3zS2Qz2IwikQA/2X/PmqnP6E+eOz7WLBzEQI4ec7wViYAcRf9vljcbg=="], + "fraction.js": ["fraction.js@5.3.4", "", {}, "sha512-1X1NTtiJphryn/uLQz3whtY6jK3fTqoE3ohKs0tT+Ujr1W59oopxmoEh7Lu5p6vBaPbgoM0bzveAW4Qi5RyWDQ=="], "fsevents": ["fsevents@2.3.3", "", { "os": "darwin" }, "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw=="], @@ -348,12 +402,20 @@ "lightningcss-win32-x64-msvc": ["lightningcss-win32-x64-msvc@1.30.2", "", { "os": "win32", "cpu": "x64" }, "sha512-5g1yc73p+iAkid5phb4oVFMB45417DkRevRbt/El/gKXJk4jid+vPFF/AXbxn05Aky8PapwzZrdJShv5C0avjw=="], + "lodash": ["lodash@4.17.23", "", {}, "sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w=="], + "magic-string": ["magic-string@0.30.21", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.5" } }, "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ=="], + "mdn-data": ["mdn-data@2.12.2", "", {}, "sha512-IEn+pegP1aManZuckezWCO+XZQDplx1366JoVhTpMpBB1sPey/SbveZQUosKiKiGYjg1wH4pMlNgXbCiYgihQA=="], + "minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="], "minimist": ["minimist@1.2.8", "", {}, "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA=="], + "mlly": ["mlly@1.8.0", "", { "dependencies": { "acorn": "^8.15.0", "pathe": "^2.0.3", "pkg-types": "^1.3.1", "ufo": "^1.6.1" } }, "sha512-l8D9ODSRWLe2KHJSifWGwBqpTZXIXTeo8mlKjY+E2HAakaTeNpqAyBZ8GSqLzHgw4XmHmC8whvpjJNMbFZN7/g=="], + + "modern-tar": ["modern-tar@0.7.3", "", {}, "sha512-4W79zekKGyYU4JXVmB78DOscMFaJth2gGhgfTl2alWE4rNe3nf4N2pqenQ0rEtIewrnD79M687Ouba3YGTLOvg=="], + "module-definition": ["module-definition@6.0.1", "", { "dependencies": { "ast-module-types": "^6.0.1", "node-source-walk": "^7.0.1" }, "bin": { "module-definition": "bin/cli.js" } }, "sha512-FeVc50FTfVVQnolk/WQT8MX+2WVcDnTGiq6Wo+/+lJ2ET1bRVi3HG3YlJUfqagNMc/kUlFSoR96AJkxGpKz13g=="], "ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="], @@ -364,12 +426,20 @@ "node-source-walk": ["node-source-walk@7.0.1", "", { "dependencies": { "@babel/parser": "^7.26.7" } }, "sha512-3VW/8JpPqPvnJvseXowjZcirPisssnBuDikk6JIZ8jQzF7KJQX52iPFX4RYYxLycYH7IbMRSPUOga/esVjy5Yg=="], + "nth-check": ["nth-check@2.1.1", "", { "dependencies": { "boolbase": "^1.0.0" } }, "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w=="], + "numeral": ["numeral@2.0.6", "", {}, "sha512-qaKRmtYPZ5qdw4jWJD6bxEf1FJEqllJrwxCLIm0sQU/A7v2/czigzOb+C2uSiFsa9lBUzeH7M1oK+Q+OLxL3kA=="], + "package-manager-detector": ["package-manager-detector@1.6.0", "", {}, "sha512-61A5ThoTiDG/C8s8UMZwSorAGwMJ0ERVGj2OjoW5pAalsNOg15+iQiPzrLJ4jhZ1HJzmC2PIHT2oEiH3R5fzNA=="], + + "pathe": ["pathe@2.0.3", "", {}, "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w=="], + "picocolors": ["picocolors@1.1.1", "", {}, "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="], "picomatch": ["picomatch@4.0.3", "", {}, "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q=="], + "pkg-types": ["pkg-types@1.3.1", "", { "dependencies": { "confbox": "^0.1.8", "mlly": "^1.7.4", "pathe": "^2.0.1" } }, "sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ=="], + "postcss": ["postcss@8.5.6", "", { "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg=="], "postcss-value-parser": ["postcss-value-parser@4.2.0", "", {}, "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ=="], @@ -380,12 +450,16 @@ "quote-unquote": ["quote-unquote@1.0.0", "", {}, "sha512-twwRO/ilhlG/FIgYeKGFqyHhoEhqgnKVkcmqMKi2r524gz3ZbDTcyFt38E9xjJI2vT+KbRNHVbnJ/e0I25Azwg=="], + "ramda": ["ramda@0.32.0", "", {}, "sha512-GQWAHhxhxWBWA8oIBr1XahFVjQ9Fic6MK9ikijfd4TZHfE2+urfk+irVlR5VOn48uwMgM+loRRBJd6Yjsbc0zQ=="], + "react": ["react@19.2.4", "", {}, "sha512-9nfp2hYpCwOjAN+8TZFGhtWEwgvWHXqESH8qT89AT/lWklpLON22Lc8pEtnpsZz7VmawabSU0gCjnj8aC0euHQ=="], "react-dom": ["react-dom@19.2.4", "", { "dependencies": { "scheduler": "^0.27.0" }, "peerDependencies": { "react": "^19.2.4" } }, "sha512-AXJdLo8kgMbimY95O2aKQqsz2iWi9jMgKJhRBAxECE4IFxfcazB2LmzloIoibJI3C12IlY20+KFaLv+71bUJeQ=="], "rollup": ["rollup@4.57.1", "", { "dependencies": { "@types/estree": "1.0.8" }, "optionalDependencies": { "@rollup/rollup-android-arm-eabi": "4.57.1", "@rollup/rollup-android-arm64": "4.57.1", "@rollup/rollup-darwin-arm64": "4.57.1", "@rollup/rollup-darwin-x64": "4.57.1", "@rollup/rollup-freebsd-arm64": "4.57.1", "@rollup/rollup-freebsd-x64": "4.57.1", "@rollup/rollup-linux-arm-gnueabihf": "4.57.1", "@rollup/rollup-linux-arm-musleabihf": "4.57.1", "@rollup/rollup-linux-arm64-gnu": "4.57.1", "@rollup/rollup-linux-arm64-musl": "4.57.1", "@rollup/rollup-linux-loong64-gnu": "4.57.1", "@rollup/rollup-linux-loong64-musl": "4.57.1", "@rollup/rollup-linux-ppc64-gnu": "4.57.1", "@rollup/rollup-linux-ppc64-musl": "4.57.1", "@rollup/rollup-linux-riscv64-gnu": "4.57.1", "@rollup/rollup-linux-riscv64-musl": "4.57.1", "@rollup/rollup-linux-s390x-gnu": "4.57.1", "@rollup/rollup-linux-x64-gnu": "4.57.1", "@rollup/rollup-linux-x64-musl": "4.57.1", "@rollup/rollup-openbsd-x64": "4.57.1", "@rollup/rollup-openharmony-arm64": "4.57.1", "@rollup/rollup-win32-arm64-msvc": "4.57.1", "@rollup/rollup-win32-ia32-msvc": "4.57.1", "@rollup/rollup-win32-x64-gnu": "4.57.1", "@rollup/rollup-win32-x64-msvc": "4.57.1", "fsevents": "~2.3.2" }, "bin": { "rollup": "dist/bin/rollup" } }, "sha512-oQL6lgK3e2QZeQ7gcgIkS2YZPg5slw37hYufJ3edKlfQSGGm8ICoxswK15ntSzF/a8+h7ekRy7k7oWc3BQ7y8A=="], + "sax": ["sax@1.4.4", "", {}, "sha512-1n3r/tGXO6b6VXMdFT54SHzT9ytu9yr7TaELowdYpMqY/Ao7EnlQGmAQ1+RatX7Tkkdm6hONI2owqNx2aZj5Sw=="], + "scheduler": ["scheduler@0.27.0", "", {}, "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q=="], "semver": ["semver@7.7.3", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q=="], @@ -394,10 +468,14 @@ "source-map-js": ["source-map-js@1.2.1", "", {}, "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA=="], + "svgo": ["svgo@4.0.0", "", { "dependencies": { "commander": "^11.1.0", "css-select": "^5.1.0", "css-tree": "^3.0.1", "css-what": "^6.1.0", "csso": "^5.0.5", "picocolors": "^1.1.1", "sax": "^1.4.1" }, "bin": "./bin/svgo.js" }, "sha512-VvrHQ+9uniE+Mvx3+C9IEe/lWasXCU0nXMY2kZeLrHNICuRiC8uMPyM14UEaMOFA5mhyQqEkB02VoQ16n3DLaw=="], + "tailwindcss": ["tailwindcss@4.1.18", "", {}, "sha512-4+Z+0yiYyEtUVCScyfHCxOYP06L5Ne+JiHhY2IjR2KWMIWhJOYZKLSGZaP5HkZ8+bY0cxfzwDE5uOmzFXyIwxw=="], "tapable": ["tapable@2.3.0", "", {}, "sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg=="], + "tinyexec": ["tinyexec@1.0.2", "", {}, "sha512-W/KYk+NFhkmsYpuHq5JykngiOCnxeVL8v8dFnqxSD8qEEdRfXk1SDM6JzNqcERbcGYj9tMrDQBYV9cjgnunFIg=="], + "tinyglobby": ["tinyglobby@0.2.15", "", { "dependencies": { "fdir": "^6.5.0", "picomatch": "^4.0.3" } }, "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ=="], "to-fast-properties": ["to-fast-properties@2.0.0", "", {}, "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog=="], @@ -406,6 +484,8 @@ "typescript": ["typescript@5.9.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="], + "ufo": ["ufo@1.6.3", "", {}, "sha512-yDJTmhydvl5lJzBmy/hyOAA0d+aqCBuwl818haVdYCRrWV84o7YyeVm4QlVHStqNrrJSTb6jKuFAVqAFsr+K3Q=="], + "undici-types": ["undici-types@7.16.0", "", {}, "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw=="], "update-browserslist-db": ["update-browserslist-db@1.2.3", "", { "dependencies": { "escalade": "^3.2.0", "picocolors": "^1.1.1" }, "peerDependencies": { "browserslist": ">= 4.21.0" }, "bin": { "update-browserslist-db": "cli.js" } }, "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w=="], @@ -434,12 +514,20 @@ "@vue/compiler-sfc/@babel/parser": ["@babel/parser@7.29.0", "", { "dependencies": { "@babel/types": "^7.29.0" }, "bin": "./bin/babel-parser.js" }, "sha512-IyDgFV5GeDUVX4YdF/3CPULtVGSXXMLh1xVIgdCgxApktqnQV0r7/8Nqthg+8YLGaAtdyIlo2qIdZrbCv4+7ww=="], + "csso/css-tree": ["css-tree@2.2.1", "", { "dependencies": { "mdn-data": "2.0.28", "source-map-js": "^1.0.1" } }, "sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA=="], + + "dom-serializer/entities": ["entities@4.5.0", "", {}, "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw=="], + "node-source-walk/@babel/parser": ["@babel/parser@7.29.0", "", { "dependencies": { "@babel/types": "^7.29.0" }, "bin": "./bin/babel-parser.js" }, "sha512-IyDgFV5GeDUVX4YdF/3CPULtVGSXXMLh1xVIgdCgxApktqnQV0r7/8Nqthg+8YLGaAtdyIlo2qIdZrbCv4+7ww=="], + "svgo/commander": ["commander@11.1.0", "", {}, "sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ=="], + "@vue/compiler-core/@babel/parser/@babel/types": ["@babel/types@7.29.0", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.28.5" } }, "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A=="], "@vue/compiler-sfc/@babel/parser/@babel/types": ["@babel/types@7.29.0", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.28.5" } }, "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A=="], + "csso/css-tree/mdn-data": ["mdn-data@2.0.28", "", {}, "sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g=="], + "node-source-walk/@babel/parser/@babel/types": ["@babel/types@7.29.0", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.28.5" } }, "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A=="], } } diff --git a/apps/embed/package.json b/apps/embed/package.json index fda983f4..6865c98f 100644 --- a/apps/embed/package.json +++ b/apps/embed/package.json @@ -22,10 +22,16 @@ }, "dependencies": { "@hono/react-renderer": "^1.0.1", + "@iconify-json/tabler": "^1.2.26", + "@iconify/tailwind4": "^1.2.1", + "@logtape/logtape": "^2.0.2", "dayjs": "^1.11.19", + "flyonui": "^2.4.1", "hono": "^4.11.7", "honox": "^0.1.53", + "lodash": "^4.17.23", "numeral": "^2.0.6", + "ramda": "^0.32.0", "react": "^19.2.4", "react-dom": "^19.2.4", "uuid": "^13.0.0" diff --git a/apps/embed/public/styles.css b/apps/embed/public/styles.css index 01013522..f0fa0b1f 100644 --- a/apps/embed/public/styles.css +++ b/apps/embed/public/styles.css @@ -1,20 +1,1472 @@ /*! tailwindcss v4.1.18 | MIT License | https://tailwindcss.com */ @layer properties; +.carousel-prev { + position: absolute; + inset-block: calc(0.25rem * 0); + margin-block: auto; + display: inline-flex; + height: max-content; + cursor: pointer; + align-items: center; + justify-content: center; + &.disabled { + pointer-events: none; + } + border-start-start-radius: var(--radius-2xl); + border-end-start-radius: var(--radius-2xl); +} +.carousel-next { + position: absolute; + inset-block: calc(0.25rem * 0); + margin-block: auto; + display: inline-flex; + height: max-content; + cursor: pointer; + align-items: center; + justify-content: center; + &.disabled { + pointer-events: none; + } + border-start-end-radius: var(--radius-2xl); + border-end-end-radius: var(--radius-2xl); +} +.menu { + display: flex; + flex-direction: column; + flex-wrap: wrap; + gap: calc(0.25rem * 0.5); + border-radius: var(--radius-box); + padding: calc(0.25rem * 2); + font-size: var(--text-base); + line-height: var(--tw-leading, var(--text-base--line-height)); + --menu-active-fg: var(--color-primary); + --menu-active-bg: var(--color-primary); + @supports (color: color-mix(in lab, red, red)) { + --menu-active-bg: color-mix(in oklab, var(--color-primary) 10%, #0000); + } + --menu-hover-fg: var(--color-base-content); + --menu-hover-bg: var(--color-neutral); + @supports (color: color-mix(in lab, red, red)) { + --menu-hover-bg: color-mix(in oklab, var(--color-neutral) 10%, #0000); + } + :where(li ul) { + position: relative; + white-space: nowrap; + } + :where(li:not(.dropdown) ul) { + margin-inline-start: calc(0.25rem * 4); + padding-inline-start: calc(0.25rem * 2); + &:before { + position: absolute; + inset-inline-start: calc(0.25rem * 0); + top: calc(0.25rem * 3); + bottom: calc(0.25rem * 2.5); + background-color: var(--color-base-content); + opacity: 10%; + width: var(--border); + content: ""; + } + } + :where(li > .menu-dropdown:not(.menu-dropdown-show)) { + display: none; + } + :where(.menu li:empty) { + background-color: var(--color-base-content); + opacity: 10%; + margin: 0.5rem 1rem; + height: 1px; + } + :where(li:not(.menu-title, .tooltip) > *:not(ul, .collapse, .accordion-content, .menu-title, .btn)) { + border-radius: var(--radius-field); + padding-inline: calc(0.25rem * 4); + padding-block: calc(0.25rem * 2.5); + text-align: start; + transition-property: color, background-color, border-color, outline-color, text-decoration-color, fill, stroke, --tw-gradient-from, --tw-gradient-via, --tw-gradient-to, opacity, box-shadow, transform, translate, scale, rotate, filter, -webkit-backdrop-filter, backdrop-filter; + transition-timing-function: var(--tw-ease, var(--default-transition-timing-function)); + transition-timing-function: var(--ease-out); + transition-duration: var(--tw-duration, var(--default-transition-duration)); + transition-duration: 200ms; + --tw-duration: 200ms; + --tw-ease: var(--ease-out); + text-wrap: balance; + } + :where(li:not(.menu-title) > *:not(ul, .collapse, .accordion-content, .menu-title, .btn)) { + display: grid; + grid-auto-flow: column; + align-content: flex-start; + align-items: center; + gap: calc(0.25rem * 2); + grid-auto-columns: minmax(auto, max-content) auto max-content; + user-select: none; + } + :where(li.tooltip) > * { + border-radius: var(--radius-field); + padding-inline: calc(0.25rem * 4); + padding-block: calc(0.25rem * 2.5); + text-align: start; + } + :where(.menu li:not(.menu-title, .menu-disabled)) { + color: var(--color-base-content); + } + :where( .menu li:not(.menu-title, .menu-disabled) > *:not(ul, .collapse, .accordion-content, .dropdown-active, .menu-title) ) { + &:not(.btn):focus-visible { + cursor: pointer; + --tw-outline-style: none; + outline-style: none; + color: var(--menu-hover-fg); + background-color: var(--menu-hover-bg); + } + &:hover { + cursor: pointer; + --tw-outline-style: none; + outline-style: none; + color: var(--menu-hover-fg); + background-color: var(--menu-hover-bg); + } + } + li:not(.menu-title, .menu-disabled) > :not(ul, .menu-title, .collapse, .accordion-content, .btn).menu-active { + color: var(--menu-active-fg); + background-color: var(--menu-active-bg); + background-size: auto, calc(var(--noise) * 100%); + background-image: none, var(--fx-noise); + } + li.menu-disabled { + pointer-events: none; + opacity: 50%; + webkit-user-select: none; + user-select: none; + } + :where(& li) { + position: relative; + display: flex; + flex-shrink: 0; + flex-direction: column; + flex-wrap: wrap; + align-items: stretch; + .badge { + justify-self: flex-end; + } + } +} +.range { + appearance: none; + webkit-appearance: none; + --range-color: var(--color-base-content); + --range-thumb-border-width: 3px; + --range-track-height: 8px; + --range-thumb-size: 16px; + position: relative; + width: 100%; + border-radius: calc(infinity * 1px); + background-color: transparent; + transition-property: all; + transition-timing-function: var(--tw-ease, var(--default-transition-timing-function)); + transition-duration: var(--tw-duration, var(--default-transition-duration)); + height: var(--range-track-height); + &::-webkit-slider-runnable-track { + width: 100%; + border-radius: calc(infinity * 1px); + background-color: var(--color-neutral); + @supports (color: color-mix(in lab, red, red)) { + background-color: color-mix(in oklab, var(--color-neutral) 10%, transparent); + } + height: var(--range-track-height); + } + &::-moz-range-track { + width: 100%; + border-radius: calc(infinity * 1px); + background-color: var(--color-neutral); + @supports (color: color-mix(in lab, red, red)) { + background-color: color-mix(in oklab, var(--color-neutral) 10%, transparent); + } + height: var(--range-track-height); + } + &::-webkit-slider-thumb { + position: relative; + top: calc(1/2 * 100%); + --tw-translate-y: calc(calc(1/2 * 100%) * -1); + translate: var(--tw-translate-x) var(--tw-translate-y); + border-radius: calc(infinity * 1px); + background-color: var(--color-base-100); + --tw-shadow: 0 1px 3px 0 var(--tw-shadow-color, rgb(0 0 0 / 0.1)), 0 1px 2px -1px var(--tw-shadow-color, rgb(0 0 0 / 0.1)); + box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow); + --tw-shadow-color: var(--color-base-300); + @supports (color: color-mix(in lab, red, red)) { + --tw-shadow-color: color-mix(in oklab, color-mix(in oklab, var(--color-base-300) 20%, transparent) var(--tw-shadow-alpha), transparent); + } + transition-property: all; + transition-timing-function: var(--tw-ease, var(--default-transition-timing-function)); + transition-timing-function: var(--ease-in-out); + transition-duration: var(--tw-duration, var(--default-transition-duration)); + transition-duration: 150ms; + --tw-duration: 150ms; + --tw-ease: var(--ease-in-out); + &:hover { + @media (hover: hover) { + --tw-scale-x: 125%; + --tw-scale-y: 125%; + --tw-scale-z: 125%; + scale: var(--tw-scale-x) var(--tw-scale-y); + } + cursor: grab; + box-shadow: 0 0 0 2px var(--range-color); + } + &:active { + --tw-scale-x: 125%; + --tw-scale-y: 125%; + --tw-scale-z: 125%; + scale: var(--tw-scale-x) var(--tw-scale-y); + cursor: grabbing; + box-shadow: 0 0 0 3px var(--range-color); + } + appearance: none; + box-sizing: border-box; + webkit-appearance: none; + color: var(--range-color); + border-color: var(--range-color); + border-style: solid; + border-width: var(--range-thumb-border-width); + height: var(--range-thumb-size); + width: var(--range-thumb-size); + } + &::-moz-range-thumb { + position: relative; + border-radius: calc(infinity * 1px); + background-color: var(--color-base-100); + --tw-shadow: 0 1px 3px 0 var(--tw-shadow-color, rgb(0 0 0 / 0.1)), 0 1px 2px -1px var(--tw-shadow-color, rgb(0 0 0 / 0.1)); + box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow); + transition-property: all; + transition-timing-function: var(--tw-ease, var(--default-transition-timing-function)); + transition-timing-function: var(--ease-in-out); + transition-duration: var(--tw-duration, var(--default-transition-duration)); + transition-duration: 150ms; + --tw-duration: 150ms; + --tw-ease: var(--ease-in-out); + top: 50%; + color: var(--range-color); + box-sizing: border-box; + border-color: var(--range-color); + border-style: solid; + border-width: var(--range-thumb-border-width); + height: var(--range-thumb-size); + width: var(--range-thumb-size); + &:hover { + cursor: grab; + box-shadow: 0 0 0 2px var(--range-color); + } + &:active { + cursor: grabbing; + box-shadow: 0 0 0 3px var(--range-color); + } + } + &:focus { + outline: none; + } + &.disabled { + pointer-events: none; + opacity: 50%; + } + &:disabled { + pointer-events: none; + opacity: 50%; + } + &[disabled] { + pointer-events: none; + opacity: 50%; + } + [dir="rtl"] &::-webkit-slider-thumb { + transform: scaleX(-1); + } + [dir="rtl"] &::-moz-range-thumb { + transform: scaleX(-1); + } + [dir="rtl"] &::-webkit-slider-runnable-track { + direction: rtl; + } + [dir="rtl"] &::-moz-range-track { + direction: rtl; + } +} +.tab { + .tabs-lifted > &:focus-visible { + border-end-end-radius: 0; + border-end-start-radius: 0; + } + position: relative; + display: inline-flex; + cursor: pointer; + appearance: none; + align-items: center; + justify-content: center; + text-align: center; + font-size: var(--text-base); + line-height: var(--tw-leading, var(--text-base--line-height)); + color: var(--color-base-content); + webkit-user-select: none; + user-select: none; + height: var(--size); + --size: calc(var(--size-field, 0.25rem) * 9.5); + --tab-p: 1rem; + --tab-bg: var(--color-base-100); + --tab-border-color: var(--color-base-content); + @supports (color: color-mix(in lab, red, red)) { + --tab-border-color: color-mix(in oklab, var(--color-base-content), #0000 90%); + } + padding-inline: var(--tab-p, 1rem); + &:focus, &:focus-visible { + --tw-outline-style: none; + outline-style: none; + } + &[disabled] { + pointer-events: none; + opacity: 40%; + } + @media (hover: hover) { + &[disabled]:hover { + pointer-events: none; + opacity: 40%; + } + } + .tabs-bordered > & { + border-color: var(--color-base-content); + @supports (color: color-mix(in lab, red, red)) { + border-color: color-mix(in oklab, var(--color-base-content) 10%, transparent); + } + @media (hover:hover) { + &:hover { + @media (hover: hover) { + border-color: var(--color-primary); + @supports (color: color-mix(in lab, red, red)) { + border-color: color-mix(in oklab, var(--color-primary) 30%, transparent); + } + } + } + } + @media (hover:hover) { + &:hover { + @media (hover: hover) { + color: var(--color-primary); + } + } + } + border-style: solid; + border-bottom-width: calc(var(--border, 1px) + 1px); + } + .tabs-lifted > & { + @media (hover:hover) { + &:hover { + @media (hover: hover) { + border-color: var(--color-primary); + @supports (color: color-mix(in lab, red, red)) { + border-color: color-mix(in oklab, var(--color-primary) 30%, transparent); + } + } + } + } + @media (hover:hover) { + &:hover { + @media (hover: hover) { + color: var(--color-primary); + } + } + } + border: var(--tab-border, 1px) solid transparent; + border-width: 0 0 var(--tab-border, 1px) 0; + border-radius: var(--radius-field, 0.375rem); + border-bottom-color: var(--tab-border-color); + padding-inline-start: var(--tab-p, 1rem); + padding-inline-end: var(--tab-p, 1rem); + padding-top: var(--tab-border, 1px); + } + .tabs-lifted > &.tab-active:not([disabled]) { + background-color: var(--tab-bg); + border-width: var(--tab-border, 1px) var(--tab-border, 1px) 0 var(--tab-border, 1px); + border-color: var(--tab-border-color); + border-end-start-radius: 0; + border-end-end-radius: 0; + padding-inline-start: calc(var(--tab-p, 1rem) - var(--tab-border, 1px)); + padding-inline-end: calc(var(--tab-p, 1rem) - var(--tab-border, 1px)); + padding-bottom: var(--tab-border, 1px); + padding-top: 0; + } + .tabs-lifted > &.tab-active:not([disabled]):before { + content: ""; + display: block; + position: absolute; + z-index: 1; + width: calc(100% + var(--radius-field, 0.375rem) * 2); + height: var(--radius-field, 0.375rem); + bottom: 0; + background-size: var(--radius-field, 0.375rem); + background-repeat: no-repeat; + background-position: top left, top right; + --tab-grad: calc(69% - var(--tab-border, 1px)); + --radius-start: radial-gradient( + circle at top left, + transparent var(--tab-grad), + var(--tab-border-color) calc(var(--tab-grad) + 0.25px), + var(--tab-border-color) calc(var(--tab-grad) + var(--tab-border, 1px)), + var(--tab-bg) calc(var(--tab-grad) + var(--tab-border, 1px) + 0.25px) + ); + --radius-end: radial-gradient( + circle at top right, + transparent var(--tab-grad), + var(--tab-border-color) calc(var(--tab-grad) + 0.25px), + var(--tab-border-color) calc(var(--tab-grad) + var(--tab-border, 1px)), + var(--tab-bg) calc(var(--tab-grad) + var(--tab-border, 1px) + 0.25px) + ); + background-image: var(--radius-start), var(--radius-end); + } + .tabs-lifted > &.tab-active:not([disabled]):first-child:before { + background-image: var(--radius-end); + background-position: top right; + } + .tabs-lifted > &.tab-active:not([disabled]):last-child:before { + background-image: var(--radius-start); + background-position: top left; + } + [dir="rtl"] .tabs-lifted > &.tab-active:not([disabled]):first-child:before { + background-image: var(--radius-start); + background-position: top left; + } + [dir="rtl"] .tabs-lifted > &.tab-active:not([disabled]):last-child:before { + background-image: var(--radius-end); + background-position: top right; + } + .tabs-xl :where(&) { + font-size: var(--text-xl); + line-height: var(--tw-leading, var(--text-xl--line-height)); + --size: calc(var(--size-field, 0.25rem) * 14); + --tab-p: 1.5rem; + } + .tabs-lg :where(&) { + font-size: var(--text-lg); + line-height: var(--tw-leading, var(--text-lg--line-height)); + --size: calc(var(--size-field, 0.25rem) * 11.5); + --tab-p: 1.25rem; + } + .tabs-md :where(&) { + font-size: var(--text-base); + line-height: var(--tw-leading, var(--text-base--line-height)); + --size: calc(var(--size-field, 0.25rem) * 9.5); + --tab-p: 1rem; + } + .tabs-sm :where(&) { + font-size: var(--text-sm); + line-height: var(--tw-leading, var(--text-sm--line-height)); + --size: calc(var(--size-field, 0.25rem) * 7.5); + --tab-p: 0.75rem; + } + .tabs-xs :where(&) { + font-size: var(--text-sm); + line-height: var(--tw-leading, var(--text-sm--line-height)); + --size: calc(var(--size-field, 0.25rem) * 6); + --tab-p: 0.5rem; + } +} +.btn { + display: inline-flex; + flex-shrink: 0; + cursor: pointer; + flex-wrap: nowrap; + align-items: center; + justify-content: center; + gap: calc(0.25rem * 2); + text-align: center; + vertical-align: middle; + font-size: var(--text-base); + line-height: var(--tw-leading, var(--text-base--line-height)); + --tw-font-weight: var(--font-weight-medium); + font-weight: var(--font-weight-medium); + text-decoration-line: none; + webkit-user-select: none; + user-select: none; + @media (prefers-reduced-motion: reduce) { + transition-property: none; + } + padding-inline: var(--btn-p); + color: var(--btn-fg); + height: var(--size); + outline-color: var(--btn-color, var(--color-neutral)); + @supports (color: color-mix(in lab, red, red)) { + outline-color: color-mix(in oklab, var(--btn-color, var(--color-neutral)) 30%, var(--color-base-100)); + } + transition-property: color, background-color, border-color, box-shadow; + transition-timing-function: cubic-bezier(0, 0, 0.96, 1.03); + transition-duration: 0.25s; + border-start-start-radius: var(--join-ss, var(--radius-field)); + border-start-end-radius: var(--join-se, var(--radius-field)); + border-end-start-radius: var(--join-es, var(--radius-field)); + border-end-end-radius: var(--join-ee, var(--radius-field)); + background-color: var(--btn-bg); + background-size: auto, calc(var(--noise) * 100%); + background-image: none, var(--btn-noise); + border: var(--border) solid var(--btn-border); + box-shadow: 0 0.5px 0 0.5px oklch(100% 0 0 / calc(var(--depth) * 8%)) inset, var(--btn-shadow); + --size: calc(var(--size-field, 0.25rem) * 9.5); + --btn-bg: var(--btn-color, var(--color-neutral)); + --btn-fg: var(--color-neutral-content); + --btn-p: 1rem; + --btn-border: var(--btn-bg); + @supports (color: color-mix(in lab, red, red)) { + --btn-border: color-mix(in oklab, var(--btn-bg), #000 calc(var(--depth) * 5%)); + } + --btn-shadow: 0px 1px 3px 0px var(--color-base-300), + 0px 1px 2px -1px var(--color-base-300); + @supports (color: color-mix(in lab, red, red)) { + --btn-shadow: 0px 1px 3px 0px color-mix(in oklab, var(--color-base-300) 40%, #0000), + 0px 1px 2px -1px color-mix(in oklab, var(--color-base-300) 40%, #0000); + } + --btn-noise: var(--fx-noise); + @media (hover: hover) { + &:hover { + --btn-bg: var(--btn-color, var(--color-neutral)); + @supports (color: color-mix(in lab, red, red)) { + --btn-bg: color-mix(in oklab, var(--btn-color, var(--color-neutral)) 90%, #000); + } + } + } + &:active:hover:not(.btn-active), &:active:focus:not(.btn-active) { + --tw-scale-x: 95%; + --tw-scale-y: 95%; + --tw-scale-z: 95%; + scale: var(--tw-scale-x) var(--tw-scale-y); + transition-property: transform, translate, scale, rotate; + transition-timing-function: var(--tw-ease, var(--default-transition-timing-function)); + transition-timing-function: ease-out; + transition-duration: var(--tw-duration, var(--default-transition-duration)); + transition-duration: 300ms; + --tw-duration: 300ms; + } + &:focus-visible { + --btn-bg: var(--btn-color, var(--color-neutral)); + @supports (color: color-mix(in lab, red, red)) { + --btn-bg: color-mix(in oklab, var(--btn-color, var(--color-neutral)), #000 10%); + } + outline-width: 2px; + outline-style: solid; + } + &:is(:disabled, [disabled], .btn-disabled) { + pointer-events: none; + opacity: 50%; + --tw-shadow: 0 0 #0000; + box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow); + } + &:is(input[type="checkbox"], input[type="radio"]) { + appearance: none; + &::after { + content: attr(aria-label); + } + &:checked { + background: var(--color-primary); + color: var(--color-primary-content); + outline-color: var(--color-primary); + --btn-shadow: 0 0 0 0 oklch(0% 0 0/0), 0 0 0 0 oklch(0% 0 0/0); + isolation: isolate; + } + } +} +.pin-input { + border-radius: var(--radius-field); + border-style: var(--tw-border-style); + border-width: 1px; + border-color: var(--color-base-content); + @supports (color: color-mix(in lab, red, red)) { + border-color: color-mix(in oklab, var(--color-base-content) 25%, transparent); + } + background-color: var(--color-base-100); + text-align: center; + font-size: var(--text-base); + line-height: var(--tw-leading, var(--text-base--line-height)); + &::placeholder { + color: var(--color-base-content); + @supports (color: color-mix(in lab, red, red)) { + color: color-mix(in oklab, var(--color-base-content) 80%, transparent); + } + } + height: var(--size); + width: var(--size); + transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; + --size: calc(var(--size-field, 0.25rem) * 9.5); + &:hover:not(:focus, :focus-within) { + border-color: var(--color-base-content); + @supports (color: color-mix(in lab, red, red)) { + border-color: color-mix(in oklab, var(--color-base-content) 60%, transparent); + } + } + &:focus, &:focus-within { + border-color: var(--color-primary); + --tw-shadow: 0 1px 2px 0 var(--tw-shadow-color, rgb(0 0 0 / 0.05)); + box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow); + --tw-shadow-color: var(--color-primary); + @supports (color: color-mix(in lab, red, red)) { + --tw-shadow-color: color-mix(in oklab, var(--color-primary) 30%, #0000); + } + outline: 1px solid var(--color-primary); + isolation: isolate; + } + &.disabled, &:disabled, &[disabled] { + pointer-events: none; + border-color: var(--color-base-content); + @supports (color: color-mix(in lab, red, red)) { + border-color: color-mix(in oklab, var(--color-base-content) 25%, transparent); + } + background-color: var(--color-base-content); + @supports (color: color-mix(in lab, red, red)) { + background-color: color-mix(in oklab, var(--color-base-content) 5%, transparent); + } + color: var(--color-base-content); + @supports (color: color-mix(in lab, red, red)) { + color: color-mix(in oklab, var(--color-base-content) 50%, transparent); + } + &::placeholder { + color: var(--color-base-content); + @supports (color: color-mix(in lab, red, red)) { + color: color-mix(in oklab, var(--color-base-content) 40%, transparent); + } + } + } +} +.dropdown-item { + clear: both; + display: flex; + width: 100%; + align-items: center; + column-gap: calc(0.25rem * 2); + border-radius: var(--radius-field); + background-color: transparent; + padding-inline: calc(0.25rem * 4); + padding-block: calc(0.25rem * 2.5); + color: var(--color-base-content); + text-decoration-line: none; + text-decoration-thickness: 0px; + text-align: inherit; + &:hover:not(.dropdown-active), &:focus:not(.dropdown-active), &:focus-within:not(.dropdown-active), &:focus-visible:not(.dropdown-active) { + background-color: var(--color-neutral); + @supports (color: color-mix(in lab, red, red)) { + background-color: color-mix(in oklab, var(--color-neutral) 10%, transparent); + } + --tw-outline-style: none; + outline-style: none; + } + &.dropdown-disabled, &:disabled, &[disabled] { + pointer-events: none; + background-color: var(--color-neutral); + @supports (color: color-mix(in lab, red, red)) { + background-color: color-mix(in oklab, var(--color-neutral) 5%, transparent); + } + color: var(--color-base-content); + @supports (color: color-mix(in lab, red, red)) { + color: color-mix(in oklab, var(--color-base-content) 50%, transparent); + } + } +} +.loading { + pointer-events: none; + display: inline-block; + aspect-ratio: 1 / 1; + background-color: currentColor; + vertical-align: middle; + width: calc(var(--size-selector, 0.25rem) * 6); + mask-size: 100%; + mask-repeat: no-repeat; + mask-position: center; + mask-image: url("data:image/svg+xml,%3Csvg width='24' height='24' stroke='%23000' viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cstyle%3E.spinner_V8m1%7Btransform-origin:center;animation:spinner_zKoa 2s linear infinite%7D.spinner_V8m1 circle%7Bstroke-linecap:round;animation:spinner_YpZS 1.5s ease-out infinite%7D%40keyframes spinner_zKoa%7B100%25%7Btransform:rotate(360deg)%7D%7D%40keyframes spinner_YpZS%7B0%25%7Bstroke-dasharray:0 150;stroke-dashoffset:0%7D47.5%25%7Bstroke-dasharray:42 150;stroke-dashoffset:-16%7D95%25%2C100%25%7Bstroke-dasharray:42 150;stroke-dashoffset:-59%7D%7D%3C%2Fstyle%3E%3Cg class='spinner_V8m1'%3E%3Ccircle cx='12' cy='12' r='9.5' fill='none' stroke-width='3'%3E%3C%2Fcircle%3E%3C%2Fg%3E%3C%2Fsvg%3E"); +} +.accordion-toggle { + width: 100%; + cursor: pointer; + padding-inline: calc(0.25rem * 5); + padding-block: calc(0.25rem * 4); + font-size: var(--text-lg); + line-height: var(--tw-leading, var(--text-lg--line-height)); + --tw-font-weight: var(--font-weight-medium); + font-weight: var(--font-weight-medium); + color: var(--color-base-content); + &:disabled { + pointer-events: none; + opacity: 50%; + } +} +.disabled { + .range& { + pointer-events: none; + opacity: 50%; + } +} +.disabled { + .carousel-prev& { + pointer-events: none; + } + .carousel-next& { + pointer-events: none; + } +} +.tooltip-content { + visibility: hidden; + position: absolute; + display: inline-block; + padding: calc(0.25rem * 2); + opacity: 0%; + transition-property: opacity; + transition-timing-function: var(--tw-ease, var(--default-transition-timing-function)); + transition-duration: var(--tw-duration, var(--default-transition-duration)); + width: max-content; + z-index: 20; +} +.collapse { + visibility: collapse; +} +.collapse { + &:not(td):not(tr):not(colgroup) { + visibility: visible; + } +} +.invisible { + visibility: hidden; +} +.table { + position: relative; + width: 100%; + overflow-x: hidden; + overflow-y: auto; + border-radius: var(--radius-box); + text-align: left; + font-size: var(--text-sm); + line-height: var(--tw-leading, var(--text-sm--line-height)); + &:where(:dir(rtl), [dir="rtl"], [dir="rtl"] *) { + text-align: right; + } + tr.row-hover { + &, &:nth-child(even) { + &:hover { + @media (hover: hover) { + background-color: var(--color-base-200); + @supports (color: color-mix(in lab, red, red)) { + background-color: color-mix(in oklab, var(--color-base-200) 80%, transparent); + } + } + } + } + } + tr.row-active { + &, &:nth-child(even) { + background-color: var(--color-base-200); + } + } + :where(th, td) { + padding-inline: calc(0.25rem * 5); + padding-block: calc(0.25rem * 3); + vertical-align: middle; + text-wrap: nowrap; + } + :where(thead, tfoot) { + font-size: var(--text-sm); + line-height: var(--tw-leading, var(--text-sm--line-height)); + white-space: nowrap; + color: var(--color-base-content); + text-transform: uppercase; + letter-spacing: 1px; + } + :where(th) { + --tw-font-weight: var(--font-weight-medium); + font-weight: var(--font-weight-medium); + } + :where(.table-pin-rows thead tr) { + position: sticky; + top: calc(0.25rem * 0); + z-index: 1; + background-color: var(--color-base-100); + } + :where(.table-pin-rows tfoot tr) { + position: sticky; + bottom: calc(0.25rem * 0); + z-index: 1; + background-color: var(--color-base-100); + } + :where(.table-pin-cols tr th) { + position: sticky; + right: calc(0.25rem * 0); + left: calc(0.25rem * 0); + background-color: var(--color-base-100); + } + :where(thead tr) { + border-bottom: var(--border) solid var(--color-base-content); + @supports (color: color-mix(in lab, red, red)) { + border-bottom: var(--border) solid color-mix(in oklch, var(--color-base-content) 25%, #0000); + } + } + :where(tbody tr:not(:last-child)) { + border-bottom: var(--border) solid var(--color-base-content); + @supports (color: color-mix(in lab, red, red)) { + border-bottom: var(--border) solid color-mix(in oklch, var(--color-base-content) 10%, #0000); + } + } + :where(tfoot) { + border-top: var(--border) solid var(--color-base-content); + @supports (color: color-mix(in lab, red, red)) { + border-top: var(--border) solid color-mix(in oklch, var(--color-base-content) 25%, #0000); + } + } +} +.select { + position: relative; + display: inline-flex; + width: 100%; + flex-shrink: 1; + cursor: pointer; + appearance: none; + background-color: var(--color-base-100); + padding-inline-start: calc(0.25rem * 3); + padding-inline-end: calc(0.25rem * 10); + vertical-align: middle; + font-size: var(--text-base); + line-height: var(--tw-leading, var(--text-base--line-height)); + color: var(--color-base-content); + webkit-user-select: none; + user-select: none; + height: var(--size); + border-start-start-radius: var(--join-ss, var(--radius-field)); + border-start-end-radius: var(--join-se, var(--radius-field)); + border-end-start-radius: var(--join-es, var(--radius-field)); + border-end-end-radius: var(--join-ee, var(--radius-field)); + background-image: url("data:image/svg+xml;utf8,"); + background-size: 1.3em; + background-position: calc(100% - 0.5rem) center; + background-repeat: no-repeat; + touch-action: manipulation; + text-overflow: ellipsis; + border: var(--border) solid #0000; + border-color: var(--input-color); + --input-color: var(--color-base-content); + @supports (color: color-mix(in lab, red, red)) { + --input-color: color-mix(in oklab, var(--color-base-content) 40%, #0000); + } + --size: calc(var(--size-field, 0.25rem) * 9.5); + &:hover:not(:focus, :focus-within), &:has(:hover):not(:focus, :focus-within) { + border-color: var(--color-base-content); + @supports (color: color-mix(in lab, red, red)) { + border-color: color-mix(in oklab, var(--color-base-content) 60%, transparent); + } + } + [dir="rtl"] & { + background-position: calc(0% + 1.3em) center; + } + select { + margin-inline-end: calc(0.25rem * -10); + height: 100%; + width: calc(100% + 2.75rem); + appearance: none; + padding-inline-start: calc(0.25rem * 3); + padding-inline-end: calc(0.25rem * 10); + background-color: transparent; + border-style: none; + &:focus, &:focus-within { + --tw-outline-style: none; + outline-style: none; + } + } + &[multiple] { + background-image: none; + } + &:focus, &:focus-within { + --tw-shadow: 0 1px 2px 0 var(--tw-shadow-color, rgb(0 0 0 / 0.05)); + box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow); + --input-color: var(--color-primary); + --tw-shadow-color: var(--input-color); + @supports (color: color-mix(in lab, red, red)) { + --tw-shadow-color: color-mix(in oklab, var(--input-color) 30%, #0000); + } + outline: 1px solid var(--input-color); + border-color: var(--input-color); + isolation: isolate; + } + &:has(> select[disabled]), &:is(:disabled, [disabled]) { + cursor: not-allowed; + border-style: var(--tw-border-style); + border-width: 0px; + border-color: var(--color-base-content); + @supports (color: color-mix(in lab, red, red)) { + border-color: color-mix(in oklab, var(--color-base-content) 10%, transparent); + } + background-color: var(--color-neutral); + @supports (color: color-mix(in lab, red, red)) { + background-color: color-mix(in oklab, var(--color-neutral) 10%, transparent); + } + color: var(--color-base-content); + @supports (color: color-mix(in lab, red, red)) { + color: color-mix(in oklab, var(--color-base-content) 50%, transparent); + } + &::placeholder { + color: var(--color-base-content); + @supports (color: color-mix(in lab, red, red)) { + color: color-mix(in oklab, var(--color-base-content) 50%, transparent); + } + } + } + &:has(> select[disabled]) > select[disabled] { + cursor: not-allowed; + } + .input > & { + height: auto; + border-style: var(--tw-border-style); + border-width: 0px; + &:focus, &:focus-within { + --tw-shadow: 0 0 #0000; + box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow); + outline-style: var(--tw-outline-style); + outline-width: 0px; + } + } + &:has(> .select-floating) select { + &::placeholder { + color: transparent; + } + &:focus { + &::placeholder { + color: var(--color-base-content); + @supports (color: color-mix(in lab, red, red)) { + color: color-mix(in oklab, var(--color-base-content) 50%, transparent); + } + } + } + } +} +.avatar { + position: relative; + display: inline-flex; + vertical-align: middle; + font-size: var(--text-base); + line-height: var(--tw-leading, var(--text-base--line-height)); + & > div { + display: block; + aspect-ratio: 1 / 1; + overflow: hidden; + } + & > span { + display: block; + aspect-ratio: 1 / 1; + overflow: hidden; + } + :where(&) img { + height: 100%; + width: 100%; + object-fit: cover; + } +} +.checkbox { + position: relative; + flex-shrink: 0; + cursor: pointer; + appearance: none; + border-radius: var(--radius-selector); + padding: calc(0.25rem * 1); + vertical-align: middle; + color: var(--color-neutral-content); + border: var(--border) solid var(--color-base-content); + @supports (color: color-mix(in lab, red, red)) { + border: var(--border) solid color-mix(in oklab, var(--color-base-content) 40%, #0000); + } + --input-color: var(--color-neutral); + box-shadow: 0 1px oklch(0% 0 0 / calc(var(--depth) * 0.1)) inset, 0 0 #0000 inset, 0 0 #0000; + transition: background-color 0.2s, box-shadow 0.2s; + --size: calc(var(--size-selector, 0.25rem) * 6); + width: var(--size); + height: var(--size); + background-size: auto, calc(var(--noise) * 100%); + background-image: none, var(--fx-noise); + &:before { + --tw-content: ""; + content: var(--tw-content); + display: block; + width: 100%; + height: 100%; + rotate: 45deg; + background-color: currentColor; + opacity: 0%; + transition: clip-path 0.3s, opacity 0.1s, rotate 0.3s, translate 0.3s; + transition-delay: 0.1s; + clip-path: polygon(20% 100%, 20% 80%, 50% 80%, 50% 80%, 70% 80%, 70% 100%); + box-shadow: 0px 3px 0 0px oklch(100% 0 0 / calc(var(--depth) * 0.1)) inset; + font-size: 1rem; + line-height: 0.75; + } + &:focus-visible { + outline: 2px solid var(--input-color, var(--color-neutral)); + @supports (color: color-mix(in lab, red, red)) { + outline: 2px solid color-mix(in oklab, var(--input-color, var(--color-neutral)) 30%, #0000); + } + outline-offset: 0px; + } + &:checked, &[aria-checked="true"] { + background-color: var(--input-color, #0000); + border-color: var(--input-color, #0000); + box-shadow: 0 0 #0000 inset, 0 8px 0 -4px oklch(100% 0 0 / calc(var(--depth) * 0.1)) inset, 0 1px 2px 0 var(--color-base-300); + @supports (color: color-mix(in lab, red, red)) { + box-shadow: 0 0 #0000 inset, 0 8px 0 -4px oklch(100% 0 0 / calc(var(--depth) * 0.1)) inset, 0 1px 2px 0 color-mix(in oklab, var(--color-base-300) 20%, #0000); + } + &:before { + clip-path: polygon(20% 100%, 20% 80%, 50% 80%, 50% 0%, 70% 0%, 70% 100%); + opacity: 100%; + } + @media (forced-colors: active) { + &:before { + rotate: 0deg; + background-color: transparent; + --tw-content: "✔︎"; + clip-path: none; + } + } + @media print { + &:before { + rotate: 0deg; + background-color: transparent; + --tw-content: "✔︎"; + clip-path: none; + } + } + } + &:indeterminate { + background-color: var(--color-neutral); + &:before { + rotate: 0deg; + opacity: 100%; + translate: 0 -35%; + clip-path: polygon(20% 100%, 20% 80%, 50% 80%, 50% 80%, 80% 80%, 80% 100%); + } + } + &:disabled { + cursor: not-allowed; + opacity: 50%; + } +} +.carousel { + position: relative; + width: 100%; + overflow: hidden; + border-radius: var(--radius-2xl); +} .absolute { position: absolute; } +.fixed { + position: fixed; +} +.relative { + position: relative; +} +.static { + position: static; +} +.sticky { + position: sticky; +} .top-\[0\] { top: 0; } +.top-full { + top: 100%; +} .right-\[0\] { right: 0; } +.bottom-full { + bottom: 100%; +} +.input { + display: inline-flex; + width: 100%; + flex-shrink: 1; + cursor: text; + appearance: none; + background-color: var(--color-base-100); + padding-inline: calc(0.25rem * 3); + font-size: var(--text-base); + line-height: var(--tw-leading, var(--text-base--line-height)); + --tw-font-weight: var(--font-weight-normal); + font-weight: var(--font-weight-normal); + color: var(--color-base-content); + &::placeholder { + color: var(--color-base-content); + @supports (color: color-mix(in lab, red, red)) { + color: color-mix(in oklab, var(--color-base-content) 50%, transparent); + } + } + &:focus-visible { + --tw-outline-style: none; + outline-style: none; + } + border: var(--border) solid #0000; + height: var(--size); + touch-action: manipulation; + border-start-start-radius: var(--join-ss, var(--radius-field)); + border-start-end-radius: var(--join-se, var(--radius-field)); + border-end-start-radius: var(--join-es, var(--radius-field)); + border-end-end-radius: var(--join-ee, var(--radius-field)); + border-color: var(--input-color); + --input-color: var(--color-base-content); + @supports (color: color-mix(in lab, red, red)) { + --input-color: color-mix(in oklab, var(--color-base-content) 40%, #0000); + } + --size: calc(var(--size-field, 0.25rem) * 9.5); + &:hover:not(:focus, :focus-within), &:has(:hover):not(:focus, :focus-within) { + border-color: var(--color-base-content); + @supports (color: color-mix(in lab, red, red)) { + border-color: color-mix(in oklab, var(--color-base-content) 60%, transparent); + } + } + &:where(input) { + display: inline-block; + } + :where(input:not([type="checkbox"]):not([type="radio"])) { + display: inline-block; + height: 100%; + width: 100%; + appearance: none; + background-color: transparent; + border: none; + &:focus, &:focus-within, &:focus-visible { + --tw-outline-style: none; + outline-style: none; + } + } + &:focus, &:focus-within { + --tw-shadow: 0 1px 2px 0 var(--tw-shadow-color, rgb(0 0 0 / 0.05)); + box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow); + --input-color: var(--color-primary); + --tw-shadow-color: var(--input-color); + @supports (color: color-mix(in lab, red, red)) { + --tw-shadow-color: color-mix(in oklab, var(--input-color) 30%, #0000); + } + outline: 1px solid var(--input-color); + isolation: isolate; + } + &:has(> input[disabled]), &:is(:disabled, [disabled]) { + cursor: not-allowed; + border-style: var(--tw-border-style); + border-width: 0px; + background-color: var(--color-neutral); + @supports (color: color-mix(in lab, red, red)) { + background-color: color-mix(in oklab, var(--color-neutral) 10%, transparent); + } + color: var(--color-base-content); + @supports (color: color-mix(in lab, red, red)) { + color: color-mix(in oklab, var(--color-base-content) 50%, transparent); + } + box-shadow: none; + } + &:has(> input[disabled]) > input[disabled] { + cursor: not-allowed; + } + &::-webkit-date-and-time-value { + text-align: inherit; + } + &[type="number"] { + &::-webkit-inner-spin-button { + margin-block: calc(0.25rem * -3); + margin-inline-end: calc(0.25rem * -3); + } + } + &:has(> .input-floating) input { + &::placeholder { + color: transparent; + } + &:focus { + &::placeholder { + color: var(--color-base-content); + @supports (color: color-mix(in lab, red, red)) { + color: color-mix(in oklab, var(--color-base-content) 50%, transparent); + } + } + } + } +} +.textarea { + display: inline-flex; + min-height: calc(0.25rem * 20); + width: 100%; + flex-shrink: 1; + appearance: none; + border-radius: var(--radius-field); + background-color: var(--color-base-100); + padding-inline: calc(0.25rem * 4); + padding-block: calc(0.25rem * 2); + font-size: var(--text-base); + line-height: var(--tw-leading, var(--text-base--line-height)); + color: var(--color-base-content); + &::placeholder { + color: var(--color-base-content); + @supports (color: color-mix(in lab, red, red)) { + color: color-mix(in oklab, var(--color-base-content) 50%, transparent); + } + } + &:hover { + @media (hover: hover) { + border-color: var(--color-base-content); + @supports (color: color-mix(in lab, red, red)) { + border-color: color-mix(in oklab, var(--color-base-content) 60%, transparent); + } + } + } + &:focus-visible { + --tw-outline-style: none; + outline-style: none; + } + border: var(--border) solid #0000; + border-color: var(--input-color); + touch-action: manipulation; + --input-color: var(--color-base-content); + @supports (color: color-mix(in lab, red, red)) { + --input-color: color-mix(in oklab, var(--color-base-content) 40%, #0000); + } + :where(textarea) { + appearance: none; + background-color: transparent; + border: none; + &:focus, &:focus-within { + --tw-outline-style: none; + outline-style: none; + } + } + &:focus, &:focus-within { + --tw-shadow: 0 1px 2px 0 var(--tw-shadow-color, rgb(0 0 0 / 0.05)); + box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow); + --input-color: var(--color-primary); + --tw-shadow-color: var(--input-color); + @supports (color: color-mix(in lab, red, red)) { + --tw-shadow-color: color-mix(in oklab, var(--input-color) 30%, #0000); + } + outline: 1px solid var(--input-color); + border-color: var(--input-color); + isolation: isolate; + } + &:has(> textarea[disabled]), &:is(:disabled, [disabled]) { + cursor: not-allowed; + border-color: var(--color-base-200); + background-color: var(--color-base-200); + color: var(--color-base-content); + @supports (color: color-mix(in lab, red, red)) { + color: color-mix(in oklab, var(--color-base-content) 40%, transparent); + } + &::placeholder { + color: var(--color-base-content); + @supports (color: color-mix(in lab, red, red)) { + color: color-mix(in oklab, var(--color-base-content) 20%, transparent); + } + } + } + &:has(> textarea[disabled]) > textarea[disabled] { + cursor: not-allowed; + } + &:has(> textarea) { + padding: calc(0.25rem * 0); + textarea { + height: auto; + min-height: calc(0.25rem * 20); + width: 100%; + &:first-child { + padding-block: calc(0.25rem * 2); + padding-inline-start: calc(0.25rem * 4); + } + &:nth-child(2) { + padding-block: calc(0.25rem * 2); + } + &:last-child { + padding-block: calc(0.25rem * 2); + padding-inline-end: calc(0.25rem * 4); + } + } + } + &:has(> .textarea-floating) { + padding: calc(0.25rem * 0); + :where(.textarea-floating:first-child) > textarea { + padding-block: calc(0.25rem * 2); + padding-inline-start: calc(0.25rem * 4); + } + :where(.textarea-floating:nth-child(2)) > textarea { + padding-block: calc(0.25rem * 2); + } + :where(.textarea-floating:last-child) > textarea { + padding-block: calc(0.25rem * 2); + padding-inline-end: calc(0.25rem * 4); + } + :where(.textarea-floating:nth-child(2)) .textarea-floating-label, :where(.textarea-floating:last-child) .textarea-floating-label { + margin-inline-start: calc(0.25rem * 0); + } + & * > textarea { + width: 100%; + height: 100%; + min-height: calc(0.25rem * 20); + } + } + &:has(> .textarea-floating) textarea { + &::placeholder { + color: transparent; + } + &:focus { + &::placeholder { + color: var(--color-base-content); + @supports (color: color-mix(in lab, red, red)) { + color: color-mix(in oklab, var(--color-base-content) 50%, transparent); + } + } + } + } +} +.dropdown-menu { + z-index: 10; + margin-top: calc(0.25rem * 2); + :where(& > :not(:last-child)) { + --tw-space-y-reverse: 0; + margin-block-start: calc(calc(0.25rem * 1) * var(--tw-space-y-reverse)); + margin-block-end: calc(calc(0.25rem * 1) * calc(1 - var(--tw-space-y-reverse))); + } + border-radius: var(--radius-box); + background-color: var(--color-base-100); + padding: calc(0.25rem * 2); + font-size: var(--text-base); + line-height: var(--tw-leading, var(--text-base--line-height)); + text-wrap: nowrap; + opacity: 0%; + --tw-shadow: 0 4px 6px -1px var(--tw-shadow-color, rgb(0 0 0 / 0.1)), 0 2px 4px -2px var(--tw-shadow-color, rgb(0 0 0 / 0.1)); + box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow); + --tw-shadow-color: var(--color-base-300); + @supports (color: color-mix(in lab, red, red)) { + --tw-shadow-color: color-mix(in oklab, color-mix(in oklab, var(--color-base-300) 20%, transparent) var(--tw-shadow-alpha), transparent); + } + transition-property: opacity,margin; + transition-timing-function: var(--tw-ease, var(--default-transition-timing-function)); + transition-duration: var(--tw-duration, var(--default-transition-duration)); + transition-duration: 300ms; + --tw-duration: 300ms; +} +.container { + width: 100%; +} .m-\[0px\] { margin: 0px; } .m-\[20px\] { margin: 20px; } +.filter { + display: flex; + flex-wrap: wrap; + input[type="radio"] { + width: auto; + } + input { + overflow: hidden; + opacity: 100%; + scale: 1; + border-width: 0; + transition: margin 0.1s, opacity 0.3s, padding 0.3s, border-width 0.1s; + &:not(:last-child) { + margin-inline-end: calc(0.25rem * 1); + } + &.filter-reset { + aspect-ratio: 1 / 1; + &::after { + content: "×"; + } + } + } + &:not(:has(input:checked:not(.filter-reset))) { + .filter-reset, input[type="reset"] { + scale: 0; + border-width: 0; + margin-inline: calc(0.25rem * 0); + width: calc(0.25rem * 0); + padding-inline: calc(0.25rem * 0); + opacity: 0%; + } + } + &:has(input:checked:not(.filter-reset)) { + input:not(:checked, .filter-reset, input[type="reset"]) { + scale: 0; + border-width: 0; + margin-inline: calc(0.25rem * 0); + width: calc(0.25rem * 0); + padding-inline: calc(0.25rem * 0); + opacity: 0%; + } + } +} +.\!ms-auto { + margin-inline-start: auto !important; +} +.input { + &::file-selector-button { + margin-inline-end: calc(0.25rem * 4); + display: inline-flex; + height: 100%; + flex-shrink: 0; + cursor: pointer; + flex-wrap: wrap; + align-items: center; + justify-content: center; + border-style: var(--tw-border-style); + border-width: 0px; + background-color: var(--color-primary); + padding-inline: calc(0.25rem * 4); + text-align: center; + font-size: var(--text-base); + line-height: var(--tw-leading, var(--text-base--line-height)); + --tw-leading: 1; + --tw-font-weight: var(--font-weight-semibold); + font-weight: var(--font-weight-semibold); + color: var(--color-primary-content); + text-transform: uppercase; + text-decoration-line: none; + webkit-user-select: none; + user-select: none; + --input-color: var(--color-primary); + &.input-sm { + font-size: var(--text-sm); + line-height: var(--tw-leading, var(--text-sm--line-height)); + } + &.input-md { + font-size: var(--text-base); + line-height: var(--tw-leading, var(--text-base--line-height)); + } + &.input-lg { + font-size: var(--text-lg); + line-height: var(--tw-leading, var(--text-lg--line-height)); + } + &.input-xl { + font-size: var(--text-xl); + line-height: var(--tw-leading, var(--text-xl--line-height)); + } + } + &[type="file"] { + overflow: hidden; + padding-inline-start: calc(0.25rem * 0); + } + .input-floating &::file-selector-button { + background-color: var(--color-base-100); + color: var(--color-base-content); + border-inline-end: var(--border) solid var(--color-base-content); + @supports (color: color-mix(in lab, red, red)) { + border-inline-end: var(--border) solid color-mix(in oklab, var(--color-base-content) 40%, #0000); + } + outline: none; + } +} +.mt-\[-2px\] { + margin-top: -2px; +} +.mt-\[-3px\] { + margin-top: -3px; +} +.mt-\[-5px\] { + margin-top: -5px; +} +.mt-\[-6px\] { + margin-top: -6px; +} +.mt-\[10px\] { + margin-top: 10px; +} .mr-\[5px\] { margin-right: 5px; } @@ -30,30 +1482,266 @@ .mr-\[25px\] { margin-right: 25px; } +.mb-\[15px\] { + margin-bottom: 15px; +} .mb-\[20px\] { margin-bottom: 20px; } .mb-\[25px\] { margin-bottom: 25px; } +.ml-\[5px\] { + margin-left: 5px; +} +.ml-\[10px\] { + margin-left: 10px; +} +.status { + display: inline-block; + aspect-ratio: 1 / 1; + width: calc(0.25rem * 2.5); + height: calc(0.25rem * 2.5); + border-radius: calc(infinity * 1px); + background-color: var(--color-neutral); + background-position: center; + background-repeat: no-repeat; + vertical-align: middle; + color: var(--color-neutral); + background-image: radial-gradient(circle at 35% 30%, oklch(1 0 0 / calc(var(--depth) * 0.5)), #0000); + box-shadow: 0 2px 3px -1px currentColor; + @supports (color: color-mix(in lab, red, red)) { + box-shadow: 0 2px 3px -1px color-mix(in oklab, currentColor calc(var(--depth) * 100%), #0000); + } +} +.divider { + display: flex; + width: 100%; + align-items: center; + align-self: stretch; + font-size: var(--text-sm); + line-height: var(--tw-leading, var(--text-sm--line-height)); + white-space: nowrap; + &:not(:empty) { + gap: calc(0.25rem * 4); + } + &:before { + content: ""; + height: 1px; + width: 100%; + flex-grow: 1; + border-inline-end-style: var(--tw-border-style); + border-inline-end-width: 0px; + border-top-style: var(--tw-border-style); + border-top-width: 1px; + --tw-border-style: solid; + border-style: solid; + border-color: var(--color-base-content); + @supports (color: color-mix(in lab, red, red)) { + border-color: color-mix(in oklab, var(--color-base-content) 20%, transparent); + } + } + &:after { + content: ""; + height: 1px; + width: 100%; + flex-grow: 1; + border-inline-end-style: var(--tw-border-style); + border-inline-end-width: 0px; + border-top-style: var(--tw-border-style); + border-top-width: 1px; + --tw-border-style: solid; + border-style: solid; + border-color: var(--color-base-content); + @supports (color: color-mix(in lab, red, red)) { + border-color: color-mix(in oklab, var(--color-base-content) 20%, transparent); + } + } +} +.progress { + display: flex; + height: calc(0.25rem * 1.5); + width: 100%; + overflow: hidden; + border-radius: var(--radius-box); + background-color: var(--color-base-200); +} +.icon-\[tabler--trending-down\] { + display: inline-block; + width: 1em; + height: 1em; + background-color: currentColor; + -webkit-mask-image: var(--svg); + mask-image: var(--svg); + -webkit-mask-repeat: no-repeat; + mask-repeat: no-repeat; + -webkit-mask-size: 100% 100%; + mask-size: 100% 100%; + --svg: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' width='24' height='24'%3E%3Cg fill='none' stroke='black' stroke-linecap='round' stroke-linejoin='round' stroke-width='2'%3E%3Cpath d='m3 7l6 6l4-4l8 8'/%3E%3Cpath d='M21 10v7h-7'/%3E%3C/g%3E%3C/svg%3E"); +} +.icon-\[tabler--trending-up\] { + display: inline-block; + width: 1em; + height: 1em; + background-color: currentColor; + -webkit-mask-image: var(--svg); + mask-image: var(--svg); + -webkit-mask-repeat: no-repeat; + mask-repeat: no-repeat; + -webkit-mask-size: 100% 100%; + mask-size: 100% 100%; + --svg: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' width='24' height='24'%3E%3Cg fill='none' stroke='black' stroke-linecap='round' stroke-linejoin='round' stroke-width='2'%3E%3Cpath d='m3 17l6-6l4 4l8-8'/%3E%3Cpath d='M14 7h7v7'/%3E%3C/g%3E%3C/svg%3E"); +} +.tabs { + display: flex; + --tabs-height: auto; + --tabs-direction: row; + height: var(--tabs-height); + flex-direction: var(--tabs-direction); +} +.progress-bar { + display: flex; + align-items: center; + justify-content: center; + overflow: hidden; + border-radius: var(--radius-box); + background-color: var(--color-neutral); + font-size: var(--text-xs); + line-height: var(--tw-leading, var(--text-xs--line-height)); + --tw-font-weight: var(--font-weight-medium); + font-weight: var(--font-weight-medium); + white-space: nowrap; + color: var(--color-neutral-content); + transition-property: color, background-color, border-color, outline-color, text-decoration-color, fill, stroke, --tw-gradient-from, --tw-gradient-via, --tw-gradient-to, opacity, box-shadow, transform, translate, scale, rotate, filter, -webkit-backdrop-filter, backdrop-filter; + transition-timing-function: var(--tw-ease, var(--default-transition-timing-function)); + transition-timing-function: var(--ease-in-out); + transition-duration: var(--tw-duration, var(--default-transition-duration)); + transition-duration: 500ms; + --tw-duration: 500ms; + --tw-ease: var(--ease-in-out); + &.progress-indeterminate { + width: 100%; + background: linear-gradient(90deg, rgba(0, 0, 0, 0) 50%, var(--progress-color) 50%); + background-size: 50% 100%; + background-repeat: no-repeat; + animation: indeterminate-progress 4s infinite ease-in-out; + } +} +.stats { + display: inline-grid; + grid-auto-flow: column; + :where(& > :not(:last-child)) { + --tw-divide-x-reverse: 0; + border-inline-style: var(--tw-border-style); + border-inline-start-width: calc(1px * var(--tw-divide-x-reverse)); + border-inline-end-width: calc(1px * calc(1 - var(--tw-divide-x-reverse))); + --tw-divide-y-reverse: 0; + border-bottom-style: var(--tw-border-style); + border-top-style: var(--tw-border-style); + border-top-width: calc(0px * var(--tw-divide-y-reverse)); + border-bottom-width: calc(0px * calc(1 - var(--tw-divide-y-reverse))); + } + overflow-x: auto; + border-radius: var(--radius-box); + --tw-border-style: solid; + border-style: solid; + border-color: var(--color-base-content); + @supports (color: color-mix(in lab, red, red)) { + border-color: color-mix(in oklab, var(--color-base-content) 20%, transparent); + } + background-color: var(--color-base-100); + box-shadow: var( --card-shadow, 0 1px 3px 0 var(--color-base-300), 0 1px 2px -1px var(--color-base-300) ); + @supports (color: color-mix(in lab, red, red)) { + box-shadow: var( --card-shadow, 0 1px 3px 0 color-mix(in oklab, var(--color-base-300) 20%, #0000), 0 1px 2px -1px color-mix(in oklab, var(--color-base-300) 20%, #0000) ); + } + border-width: var(--card-border, 0px); + &:where(.stats-border) { + border: var(--border) solid var(--color-base-content); + @supports (color: color-mix(in lab, red, red)) { + border: var(--border) solid color-mix(in oklab, var(--color-base-content) 20%, transparent); + } + } +} +.carousel-body { + display: flex; + flex-wrap: nowrap; + transition-property: transform, translate, scale, rotate; + transition-timing-function: var(--tw-ease, var(--default-transition-timing-function)); + transition-duration: var(--tw-duration, var(--default-transition-duration)); + transition-duration: 700ms; + --tw-duration: 700ms; +} +.tooltip { + display: inline-block; + text-align: center; +} +.\!flex { + display: flex !important; +} +.block { + display: block; +} +.contents { + display: contents; +} .flex { display: flex; } +.hidden { + display: none; +} +.inline { + display: inline; +} +.inline-block { + display: inline-block; +} +.table { + display: table; +} +.btn-circle { + border-radius: calc(infinity * 1px); + padding-inline: calc(0.25rem * 0); + width: var(--size); + height: var(--size); +} +.input { + & > .select { + height: auto; + border-style: var(--tw-border-style); + border-width: 0px; + &:focus, &:focus-within { + --tw-shadow: 0 0 #0000; + box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow); + outline-style: var(--tw-outline-style); + outline-width: 0px; + } + } +} +.h-\[30px\] { + height: 30px; +} +.h-\[60px\] { + height: 60px; +} +.max-h-\[18px\] { + max-height: 18px; +} .max-h-\[20px\] { max-height: 20px; } .max-h-\[22px\] { max-height: 22px; } -.max-h-\[24px\] { - max-height: 24px; -} .max-h-\[25px\] { max-height: 25px; } .max-h-\[30px\] { max-height: 30px; } +.max-h-\[60px\] { + max-height: 60px; +} .max-h-\[70px\] { max-height: 70px; } @@ -63,72 +1751,630 @@ .min-h-screen { min-height: 100vh; } +.advance-select-option { + width: 100%; + cursor: pointer; + border-radius: var(--radius-field); + padding-inline: calc(0.25rem * 4); + padding-block: calc(0.25rem * 2.5); + font-size: var(--text-base); + line-height: var(--tw-leading, var(--text-base--line-height)); + --tw-font-weight: var(--font-weight-normal); + font-weight: var(--font-weight-normal); + color: var(--color-base-content); + &:hover { + @media (hover: hover) { + background-color: var(--color-neutral); + @supports (color: color-mix(in lab, red, red)) { + background-color: color-mix(in oklab, var(--color-neutral) 10%, transparent); + } + } + } + &:focus { + background-color: var(--color-neutral); + @supports (color: color-mix(in lab, red, red)) { + background-color: color-mix(in oklab, var(--color-neutral) 10%, transparent); + } + --tw-outline-style: none; + outline-style: none; + } +} +.w-\[30px\] { + width: 30px; +} +.w-\[60px\] { + width: 60px; +} .w-full { width: 100%; } +.max-w-\[18px\] { + max-width: 18px; +} .max-w-\[20px\] { max-width: 20px; } .max-w-\[22px\] { max-width: 22px; } -.max-w-\[24px\] { - max-width: 24px; -} .max-w-\[25px\] { max-width: 25px; } -.max-w-\[30px\] { - max-width: 30px; +.max-w-\[30px\] { + max-width: 30px; +} +.max-w-\[60px\] { + max-width: 60px; +} +.max-w-\[70px\] { + max-width: 70px; +} +.max-w-\[100px\] { + max-width: 100px; +} +.max-w-full { + max-width: 100%; +} +.min-w-\[30px\] { + min-width: 30px; +} +.flex-1 { + flex: 1; +} +.shrink-0 { + flex-shrink: 0; +} +.transform { + transform: var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,); +} +.cursor-pointer { + cursor: pointer; +} +.resize { + resize: both; +} +.flex-col { + flex-direction: column; +} +.flex-row { + flex-direction: row; +} +.flex-nowrap { + flex-wrap: nowrap; +} +.items-center { + align-items: center; +} +.items-end { + align-items: flex-end; +} +.\!justify-between { + justify-content: space-between !important; +} +.justify-between { + justify-content: space-between; +} +.justify-center { + justify-content: center; +} +.justify-end { + justify-content: flex-end; +} +.accordion { + &:where(.accordion-bordered) { + :where(& > :not(:last-child)) { + --tw-divide-y-reverse: 0; + border-bottom-style: var(--tw-border-style); + border-top-style: var(--tw-border-style); + border-top-width: calc(1px * var(--tw-divide-y-reverse)); + border-bottom-width: calc(1px * calc(1 - var(--tw-divide-y-reverse))); + border-color: var(--color-base-content); + @supports (color: color-mix(in lab, red, red)) { + border-color: color-mix(in oklab, var(--color-base-content) 25%, transparent); + } + } + border-radius: var(--radius-box); + border-style: var(--tw-border-style); + border-width: 1px; + border-color: var(--color-base-content); + @supports (color: color-mix(in lab, red, red)) { + border-color: color-mix(in oklab, var(--color-base-content) 25%, transparent); + } + background-color: var(--color-base-100); + } +} +.truncate { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} +.overflow-x-auto { + overflow-x: auto; +} +.overflow-y-auto { + overflow-y: auto; +} +.collapse { + :where(.menu-horizontal > li:not(.menu-title) > & > ul) { + border-radius: var(--radius-box); + background-color: var(--color-base-100); + --tw-shadow: 0 1px 3px 0 var(--tw-shadow-color, rgb(0 0 0 / 0.1)), 0 1px 2px -1px var(--tw-shadow-color, rgb(0 0 0 / 0.1)); + box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow); + --tw-shadow-color: var(--color-base-300); + @supports (color: color-mix(in lab, red, red)) { + --tw-shadow-color: color-mix(in oklab, color-mix(in oklab, var(--color-base-300) 20%, transparent) var(--tw-shadow-alpha), transparent); + } + } +} +.\!rounded-full { + border-radius: calc(infinity * 1px) !important; +} +.rounded-box { + border-radius: var(--radius-box); +} +.rounded-box { + border-radius: var(--radius-box); +} +.rounded-field { + border-radius: var(--radius-field); +} +.rounded-field { + border-radius: var(--radius-field); +} +.rounded-full { + border-radius: calc(infinity * 1px); +} +.border { + border-style: var(--tw-border-style); + border-width: 1px; +} +.btn-text { + --btn-shadow: ""; + color: var(--btn-color, var(--color-neutral)); + --btn-bg: ""; + --btn-border: ""; + --btn-noise: none; + border-width: 0; + outline-color: var(--btn-color, var(--color-neutral)); + @media (hover: hover) { + &:hover { + --btn-bg: var(--btn-color, var(--color-neutral)); + @supports (color: color-mix(in lab, red, red)) { + --btn-bg: color-mix(in oklab, var(--btn-color, var(--color-neutral)) 10%, #0000); + } + } + } + &:focus-visible { + --btn-bg: var(--btn-color, var(--color-neutral)); + @supports (color: color-mix(in lab, red, red)) { + --btn-bg: color-mix(in oklab, var(--btn-color, var(--color-neutral)) 10%, #0000); + } + } + &.btn-active { + --btn-bg: var(--btn-color, var(--color-neutral)); + @supports (color: color-mix(in lab, red, red)) { + --btn-bg: color-mix(in oklab, var(--btn-color, var(--color-neutral)) 10%, #0000); + } + } +} +.btn-soft { + --btn-shadow: ""; + color: var(--btn-color, var(--color-neutral)); + --btn-bg: var(--btn-color, var(--color-neutral)); + @supports (color: color-mix(in lab, red, red)) { + --btn-bg: color-mix(in oklab, var(--btn-color, var(--color-neutral)) 10%, var(--color-base-100)); + } + border-width: 0; + --btn-noise: none; + &:focus-visible { + --btn-bg: var(--btn-color, var(--color-neutral)); + @supports (color: color-mix(in lab, red, red)) { + --btn-bg: color-mix(in oklab, var(--btn-color, var(--color-neutral)) 20%, var(--color-base-100)); + } + } + @media (hover: hover) { + &:hover { + --btn-bg: var(--btn-color, var(--color-neutral)); + @supports (color: color-mix(in lab, red, red)) { + --btn-bg: color-mix(in oklab, var(--btn-color, var(--color-neutral)) 20%, var(--color-base-100)); + } + } + } + &.btn-active { + --btn-bg: var(--btn-color, var(--color-neutral)); + @supports (color: color-mix(in lab, red, red)) { + --btn-bg: color-mix(in oklab, var(--btn-color, var(--color-neutral)) 20%, var(--color-base-100)); + } + } +} +.table-borderless { + --tw-border-style: none; + border-style: none; + :where(thead, tbody) { + :where(tr:not(:last-child)), :where(tr:first-child:last-child) { + --tw-border-style: none; + border-style: none; + } + } +} +.\!border-none { + --tw-border-style: none !important; + border-style: none !important; +} +.input { + &.is-valid, &:has(.is-valid), .validate &:valid, .validate &:has(:valid) { + border-color: var(--color-success); + &:hover { + @media (hover: hover) { + border-color: var(--color-success); + } + } + &:has(:hover):not(:focus, :focus-within) { + border-color: var(--color-success); + } + &:focus, &:focus-within { + --input-color: var(--color-success); + } + } + &.is-invalid, &:has(.is-invalid), .validate &:invalid, .validate &:has(:invalid) { + border-color: var(--color-error); + &:hover { + @media (hover: hover) { + border-color: var(--color-error); + } + } + &:has(:hover):not(:focus, :focus-within) { + border-color: var(--color-error); + } + &:focus, &:focus-within { + --input-color: var(--color-error); + } + } + &.is-valid::file-selector-button { + background-color: var(--color-success); + color: var(--color-success-content); + --input-color: var(--color-success); + } + .validate &:valid::file-selector-button { + background-color: var(--color-success); + color: var(--color-success-content); + --input-color: var(--color-success); + } + &.is-invalid::file-selector-button { + background-color: var(--color-error); + color: var(--color-error-content); + --input-color: var(--color-error); + } + .validate &:invalid::file-selector-button { + background-color: var(--color-error); + color: var(--color-error-content); + --input-color: var(--color-error); + } + .input-floating > &.is-valid::file-selector-button { + background-color: var(--color-base-100); + color: var(--color-base-content); + border-inline-end: var(--border) solid var(--color-success); + } + .validate .input-floating > &:valid::file-selector-button { + background-color: var(--color-base-100); + color: var(--color-base-content); + border-inline-end: var(--border) solid var(--color-success); + } + .input-floating > &.is-invalid::file-selector-button { + background-color: var(--color-base-100); + color: var(--color-base-content); + border-inline-end: var(--border) solid var(--color-error); + } + .validate .input-floating > &:invalid::file-selector-button { + background-color: var(--color-base-100); + color: var(--color-base-content); + border-inline-end: var(--border) solid var(--color-error); + } +} +.is-invalid { + .input&::file-selector-button { + background-color: var(--color-error); + color: var(--color-error-content); + --input-color: var(--color-error); + } + .input-floating > .input&::file-selector-button { + background-color: var(--color-base-100); + color: var(--color-base-content); + border-inline-end: var(--border) solid var(--color-error); + } + .label-text:has(~ &) { + color: var(--color-error); + } + .label-text:has(~ * &) { + color: var(--color-error); + } + :is(&) ~ .helper-text { + color: var(--color-error); + } + *:has(&) ~ .helper-text { + color: var(--color-error); + } + :is(&) ~ .label-text { + color: var(--color-error); + } + :is(&) ~ .label-text * { + color: var(--color-error); + } + :is(&) ~ * >.label-text { + color: var(--color-error); + } + select& + .advance-select-toggle { + --input-color: var(--color-error); + &:focus, &:focus-within { + --input-color: var(--color-error); + } + } + .advance-select-tag:has(> &) { + --input-color: var(--color-error); + &:focus, &:focus-within { + --input-color: var(--color-error); + } + } + .input-floating:has(&) { + &:hover { + @media (hover: hover) { + border-color: var(--color-error); + } + } + .input-floating-label { + color: var(--color-error); + } + &:focus-within, &:not(:has(input:placeholder-shown)), &:has(.input:focus) { + .input-floating-label { + color: var(--color-error); + } + } + } + .textarea-floating:has(&) { + .textarea-floating-label { + color: var(--color-error); + } + &:focus-within, &:not(:has(textarea:placeholder-shown)), &:has(.textarea:focus) { + .textarea-floating-label { + color: var(--color-error); + } + } + } + .select-floating:has(&) { + .select-floating-label { + color: var(--color-error); + } + &:focus-within, &:not(:has(select:placeholder-shown)), &:has(.select:focus) { + .select-floating-label { + color: var(--color-error); + } + } + } +} +.is-valid { + .input&::file-selector-button { + background-color: var(--color-success); + color: var(--color-success-content); + --input-color: var(--color-success); + } + .input-floating > .input&::file-selector-button { + background-color: var(--color-base-100); + color: var(--color-base-content); + border-inline-end: var(--border) solid var(--color-success); + } + .label-text:has(~ &) { + color: var(--color-success); + } + .label-text:has(~ * &) { + color: var(--color-success); + } + :is(&) ~ .helper-text { + color: var(--color-success); + } + *:has(&) ~ .helper-text { + color: var(--color-success); + } + :is(&) ~ .label-text { + color: var(--color-success); + } + :is(&) ~ .label-text * { + color: var(--color-success); + } + :is(&) ~ * >.label-text { + color: var(--color-success); + } + select& + .advance-select-toggle { + --input-color: var(--color-success); + &:focus, &:focus-within { + --input-color: var(--color-success); + } + } + .advance-select-tag:has(> &) { + --input-color: var(--color-success); + &:focus, &:focus-within { + --input-color: var(--color-success); + } + } + .input-floating:has(&) { + &:hover { + @media (hover: hover) { + border-color: var(--color-success); + } + } + .input-floating-label { + color: var(--color-success); + } + &:focus-within, &:not(:has(input:placeholder-shown)), &:has(.input:focus) { + .input-floating-label { + color: var(--color-success); + } + } + } + .textarea-floating:has(&) { + .textarea-floating-label { + color: var(--color-success); + } + &:focus-within, &:not(:has(textarea:placeholder-shown)), &:has(.textarea:focus) { + .textarea-floating-label { + color: var(--color-success); + } + } + } + .select-floating:has(&) { + .select-floating-label { + color: var(--color-success); + } + &:focus-within, &:not(:has(select:placeholder-shown)), &:has(.select:focus) { + .select-floating-label { + color: var(--color-success); + } + } + } } -.max-w-\[70px\] { - max-width: 70px; +.checkbox { + &.is-valid, &:has(.is-valid), .validate &:valid, .validate &:has(:valid) { + --input-color: var(--color-success); + border-color: var(--input-color); + &:checked, &[aria-checked="true"], &:has(> input:checked) { + --input-color: var(--color-success); + } + } + &.is-invalid, &:has(.is-invalid), .validate &:invalid, .validate &:has(:invalid) { + --input-color: var(--color-error); + border-color: var(--input-color); + &:checked, &[aria-checked="true"], &:has(> input:checked) { + --input-color: var(--color-error); + } + } + &.is-valid, &:has(.is-valid), .validate &:valid, .validate &:has(:valid) { + color: var(--color-success-content); + } + &.is-invalid, &:has(.is-invalid), .validate &:invalid, .validate &:has(:invalid) { + color: var(--color-error-content); + } } -.max-w-\[100px\] { - max-width: 100px; +.select { + &.is-valid, &:has(.is-valid), .validate &:valid, .validate &:has(:valid) { + border-color: var(--color-success); + &:hover { + @media (hover: hover) { + border-color: var(--color-success); + } + } + &:has(:hover):not(:focus, :focus-within) { + border-color: var(--color-success); + } + &:focus, &:focus-within { + --input-color: var(--color-success); + } + } + &.is-invalid, &:has(.is-invalid), .validate &:invalid, .validate &:has(:invalid) { + border-color: var(--color-error); + &:hover { + @media (hover: hover) { + border-color: var(--color-error); + } + } + &:has(:hover):not(:focus, :focus-within) { + border-color: var(--color-error); + } + &:focus, &:focus-within { + --input-color: var(--color-error); + } + } } -.flex-col { - flex-direction: column; +.textarea { + &.is-valid, &:has(.is-valid), .validate &:valid, .validate &:has(:valid) { + border-color: var(--color-success); + &:hover { + @media (hover: hover) { + border-color: var(--color-success); + } + } + &:has(:hover):not(:focus, :focus-within) { + border-color: var(--color-success); + } + &:focus, &:focus-within { + --input-color: var(--color-success); + } + } + &.is-invalid, &:has(.is-invalid), .validate &:invalid, .validate &:has(:invalid) { + border-color: var(--color-error); + &:hover { + @media (hover: hover) { + border-color: var(--color-error); + } + } + &:has(:hover):not(:focus, :focus-within) { + border-color: var(--color-error); + } + &:focus, &:focus-within { + --input-color: var(--color-error); + } + } } -.flex-row { - flex-direction: row; +.\!border-base-content\/40 { + border-color: var(--color-base-content) !important; + @supports (color: color-mix(in lab, red, red)) { + border-color: color-mix(in oklab, var(--color-base-content) 40%, transparent) !important; + } } -.items-center { - align-items: center; +.border-base-content\/20 { + border-color: var(--color-base-content); + @supports (color: color-mix(in lab, red, red)) { + border-color: color-mix(in oklab, var(--color-base-content) 20%, transparent); + } } -.items-end { - align-items: flex-end; +.border-base-content\/40 { + border-color: var(--color-base-content); + @supports (color: color-mix(in lab, red, red)) { + border-color: color-mix(in oklab, var(--color-base-content) 40%, transparent); + } } -.justify-center { - justify-content: center; +.progress-primary { + background-color: var(--color-primary); + color: var(--color-primary-content); } -.justify-end { - justify-content: flex-end; +.\!bg-base-100 { + background-color: var(--color-base-100) !important; } -.rounded-full { - border-radius: calc(infinity * 1px); +.bg-\[var\(--color-avatar-background\)\] { + background-color: var(--color-avatar-background); } -.border-r-2 { - border-right-style: var(--tw-border-style); - border-right-width: 2px; +.bg-base-100 { + background-color: var(--color-base-100); } -.border-r-4 { - border-right-style: var(--tw-border-style); - border-right-width: 4px; +.bg-base-300\/60 { + background-color: var(--color-base-300); + @supports (color: color-mix(in lab, red, red)) { + background-color: color-mix(in oklab, var(--color-base-300) 60%, transparent); + } } .bg-gradient-to-br { --tw-gradient-position: to bottom right in oklab; background-image: linear-gradient(var(--tw-gradient-stops)); } +.loading-spinner { + mask-image: url("data:image/svg+xml,%3Csvg width='24' height='24' stroke='%23000' viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cstyle%3E.spinner_V8m1%7Btransform-origin:center;animation:spinner_zKoa 2s linear infinite%7D.spinner_V8m1 circle%7Bstroke-linecap:round;animation:spinner_YpZS 1.5s ease-out infinite%7D%40keyframes spinner_zKoa%7B100%25%7Btransform:rotate(360deg)%7D%7D%40keyframes spinner_YpZS%7B0%25%7Bstroke-dasharray:0 150;stroke-dashoffset:0%7D47.5%25%7Bstroke-dasharray:42 150;stroke-dashoffset:-16%7D95%25%2C100%25%7Bstroke-dasharray:42 150;stroke-dashoffset:-59%7D%7D%3C%2Fstyle%3E%3Cg class='spinner_V8m1'%3E%3Ccircle cx='12' cy='12' r='9.5' fill='none' stroke-width='3'%3E%3C%2Fcircle%3E%3C%2Fg%3E%3C%2Fsvg%3E"); +} .p-\[15px\] { padding: 15px; } .pr-\[15px\] { padding-right: 15px; } +.align-bottom { + vertical-align: bottom; +} .font-rockford-light { font-family: var(--font-rockford-light); } +.btn-sm { + font-size: var(--text-sm); + line-height: var(--tw-leading, var(--text-sm--line-height)); + --btn-p: 0.75rem; + --size: calc(var(--size-field, 0.25rem) * 7.5); +} .text-\[12px\] { font-size: 12px; } @@ -138,6 +2384,9 @@ .text-\[14px\] { font-size: 14px; } +.text-\[15px\] { + font-size: 15px; +} .text-\[18px\] { font-size: 18px; } @@ -147,18 +2396,107 @@ .text-\[24px\] { font-size: 24px; } +.whitespace-nowrap { + white-space: nowrap; +} .text-\[var\(--color-genre\)\] { color: var(--color-genre); } .text-\[var\(--color-text-muted\)\] { color: var(--color-text-muted); } +.text-base-content { + color: var(--color-base-content); +} +.text-base-content\/50 { + color: var(--color-base-content); + @supports (color: color-mix(in lab, red, red)) { + color: color-mix(in oklab, var(--color-base-content) 50%, transparent); + } +} +.text-base-content\/80 { + color: var(--color-base-content); + @supports (color: color-mix(in lab, red, red)) { + color: color-mix(in oklab, var(--color-base-content) 80%, transparent); + } +} +.text-error { + color: var(--color-error); +} .text-inherit { color: inherit; } +.text-primary { + color: var(--color-primary); +} +.text-success { + color: var(--color-success); +} +.lowercase { + text-transform: lowercase; +} +.uppercase { + text-transform: uppercase; +} .no-underline { text-decoration-line: none; } +.opacity-0 { + opacity: 0%; +} +.opacity-100 { + opacity: 100%; +} +.shadow-base-300\/20 { + --tw-shadow-color: var(--color-base-300); + @supports (color: color-mix(in lab, red, red)) { + --tw-shadow-color: color-mix(in oklab, color-mix(in oklab, var(--color-base-300) 20%, transparent) var(--tw-shadow-alpha), transparent); + } +} +.outline { + outline-style: var(--tw-outline-style); + outline-width: 1px; +} +.filter { + filter: var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,); +} +.carousel-slide { + transition-property: transform, translate, scale, rotate; + transition-timing-function: var(--tw-ease, var(--default-transition-timing-function)); + transition-duration: var(--tw-duration, var(--default-transition-duration)); + transition-duration: 700ms; + --tw-duration: 700ms; +} +.transition { + transition-property: color, background-color, border-color, outline-color, text-decoration-color, fill, stroke, --tw-gradient-from, --tw-gradient-via, --tw-gradient-to, opacity, box-shadow, transform, translate, scale, rotate, filter, -webkit-backdrop-filter, backdrop-filter, display, content-visibility, overlay, pointer-events; + transition-timing-function: var(--tw-ease, ease); + transition-duration: var(--tw-duration, 0s); +} +.transition-all { + transition-property: all; + transition-timing-function: var(--tw-ease, ease); + transition-duration: var(--tw-duration, 0s); +} +.duration-300 { + --tw-duration: 300ms; + transition-duration: 300ms; +} +.duration-500 { + --tw-duration: 500ms; + transition-duration: 500ms; +} +.btn-primary { + --btn-color: var(--color-primary); + --btn-fg: var(--color-primary-content); +} +.selected { + .validate select:has(~ * > &) + .advance-select-toggle { + --input-color: var(--color-success); + &:focus, &:focus-within { + --input-color: var(--color-success); + } + } +} .hover\:underline { &:hover { @media (hover: hover) { @@ -166,6 +2504,56 @@ } } } +.focus\:border-primary { + &:focus { + border-color: var(--color-primary); + } +} +.focus\:outline-1 { + &:focus { + outline-style: var(--tw-outline-style); + outline-width: 1px; + } +} +.focus\:outline-primary { + &:focus { + outline-color: var(--color-primary); + } +} +.combo-box-selected\:block { + &.selected { + display: block; + } + .selected & { + display: block; + } +} +.combo-box-selected\:dropdown-active { + &.selected { + background-color: var(--color-primary); + @supports (color: color-mix(in lab, red, red)) { + background-color: color-mix(in oklab, var(--color-primary) 10%, transparent); + } + color: var(--color-primary); + } + .selected & { + background-color: var(--color-primary); + @supports (color: color-mix(in lab, red, red)) { + background-color: color-mix(in oklab, var(--color-primary) 10%, transparent); + } + color: var(--color-primary); + } +} +.file-upload-complete\:progress-success { + &.complete { + background-color: var(--color-success); + color: var(--color-success-content); + } + .complete & { + background-color: var(--color-success); + color: var(--color-success-content); + } +} @font-face { font-family: "RockfordSansLight"; src: url("/public/fonts/RockfordSans-Light.otf") format("opentype"); @@ -224,6 +2612,7 @@ --font-rockford-light: "RockfordSansLight"; --color-text-muted: #42576ca6; --color-genre: #3f03fb; + --color-avatar-background: #f4f0ff; } .dark { --color-text-muted: rgb(191 174 195 / 65%) !important; @@ -232,15 +2621,407 @@ body { font-family: "RockfordSansRegular"; } +@layer base { + :where(:root),:root:has(input.theme-controller[value=light]:checked),[data-theme=light] { + color-scheme: light; + --color-base-100: oklch(100% 0 0); + --color-base-200: oklch(97.8% 0.005 297.73); + --color-base-300: oklch(37.01% 0.0069 297.49); + --color-base-content: oklch(37.57% 0.022 281.8); + --color-primary: oklch(57.59% 0.247 287.24); + --color-primary-content: oklch(96.57% 0.017 289.61); + --color-secondary: oklch(55.79% 0.022 301.91); + --color-secondary-content: oklch(97.64% 0.001 286.38); + --color-accent: oklch(62.31% 0.188 259.81); + --color-accent-content: oklch(97.05% 0.014 254.6); + --color-neutral: oklch(37.57% 0.0222 281.8); + --color-neutral-content: oklch(0.98 0.0013 286.38); + --color-info: oklch(71.48% 0.126 215.22); + --color-info-content: oklch(98.41% 0.019 200.87); + --color-success: oklch(73.11% 0.217 147.04); + --color-success-content: oklch(98.1% 0.014 174.18); + --color-warning: oklch(79.87% 0.164 73.09); + --color-warning-content: oklch(99.34% 0.011 95.16); + --color-error: oklch(65.39% 0.222 25.86); + --color-error-content: oklch(98.76% 0.009 67.73); + --radius-selector: 0.25rem; + --radius-field: 0.375rem; + --radius-box: 0.5rem; + --size-selector: 0.25rem; + --size-field: 0.25rem; + --border: 1px; + --depth: 0; + --noise: 0; + } +} +@layer base { + @media (prefers-color-scheme: dark) { + :root { + color-scheme: dark; + --color-base-100: oklch(31.23% 0.026 301.24); + --color-base-200: oklch(25.39% 0.025 298.72); + --color-base-300: oklch(23.44% 0.0194 298.63); + --color-base-content: oklch(84.98% 0.014 295.28); + --color-primary: oklch(53.93% 0.271 286.75); + --color-primary-content: oklch(88.22% 0.062 290.17); + --color-secondary: oklch(49.12% 0.021 303.05); + --color-secondary-content: oklch(88.83% 0.007 304.23); + --color-accent: oklch(54.61% 0.215 262.88); + --color-accent-content: oklch(88.23% 0.057 254.13); + --color-neutral: oklch(65.75% 0.022 294.95); + --color-neutral-content: oklch(18.51% 0.017 301.92); + --color-info: oklch(60.89% 0.111 221.72); + --color-info-content: oklch(91.67% 0.077 205.04); + --color-success: oklch(67.35% 0.201 146.84); + --color-success-content: oklch(91.38% 0.069 168.24); + --color-warning: oklch(72.59% 0.152 69.05); + --color-warning-content: oklch(96.07% 0.057 93.2); + --color-error: oklch(59.54% 0.208 26.28); + --color-error-content: oklch(93.4% 0.039 54.86); + --radius-selector: 0.25rem; + --radius-field: 0.375rem; + --radius-box: 0.5rem; + --size-selector: 0.25rem; + --size-field: 0.25rem; + --border: 1px; + --depth: 0; + --noise: 0; + } + } +} +@layer base { + :root:has(input.theme-controller[value=light]:checked),[data-theme=light] { + color-scheme: light; + --color-base-100: oklch(100% 0 0); + --color-base-200: oklch(97.8% 0.005 297.73); + --color-base-300: oklch(37.01% 0.0069 297.49); + --color-base-content: oklch(37.57% 0.022 281.8); + --color-primary: oklch(57.59% 0.247 287.24); + --color-primary-content: oklch(96.57% 0.017 289.61); + --color-secondary: oklch(55.79% 0.022 301.91); + --color-secondary-content: oklch(97.64% 0.001 286.38); + --color-accent: oklch(62.31% 0.188 259.81); + --color-accent-content: oklch(97.05% 0.014 254.6); + --color-neutral: oklch(37.57% 0.0222 281.8); + --color-neutral-content: oklch(0.98 0.0013 286.38); + --color-info: oklch(71.48% 0.126 215.22); + --color-info-content: oklch(98.41% 0.019 200.87); + --color-success: oklch(73.11% 0.217 147.04); + --color-success-content: oklch(98.1% 0.014 174.18); + --color-warning: oklch(79.87% 0.164 73.09); + --color-warning-content: oklch(99.34% 0.011 95.16); + --color-error: oklch(65.39% 0.222 25.86); + --color-error-content: oklch(98.76% 0.009 67.73); + --radius-selector: 0.25rem; + --radius-field: 0.375rem; + --radius-box: 0.5rem; + --size-selector: 0.25rem; + --size-field: 0.25rem; + --border: 1px; + --depth: 0; + --noise: 0; + } +} +@layer base { + :root:has(input.theme-controller[value=dark]:checked),[data-theme=dark] { + color-scheme: dark; + --color-base-100: oklch(31.23% 0.026 301.24); + --color-base-200: oklch(25.39% 0.025 298.72); + --color-base-300: oklch(23.44% 0.0194 298.63); + --color-base-content: oklch(84.98% 0.014 295.28); + --color-primary: oklch(53.93% 0.271 286.75); + --color-primary-content: oklch(88.22% 0.062 290.17); + --color-secondary: oklch(49.12% 0.021 303.05); + --color-secondary-content: oklch(88.83% 0.007 304.23); + --color-accent: oklch(54.61% 0.215 262.88); + --color-accent-content: oklch(88.23% 0.057 254.13); + --color-neutral: oklch(65.75% 0.022 294.95); + --color-neutral-content: oklch(18.51% 0.017 301.92); + --color-info: oklch(60.89% 0.111 221.72); + --color-info-content: oklch(91.67% 0.077 205.04); + --color-success: oklch(67.35% 0.201 146.84); + --color-success-content: oklch(91.38% 0.069 168.24); + --color-warning: oklch(72.59% 0.152 69.05); + --color-warning-content: oklch(96.07% 0.057 93.2); + --color-error: oklch(59.54% 0.208 26.28); + --color-error-content: oklch(93.4% 0.039 54.86); + --radius-selector: 0.25rem; + --radius-field: 0.375rem; + --radius-box: 0.5rem; + --size-selector: 0.25rem; + --size-field: 0.25rem; + --border: 1px; + --depth: 0; + --noise: 0; + } +} +@layer base { + :root { + --fx-noise: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='a'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='1.34' numOctaves='4' stitchTiles='stitch'%3E%3C/feTurbulence%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23a)' opacity='0.2'%3E%3C/rect%3E%3C/svg%3E"); + } + .chat { + --mask-chat: url("data:image/svg+xml,%3csvg width='13' height='13' xmlns='http://www.w3.org/2000/svg'%3e%3cpath fill='black' d='M0 11.5004C0 13.0004 2 13.0004 2 13.0004H12H13V0.00036329L12.5 0C12.5 0 11.977 2.09572 11.8581 2.50033C11.6075 3.35237 10.9149 4.22374 9 5.50036C6 7.50036 0 10.0004 0 11.5004Z'/%3e%3c/svg%3e"); + } + .tooltip { + --mask-tooltip: url("data:image/svg+xml,%3Csvg width='10' height='4' viewBox='0 0 8 4' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M0.500009 1C3.5 1 3.00001 4 5.00001 4C7 4 6.5 1 9.5 1C10 1 10 0.499897 10 0H0C-1.99338e-08 0.5 0 1 0.500009 1Z' fill='black'/%3E%3C/svg%3E%0A"); + } +} +@layer base { + :root { + scrollbar-color: currentColor #0000; + @supports (color: color-mix(in lab, red, red)) { + scrollbar-color: color-mix(in oklch, currentColor 20%, #0000) #0000; + } + } +} +@layer base { + @property --radialprogress { + syntax: ""; + inherits: true; + initial-value: 0%; + } +} +@layer base { + :root, [data-theme] { + background-color: var(--root-bg, var(--color-base-100)); + color: var(--color-base-content); + } +} +@layer base { + button:not(:disabled), [role="button"]:not(:disabled) { + cursor: pointer; + } +} +@keyframes radio { + 0% { + padding: 5px; + } + 50% { + padding: 3px; + } +} +@keyframes radio-inset { + 0% { + padding: 1px; + } + 50% { + padding: 4px; + } +} +@keyframes skeleton { + 0% { + background-position: 150%; + } + 100% { + background-position: -50%; + } +} +@keyframes indeterminate-progress { + 0% { + background-position-x: -75%; + } + 50% { + background-position-x: 125%; + } + 100% { + background-position-x: -75%; + } +} +@keyframes progress-bar-stripes { + 0% { + background-position-x: 0.75rem; + } +} +@property --tw-rotate-x { + syntax: "*"; + inherits: false; +} +@property --tw-rotate-y { + syntax: "*"; + inherits: false; +} +@property --tw-rotate-z { + syntax: "*"; + inherits: false; +} +@property --tw-skew-x { + syntax: "*"; + inherits: false; +} +@property --tw-skew-y { + syntax: "*"; + inherits: false; +} @property --tw-border-style { syntax: "*"; inherits: false; initial-value: solid; } +@property --tw-shadow { + syntax: "*"; + inherits: false; + initial-value: 0 0 #0000; +} +@property --tw-shadow-color { + syntax: "*"; + inherits: false; +} +@property --tw-shadow-alpha { + syntax: ""; + inherits: false; + initial-value: 100%; +} +@property --tw-inset-shadow { + syntax: "*"; + inherits: false; + initial-value: 0 0 #0000; +} +@property --tw-inset-shadow-color { + syntax: "*"; + inherits: false; +} +@property --tw-inset-shadow-alpha { + syntax: ""; + inherits: false; + initial-value: 100%; +} +@property --tw-ring-color { + syntax: "*"; + inherits: false; +} +@property --tw-ring-shadow { + syntax: "*"; + inherits: false; + initial-value: 0 0 #0000; +} +@property --tw-inset-ring-color { + syntax: "*"; + inherits: false; +} +@property --tw-inset-ring-shadow { + syntax: "*"; + inherits: false; + initial-value: 0 0 #0000; +} +@property --tw-ring-inset { + syntax: "*"; + inherits: false; +} +@property --tw-ring-offset-width { + syntax: ""; + inherits: false; + initial-value: 0px; +} +@property --tw-ring-offset-color { + syntax: "*"; + inherits: false; + initial-value: #fff; +} +@property --tw-ring-offset-shadow { + syntax: "*"; + inherits: false; + initial-value: 0 0 #0000; +} +@property --tw-outline-style { + syntax: "*"; + inherits: false; + initial-value: solid; +} +@property --tw-blur { + syntax: "*"; + inherits: false; +} +@property --tw-brightness { + syntax: "*"; + inherits: false; +} +@property --tw-contrast { + syntax: "*"; + inherits: false; +} +@property --tw-grayscale { + syntax: "*"; + inherits: false; +} +@property --tw-hue-rotate { + syntax: "*"; + inherits: false; +} +@property --tw-invert { + syntax: "*"; + inherits: false; +} +@property --tw-opacity { + syntax: "*"; + inherits: false; +} +@property --tw-saturate { + syntax: "*"; + inherits: false; +} +@property --tw-sepia { + syntax: "*"; + inherits: false; +} +@property --tw-drop-shadow { + syntax: "*"; + inherits: false; +} +@property --tw-drop-shadow-color { + syntax: "*"; + inherits: false; +} +@property --tw-drop-shadow-alpha { + syntax: ""; + inherits: false; + initial-value: 100%; +} +@property --tw-drop-shadow-size { + syntax: "*"; + inherits: false; +} +@property --tw-duration { + syntax: "*"; + inherits: false; +} @layer properties { @supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))) { *, ::before, ::after, ::backdrop { + --tw-rotate-x: initial; + --tw-rotate-y: initial; + --tw-rotate-z: initial; + --tw-skew-x: initial; + --tw-skew-y: initial; --tw-border-style: solid; + --tw-shadow: 0 0 #0000; + --tw-shadow-color: initial; + --tw-shadow-alpha: 100%; + --tw-inset-shadow: 0 0 #0000; + --tw-inset-shadow-color: initial; + --tw-inset-shadow-alpha: 100%; + --tw-ring-color: initial; + --tw-ring-shadow: 0 0 #0000; + --tw-inset-ring-color: initial; + --tw-inset-ring-shadow: 0 0 #0000; + --tw-ring-inset: initial; + --tw-ring-offset-width: 0px; + --tw-ring-offset-color: #fff; + --tw-ring-offset-shadow: 0 0 #0000; + --tw-outline-style: solid; + --tw-blur: initial; + --tw-brightness: initial; + --tw-contrast: initial; + --tw-grayscale: initial; + --tw-hue-rotate: initial; + --tw-invert: initial; + --tw-opacity: initial; + --tw-saturate: initial; + --tw-sepia: initial; + --tw-drop-shadow: initial; + --tw-drop-shadow-color: initial; + --tw-drop-shadow-alpha: 100%; + --tw-drop-shadow-size: initial; + --tw-duration: initial; } } } diff --git a/apps/embed/src/components/Header/Header.tsx b/apps/embed/src/components/Header/Header.tsx new file mode 100644 index 00000000..f5a2ca60 --- /dev/null +++ b/apps/embed/src/components/Header/Header.tsx @@ -0,0 +1,55 @@ +import dayjs from "dayjs"; +import type { Profile } from "../../types/profile"; + +export type HeaderProps = { + profile: Profile; +}; + +function Header(props: HeaderProps) { + const end = dayjs(); + const start = end.subtract(7, "day"); + const range = `${start.format("DD MMM YYYY")} — ${end.format("DD MMM YYYY")}`; + + return ( + <> + + + ); +} + +export default Header; diff --git a/apps/embed/src/components/Header/index.tsx b/apps/embed/src/components/Header/index.tsx new file mode 100644 index 00000000..0d87fe12 --- /dev/null +++ b/apps/embed/src/components/Header/index.tsx @@ -0,0 +1,3 @@ +import Header from "./Header"; + +export default Header; diff --git a/apps/embed/src/components/Icons/Artist.tsx b/apps/embed/src/components/Icons/Artist.tsx new file mode 100644 index 00000000..527ac430 --- /dev/null +++ b/apps/embed/src/components/Icons/Artist.tsx @@ -0,0 +1,23 @@ +import type { FC } from "react"; + +export type ArtistProps = { + size?: number; + color?: string; + width?: number; + height?: number; +}; + +const Artist: FC = ({ size = 24, color = "#000", ...props }) => ( + + + +); + +export default Artist; diff --git a/apps/embed/src/embeds/ProfileEmbedPage.tsx b/apps/embed/src/embeds/ProfileEmbedPage.tsx index fe615280..c183a89c 100644 --- a/apps/embed/src/embeds/ProfileEmbedPage.tsx +++ b/apps/embed/src/embeds/ProfileEmbedPage.tsx @@ -32,13 +32,14 @@ export function ProfileEmbedPage(props: ProfileEmbedPageProps) { >
- Rocksky + Rocksky
-
+ +
; +import type { Profile } from "../types/profile"; +import type { Scrobble } from "../types/scrobble"; + +export type RecentScrobblesEmbedPageProps = { + profile: Profile; + scrobbles: Scrobble[]; +}; + +export function RecentScrobblesEmbedPage(props: RecentScrobblesEmbedPageProps) { + return ( +
+

Recent Listens

+
+ ); } diff --git a/apps/embed/src/embeds/TopAlbumsEmbedPage.tsx b/apps/embed/src/embeds/TopAlbumsEmbedPage.tsx index 3f533053..3bdb1e17 100644 --- a/apps/embed/src/embeds/TopAlbumsEmbedPage.tsx +++ b/apps/embed/src/embeds/TopAlbumsEmbedPage.tsx @@ -1,3 +1,15 @@ -export function TopAlbumsEmbedPage() { - return <>; +import type { Album } from "../types/album"; +import type { Profile } from "../types/profile"; + +export type TopAlbumEmbedPageProps = { + profile: Profile; + albums: Album[]; +}; + +export function TopAlbumsEmbedPage(props: TopAlbumEmbedPageProps) { + return ( +
+

Top Albums

+
+ ); } diff --git a/apps/embed/src/embeds/TopArtistsEmbedPage.tsx b/apps/embed/src/embeds/TopArtistsEmbedPage.tsx index d49a9eb8..2099898c 100644 --- a/apps/embed/src/embeds/TopArtistsEmbedPage.tsx +++ b/apps/embed/src/embeds/TopArtistsEmbedPage.tsx @@ -1,3 +1,56 @@ -export function TopArtistsEmbedPage() { - return <>; +import { v4 } from "uuid"; +import type { Artist } from "../types/artist"; +import type { Profile } from "../types/profile"; +import ArtistIcon from "../components/Icons/Artist"; +import dayjs from "dayjs"; +import Header from "../components/Header"; + +export type TopArtistsEmbedPageProps = { + profile: Profile; + artists: Artist[]; +}; + +export function TopArtistsEmbedPage(props: TopArtistsEmbedPageProps) { + return ( +
+
+

Top Artists

+ +
+ + + {props.artists.map((artist, index) => ( + + + + ))} + +
+ +
+
+
+ ); } diff --git a/apps/embed/src/embeds/TopTracksEmbedPage.tsx b/apps/embed/src/embeds/TopTracksEmbedPage.tsx index 105d901d..69afa6bb 100644 --- a/apps/embed/src/embeds/TopTracksEmbedPage.tsx +++ b/apps/embed/src/embeds/TopTracksEmbedPage.tsx @@ -1,3 +1,15 @@ -export function TopTracksEmbedPage() { - return <>; +import type { Profile } from "../types/profile"; +import type { Track } from "../types/track"; + +export type TopTracksEmbedPageProps = { + profile: Profile; + tracks: Track[]; +}; + +export function TopTracksEmbedPage(props: TopTracksEmbedPageProps) { + return ( +
+

Top Tracks

+
+ ); } diff --git a/apps/embed/src/index.tsx b/apps/embed/src/index.tsx index 70e228c5..db3dc5b9 100644 --- a/apps/embed/src/index.tsx +++ b/apps/embed/src/index.tsx @@ -15,6 +15,10 @@ import getProfile from "./xrpc/getProfile"; import getProfileStats from "./xrpc/getStats"; import getTopGenres from "./xrpc/getTopGenres"; import getTopTrack from "./xrpc/getTopTrack"; +import getTopArtists from "./xrpc/getTopArtists"; +import getTopAlbums from "./xrpc/getTopAlbums"; +import getTopTracks from "./xrpc/getTopTracks"; +import getRecentScrobbles from "./xrpc/getRecentScrobbles"; const app = new Hono(); @@ -22,16 +26,41 @@ app.use("/public/*", serveStatic({ root: "./" })); app.use(renderer); -app.get("/embed/u/:handle/top/artists", (c) => { - return c.render(); +app.get("/embed/u/:handle/top/artists", async (c) => { + const handle = c.req.param("handle"); + const [{ profile, ok: profileOk }, { topArtists, ok: artistsOk }] = + await Promise.all([getProfile(handle), getTopArtists(handle)]); + + if (!profileOk || !artistsOk) { + return c.text("Profile not found", 404); + } + + return c.render( + , + ); }); -app.get("/embed/u/:handle/top/albums", (c) => { - return c.render(); +app.get("/embed/u/:handle/top/albums", async (c) => { + const handle = c.req.param("handle"); + const [{ profile, ok: profileOk }, { topAlbums, ok: albumsOk }] = + await Promise.all([getProfile(handle), getTopAlbums(handle)]); + if (!profileOk || !albumsOk) { + return c.text("Profile not found", 404); + } + + return c.render(); }); -app.get("/embed/u/:handle/top/tracks", (c) => { - return c.render(); +app.get("/embed/u/:handle/top/tracks", async (c) => { + const handle = c.req.param("handle"); + const [{ profile, ok: profileOk }, { topTracks, ok: tracksOk }] = + await Promise.all([getProfile(handle), getTopTracks(handle)]); + + if (!profileOk || !tracksOk) { + return c.text("Profile not found", 404); + } + + return c.render(); }); app.get("/embed/song/:id", (c) => { @@ -88,8 +117,18 @@ app.get("/embed/u/:handle/now", (c) => { return c.render(); }); -app.get("/embed/u/:handle/recent", (c) => { - return c.render(); +app.get("/embed/u/:handle/recent", async (c) => { + const handle = c.req.param("handle"); + const [{ profile, ok: profileOk }, { scrobbles, ok: scrobblesOk }] = + await Promise.all([getProfile(handle), getRecentScrobbles(handle)]); + + if (!profileOk || !scrobblesOk) { + return c.text("Profile not found", 404); + } + + return c.render( + , + ); }); app.get("/embed/u/:handle/summary", (c) => { @@ -101,7 +140,7 @@ app.get("/", (c) => {

- Hello from Hono + React! + Embed a Rocksky Scrobble

This is server-side rendered with Tailwind CSS diff --git a/apps/embed/src/styles.css b/apps/embed/src/styles.css index 6f4f1218..df46fe79 100644 --- a/apps/embed/src/styles.css +++ b/apps/embed/src/styles.css @@ -2,6 +2,12 @@ @tailwind components; @tailwind utilities; +@plugin "flyonui"; +@plugin "@iconify/tailwind4"; + +@import "../node_modules/flyonui/variants.css"; +@source "../node_modules/flyonui/dist/index.js"; + @font-face { font-family: "RockfordSansLight"; src: url("/public/fonts/RockfordSans-Light.otf") format("opentype"); @@ -69,6 +75,7 @@ --font-rockford-light: "RockfordSansLight"; --color-text-muted: #42576ca6; --color-genre: #3f03fb; + --color-avatar-background: #f4f0ff; } .dark { diff --git a/apps/embed/src/types/album.ts b/apps/embed/src/types/album.ts new file mode 100644 index 00000000..2e3a22e9 --- /dev/null +++ b/apps/embed/src/types/album.ts @@ -0,0 +1,11 @@ +export type Album = { + id: string; + title: string; + artist: string; + albumArt: string; + year: number | null; + uri: string; + artistUri: string; + playCount: number; + uniqueListeners: number; +}; diff --git a/apps/embed/src/types/artist.ts b/apps/embed/src/types/artist.ts index ce01d7ed..33c34d75 100644 --- a/apps/embed/src/types/artist.ts +++ b/apps/embed/src/types/artist.ts @@ -1,5 +1,9 @@ export type Artist = { id: string; name: string; - tags: string[]; + playCount: number; + uniqueListeners: number; + picture: string | null; + uri: string; + tags: string[] | null; }; diff --git a/apps/embed/src/types/scrobble.ts b/apps/embed/src/types/scrobble.ts new file mode 100644 index 00000000..95b8b776 --- /dev/null +++ b/apps/embed/src/types/scrobble.ts @@ -0,0 +1,16 @@ +export type Scrobble = { + id: string; + trackId: string; + title: string; + artist: string; + albumArtist: string; + albumArt: string; + album: string; + handle: string; + did: string; + uri: string; + trackUri: string; + artistUri: string; + albumUri: string; + createdAt: string; +}; diff --git a/apps/embed/src/types/track.ts b/apps/embed/src/types/track.ts index e2c4d4de..64e94f2f 100644 --- a/apps/embed/src/types/track.ts +++ b/apps/embed/src/types/track.ts @@ -1,11 +1,16 @@ export type Track = { id: string; title: string; - album: string; - albumArt: string; - albumUri: string; artist: string; - artistUri: string; albumArtist: string; + albumArt: string; + trackNumber: number; + duration: number; + discNumber: number; uri: string; + artistUri: string; + albumUri: string; + album: string; + playCount: number; + uniqueListeners: number; }; diff --git a/apps/embed/src/xrpc/getRecentScrobbles.ts b/apps/embed/src/xrpc/getRecentScrobbles.ts new file mode 100644 index 00000000..992d92c5 --- /dev/null +++ b/apps/embed/src/xrpc/getRecentScrobbles.ts @@ -0,0 +1,18 @@ +import { ROCKSKY_API_URL } from "../consts"; +import type { Scrobble } from "../types/scrobble"; + +export default async function getRecentScrobbles(handle: string) { + const url = new URL( + `${ROCKSKY_API_URL}/xrpc/app.rocksky.actor.getActorScrobbles`, + ); + url.searchParams.append("did", handle); + url.searchParams.append("limit", "20"); + const res = await fetch(url); + + if (!res.ok) { + return { scrobbles: [], ok: res.ok }; + } + + const { scrobbles } = (await res.json()) as { scrobbles: Scrobble[] }; + return { scrobbles, ok: res.ok }; +} diff --git a/apps/embed/src/xrpc/getTopAlbums.ts b/apps/embed/src/xrpc/getTopAlbums.ts new file mode 100644 index 00000000..d7759585 --- /dev/null +++ b/apps/embed/src/xrpc/getTopAlbums.ts @@ -0,0 +1,18 @@ +import { ROCKSKY_API_URL } from "../consts"; +import type { Album } from "../types/album"; + +export default async function getTopAlbums(handle: string) { + const url = new URL( + `${ROCKSKY_API_URL}/xrpc/app.rocksky.actor.getActorAlbums`, + ); + url.searchParams.append("did", handle); + url.searchParams.append("limit", "20"); + const res = await fetch(url); + + if (!res.ok) { + return { topAlbums: [], ok: res.ok }; + } + + const { albums } = (await res.json()) as { albums: Album[] }; + return { topAlbums: albums, ok: res.ok }; +} diff --git a/apps/embed/src/xrpc/getTopArtists.ts b/apps/embed/src/xrpc/getTopArtists.ts new file mode 100644 index 00000000..1d69e13e --- /dev/null +++ b/apps/embed/src/xrpc/getTopArtists.ts @@ -0,0 +1,23 @@ +import { ROCKSKY_API_URL } from "../consts"; +import getLastDays from "../lib/getLastDays"; +import type { Artist } from "../types/artist"; + +export default async function getTopArtists(handle: string) { + const [start, end] = getLastDays(7); + const url = new URL( + `${ROCKSKY_API_URL}/xrpc/app.rocksky.actor.getActorArtists`, + ); + url.searchParams.append("did", handle); + url.searchParams.append("startDate", start.toISOString()); + url.searchParams.append("endDate", end.toISOString()); + url.searchParams.append("limit", "20"); + + const res = await fetch(url); + + if (!res.ok) { + return { topArtists: [], ok: res.ok }; + } + + const { artists } = (await res.json()) as { artists: Artist[] }; + return { topArtists: artists, ok: res.ok }; +} diff --git a/apps/embed/src/xrpc/getTopTracks.ts b/apps/embed/src/xrpc/getTopTracks.ts new file mode 100644 index 00000000..439a8d56 --- /dev/null +++ b/apps/embed/src/xrpc/getTopTracks.ts @@ -0,0 +1,19 @@ +import { ROCKSKY_API_URL } from "../consts"; +import type { Track } from "../types/track"; + +export default async function getTopAlbums(handle: string) { + const url = new URL( + `${ROCKSKY_API_URL}/xrpc/app.rocksky.actor.getActorSongs`, + ); + url.searchParams.append("did", handle); + url.searchParams.append("limit", "20"); + + const res = await fetch(url); + + if (!res.ok) { + return { topTracks: [], ok: res.ok }; + } + + const { tracks } = (await res.json()) as { tracks: Track[] }; + return { topTracks: tracks, ok: res.ok }; +} -- 2.51.2