From 14a10d5e4e2f3f1095e5279b7ccdf86574817fed Mon Sep 17 00:00:00 2001 From: Tiago Mota Date: Thu, 9 Apr 2026 17:39:18 +0100 Subject: [PATCH] chore: release pipeline --- .github/workflows/build-and-release.yml | 111 ++++++ package.json | 22 +- pnpm-lock.yaml | 495 +++++++++++++++++++++++- scripts/package-extension.js | 195 ++++++++++ src/background/background_ff.html | 23 ++ src/background/offscreen/offscreen.ts | 8 +- src/background/service-worker.ts | 17 +- src/background/services/notary.ts | 3 +- src/lib/compat.ts | 20 + src/lib/utils.ts | 6 +- src/styles/tailwind.css | 11 +- styles.css | 3 +- tailwind.config.js | 3 +- webpack.config.js | 65 +++- 14 files changed, 954 insertions(+), 28 deletions(-) create mode 100644 .github/workflows/build-and-release.yml create mode 100755 scripts/package-extension.js create mode 100644 src/background/background_ff.html create mode 100644 src/lib/compat.ts diff --git a/.github/workflows/build-and-release.yml b/.github/workflows/build-and-release.yml new file mode 100644 index 0000000..bfe2fc2 --- /dev/null +++ b/.github/workflows/build-and-release.yml @@ -0,0 +1,111 @@ +# Build & Release +# +# Builds the Chrome extension, packages artifacts, +# and creates a GitHub Release when a version tag is pushed. +# +# Triggers: +# push to main → build + upload artifacts (CI validation) +# pull_request → build only (validation) +# tag v* → build + package + GitHub Release +# +# Artifacts produced: +# Chrome: cstradeup-v{ver}-chrome.zip + +name: Build & Release + +on: + push: + branches: [main] + tags: ["v*"] + +# Cancel in-progress runs for the same branch/PR +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + # ───────────────────────────────────────────────────────────────────────── + # Build: Chrome only (production) + # ───────────────────────────────────────────────────────────────────────── + build: + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + browser: [chrome] + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Install pnpm + uses: pnpm/action-setup@v4 + with: + version: 9 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: 20 + cache: pnpm + + - name: Install dependencies + run: pnpm install --frozen-lockfile + + - name: Build (${{ matrix.browser }}, production) + run: pnpm build:${{ matrix.browser }} + + - name: Package extension + run: pnpm package:${{ matrix.browser }} + env: + SKIP_CRX: '1' + + - name: Upload build artifacts + uses: actions/upload-artifact@v4 + with: + name: ${{ matrix.browser }}-build + path: dist/ + if-no-files-found: error + retention-days: 30 + + - name: Upload unpacked build + uses: actions/upload-artifact@v4 + with: + name: ${{ matrix.browser }}-unpacked + path: build/ + if-no-files-found: error + retention-days: 14 + + # ───────────────────────────────────────────────────────────────────────── + # Release: triggered only on version tags (v*) + # ───────────────────────────────────────────────────────────────────────── + release: + needs: build + if: startsWith(github.ref, 'refs/tags/v') + runs-on: ubuntu-latest + permissions: + contents: write + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Download Chrome artifacts + uses: actions/download-artifact@v4 + with: + name: chrome-build + path: release/chrome + + - name: List release artifacts + run: find release/ -type f | sort + + - name: Create GitHub Release + uses: softprops/action-gh-release@v2 + with: + generate_release_notes: true + draft: false + prerelease: ${{ contains(github.ref_name, '-') }} + files: | + release/chrome/*.zip + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/package.json b/package.json index 3ee7e78..e7fe248 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cstradeup-extension", - "version": "0.1.0", + "version": "0.2.0", "description": "Analyze your CS2 inventory for profitable trade ups. View hidden skins in your Storage Units and other inventory insights.", "license": "MIT", "directories": { @@ -11,13 +11,24 @@ "url": "git+https://github.com/cstradeup/extension.git" }, "scripts": { - "clean": "node -e \"require('fs').rmSync('./build', { recursive: true, force: true })\"", + "clean": "node -e \"require('fs').rmSync('./build', { recursive: true, force: true }); require('fs').rmSync('./dist', { recursive: true, force: true })\"", "build:ts": "tsc", "build:css": "tailwindcss -i src/styles/tailwind.css -o styles.css --minify", "watch:css": "tailwindcss -i src/styles/tailwind.css -o styles.css --watch", "build:webpack": "npm run build:css && NODE_ENV=production webpack --config webpack.config.js", "build:webpack:dev": "npm run build:css && NODE_ENV=development webpack --config webpack.config.js", + "build:chrome": "BROWSER=chrome npm run build:webpack", + "build:firefox": "BROWSER=firefox npm run build:webpack", + "build:chrome:dev": "BROWSER=chrome npm run build:webpack:dev", + "build:firefox:dev": "BROWSER=firefox npm run build:webpack:dev", + "build:all": "npm run build:chrome && npm run package:chrome && npm run clean:build && npm run build:firefox && npm run package:firefox", + "clean:build": "node -e \"require('fs').rmSync('./build', { recursive: true, force: true })\"", "dev": "npm run build:webpack:dev", + "dev:chrome": "npm run build:chrome:dev", + "dev:firefox": "npm run build:firefox:dev", + "package": "node scripts/package-extension.js", + "package:chrome": "BROWSER=chrome node scripts/package-extension.js", + "package:firefox": "BROWSER=firefox node scripts/package-extension.js", "zip": "cd build && zip -r ../extension.zip . && echo 'Created extension.zip'" }, "homepage": "https://github.com/cstradeup/extension#readme", @@ -26,6 +37,7 @@ "@babel/plugin-proposal-class-properties": "^7.18.6", "@babel/preset-env": "^7.20.2", "@babel/preset-react": "^7.18.6", + "@tailwindcss/cli": "^4.2.2", "@types/chrome": "^0.1.28", "@types/firefox-webext-browser": "^120.0.4", "@types/node": "^20.4.10", @@ -40,6 +52,7 @@ "buffer": "^6.0.3", "clean-webpack-plugin": "^4.0.0", "copy-webpack-plugin": "^11.0.0", + "crx3": "^1.1.3", "css-loader": "^6.7.3", "daisyui": "^5.5.5", "file-loader": "^6.2.0", @@ -50,7 +63,7 @@ "postcss": "^8.5.6", "process": "^0.11.10", "stream-browserify": "^3.0.0", - "tailwindcss": "^4.1.17", + "tailwindcss": "^4.2.2", "terser-webpack-plugin": "^5.3.6", "ts-loader": "^9.4.2", "type-fest": "^3.5.2", @@ -67,6 +80,5 @@ "comlink": "^4.4.2", "tlsn-js": "0.1.0-alpha.12.0" }, - "overrides": { - } + "overrides": {} } \ No newline at end of file diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index db61cc3..66cb856 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -5,6 +5,7 @@ specifiers: '@babel/plugin-proposal-class-properties': ^7.18.6 '@babel/preset-env': ^7.20.2 '@babel/preset-react': ^7.18.6 + '@tailwindcss/cli': ^4.2.2 '@types/chrome': ^0.1.28 '@types/firefox-webext-browser': ^120.0.4 '@types/node': ^20.4.10 @@ -20,6 +21,7 @@ specifiers: clean-webpack-plugin: ^4.0.0 comlink: ^4.4.2 copy-webpack-plugin: ^11.0.0 + crx3: ^1.1.3 css-loader: ^6.7.3 daisyui: ^5.5.5 file-loader: ^6.2.0 @@ -30,7 +32,7 @@ specifiers: postcss: ^8.5.6 process: ^0.11.10 stream-browserify: ^3.0.0 - tailwindcss: ^4.1.17 + tailwindcss: ^4.2.2 terser-webpack-plugin: ^5.3.6 tlsn-js: 0.1.0-alpha.12.0 ts-loader: ^9.4.2 @@ -53,6 +55,7 @@ devDependencies: '@babel/plugin-proposal-class-properties': 7.18.6_@babel+core@7.28.5 '@babel/preset-env': 7.28.5_@babel+core@7.28.5 '@babel/preset-react': 7.28.5_@babel+core@7.28.5 + '@tailwindcss/cli': 4.2.2 '@types/chrome': 0.1.28 '@types/firefox-webext-browser': 120.0.5 '@types/node': 20.19.25 @@ -67,6 +70,7 @@ devDependencies: buffer: 6.0.3 clean-webpack-plugin: 4.0.0_webpack@5.102.1 copy-webpack-plugin: 11.0.0_webpack@5.102.1 + crx3: 1.1.3 css-loader: 6.11.0_webpack@5.102.1 daisyui: 5.5.5 file-loader: 6.2.0_webpack@5.102.1 @@ -77,7 +81,7 @@ devDependencies: postcss: 8.5.6 process: 0.11.10 stream-browserify: 3.0.0 - tailwindcss: 4.1.17 + tailwindcss: 4.2.2 terser-webpack-plugin: 5.3.14_webpack@5.102.1 ts-loader: 9.5.4_kg7fczjm3r6my47lhru2l2c62e type-fest: 3.13.1 @@ -1315,6 +1319,305 @@ packages: fastq: 1.19.1 dev: true + /@parcel/watcher-android-arm64/2.5.6: + resolution: {integrity: sha512-YQxSS34tPF/6ZG7r/Ih9xy+kP/WwediEUsqmtf0cuCV5TPPKw/PQHRhueUo6JdeFJaqV3pyjm0GdYjZotbRt/A==} + engines: {node: '>= 10.0.0'} + cpu: [arm64] + os: [android] + requiresBuild: true + dev: true + optional: true + + /@parcel/watcher-darwin-arm64/2.5.6: + resolution: {integrity: sha512-Z2ZdrnwyXvvvdtRHLmM4knydIdU9adO3D4n/0cVipF3rRiwP+3/sfzpAwA/qKFL6i1ModaabkU7IbpeMBgiVEA==} + engines: {node: '>= 10.0.0'} + cpu: [arm64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /@parcel/watcher-darwin-x64/2.5.6: + resolution: {integrity: sha512-HgvOf3W9dhithcwOWX9uDZyn1lW9R+7tPZ4sug+NGrGIo4Rk1hAXLEbcH1TQSqxts0NYXXlOWqVpvS1SFS4fRg==} + engines: {node: '>= 10.0.0'} + cpu: [x64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /@parcel/watcher-freebsd-x64/2.5.6: + resolution: {integrity: sha512-vJVi8yd/qzJxEKHkeemh7w3YAn6RJCtYlE4HPMoVnCpIXEzSrxErBW5SJBgKLbXU3WdIpkjBTeUNtyBVn8TRng==} + engines: {node: '>= 10.0.0'} + cpu: [x64] + os: [freebsd] + requiresBuild: true + dev: true + optional: true + + /@parcel/watcher-linux-arm-glibc/2.5.6: + resolution: {integrity: sha512-9JiYfB6h6BgV50CCfasfLf/uvOcJskMSwcdH1PHH9rvS1IrNy8zad6IUVPVUfmXr+u+Km9IxcfMLzgdOudz9EQ==} + engines: {node: '>= 10.0.0'} + cpu: [arm] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@parcel/watcher-linux-arm-musl/2.5.6: + resolution: {integrity: sha512-Ve3gUCG57nuUUSyjBq/MAM0CzArtuIOxsBdQ+ftz6ho8n7s1i9E1Nmk/xmP323r2YL0SONs1EuwqBp2u1k5fxg==} + engines: {node: '>= 10.0.0'} + cpu: [arm] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@parcel/watcher-linux-arm64-glibc/2.5.6: + resolution: {integrity: sha512-f2g/DT3NhGPdBmMWYoxixqYr3v/UXcmLOYy16Bx0TM20Tchduwr4EaCbmxh1321TABqPGDpS8D/ggOTaljijOA==} + engines: {node: '>= 10.0.0'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@parcel/watcher-linux-arm64-musl/2.5.6: + resolution: {integrity: sha512-qb6naMDGlbCwdhLj6hgoVKJl2odL34z2sqkC7Z6kzir8b5W65WYDpLB6R06KabvZdgoHI/zxke4b3zR0wAbDTA==} + engines: {node: '>= 10.0.0'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@parcel/watcher-linux-x64-glibc/2.5.6: + resolution: {integrity: sha512-kbT5wvNQlx7NaGjzPFu8nVIW1rWqV780O7ZtkjuWaPUgpv2NMFpjYERVi0UYj1msZNyCzGlaCWEtzc+exjMGbQ==} + engines: {node: '>= 10.0.0'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@parcel/watcher-linux-x64-musl/2.5.6: + resolution: {integrity: sha512-1JRFeC+h7RdXwldHzTsmdtYR/Ku8SylLgTU/reMuqdVD7CtLwf0VR1FqeprZ0eHQkO0vqsbvFLXUmYm/uNKJBg==} + engines: {node: '>= 10.0.0'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@parcel/watcher-win32-arm64/2.5.6: + resolution: {integrity: sha512-3ukyebjc6eGlw9yRt678DxVF7rjXatWiHvTXqphZLvo7aC5NdEgFufVwjFfY51ijYEWpXbqF5jtrK275z52D4Q==} + engines: {node: '>= 10.0.0'} + cpu: [arm64] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@parcel/watcher-win32-ia32/2.5.6: + resolution: {integrity: sha512-k35yLp1ZMwwee3Ez/pxBi5cf4AoBKYXj00CZ80jUz5h8prpiaQsiRPKQMxoLstNuqe2vR4RNPEAEcjEFzhEz/g==} + engines: {node: '>= 10.0.0'} + cpu: [ia32] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@parcel/watcher-win32-x64/2.5.6: + resolution: {integrity: sha512-hbQlYcCq5dlAX9Qx+kFb0FHue6vbjlf0FrNzSKdYK2APUf7tGfGxQCk2ihEREmbR6ZMc0MVAD5RIX/41gpUzTw==} + engines: {node: '>= 10.0.0'} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@parcel/watcher/2.5.6: + resolution: {integrity: sha512-tmmZ3lQxAe/k/+rNnXQRawJ4NjxO2hqiOLTHvWchtGZULp4RyFeh6aU4XdOYBFe2KE1oShQTv4AblOs2iOrNnQ==} + engines: {node: '>= 10.0.0'} + requiresBuild: true + dependencies: + detect-libc: 2.1.2 + is-glob: 4.0.3 + node-addon-api: 7.1.1 + picomatch: 4.0.4 + optionalDependencies: + '@parcel/watcher-android-arm64': 2.5.6 + '@parcel/watcher-darwin-arm64': 2.5.6 + '@parcel/watcher-darwin-x64': 2.5.6 + '@parcel/watcher-freebsd-x64': 2.5.6 + '@parcel/watcher-linux-arm-glibc': 2.5.6 + '@parcel/watcher-linux-arm-musl': 2.5.6 + '@parcel/watcher-linux-arm64-glibc': 2.5.6 + '@parcel/watcher-linux-arm64-musl': 2.5.6 + '@parcel/watcher-linux-x64-glibc': 2.5.6 + '@parcel/watcher-linux-x64-musl': 2.5.6 + '@parcel/watcher-win32-arm64': 2.5.6 + '@parcel/watcher-win32-ia32': 2.5.6 + '@parcel/watcher-win32-x64': 2.5.6 + dev: true + + /@tailwindcss/cli/4.2.2: + resolution: {integrity: sha512-iJS+8kAFZ8HPqnh0O5DHCLjo4L6dD97DBQEkrhfSO4V96xeefUus2jqsBs1dUMt3OU9Ks4qIkiY0mpL5UW+4LQ==} + hasBin: true + dependencies: + '@parcel/watcher': 2.5.6 + '@tailwindcss/node': 4.2.2 + '@tailwindcss/oxide': 4.2.2 + enhanced-resolve: 5.20.1 + mri: 1.2.0 + picocolors: 1.1.1 + tailwindcss: 4.2.2 + dev: true + + /@tailwindcss/node/4.2.2: + resolution: {integrity: sha512-pXS+wJ2gZpVXqFaUEjojq7jzMpTGf8rU6ipJz5ovJV6PUGmlJ+jvIwGrzdHdQ80Sg+wmQxUFuoW1UAAwHNEdFA==} + dependencies: + '@jridgewell/remapping': 2.3.5 + enhanced-resolve: 5.20.1 + jiti: 2.6.1 + lightningcss: 1.32.0 + magic-string: 0.30.21 + source-map-js: 1.2.1 + tailwindcss: 4.2.2 + dev: true + + /@tailwindcss/oxide-android-arm64/4.2.2: + resolution: {integrity: sha512-dXGR1n+P3B6748jZO/SvHZq7qBOqqzQ+yFrXpoOWWALWndF9MoSKAT3Q0fYgAzYzGhxNYOoysRvYlpixRBBoDg==} + engines: {node: '>= 20'} + cpu: [arm64] + os: [android] + requiresBuild: true + dev: true + optional: true + + /@tailwindcss/oxide-darwin-arm64/4.2.2: + resolution: {integrity: sha512-iq9Qjr6knfMpZHj55/37ouZeykwbDqF21gPFtfnhCCKGDcPI/21FKC9XdMO/XyBM7qKORx6UIhGgg6jLl7BZlg==} + engines: {node: '>= 20'} + cpu: [arm64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /@tailwindcss/oxide-darwin-x64/4.2.2: + resolution: {integrity: sha512-BlR+2c3nzc8f2G639LpL89YY4bdcIdUmiOOkv2GQv4/4M0vJlpXEa0JXNHhCHU7VWOKWT/CjqHdTP8aUuDJkuw==} + engines: {node: '>= 20'} + cpu: [x64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /@tailwindcss/oxide-freebsd-x64/4.2.2: + resolution: {integrity: sha512-YUqUgrGMSu2CDO82hzlQ5qSb5xmx3RUrke/QgnoEx7KvmRJHQuZHZmZTLSuuHwFf0DJPybFMXMYf+WJdxHy/nQ==} + engines: {node: '>= 20'} + cpu: [x64] + os: [freebsd] + requiresBuild: true + dev: true + optional: true + + /@tailwindcss/oxide-linux-arm-gnueabihf/4.2.2: + resolution: {integrity: sha512-FPdhvsW6g06T9BWT0qTwiVZYE2WIFo2dY5aCSpjG/S/u1tby+wXoslXS0kl3/KXnULlLr1E3NPRRw0g7t2kgaQ==} + engines: {node: '>= 20'} + cpu: [arm] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@tailwindcss/oxide-linux-arm64-gnu/4.2.2: + resolution: {integrity: sha512-4og1V+ftEPXGttOO7eCmW7VICmzzJWgMx+QXAJRAhjrSjumCwWqMfkDrNu1LXEQzNAwz28NCUpucgQPrR4S2yw==} + engines: {node: '>= 20'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@tailwindcss/oxide-linux-arm64-musl/4.2.2: + resolution: {integrity: sha512-oCfG/mS+/+XRlwNjnsNLVwnMWYH7tn/kYPsNPh+JSOMlnt93mYNCKHYzylRhI51X+TbR+ufNhhKKzm6QkqX8ag==} + engines: {node: '>= 20'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@tailwindcss/oxide-linux-x64-gnu/4.2.2: + resolution: {integrity: sha512-rTAGAkDgqbXHNp/xW0iugLVmX62wOp2PoE39BTCGKjv3Iocf6AFbRP/wZT/kuCxC9QBh9Pu8XPkv/zCZB2mcMg==} + engines: {node: '>= 20'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@tailwindcss/oxide-linux-x64-musl/4.2.2: + resolution: {integrity: sha512-XW3t3qwbIwiSyRCggeO2zxe3KWaEbM0/kW9e8+0XpBgyKU4ATYzcVSMKteZJ1iukJ3HgHBjbg9P5YPRCVUxlnQ==} + engines: {node: '>= 20'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@tailwindcss/oxide-wasm32-wasi/4.2.2: + resolution: {integrity: sha512-eKSztKsmEsn1O5lJ4ZAfyn41NfG7vzCg496YiGtMDV86jz1q/irhms5O0VrY6ZwTUkFy/EKG3RfWgxSI3VbZ8Q==} + engines: {node: '>=14.0.0'} + cpu: [wasm32] + requiresBuild: true + dev: true + optional: true + bundledDependencies: + - '@napi-rs/wasm-runtime' + - '@emnapi/core' + - '@emnapi/runtime' + - '@tybys/wasm-util' + - '@emnapi/wasi-threads' + - tslib + + /@tailwindcss/oxide-win32-arm64-msvc/4.2.2: + resolution: {integrity: sha512-qPmaQM4iKu5mxpsrWZMOZRgZv1tOZpUm+zdhhQP0VhJfyGGO3aUKdbh3gDZc/dPLQwW4eSqWGrrcWNBZWUWaXQ==} + engines: {node: '>= 20'} + cpu: [arm64] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@tailwindcss/oxide-win32-x64-msvc/4.2.2: + resolution: {integrity: sha512-1T/37VvI7WyH66b+vqHj/cLwnCxt7Qt3WFu5Q8hk65aOvlwAhs7rAp1VkulBJw/N4tMirXjVnylTR72uI0HGcA==} + engines: {node: '>= 20'} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@tailwindcss/oxide/4.2.2: + resolution: {integrity: sha512-qEUA07+E5kehxYp9BVMpq9E8vnJuBHfJEC0vPC5e7iL/hw7HR61aDKoVoKzrG+QKp56vhNZe4qwkRmMC0zDLvg==} + engines: {node: '>= 20'} + optionalDependencies: + '@tailwindcss/oxide-android-arm64': 4.2.2 + '@tailwindcss/oxide-darwin-arm64': 4.2.2 + '@tailwindcss/oxide-darwin-x64': 4.2.2 + '@tailwindcss/oxide-freebsd-x64': 4.2.2 + '@tailwindcss/oxide-linux-arm-gnueabihf': 4.2.2 + '@tailwindcss/oxide-linux-arm64-gnu': 4.2.2 + '@tailwindcss/oxide-linux-arm64-musl': 4.2.2 + '@tailwindcss/oxide-linux-x64-gnu': 4.2.2 + '@tailwindcss/oxide-linux-x64-musl': 4.2.2 + '@tailwindcss/oxide-wasm32-wasi': 4.2.2 + '@tailwindcss/oxide-win32-arm64-msvc': 4.2.2 + '@tailwindcss/oxide-win32-x64-msvc': 4.2.2 + dev: true + /@types/body-parser/1.19.6: resolution: {integrity: sha512-HLFeCYgz89uk22N5Qg3dvGvsv46B8GLvKKo1zKG4NybA8U2DiEO3w9lqGg29t/tfLRJpJ6iQxnVw4OnB7MoM9g==} dependencies: @@ -2297,6 +2600,16 @@ packages: which: 2.0.2 dev: true + /crx3/1.1.3: + resolution: {integrity: sha512-E4c3y/2ak83wAGN4h9Q8j3A2ii4bpRVf2vxinYYy+wJs8pyscMfEnKGzhgngZcRfOhUMr7/sxzy+lTZmQ/4KpQ==} + engines: {node: '>=12'} + hasBin: true + dependencies: + mri: 1.2.0 + pbf: 3.3.0 + yazl: 2.5.1 + dev: true + /css-loader/6.11.0_webpack@5.102.1: resolution: {integrity: sha512-CTJ+AEQJjq5NzLga5pE39qdiSV56F8ywCIsqNIRF0r7BDgWsN25aazToqAFg7ZrtA/U016xudB3ffgweORxX7g==} engines: {node: '>= 12.13.0'} @@ -2433,6 +2746,11 @@ packages: engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} dev: true + /detect-libc/2.1.2: + resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==} + engines: {node: '>=8'} + dev: true + /detect-node/2.1.0: resolution: {integrity: sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==} dev: true @@ -2538,6 +2856,14 @@ packages: tapable: 2.3.0 dev: true + /enhanced-resolve/5.20.1: + resolution: {integrity: sha512-Qohcme7V1inbAfvjItgw0EaxVX5q2rdVEZHRBrEQdRZTssLDGsL8Lwrznl8oQ/6kuTJONLaDcGjkNP247XEhcA==} + engines: {node: '>=10.13.0'} + dependencies: + graceful-fs: 4.2.11 + tapable: 2.3.0 + dev: true + /entities/2.2.0: resolution: {integrity: sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==} dev: true @@ -3405,6 +3731,11 @@ packages: supports-color: 8.1.1 dev: true + /jiti/2.6.1: + resolution: {integrity: sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==} + hasBin: true + dev: true + /js-tokens/4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} dev: true @@ -3475,6 +3806,124 @@ packages: shell-quote: 1.8.3 dev: true + /lightningcss-android-arm64/1.32.0: + resolution: {integrity: sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [android] + requiresBuild: true + dev: true + optional: true + + /lightningcss-darwin-arm64/1.32.0: + resolution: {integrity: sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /lightningcss-darwin-x64/1.32.0: + resolution: {integrity: sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /lightningcss-freebsd-x64/1.32.0: + resolution: {integrity: sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [freebsd] + requiresBuild: true + dev: true + optional: true + + /lightningcss-linux-arm-gnueabihf/1.32.0: + resolution: {integrity: sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw==} + engines: {node: '>= 12.0.0'} + cpu: [arm] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /lightningcss-linux-arm64-gnu/1.32.0: + resolution: {integrity: sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /lightningcss-linux-arm64-musl/1.32.0: + resolution: {integrity: sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /lightningcss-linux-x64-gnu/1.32.0: + resolution: {integrity: sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /lightningcss-linux-x64-musl/1.32.0: + resolution: {integrity: sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /lightningcss-win32-arm64-msvc/1.32.0: + resolution: {integrity: sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /lightningcss-win32-x64-msvc/1.32.0: + resolution: {integrity: sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /lightningcss/1.32.0: + resolution: {integrity: sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==} + engines: {node: '>= 12.0.0'} + dependencies: + detect-libc: 2.1.2 + optionalDependencies: + lightningcss-android-arm64: 1.32.0 + lightningcss-darwin-arm64: 1.32.0 + lightningcss-darwin-x64: 1.32.0 + lightningcss-freebsd-x64: 1.32.0 + lightningcss-linux-arm-gnueabihf: 1.32.0 + lightningcss-linux-arm64-gnu: 1.32.0 + lightningcss-linux-arm64-musl: 1.32.0 + lightningcss-linux-x64-gnu: 1.32.0 + lightningcss-linux-x64-musl: 1.32.0 + lightningcss-win32-arm64-msvc: 1.32.0 + lightningcss-win32-x64-msvc: 1.32.0 + dev: true + /loader-runner/4.3.1: resolution: {integrity: sha512-IWqP2SCPhyVFTBtRcgMHdzlf9ul25NwaFx4wCEH/KjAXuuHY4yNjvPXsBokp8jCB936PyWRaPKUNh8NvylLp2Q==} engines: {node: '>=6.11.5'} @@ -3530,6 +3979,12 @@ packages: yallist: 3.1.1 dev: true + /magic-string/0.30.21: + resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} + dependencies: + '@jridgewell/sourcemap-codec': 1.5.5 + dev: true + /math-intrinsics/1.1.0: resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} engines: {node: '>= 0.4'} @@ -3622,6 +4077,11 @@ packages: resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} dev: true + /mri/1.2.0: + resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==} + engines: {node: '>=4'} + dev: true + /ms/2.0.0: resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==} dev: true @@ -3665,6 +4125,10 @@ packages: tslib: 2.8.1 dev: true + /node-addon-api/7.1.1: + resolution: {integrity: sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==} + dev: true + /node-forge/1.3.1: resolution: {integrity: sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==} engines: {node: '>= 6.13.0'} @@ -3866,6 +4330,14 @@ packages: engines: {node: '>=8'} dev: true + /pbf/3.3.0: + resolution: {integrity: sha512-XDF38WCH3z5OV/OVa8GKUNtLAyneuzbCisx7QUCF8Q6Nutx0WnJrQe5O+kOtBlLfRNUws98Y58Lblp+NJG5T4Q==} + hasBin: true + dependencies: + ieee754: 1.2.1 + resolve-protobuf-schema: 2.1.0 + dev: true + /performance-now/2.1.0: resolution: {integrity: sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==} dev: true @@ -3879,6 +4351,11 @@ packages: engines: {node: '>=8.6'} dev: true + /picomatch/4.0.4: + resolution: {integrity: sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==} + engines: {node: '>=12'} + dev: true + /pify/2.3.0: resolution: {integrity: sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==} engines: {node: '>=0.10.0'} @@ -3998,6 +4475,10 @@ packages: engines: {node: '>= 0.6.0'} dev: true + /protocol-buffers-schema/3.6.0: + resolution: {integrity: sha512-TdDRD+/QNdrCGCE7v8340QyuXd4kIWIgapsE2+n/SaGiSSbomYl4TjHlvIoCWRpE7wFt02EpB35VVA2ImcBVqw==} + dev: true + /proxy-addr/2.0.7: resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==} engines: {node: '>= 0.10'} @@ -4194,6 +4675,12 @@ packages: engines: {node: '>=8'} dev: true + /resolve-protobuf-schema/2.1.0: + resolution: {integrity: sha512-kI5ffTiZWmJaS/huM8wZfEMer1eRd7oJQhDuxeCLe3t7N7mX3z94CN0xPxBQxFYQTSNz9T0i+v6inKqSdK8xrQ==} + dependencies: + protocol-buffers-schema: 3.6.0 + dev: true + /resolve/1.22.11: resolution: {integrity: sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==} engines: {node: '>= 0.4'} @@ -4583,8 +5070,8 @@ packages: engines: {node: '>= 0.4'} dev: true - /tailwindcss/4.1.17: - resolution: {integrity: sha512-j9Ee2YjuQqYT9bbRTfTZht9W/ytp5H+jJpZKiYdP/bpnXARAuELt9ofP0lPnmHjbga7SNQIxdTAXCmtKVYjN+Q==} + /tailwindcss/4.2.2: + resolution: {integrity: sha512-KWBIxs1Xb6NoLdMVqhbhgwZf2PGBpPEiwOqgI4pFIYbNTfBXiKYyWoTsXgBQ9WFg/OlhnvHaY+AEpW7wSmFo2Q==} dev: true /tapable/2.3.0: diff --git a/scripts/package-extension.js b/scripts/package-extension.js new file mode 100755 index 0000000..24b7dcb --- /dev/null +++ b/scripts/package-extension.js @@ -0,0 +1,195 @@ +#!/usr/bin/env node + +/** + * package-extension.js — Packages the build/ directory into distributable + * archives for Chrome (ZIP + CRX) and Firefox (XPI). + * + * Usage: + * BROWSER=chrome node scripts/package-extension.js # → dist/*.zip (+ *.crx if key present) + * BROWSER=firefox node scripts/package-extension.js # → dist/*.xpi + * + * Environment variables: + * BROWSER "chrome" | "firefox" (default: "chrome") + * CRX_KEY_PATH Path to .pem private key for CRX signing (optional) + * CRX_KEY_BASE64 Base64-encoded .pem key (CI-friendly, optional) + * SKIP_CRX "1" to skip CRX creation even if key is available + * + * Outputs go to dist/ relative to the project root: + * dist/cstradeup-v{version}-chrome.zip + * dist/cstradeup-v{version}-chrome.crx (Chrome only, key required) + * dist/cstradeup-v{version}-firefox.xpi (Firefox only) + */ + +const fs = require("fs"); +const path = require("path"); +const { execSync } = require("child_process"); + +// --------------------------------------------------------------------------- +// Configuration +// --------------------------------------------------------------------------- + +const ROOT = path.resolve(__dirname, ".."); +const BUILD_DIR = path.join(ROOT, "build"); +const DIST_DIR = path.join(ROOT, "dist"); +const PKG = require(path.join(ROOT, "package.json")); + +const BROWSER = process.env.BROWSER || "chrome"; +const VERSION = PKG.version; +const NAME = "cstradeup"; +const PREFIX = `${NAME}-v${VERSION}-${BROWSER}`; + +// --------------------------------------------------------------------------- +// Helpers +// --------------------------------------------------------------------------- + +function ensureDir(dir) { + if (!fs.existsSync(dir)) { + fs.mkdirSync(dir, { recursive: true }); + } +} + +function exec(cmd, opts = {}) { + console.log(` $ ${cmd}`); + return execSync(cmd, { stdio: "inherit", ...opts }); +} + +function fileSize(filePath) { + const bytes = fs.statSync(filePath).size; + if (bytes < 1024) return `${bytes} B`; + if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`; + return `${(bytes / (1024 * 1024)).toFixed(2)} MB`; +} + +// --------------------------------------------------------------------------- +// Validation +// --------------------------------------------------------------------------- + +if (!fs.existsSync(BUILD_DIR)) { + console.error(`Error: build/ directory not found. Run the build first:\n pnpm build:${BROWSER}`); + process.exit(1); +} + +if (!fs.existsSync(path.join(BUILD_DIR, "manifest.json"))) { + console.error("Error: manifest.json not found in build/. Build may have failed."); + process.exit(1); +} + +// --------------------------------------------------------------------------- +// Create ZIP archive (works for both Chrome and Firefox) +// --------------------------------------------------------------------------- + +function createZip(outputPath) { + console.log(`\nCreating ZIP: ${path.basename(outputPath)}`); + // Remove previous artifact if it exists + if (fs.existsSync(outputPath)) fs.unlinkSync(outputPath); + + exec(`cd "${BUILD_DIR}" && zip -r "${outputPath}" . -x "*.DS_Store" -x "__MACOSX/*"`); + console.log(` ✓ ${path.basename(outputPath)} (${fileSize(outputPath)})`); + return outputPath; +} + +// --------------------------------------------------------------------------- +// Create CRX3 (Chrome only, requires private key) +// --------------------------------------------------------------------------- + +function resolveCrxKey() { + // 1. Explicit path + if (process.env.CRX_KEY_PATH) { + const keyPath = path.resolve(process.env.CRX_KEY_PATH); + if (!fs.existsSync(keyPath)) { + console.warn(` ⚠ CRX_KEY_PATH set but file not found: ${keyPath}`); + return null; + } + return keyPath; + } + + // 2. Base64-encoded key (CI-friendly) + if (process.env.CRX_KEY_BASE64) { + const tmpKey = path.join(DIST_DIR, ".crx-key.pem"); + fs.writeFileSync(tmpKey, Buffer.from(process.env.CRX_KEY_BASE64, "base64")); + return tmpKey; + } + + // 3. Convention: key.pem in project root + const defaultKey = path.join(ROOT, "key.pem"); + if (fs.existsSync(defaultKey)) { + return defaultKey; + } + + return null; +} + +function createCrx(zipPath, outputPath) { + if (process.env.SKIP_CRX === "1") { + console.log("\n Skipping CRX (SKIP_CRX=1)"); + return null; + } + + const keyPath = resolveCrxKey(); + if (!keyPath) { + console.log("\n Skipping CRX (no signing key found)"); + console.log(" To enable CRX: set CRX_KEY_PATH, CRX_KEY_BASE64, or place key.pem in project root"); + return null; + } + + console.log(`\nCreating CRX: ${path.basename(outputPath)}`); + + try { + // Use crx3 CLI if available, fallback to npx + const crx3Bin = path.join(ROOT, "node_modules", ".bin", "crx3"); + const crx3Cmd = fs.existsSync(crx3Bin) ? crx3Bin : "npx crx3"; + + // crx3 packs a directory into a .crx file + exec(`${crx3Cmd} "${BUILD_DIR}" -p "${keyPath}" -o "${outputPath}"`); + console.log(` ✓ ${path.basename(outputPath)} (${fileSize(outputPath)})`); + + // Clean up temp key if we created one + const tmpKey = path.join(DIST_DIR, ".crx-key.pem"); + if (fs.existsSync(tmpKey)) fs.unlinkSync(tmpKey); + + return outputPath; + } catch (e) { + console.warn(` ⚠ CRX creation failed: ${e.message}`); + console.warn(" Install crx3: pnpm add -D crx3"); + return null; + } +} + +// --------------------------------------------------------------------------- +// Main +// --------------------------------------------------------------------------- + +function main() { + console.log(`\n📦 Packaging ${BROWSER} extension v${VERSION}\n`); + ensureDir(DIST_DIR); + + const artifacts = []; + + if (BROWSER === "chrome") { + // Chrome: ZIP (for Web Store) + CRX (for website / self-hosting) + const zipPath = path.join(DIST_DIR, `${PREFIX}.zip`); + createZip(zipPath); + artifacts.push(zipPath); + + const crxPath = path.join(DIST_DIR, `${PREFIX}.crx`); + const crxResult = createCrx(zipPath, crxPath); + if (crxResult) artifacts.push(crxResult); + } else if (BROWSER === "firefox") { + // Firefox: XPI (a ZIP with .xpi extension — for AMO and self-hosting) + const xpiPath = path.join(DIST_DIR, `${PREFIX}.xpi`); + createZip(xpiPath); + artifacts.push(xpiPath); + + // Also create a .zip for AMO submission (some workflows prefer .zip) + const zipPath = path.join(DIST_DIR, `${PREFIX}.zip`); + createZip(zipPath); + artifacts.push(zipPath); + } + + console.log("\n✅ Packaging complete!"); + console.log("Artifacts:"); + artifacts.forEach((a) => console.log(` → ${path.relative(ROOT, a)}`)); + console.log(); +} + +main(); diff --git a/src/background/background_ff.html b/src/background/background_ff.html new file mode 100644 index 0000000..b8aee3c --- /dev/null +++ b/src/background/background_ff.html @@ -0,0 +1,23 @@ + + + + + + CSTRADEUP Background + + + + + + diff --git a/src/background/offscreen/offscreen.ts b/src/background/offscreen/offscreen.ts index 8213f7e..150b88b 100644 --- a/src/background/offscreen/offscreen.ts +++ b/src/background/offscreen/offscreen.ts @@ -10,6 +10,8 @@ import { getAccountAge, SteamAccountAge } from "./user/badges"; import { GetParmsFromCursor, SteamHttpError } from "./inventory_history/helpers"; import { doSteamRequestAndSendToBackend } from "./inventory_history/request"; +import { IS_CHROME } from "../../lib/compat"; + // ============================================================================= // Configuration // ============================================================================= @@ -193,7 +195,11 @@ function setupMessageListener(): void { } function signalReady(): void { - chrome.runtime.sendMessage({ type: "offscreen_ready" }); + // On Chrome, the service worker waits for this signal before proceeding. + // On Firefox, both scripts run in the same background page — no signal needed. + if (IS_CHROME) { + chrome.runtime.sendMessage({ type: "offscreen_ready" }); + } } // ============================================================================= diff --git a/src/background/service-worker.ts b/src/background/service-worker.ts index 6105fe4..81a6128 100644 --- a/src/background/service-worker.ts +++ b/src/background/service-worker.ts @@ -35,6 +35,7 @@ import { getStore as getCstradeupStore, saveHistoryCursor, invalidateAuth as inv import { SteamAccountAge } from "./offscreen/user/badges"; import { syncBadge } from "../lib/badge"; import { CSTRADEUP_HOSTNAME, CSTRADEUP_DOMAIN } from "../lib/env"; +import { IS_CHROME } from "../lib/compat"; const HOSTNAME = CSTRADEUP_HOSTNAME; const UPDATE_INVENTORY_ROUTE = "/account/inventory/extension/update"; const INVENTORY_HISTORY_ROUTE = "/account/inventory/extension/history"; @@ -226,7 +227,9 @@ async function handleNotarizeCursor( // 2. Resolve Steam profile URL const profileBaseUrl = await resolveProfileBaseUrl(steamStore.steam_id, steamStore.token); - // 3. Open offscreen document and forward request + // 3. Open offscreen document and forward request. + // Chrome: dynamically creates an offscreen document via chrome.offscreen API. + // Firefox: no-op — the offscreen bundle is already loaded in background_ff.html. await openOffscreenDocument(); const resp = await chrome.runtime.sendMessage({ @@ -239,7 +242,8 @@ async function handleNotarizeCursor( }); // Handle WASM restart signal (same pattern as existing notarization) - if (resp?.shouldShutdown) { + // chrome.offscreen API is Chrome-only; Firefox background page persists. + if (resp?.shouldShutdown && IS_CHROME) { const hasDoc = await chrome.offscreen.hasDocument(); if (hasDoc) { await chrome.offscreen.closeDocument(); @@ -262,7 +266,16 @@ const OFFSCREEN_DOCUMENT_PATH = "offscreen.html"; let creating: Promise | null = null; +/** + * Opens the Chrome offscreen document for WASM operations. + * + * On Chrome: creates a separate offscreen document via the chrome.offscreen API. + * On Firefox: no-op — the offscreen bundle is loaded directly in the persistent + * background page (background_ff.html) alongside service-worker. + */ export async function openOffscreenDocument(): Promise { + if (!IS_CHROME) return; // Firefox: offscreen code lives in background page + const offscreenUrl = chrome.runtime.getURL(OFFSCREEN_DOCUMENT_PATH); const hasExistingContext = await chrome.offscreen.hasDocument(); diff --git a/src/background/services/notary.ts b/src/background/services/notary.ts index 03b39a8..57e2f7b 100644 --- a/src/background/services/notary.ts +++ b/src/background/services/notary.ts @@ -9,6 +9,7 @@ import { sleep, withTimeout } from "../../lib/utils"; import { getStore as getSteamStore, saveMemberSince } from "../../lib/storage/reducer/steam"; import { openOffscreenDocument } from "../service-worker"; import { ensureLocaleCookies } from "../../lib/session"; +import { IS_CHROME } from "../../lib/compat"; // ============================================================================= // Configuration @@ -503,7 +504,7 @@ export async function sendToOffscreen( }); // Check if offscreen signaled it should be closed (WASM workaround for tlsn issue #959) - if (resp?.shouldShutdown) { + if (resp?.shouldShutdown && IS_CHROME) { const hasExistingContext = await chrome.offscreen.hasDocument(); if (hasExistingContext) { diff --git a/src/lib/compat.ts b/src/lib/compat.ts new file mode 100644 index 0000000..f18cf49 --- /dev/null +++ b/src/lib/compat.ts @@ -0,0 +1,20 @@ +/** + * compat.ts — Build-time browser target constants. + * + * Values are injected by webpack DefinePlugin (see webpack.config.js). + * Dead-code elimination removes unused branches at build time, so + * Chrome-only code never ships in the Firefox bundle and vice-versa. + * + * Usage: + * import { IS_CHROME, IS_FIREFOX } from '../lib/compat'; + * + * if (IS_CHROME) { + * // Chrome-only code — tree-shaken from Firefox builds + * } + */ + +declare const __BROWSER__: 'chrome' | 'firefox'; + +export const BROWSER: 'chrome' | 'firefox' = __BROWSER__; +export const IS_CHROME = BROWSER === 'chrome'; +export const IS_FIREFOX = BROWSER === 'firefox'; diff --git a/src/lib/utils.ts b/src/lib/utils.ts index 23838a5..54877cb 100644 --- a/src/lib/utils.ts +++ b/src/lib/utils.ts @@ -55,10 +55,12 @@ export function getCookie(cname: string) { return null; } +import { IS_CHROME } from './compat'; + export async function isRunningOffscreen() { - const existingContexts = await chrome.runtime.getContexts({}); + if (!IS_CHROME) return false; // Offscreen API is Chrome-only - console.log('existingContexts', existingContexts); + const existingContexts = await chrome.runtime.getContexts({}); const offscreenDocument = existingContexts.find( (c) => c.contextType === 'OFFSCREEN_DOCUMENT' diff --git a/src/styles/tailwind.css b/src/styles/tailwind.css index bd6213e..89be1fc 100644 --- a/src/styles/tailwind.css +++ b/src/styles/tailwind.css @@ -1,3 +1,8 @@ -@tailwind base; -@tailwind components; -@tailwind utilities; \ No newline at end of file +@import "tailwindcss"; +@plugin "daisyui"; +@source "../../src"; + +@theme { + --font-sans: "Graphik", sans-serif; + --font-serif: "Merriweather", serif; +} \ No newline at end of file diff --git a/styles.css b/styles.css index 97bbe7d..67fa69f 100644 --- a/styles.css +++ b/styles.css @@ -1 +1,2 @@ -/*! tailwindcss v3.4.3 | MIT License | https://tailwindcss.com*/*,:after,:before{box-sizing:border-box;border:0 solid oklch(92.8% .006 264.531)}:after,:before{--tw-content:""}:host,html{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:Graphik,sans-serif;font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,pre,samp{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-feature-settings:normal;font-variation-settings:normal;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:initial}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-feature-settings:inherit;font-variation-settings:inherit;font-size:100%;font-weight:inherit;line-height:inherit;letter-spacing:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:initial;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:initial}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dd,dl,figure,h1,h2,h3,h4,h5,h6,hr,p,pre{margin:0}fieldset{margin:0}fieldset,legend{padding:0}menu,ol,ul{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{opacity:1;color:oklch(70.7% .022 261.325)}input::placeholder,textarea::placeholder{opacity:1;color:oklch(70.7% .022 261.325)}[role=button],button{cursor:pointer}:disabled{cursor:default}audio,canvas,embed,iframe,img,object,svg,video{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]{display:none}:root:has(input.theme-controller[value=light]:checked),:where(:root),[data-theme=light]{color-scheme:light;--color-base-100:oklch(100% 0 0);--color-base-200:oklch(98% 0 0);--color-base-300:oklch(95% 0 0);--color-base-content:oklch(21% 0.006 285.885);--color-primary:oklch(45% 0.24 277.023);--color-primary-content:oklch(93% 0.034 272.788);--color-secondary:oklch(65% 0.241 354.308);--color-secondary-content:oklch(94% 0.028 342.258);--color-accent:oklch(77% 0.152 181.912);--color-accent-content:oklch(38% 0.063 188.416);--color-neutral:oklch(14% 0.005 285.823);--color-neutral-content:oklch(92% 0.004 286.32);--color-info:oklch(74% 0.16 232.661);--color-info-content:oklch(29% 0.066 243.157);--color-success:oklch(76% 0.177 163.223);--color-success-content:oklch(37% 0.077 168.94);--color-warning:oklch(82% 0.189 84.429);--color-warning-content:oklch(41% 0.112 45.904);--color-error:oklch(71% 0.194 13.428);--color-error-content:oklch(27% 0.105 12.094);--radius-selector:0.5rem;--radius-field:0.25rem;--radius-box:0.5rem;--size-selector:0.25rem;--size-field:0.25rem;--border:1px;--depth:1;--noise:0}@media (prefers-color-scheme:dark){:root:not([data-theme]){color-scheme:dark;--color-base-100:oklch(25.33% 0.016 252.42);--color-base-200:oklch(23.26% 0.014 253.1);--color-base-300:oklch(21.15% 0.012 254.09);--color-base-content:oklch(97.807% 0.029 256.847);--color-primary:oklch(58% 0.233 277.117);--color-primary-content:oklch(96% 0.018 272.314);--color-secondary:oklch(65% 0.241 354.308);--color-secondary-content:oklch(94% 0.028 342.258);--color-accent:oklch(77% 0.152 181.912);--color-accent-content:oklch(38% 0.063 188.416);--color-neutral:oklch(14% 0.005 285.823);--color-neutral-content:oklch(92% 0.004 286.32);--color-info:oklch(74% 0.16 232.661);--color-info-content:oklch(29% 0.066 243.157);--color-success:oklch(76% 0.177 163.223);--color-success-content:oklch(37% 0.077 168.94);--color-warning:oklch(82% 0.189 84.429);--color-warning-content:oklch(41% 0.112 45.904);--color-error:oklch(71% 0.194 13.428);--color-error-content:oklch(27% 0.105 12.094);--radius-selector:0.5rem;--radius-field:0.25rem;--radius-box:0.5rem;--size-selector:0.25rem;--size-field:0.25rem;--border:1px;--depth:1;--noise:0}}: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(98% 0 0);--color-base-300:oklch(95% 0 0);--color-base-content:oklch(21% 0.006 285.885);--color-primary:oklch(45% 0.24 277.023);--color-primary-content:oklch(93% 0.034 272.788);--color-secondary:oklch(65% 0.241 354.308);--color-secondary-content:oklch(94% 0.028 342.258);--color-accent:oklch(77% 0.152 181.912);--color-accent-content:oklch(38% 0.063 188.416);--color-neutral:oklch(14% 0.005 285.823);--color-neutral-content:oklch(92% 0.004 286.32);--color-info:oklch(74% 0.16 232.661);--color-info-content:oklch(29% 0.066 243.157);--color-success:oklch(76% 0.177 163.223);--color-success-content:oklch(37% 0.077 168.94);--color-warning:oklch(82% 0.189 84.429);--color-warning-content:oklch(41% 0.112 45.904);--color-error:oklch(71% 0.194 13.428);--color-error-content:oklch(27% 0.105 12.094);--radius-selector:0.5rem;--radius-field:0.25rem;--radius-box:0.5rem;--size-selector:0.25rem;--size-field:0.25rem;--border:1px;--depth:1;--noise:0}:root:has(input.theme-controller[value=dark]:checked),[data-theme=dark]{color-scheme:dark;--color-base-100:oklch(25.33% 0.016 252.42);--color-base-200:oklch(23.26% 0.014 253.1);--color-base-300:oklch(21.15% 0.012 254.09);--color-base-content:oklch(97.807% 0.029 256.847);--color-primary:oklch(58% 0.233 277.117);--color-primary-content:oklch(96% 0.018 272.314);--color-secondary:oklch(65% 0.241 354.308);--color-secondary-content:oklch(94% 0.028 342.258);--color-accent:oklch(77% 0.152 181.912);--color-accent-content:oklch(38% 0.063 188.416);--color-neutral:oklch(14% 0.005 285.823);--color-neutral-content:oklch(92% 0.004 286.32);--color-info:oklch(74% 0.16 232.661);--color-info-content:oklch(29% 0.066 243.157);--color-success:oklch(76% 0.177 163.223);--color-success-content:oklch(37% 0.077 168.94);--color-warning:oklch(82% 0.189 84.429);--color-warning-content:oklch(41% 0.112 45.904);--color-error:oklch(71% 0.194 13.428);--color-error-content:oklch(27% 0.105 12.094);--radius-selector:0.5rem;--radius-field:0.25rem;--radius-box:0.5rem;--size-selector:0.25rem;--size-field:0.25rem;--border:1px;--depth:1;--noise:0}:root{--fx-noise:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 200 200'%3E%3Cfilter id='a'%3E%3CfeTurbulence baseFrequency='1.34' numOctaves='4' stitchTiles='stitch' type='fractalNoise'/%3E%3C/filter%3E%3Cpath d='M0 0h200v200H0z' filter='url(%23a)' opacity='.2'/%3E%3C/svg%3E");scrollbar-color:color-mix(in oklch,currentColor 35%,#0000) #0000}@property --radialprogress{syntax:"";inherits:true;initial-value:0}:root:not(span){overflow:var(--page-overflow)}:root{--page-scroll-bg-on:linear-gradient(var(--root-bg),var(--root-bg)) color-mix(in srgb,var(--root-bg),oklch(0% 0 0) calc(var(--page-has-backdrop, 0)*40%));--page-scroll-transition-on:background-color 0.3s ease-out;transition:var(--page-scroll-transition);scrollbar-gutter:var(--page-scroll-gutter,unset);scrollbar-gutter:if(style(--page-has-scroll:1):var(--page-scroll-gutter,unset) ; else:unset)}:root:root{background:var(--page-scroll-bg,var(--root-bg,var(--color-base-100)))}@keyframes set-page-has-scroll{0%,to{--page-has-scroll:1}}:root,[data-theme]{background-color:var(--root-bg,var(--color-base-100));color:var(--color-base-content)}:where(:root,[data-theme]){--root-bg:var(--color-base-100)}*,::backdrop,:after,:before{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:#93c5fd80;--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }.container{width:100%}@media (min-width:640px){.container{max-width:640px}}@media (min-width:768px){.container{max-width:768px}}@media (min-width:1024px){.container{max-width:1024px}}@media (min-width:1280px){.container{max-width:1280px}}@media (min-width:1536px){.container{max-width:1536px}}@keyframes rating{0%,40%{scale:1.1;filter:brightness(1.05) contrast(1.05)}}@layer daisyui.l1.l2.l3{.dropdown{position:relative;display:inline-block;position-area:var(--anchor-v,bottom) var(--anchor-h,span-right);@starting-style{&[popover],.dropdown-content{scale:95%;opacity:0}}}.dropdown>:not(:has(~[class*=dropdown-content])):focus{--tw-outline-style:none;outline-style:none}@media (forced-colors:active){.dropdown>:not(:has(~[class*=dropdown-content])):focus{outline:2px solid #0000;outline-offset:2px}}.dropdown .dropdown-content{position:absolute}.dropdown.dropdown-close .dropdown-content,.dropdown.dropdown-hover:not(:hover) [tabindex]:first-child:focus:not(:focus-visible)~.dropdown-content,.dropdown:not(details,.dropdown-open,.dropdown-hover:hover,:focus-within) .dropdown-content{display:none;transform-origin:top;opacity:0;scale:95%}.dropdown .dropdown-content,.dropdown[popover]{z-index:999}@media (prefers-reduced-motion:no-preference){.dropdown .dropdown-content,.dropdown[popover]{animation:dropdown .2s;transition-property:opacity,scale,display;transition-behavior:allow-discrete;transition-duration:.2s;transition-timing-function:cubic-bezier(.4,0,.2,1)}}.dropdown:not(.dropdown-close).dropdown-open>[tabindex]:first-child,.dropdown:not(.dropdown-close):focus-within>[tabindex]:first-child,.dropdown:not(.dropdown-close):not(.dropdown-hover):focus>[tabindex]:first-child{pointer-events:none}.dropdown:not(.dropdown-close).dropdown-hover:hover .dropdown-content,.dropdown:not(.dropdown-close).dropdown-open .dropdown-content,.dropdown:not(.dropdown-close):focus-within .dropdown-content,.dropdown:not(.dropdown-close):not(.dropdown-hover):focus .dropdown-content{opacity:100%;scale:100%}.dropdown:is(details) summary::-webkit-details-marker{display:none}.dropdown:where([popover]){background:#0000}.dropdown[popover]{position:fixed;color:inherit}@supports not (position-area:bottom){.dropdown[popover]{margin:auto}.dropdown[popover].dropdown-close,.dropdown[popover].dropdown-open:not(:popover-open){display:none;transform-origin:top;opacity:0;scale:95%}.dropdown[popover]::backdrop{background-color:color-mix(in oklab,#000 30%,#0000)}}.dropdown[popover].dropdown-close,.dropdown[popover]:not(.dropdown-open,:popover-open){display:none;transform-origin:top;opacity:0;scale:95%}}@keyframes dropdown{0%{opacity:0}}@layer daisyui.l1.l2.l3{.tabs{display:flex;--tabs-height:auto;--tabs-direction:row;--tab-height:calc(var(--size-field, 0.25rem)*10);height:var(--tabs-height);flex-direction:var(--tabs-direction)}.tab,.tabs{flex-wrap:wrap}.tab{position:relative;display:inline-flex;cursor:pointer;-webkit-appearance:none;-moz-appearance:none;appearance:none;align-items:center;justify-content:center;text-align:center;webkit-user-select:none;-webkit-user-select:none;-moz-user-select:none;user-select:none;--tab-p:0.75rem;--tab-bg:var(--color-base-100);--tab-border-color:var(--color-base-300);--tab-radius-ss:0;--tab-radius-se:0;--tab-radius-es:0;--tab-radius-ee:0;--tab-order:0;--tab-radius-min:calc(0.75rem - var(--border));--tab-radius-limit:min(var(--radius-field),var(--tab-radius-min));--tab-radius-grad:#0000 calc(69% - var(--border)),var(--tab-border-color) calc(69% - var(--border) + 0.25px),var(--tab-border-color) calc(69% - var(--border) + var(--border)),var(--tab-bg) calc(69% - var(--border) + var(--border) + 0.25px);border-color:#0000;order:var(--tab-order);height:var(--tab-height);font-size:.875rem;padding-inline-start:var(--tab-p);padding-inline-end:var(--tab-p)}@media (hover:hover){.tab:hover{color:var(--color-base-content)}}.tab:is(input[type=radio]){min-width:-moz-fit-content;min-width:fit-content}.tab:is(input[type=radio]):after{--tw-content:attr(aria-label);content:var(--tw-content)}.tab:is(label){position:relative}.tab:is(label) input{position:absolute;inset:0;cursor:pointer;-webkit-appearance:none;-moz-appearance:none;appearance:none;opacity:0}.tab:checked+.tab-content,.tab:is(.tab-active,[aria-selected=true],[aria-current=true],[aria-current=page])+.tab-content,.tab:is(label:has(:checked))+.tab-content{display:block}.tab:not(:checked,label:has(:checked),:hover,.tab-active,[aria-selected=true],[aria-current=true],[aria-current=page]){color:color-mix(in oklab,var(--color-base-content) 50%,#0000)}.tab:not(input):empty{flex-grow:1;cursor:default}.tab:focus{--tw-outline-style:none;outline-style:none}@media (forced-colors:active){.tab:focus{outline:2px solid #0000;outline-offset:2px}}.tab:focus-visible,.tab:is(label:has(:checked:focus-visible)){outline:2px solid currentColor;outline-offset:-5px}.tab[disabled]{pointer-events:none;opacity:40%}.\!tab{position:relative!important;display:inline-flex!important;cursor:pointer!important;-webkit-appearance:none!important;-moz-appearance:none!important;appearance:none!important;flex-wrap:wrap!important;align-items:center!important;justify-content:center!important;text-align:center!important;webkit-user-select:none!important;-webkit-user-select:none!important;-moz-user-select:none!important;user-select:none!important;--tab-p:0.75rem!important;--tab-bg:var(--color-base-100)!important;--tab-border-color:var(--color-base-300)!important;--tab-radius-ss:0!important;--tab-radius-se:0!important;--tab-radius-es:0!important;--tab-radius-ee:0!important;--tab-order:0!important;--tab-radius-min:calc(0.75rem - var(--border))!important;--tab-radius-limit:min(var(--radius-field),var(--tab-radius-min))!important;--tab-radius-grad:#0000 calc(69% - var(--border)),var(--tab-border-color) calc(69% - var(--border) + 0.25px),var(--tab-border-color) calc(69% - var(--border) + var(--border)),var(--tab-bg) calc(69% - var(--border) + var(--border) + 0.25px)!important;border-color:#0000!important;order:var(--tab-order)!important;height:var(--tab-height)!important;font-size:.875rem!important;padding-inline-start:var(--tab-p)!important;padding-inline-end:var(--tab-p)!important}@media (hover:hover){.\!tab:hover{color:var(--color-base-content)!important}}.\!tab:is(input[type=radio]){min-width:-moz-fit-content!important;min-width:fit-content!important}.\!tab:is(input[type=radio]):after{--tw-content:attr(aria-label)!important;content:var(--tw-content)!important}.\!tab:is(label){position:relative!important}.\!tab:is(label) input{position:absolute!important;inset:0!important;cursor:pointer!important;-webkit-appearance:none!important;-moz-appearance:none!important;appearance:none!important;opacity:0!important}.\!tab:checked+.tab-content,.\!tab:is(.tab-active,[aria-selected=true],[aria-current=true],[aria-current=page])+.tab-content,.\!tab:is(label:has(:checked))+.tab-content{display:block!important}.\!tab:not(:checked,label:has(:checked),:hover,.tab-active,[aria-selected=true],[aria-current=true],[aria-current=page]){color:color-mix(in oklab,var(--color-base-content) 50%,#0000)!important}.\!tab:not(input):empty{flex-grow:1!important;cursor:default!important}.\!tab:focus{--tw-outline-style:none!important;outline-style:none!important}@media (forced-colors:active){.\!tab:focus{outline:2px solid #0000!important;outline-offset:2px!important}}.\!tab:focus-visible,.\!tab:is(label:has(:checked:focus-visible)){outline:2px solid currentColor!important;outline-offset:-5px!important}.\!tab[disabled]{pointer-events:none!important;opacity:40%!important}}@layer daisyui.l1.l2{.tabs-border>.tab{--tab-border-color:#0000 #0000 var(--tab-border-color) #0000;position:relative;border-radius:var(--radius-field)}.tabs-border>.tab:before{content:"";background-color:var(--tab-border-color);transition:background-color .2s ease;width:80%;height:3px;border-radius:var(--radius-field);bottom:0;left:10%;position:absolute}.tabs-border>.tab:is(.tab-active,[aria-selected=true],[aria-current=true],[aria-current=page]):not(.tab-disabled,[disabled]):before,.tabs-border>.tab:is(input:checked):before,.tabs-border>.tab:is(label:has(:checked)):before{--tab-border-color:currentColor;border-top:3px solid}.tabs-border>.\!tab{--tab-border-color:#0000 #0000 var(--tab-border-color) #0000!important;position:relative!important}.tabs-border>.\!tab,.tabs-border>.\!tab:before{border-radius:var(--radius-field)!important}.tabs-border>.\!tab:before{content:""!important;background-color:var(--tab-border-color)!important;transition:background-color .2s ease!important;width:80%!important;height:3px!important;bottom:0!important;left:10%!important;position:absolute!important}.tabs-border>.\!tab:is(.tab-active,[aria-selected=true],[aria-current=true],[aria-current=page]):not(.tab-disabled,[disabled]):before,.tabs-border>.\!tab:is(input:checked):before,.tabs-border>.\!tab:is(label:has(:checked)):before{--tab-border-color:currentColor!important;border-top:3px solid!important}.tabs-lift{--tabs-height:auto;--tabs-direction:row}.tabs-lift>.tab{--tab-border:0 0 var(--border) 0;--tab-radius-ss:var(--tab-radius-limit);--tab-radius-se:var(--tab-radius-limit);--tab-radius-es:0;--tab-radius-ee:0;--tab-paddings:var(--border) var(--tab-p) 0 var(--tab-p);--tab-border-colors:#0000 #0000 var(--tab-border-color) #0000;--tab-corner-width:calc(100% + var(--tab-radius-limit)*2);--tab-corner-height:var(--tab-radius-limit);--tab-corner-position:top left,top right;border-width:var(--tab-border);border-start-start-radius:var(--tab-radius-ss);border-start-end-radius:var(--tab-radius-se);border-end-start-radius:var(--tab-radius-es);border-end-end-radius:var(--tab-radius-ee);padding:var(--tab-paddings);border-color:var(--tab-border-colors)}.tabs-lift>.tab:is(.tab-active,[aria-selected=true],[aria-current=true],[aria-current=page]):not(.tab-disabled,[disabled]),.tabs-lift>.tab:is(input:checked,label:has(:checked)){--tab-border:var(--border) var(--border) 0 var(--border);--tab-border-colors:var(--tab-border-color) var(--tab-border-color) #0000 var(--tab-border-color);--tab-paddings:0 calc(var(--tab-p) - var(--border)) var(--border) calc(var(--tab-p) - var(--border));--tab-inset:auto auto 0 auto;--radius-start:radial-gradient(circle at top left,var(--tab-radius-grad));--radius-end:radial-gradient(circle at top right,var(--tab-radius-grad));background-color:var(--tab-bg)}.tabs-lift>.tab:is(.tab-active,[aria-selected=true],[aria-current=true],[aria-current=page]):not(.tab-disabled,[disabled]):before,.tabs-lift>.tab:is(input:checked,label:has(:checked)):before{z-index:1;content:"";display:block;position:absolute;width:var(--tab-corner-width);height:var(--tab-corner-height);background-position:var(--tab-corner-position);background-image:var(--radius-start),var(--radius-end);background-size:var(--tab-radius-limit) var(--tab-radius-limit);background-repeat:no-repeat;inset:var(--tab-inset)}.tabs-lift>.tab:is(.tab-active,[aria-selected=true],[aria-current=true],[aria-current=page]):not(.tab-disabled,[disabled]):first-child:before,.tabs-lift>.tab:is(input:checked,label:has(:checked)):first-child:before{--radius-start:none}[dir=rtl] .tabs-lift>.tab:is(.tab-active,[aria-selected=true],[aria-current=true],[aria-current=page]):not(.tab-disabled,[disabled]):first-child:before,[dir=rtl] .tabs-lift>.tab:is(input:checked,label:has(:checked)):first-child:before{transform:rotateY(180deg)}.tabs-lift>.tab:is(.tab-active,[aria-selected=true],[aria-current=true],[aria-current=page]):not(.tab-disabled,[disabled]):last-child:before,.tabs-lift>.tab:is(input:checked,label:has(:checked)):last-child:before{--radius-end:none}[dir=rtl] .tabs-lift>.tab:is(.tab-active,[aria-selected=true],[aria-current=true],[aria-current=page]):not(.tab-disabled,[disabled]):last-child:before,[dir=rtl] .tabs-lift>.tab:is(input:checked,label:has(:checked)):last-child:before{transform:rotateY(180deg)}.tabs-lift:has(>.tab-content)>.tab:first-child:not(.tab-active,[aria-selected=true],[aria-current=true],[aria-current=page]){--tab-border-colors:var(--tab-border-color) var(--tab-border-color) #0000 var(--tab-border-color)}.tabs-lift>.tab-content{--tabcontent-margin:calc(var(--border)*-1) 0 0 0;--tabcontent-radius-ss:0;--tabcontent-radius-se:var(--radius-box);--tabcontent-radius-es:var(--radius-box);--tabcontent-radius-ee:var(--radius-box)}.tabs-lift :checked+.tab-content:first-child,.tabs-lift :checked+.tab-content:nth-child(n+3),.tabs-lift :is(.tab-active,[aria-selected=true],[aria-current=true],[aria-current=page])+.tab-content:first-child,.tabs-lift :is(.tab-active,[aria-selected=true],[aria-current=true],[aria-current=page])+.tab-content:nth-child(n+3),.tabs-lift label:has(:checked)+.tab-content:first-child,.tabs-lift label:has(:checked)+.tab-content:nth-child(n+3){--tabcontent-radius-ss:var(--radius-box)}.tabs-lift>.\!tab{--tab-border:0 0 var(--border) 0!important;--tab-radius-ss:var(--tab-radius-limit)!important;--tab-radius-se:var(--tab-radius-limit)!important;--tab-radius-es:0!important;--tab-radius-ee:0!important;--tab-paddings:var(--border) var(--tab-p) 0 var(--tab-p)!important;--tab-border-colors:#0000 #0000 var(--tab-border-color) #0000!important;--tab-corner-width:calc(100% + var(--tab-radius-limit)*2)!important;--tab-corner-height:var(--tab-radius-limit)!important;--tab-corner-position:top left,top right!important;border-width:var(--tab-border)!important;border-start-start-radius:var(--tab-radius-ss)!important;border-start-end-radius:var(--tab-radius-se)!important;border-end-start-radius:var(--tab-radius-es)!important;border-end-end-radius:var(--tab-radius-ee)!important;padding:var(--tab-paddings)!important;border-color:var(--tab-border-colors)!important}.tabs-lift>.\!tab:is(.tab-active,[aria-selected=true],[aria-current=true],[aria-current=page]):not(.tab-disabled,[disabled]),.tabs-lift>.\!tab:is(input:checked,label:has(:checked)){--tab-border:var(--border) var(--border) 0 var(--border)!important;--tab-border-colors:var(--tab-border-color) var(--tab-border-color) #0000 var(--tab-border-color)!important;--tab-paddings:0 calc(var(--tab-p) - var(--border)) var(--border) calc(var(--tab-p) - var(--border))!important;--tab-inset:auto auto 0 auto!important;--radius-start:radial-gradient(circle at top left,var(--tab-radius-grad))!important;--radius-end:radial-gradient(circle at top right,var(--tab-radius-grad))!important;background-color:var(--tab-bg)!important}.tabs-lift>.\!tab:is(.tab-active,[aria-selected=true],[aria-current=true],[aria-current=page]):not(.tab-disabled,[disabled]):before,.tabs-lift>.\!tab:is(input:checked,label:has(:checked)):before{z-index:1!important;content:""!important;display:block!important;position:absolute!important;width:var(--tab-corner-width)!important;height:var(--tab-corner-height)!important;background-position:var(--tab-corner-position)!important;background-image:var(--radius-start),var(--radius-end)!important;background-size:var(--tab-radius-limit) var(--tab-radius-limit)!important;background-repeat:no-repeat!important;inset:var(--tab-inset)!important}.tabs-lift>.\!tab:is(.tab-active,[aria-selected=true],[aria-current=true],[aria-current=page]):not(.tab-disabled,[disabled]):first-child:before,.tabs-lift>.\!tab:is(input:checked,label:has(:checked)):first-child:before{--radius-start:none!important}[dir=rtl] .tabs-lift>.\!tab:is(.tab-active,[aria-selected=true],[aria-current=true],[aria-current=page]):not(.tab-disabled,[disabled]):first-child:before,[dir=rtl] .tabs-lift>.\!tab:is(input:checked,label:has(:checked)):first-child:before{transform:rotateY(180deg)!important}.tabs-lift>.\!tab:is(.tab-active,[aria-selected=true],[aria-current=true],[aria-current=page]):not(.tab-disabled,[disabled]):last-child:before,.tabs-lift>.\!tab:is(input:checked,label:has(:checked)):last-child:before{--radius-end:none!important}[dir=rtl] .tabs-lift>.\!tab:is(.tab-active,[aria-selected=true],[aria-current=true],[aria-current=page]):not(.tab-disabled,[disabled]):last-child:before,[dir=rtl] .tabs-lift>.\!tab:is(input:checked,label:has(:checked)):last-child:before{transform:rotateY(180deg)!important}.tabs-lift:has(>.tab-content)>.\!tab:first-child:not(.tab-active,[aria-selected=true],[aria-current=true],[aria-current=page]){--tab-border-colors:var(--tab-border-color) var(--tab-border-color) #0000 var(--tab-border-color)!important}.tabs-top{--tabs-height:auto;--tabs-direction:row}.tabs-top>.tab{--tab-order:0;--tab-border:0 0 var(--border) 0;--tab-radius-ss:var(--tab-radius-limit);--tab-radius-se:var(--tab-radius-limit);--tab-radius-es:0;--tab-radius-ee:0;--tab-paddings:var(--border) var(--tab-p) 0 var(--tab-p);--tab-border-colors:#0000 #0000 var(--tab-border-color) #0000;--tab-corner-width:calc(100% + var(--tab-radius-limit)*2);--tab-corner-height:var(--tab-radius-limit);--tab-corner-position:top left,top right}.tabs-top>.tab:is(.tab-active,[aria-selected=true],[aria-current=true],[aria-current=page]):not(.tab-disabled,[disabled]),.tabs-top>.tab:is(input:checked),.tabs-top>.tab:is(label:has(:checked)){--tab-border:var(--border) var(--border) 0 var(--border);--tab-border-colors:var(--tab-border-color) var(--tab-border-color) #0000 var(--tab-border-color);--tab-paddings:0 calc(var(--tab-p) - var(--border)) var(--border) calc(var(--tab-p) - var(--border));--tab-inset:auto auto 0 auto;--radius-start:radial-gradient(circle at top left,var(--tab-radius-grad));--radius-end:radial-gradient(circle at top right,var(--tab-radius-grad))}.tabs-top:has(>.tab-content)>.tab:first-child:not(.tab-active,[aria-selected=true],[aria-current=true],[aria-current=page]){--tab-border-colors:var(--tab-border-color) var(--tab-border-color) #0000 var(--tab-border-color)}.tabs-top>.tab-content{--tabcontent-order:1;--tabcontent-margin:calc(var(--border)*-1) 0 0 0;--tabcontent-radius-ss:0;--tabcontent-radius-se:var(--radius-box);--tabcontent-radius-es:var(--radius-box);--tabcontent-radius-ee:var(--radius-box)}.tabs-top :checked+.tab-content:first-child,.tabs-top :checked+.tab-content:nth-child(n+3),.tabs-top :is(.tab-active,[aria-selected=true],[aria-current=true],[aria-current=page])+.tab-content:first-child,.tabs-top :is(.tab-active,[aria-selected=true],[aria-current=true],[aria-current=page])+.tab-content:nth-child(n+3),.tabs-top label:has(:checked)+.tab-content:first-child,.tabs-top label:has(:checked)+.tab-content:nth-child(n+3){--tabcontent-radius-ss:var(--radius-box)}.tabs-top>.\!tab{--tab-order:0!important;--tab-border:0 0 var(--border) 0!important;--tab-radius-ss:var(--tab-radius-limit)!important;--tab-radius-se:var(--tab-radius-limit)!important;--tab-radius-es:0!important;--tab-radius-ee:0!important;--tab-paddings:var(--border) var(--tab-p) 0 var(--tab-p)!important;--tab-border-colors:#0000 #0000 var(--tab-border-color) #0000!important;--tab-corner-width:calc(100% + var(--tab-radius-limit)*2)!important;--tab-corner-height:var(--tab-radius-limit)!important;--tab-corner-position:top left,top right!important}.tabs-top>.\!tab:is(.tab-active,[aria-selected=true],[aria-current=true],[aria-current=page]):not(.tab-disabled,[disabled]),.tabs-top>.\!tab:is(input:checked),.tabs-top>.\!tab:is(label:has(:checked)){--tab-border:var(--border) var(--border) 0 var(--border)!important;--tab-border-colors:var(--tab-border-color) var(--tab-border-color) #0000 var(--tab-border-color)!important;--tab-paddings:0 calc(var(--tab-p) - var(--border)) var(--border) calc(var(--tab-p) - var(--border))!important;--tab-inset:auto auto 0 auto!important;--radius-start:radial-gradient(circle at top left,var(--tab-radius-grad))!important;--radius-end:radial-gradient(circle at top right,var(--tab-radius-grad))!important}.tabs-top:has(>.tab-content)>.\!tab:first-child:not(.tab-active,[aria-selected=true],[aria-current=true],[aria-current=page]){--tab-border-colors:var(--tab-border-color) var(--tab-border-color) #0000 var(--tab-border-color)!important}.tabs-bottom{--tabs-height:auto;--tabs-direction:row}.tabs-bottom>.tab{--tab-order:1;--tab-border:var(--border) 0 0 0;--tab-radius-ss:0;--tab-radius-se:0;--tab-radius-es:var(--tab-radius-limit);--tab-radius-ee:var(--tab-radius-limit);--tab-border-colors:var(--tab-border-color) #0000 #0000 #0000;--tab-paddings:0 var(--tab-p) var(--border) var(--tab-p);--tab-corner-width:calc(100% + var(--tab-radius-limit)*2);--tab-corner-height:var(--tab-radius-limit);--tab-corner-position:top left,top right}.tabs-bottom>.tab:is(.tab-active,[aria-selected=true],[aria-current=true],[aria-current=page]):not(.tab-disabled,[disabled]),.tabs-bottom>.tab:is(input:checked),.tabs-bottom>.tab:is(label:has(:checked)){--tab-border:0 var(--border) var(--border) var(--border);--tab-border-colors:#0000 var(--tab-border-color) var(--tab-border-color) var(--tab-border-color);--tab-paddings:var(--border) calc(var(--tab-p) - var(--border)) 0 calc(var(--tab-p) - var(--border));--tab-inset:0 auto auto auto;--radius-start:radial-gradient(circle at bottom left,var(--tab-radius-grad));--radius-end:radial-gradient(circle at bottom right,var(--tab-radius-grad))}.tabs-bottom:has(>.tab-content)>.tab:first-child:not(.tab-active,[aria-selected=true],[aria-current=true],[aria-current=page]){--tab-border-colors:#0000 var(--tab-border-color) var(--tab-border-color) var(--tab-border-color)}.tabs-bottom>.tab-content{--tabcontent-order:0;--tabcontent-margin:0 0 calc(var(--border)*-1) 0;--tabcontent-radius-ss:var(--radius-box);--tabcontent-radius-se:var(--radius-box);--tabcontent-radius-es:0;--tabcontent-radius-ee:var(--radius-box)}.tabs-bottom>:checked+.tab-content:not(:nth-child(2)),.tabs-bottom>:is(.tab-active,[aria-selected=true],[aria-current=true],[aria-current=page])+.tab-content:not(:nth-child(2)),.tabs-bottom>:is(label:has(:checked))+.tab-content:not(:nth-child(2)){--tabcontent-radius-es:var(--radius-box)}.tabs-bottom>.\!tab{--tab-order:1!important;--tab-border:var(--border) 0 0 0!important;--tab-radius-ss:0!important;--tab-radius-se:0!important;--tab-radius-es:var(--tab-radius-limit)!important;--tab-radius-ee:var(--tab-radius-limit)!important;--tab-border-colors:var(--tab-border-color) #0000 #0000 #0000!important;--tab-paddings:0 var(--tab-p) var(--border) var(--tab-p)!important;--tab-corner-width:calc(100% + var(--tab-radius-limit)*2)!important;--tab-corner-height:var(--tab-radius-limit)!important;--tab-corner-position:top left,top right!important}.tabs-bottom>.\!tab:is(.tab-active,[aria-selected=true],[aria-current=true],[aria-current=page]):not(.tab-disabled,[disabled]),.tabs-bottom>.\!tab:is(input:checked),.tabs-bottom>.\!tab:is(label:has(:checked)){--tab-border:0 var(--border) var(--border) var(--border)!important;--tab-border-colors:#0000 var(--tab-border-color) var(--tab-border-color) var(--tab-border-color)!important;--tab-paddings:var(--border) calc(var(--tab-p) - var(--border)) 0 calc(var(--tab-p) - var(--border))!important;--tab-inset:0 auto auto auto!important;--radius-start:radial-gradient(circle at bottom left,var(--tab-radius-grad))!important;--radius-end:radial-gradient(circle at bottom right,var(--tab-radius-grad))!important}.tabs-bottom:has(>.tab-content)>.\!tab:first-child:not(.tab-active,[aria-selected=true],[aria-current=true],[aria-current=page]){--tab-border-colors:#0000 var(--tab-border-color) var(--tab-border-color) var(--tab-border-color)!important}@media (forced-colors:active){margin-top:.25rem!important;height:calc(100% - var(--tab-height) + var(--border) - .5rem)!important;border-radius:calc(min(calc(var(--tab-height) / 2), var(--radius-field)) + min(.25rem, var(--tabs-box-radius)) - var(--border))!important}.tabs-box{background-color:var(--color-base-200);padding:.25rem;--tabs-box-radius:calc(var(--radius-field)*3);border-radius:calc(min(calc(var(--tab-height) / 2), var(--radius-field)) + min(.25rem, var(--tabs-box-radius)));box-shadow:0 -.5px oklch(100% 0 0/calc(var(--depth)*.1)) inset,0 .5px oklch(0 0 0/calc(var(--depth)*.05)) inset}.tabs-box>.tab{border-radius:var(--radius-field);border-style:none}.tabs-box>.tab:focus-visible,.tabs-box>.tab:is(label:has(:checked:focus-visible)){outline-offset:2px}.tabs-box>:is(.tab-active,[aria-selected=true],[aria-current=true],[aria-current=page]):not(.tab-disabled,[disabled]),.tabs-box>:is(input:checked),.tabs-box>:is(label:has(:checked)){background-color:var(--tab-bg,var(--color-base-100));box-shadow:0 1px oklch(100% 0 0/calc(var(--depth)*.1)) inset,0 1px 1px -1px color-mix(in oklab,var(--color-neutral) calc(var(--depth)*50%),#0000),0 1px 6px -4px color-mix(in oklab,var(--color-neutral) calc(var(--depth)*100%),#0000)}@media (forced-colors:active){.tabs-box>:is(.tab-active,[aria-selected=true],[aria-current=true],[aria-current=page]):not(.tab-disabled,[disabled]),.tabs-box>:is(input:checked),.tabs-box>:is(label:has(:checked)){border:1px solid}}.tabs-box>.tab-content{margin-top:.25rem;height:calc(100% - var(--tab-height) + var(--border) - .5rem);border-radius:calc(min(calc(var(--tab-height) / 2), var(--radius-field)) + min(.25rem, var(--tabs-box-radius)) - var(--border))}@media (forced-colors:active){margin-top:.25rem!important;height:calc(100% - var(--tab-height) + var(--border) - .5rem)!important;border-radius:calc(min(calc(var(--tab-height) / 2), var(--radius-field)) + min(.25rem, var(--tabs-box-radius)) - var(--border))!important;background-color:var(--color-base-200)!important;padding:.25rem!important;--tabs-box-radius:calc(var(--radius-field)*3)!important;border-radius:calc(min(calc(var(--tab-height) / 2), var(--radius-field)) + min(.25rem, var(--tabs-box-radius)))!important;box-shadow:0 -.5px oklch(100% 0 0/calc(var(--depth)*.1)) inset,0 .5px oklch(0 0 0/calc(var(--depth)*.05)) inset!important}.tabs-box>.\!tab{border-radius:var(--radius-field)!important;border-style:none!important}.tabs-box>.\!tab:focus-visible,.tabs-box>.\!tab:is(label:has(:checked:focus-visible)){outline-offset:2px!important}@media (forced-colors:active){margin-top:.25rem!important;height:calc(100% - var(--tab-height) + var(--border) - .5rem)!important;border-radius:calc(min(calc(var(--tab-height) / 2), var(--radius-field)) + min(.25rem, var(--tabs-box-radius)) - var(--border))!important;--tab-height:calc(var(--size-field, 0.25rem)*6)!important}.tabs-xs>.\!tab{font-size:.75rem!important;--tab-p:0.375rem!important;--tab-radius-min:calc(0.5rem - var(--border))!important}.tabs-xs{--tab-height:calc(var(--size-field, 0.25rem)*6)}.tabs-xs>.tab{font-size:.75rem;--tab-p:0.375rem;--tab-radius-min:calc(0.5rem - var(--border))}.tabs-sm>.\!tab{font-size:.875rem!important;--tab-p:0.5rem!important;--tab-radius-min:calc(0.5rem - var(--border))!important}.tabs-sm{--tab-height:calc(var(--size-field, 0.25rem)*8)}.tabs-sm>.tab{font-size:.875rem;--tab-p:0.5rem;--tab-radius-min:calc(0.5rem - var(--border))}.tabs-md>.\!tab{font-size:.875rem!important;--tab-p:0.75rem!important;--tab-radius-min:calc(0.75rem - var(--border))!important}.tabs-md{--tab-height:calc(var(--size-field, 0.25rem)*10)}.tabs-md>.tab{font-size:.875rem;--tab-p:0.75rem;--tab-radius-min:calc(0.75rem - var(--border))}.tabs-lg>.\!tab{font-size:1.125rem!important;--tab-p:1rem!important;--tab-radius-min:calc(1.5rem - var(--border))!important}.tabs-lg{--tab-height:calc(var(--size-field, 0.25rem)*12)}.tabs-lg>.tab{font-size:1.125rem;--tab-p:1rem;--tab-radius-min:calc(1.5rem - var(--border))}.tabs-xl>.\!tab{font-size:1.125rem!important;--tab-p:1.25rem!important;--tab-radius-min:calc(2rem - var(--border))!important}.tabs-xl{--tab-height:calc(var(--size-field, 0.25rem)*14)}.tabs-xl>.tab{font-size:1.125rem;--tab-p:1.25rem;--tab-radius-min:calc(2rem - var(--border))}}@layer daisyui.l1.l2.l3{.modal{pointer-events:none;visibility:hidden;position:fixed;inset:0;margin:0;display:grid;height:100%;max-height:none;width:100%;max-width:none;align-items:center;justify-items:center;background-color:initial;padding:0;color:inherit;transition:visibility allow-discrete .3s,background-color .3s ease-out,opacity .1s ease-out;overflow:clip;overscroll-behavior:contain;z-index:999;scrollbar-gutter:auto}.modal::backdrop{display:none}}@layer daisyui.l1.l2{.modal{@starting-style{&.modal-open,&:target,&[open],.modal-toggle:checked+&{opacity:0}}}.modal-toggle:checked+.modal,.modal.modal-open,.modal:target,.modal[open]{pointer-events:auto;visibility:visible;opacity:100%;transition:visibility allow-discrete 0s,background-color .3s ease-out,opacity .1s ease-out;background-color:oklch(0 0 0/.4)}.modal-toggle:checked+.modal .modal-box,.modal.modal-open .modal-box,.modal:target .modal-box,.modal[open] .modal-box{translate:0 0;scale:1;opacity:1}:root:has(.modal-toggle:checked+.modal),:root:has(.modal.modal-open),:root:has(.modal:target),:root:has(.modal[open]){--page-has-backdrop:1;--page-overflow:hidden;--page-scroll-bg:var(--page-scroll-bg-on);--page-scroll-gutter:stable;--page-scroll-transition:var(--page-scroll-transition-on);animation:set-page-has-scroll forwards;animation-timeline:scroll()}}@layer daisyui.l1.l2.l3{.checkbox{border:var(--border) solid var(--input-color,color-mix(in oklab,var(--color-base-content) 20%,#0000));position:relative;display:inline-block;flex-shrink:0;cursor:pointer;-webkit-appearance:none;-moz-appearance:none;appearance:none;border-radius:var(--radius-selector);padding:.25rem;vertical-align:middle;color:var(--color-base-content);box-shadow:0 1px oklch(0 0 0/calc(var(--depth)*.1)) inset,0 0 #0000 inset,0 0 #0000;transition:background-color .2s,box-shadow .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)}.checkbox:before{--tw-content:"";content:var(--tw-content);display:block;width:100%;height:100%;rotate:45deg;background-color:currentcolor;opacity:0;transition:opacity .1s,rotate .3s,translate .3s,-webkit-clip-path .3s;transition:clip-path .3s,opacity .1s,rotate .3s,translate .3s;transition:clip-path .3s,opacity .1s,rotate .3s,translate .3s,-webkit-clip-path .3s;transition-delay:.1s;-webkit-clip-path:polygon(20% 100%,20% 80%,50% 80%,50% 80%,70% 80%,70% 100%);clip-path:polygon(20% 100%,20% 80%,50% 80%,50% 80%,70% 80%,70% 100%);box-shadow:0 3px 0 0 oklch(100% 0 0/calc(var(--depth)*.1)) inset;font-size:1rem;line-height:.75}.checkbox:focus-visible{outline:2px solid var(--input-color,currentColor);outline-offset:2px}.checkbox:checked,.checkbox[aria-checked=true]{background-color:var(--input-color,#0000);box-shadow:0 0 #0000 inset,0 8px 0 -4px oklch(100% 0 0/calc(var(--depth)*.1)) inset,0 1px oklch(0 0 0/calc(var(--depth)*.1))}.checkbox:checked:before,.checkbox[aria-checked=true]:before{-webkit-clip-path:polygon(20% 100%,20% 80%,50% 80%,50% 0,70% 0,70% 100%);clip-path:polygon(20% 100%,20% 80%,50% 80%,50% 0,70% 0,70% 100%);opacity:100%}@media (forced-colors:active){.checkbox:checked:before,.checkbox[aria-checked=true]:before{rotate:0deg;background-color:initial;--tw-content:"✔︎";-webkit-clip-path:none;clip-path:none}}@media print{.checkbox:checked:before,.checkbox[aria-checked=true]:before{rotate:0deg;background-color:initial;--tw-content:"✔︎";-webkit-clip-path:none;clip-path:none}}.checkbox:indeterminate{background-color:var( --input-color,color-mix(in oklab,var(--color-base-content) 20%,#0000) )}.checkbox:indeterminate:before{rotate:0deg;opacity:100%;translate:0 -35%;-webkit-clip-path:polygon(20% 100%,20% 80%,50% 80%,50% 80%,80% 80%,80% 100%);clip-path:polygon(20% 100%,20% 80%,50% 80%,50% 80%,80% 80%,80% 100%)}}@layer daisyui.l1.l2{.checkbox:disabled{cursor:not-allowed;opacity:20%}}@keyframes radio{0%{padding:5px}50%{padding:3px}}@keyframes toast{0%{scale:.9;opacity:0}to{scale:1;opacity:1}}@keyframes rotator{89.9999%,to{--first-item-position:0 0%}90%,99.9999%{--first-item-position:0 calc(var(--items)*100%)}to{translate:0 -100%}}@layer daisyui.l1.l2.l3{.mockup-browser{position:relative;overflow:hidden;overflow-x:auto;border-radius:var(--radius-box)}.mockup-browser pre[data-prefix]:before{--tw-content:attr(data-prefix);content:var(--tw-content);display:inline-block;text-align:right}.mockup-browser .mockup-browser-toolbar{margin-block:.75rem;display:inline-flex;width:100%;align-items:center;padding-right:1.4em}.mockup-browser .mockup-browser-toolbar:where(:dir(rtl),[dir=rtl],[dir=rtl] *){flex-direction:row-reverse}.mockup-browser .mockup-browser-toolbar:before{content:"";margin-right:4.8rem;display:inline-block;aspect-ratio:1/1;height:.75rem;border-radius:calc(infinity * 1px);opacity:30%;box-shadow:1.4em 0,2.8em 0,4.2em 0}.mockup-browser .mockup-browser-toolbar .input{margin-inline:auto;display:flex;height:100%;align-items:center;gap:.5rem;overflow:hidden;background-color:var(--color-base-200);text-overflow:ellipsis;white-space:nowrap;font-size:.75rem;direction:ltr}.mockup-browser .mockup-browser-toolbar .input:before{content:"";width:1rem;height:1rem;opacity:50%;background-color:currentColor;-webkit-mask:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath fill-rule='evenodd' d='M9.965 11.026a5 5 0 1 1 1.06-1.06l2.755 2.754a.75.75 0 1 1-1.06 1.06l-2.755-2.754ZM10.5 7a3.5 3.5 0 1 1-7 0 3.5 3.5 0 0 1 7 0Z' clip-rule='evenodd'/%3E%3C/svg%3E") no-repeat center;mask:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath fill-rule='evenodd' d='M9.965 11.026a5 5 0 1 1 1.06-1.06l2.755 2.754a.75.75 0 1 1-1.06 1.06l-2.755-2.754ZM10.5 7a3.5 3.5 0 1 1-7 0 3.5 3.5 0 0 1 7 0Z' clip-rule='evenodd'/%3E%3C/svg%3E") no-repeat center;-webkit-mask-size:contain;mask-size:contain}:where(.btn){width:unset}.btn{display:inline-flex;flex-shrink:0;cursor:pointer;flex-wrap:nowrap;align-items:center;justify-content:center;gap:.375rem;text-align:center;vertical-align:middle;outline-offset:2px;webkit-user-select:none;-webkit-user-select:none;-moz-user-select:none;user-select:none;padding-inline:var(--btn-p);color:var(--btn-fg);--tw-prose-links:var(--btn-fg);height:var(--size);font-size:var(--fontsize,.875rem);font-weight:600;outline-color:var(--btn-color,var(--color-base-content));transition-property:color,background-color,border-color,box-shadow;transition-timing-function:cubic-bezier(0,0,.2,1);transition-duration:.2s;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-width:var(--border);border-style:solid;border-color:var(--btn-border);text-shadow:0 .5px oklch(100% 0 0/calc(var(--depth)*.15));touch-action:manipulation;box-shadow:0 .5px 0 .5px oklch(100% 0 0/calc(var(--depth)*6%)) inset,var(--btn-shadow);--size:calc(var(--size-field, 0.25rem)*10);--btn-bg:var(--btn-color,var(--color-base-200));--btn-fg:var(--color-base-content);--btn-p:1rem;--btn-border:color-mix(in oklab,var(--btn-bg),#000 calc(var(--depth)*5%));--btn-shadow:0 3px 2px -2px color-mix(in oklab,var(--btn-bg) calc(var(--depth)*30%),#0000),0 4px 3px -2px color-mix(in oklab,var(--btn-bg) calc(var(--depth)*30%),#0000);--btn-noise:var(--fx-noise)}@media (hover:hover){.btn:hover{--btn-bg:color-mix(in oklab,var(--btn-color,var(--color-base-200)),#000 7%)}}.btn:focus-visible,.btn:has(:focus-visible){outline-width:2px;outline-style:solid;isolation:isolate}.btn:active:not(.btn-active){translate:0 .5px;--btn-bg:color-mix(in oklab,var(--btn-color,var(--color-base-200)),#000 5%);--btn-border:color-mix(in oklab,var(--btn-color,var(--color-base-200)),#000 7%);--btn-shadow:0 0 0 0 oklch(0% 0 0/0),0 0 0 0 oklch(0% 0 0/0)}.btn:is(input[type=checkbox],input[type=radio]){-webkit-appearance:none;-moz-appearance:none;appearance:none}.btn:is(input[type=checkbox],input[type=radio])[aria-label]:after{--tw-content:attr(aria-label);content:var(--tw-content)}.btn:where(input:checked:not(.filter .btn)){--btn-color:var(--color-primary);--btn-fg:var(--color-primary-content);isolation:isolate}}@layer daisyui.l1.l2{.btn-disabled,.btn:disabled,.btn[disabled]{pointer-events:none;--btn-border:#0000;--btn-noise:none;--btn-fg:color-mix(in oklch,var(--color-base-content) 20%,#0000)}.btn-disabled:not(.btn-link,.btn-ghost),.btn:disabled:not(.btn-link,.btn-ghost),.btn[disabled]:not(.btn-link,.btn-ghost){background-color:color-mix(in oklab,var(--color-base-content) 10%,#0000);box-shadow:none}}@layer daisyui.l1.l2.l3{.btn-primary{--btn-color:var(--color-primary);--btn-fg:var(--color-primary-content)}.steps{display:inline-grid;grid-auto-flow:column;overflow:hidden;overflow-x:auto;counter-reset:step;grid-auto-columns:1fr}.steps .step{display:grid;grid-template-columns:repeat(1,minmax(0,1fr));grid-template-columns:auto;grid-template-rows:repeat(2,minmax(0,1fr));grid-template-rows:40px 1fr;place-items:center;text-align:center;min-width:4rem;--step-bg:var(--color-base-300);--step-fg:var(--color-base-content)}.steps .step:before{top:0;grid-column-start:1;grid-row-start:1;height:.5rem;width:100%;border:1px solid;color:var(--step-bg);background-color:var(--step-bg);content:"";margin-inline-start:-100%}.steps .step:not(:has(.step-icon)):after,.steps .step>.step-icon{--tw-content:counter(step);content:var(--tw-content);counter-increment:step;z-index:1;color:var(--step-fg);background-color:var(--step-bg);border:1px solid var(--step-bg);position:relative;grid-column-start:1;grid-row-start:1;display:grid;height:2rem;width:2rem;place-items:center;place-self:center;border-radius:calc(infinity * 1px)}.steps .step:first-child:before{--tw-content:none;content:var(--tw-content)}.steps .step[data-content]:after{--tw-content:attr(data-content);content:var(--tw-content)}}@layer daisyui.l1.l2{.steps-horizontal{grid-auto-columns:1fr;display:inline-grid;grid-auto-flow:column;overflow:hidden;overflow-x:auto}.steps-horizontal .step{display:grid;grid-template-columns:repeat(1,minmax(0,1fr));grid-template-columns:auto;grid-template-rows:repeat(2,minmax(0,1fr));grid-template-rows:40px 1fr;place-items:center;text-align:center;min-width:4rem}.steps-horizontal .step:before{height:.5rem;width:100%;translate:0;margin-inline-start:-100%}[dir=rtl] .steps-horizontal .step:before{translate:0}.steps-vertical{grid-auto-rows:1fr;grid-auto-flow:row}.steps-vertical .step{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));grid-template-columns:40px 1fr;grid-template-rows:repeat(1,minmax(0,1fr));grid-template-rows:auto;gap:.5rem;min-height:4rem;justify-items:start}.steps-vertical .step:before{height:100%;width:.5rem;translate:-50% -50%;margin-inline-start:50%}[dir=rtl] .steps-vertical .step:before{translate:50% -50%}}@layer daisyui.l1.l2.l3{.stats{position:relative;display:inline-grid;grid-auto-flow:column;overflow-x:auto;border-radius:var(--radius-box)}}@keyframes skeleton{0%{background-position:150%}to{background-position:-50%}}@layer daisyui.l1.l2.l3{.indicator{position:relative;display:inline-flex;width:-moz-max-content;width:max-content}.indicator :where(.indicator-item){z-index:1;position:absolute;white-space:nowrap;top:var(--indicator-t,0);bottom:var(--indicator-b,auto);left:var(--indicator-s,auto);right:var(--indicator-e,0);translate:var(--indicator-x,50%) var(--indicator-y,-50%)}.loading{pointer-events:none;display:inline-block;aspect-ratio:1/1;background-color:currentcolor;vertical-align:middle;width:calc(var(--size-selector, .25rem)*6);-webkit-mask-size:100%;mask-size:100%;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-position:center;mask-position:center;-webkit-mask-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' stroke='%23000'%3E%3Ccircle cx='12' cy='12' r='9.5' fill='none' stroke-linecap='round' stroke-width='3'%3E%3CanimateTransform attributeName='transform' dur='2s' from='0 12 12' repeatCount='indefinite' to='360 12 12' type='rotate'/%3E%3Canimate attributeName='stroke-dasharray' dur='1.5s' keyTimes='0;0.475;1' repeatCount='indefinite' values='0,150;42,150;42,150'/%3E%3Canimate attributeName='stroke-dashoffset' dur='1.5s' keyTimes='0;0.475;1' repeatCount='indefinite' values='0;-16;-59'/%3E%3C/circle%3E%3C/svg%3E");mask-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' stroke='%23000'%3E%3Ccircle cx='12' cy='12' r='9.5' fill='none' stroke-linecap='round' stroke-width='3'%3E%3CanimateTransform attributeName='transform' dur='2s' from='0 12 12' repeatCount='indefinite' to='360 12 12' type='rotate'/%3E%3Canimate attributeName='stroke-dasharray' dur='1.5s' keyTimes='0;0.475;1' repeatCount='indefinite' values='0,150;42,150;42,150'/%3E%3Canimate attributeName='stroke-dashoffset' dur='1.5s' keyTimes='0;0.475;1' repeatCount='indefinite' values='0;-16;-59'/%3E%3C/circle%3E%3C/svg%3E")}.menu{display:flex;width:-moz-fit-content;width:fit-content;flex-direction:column;flex-wrap:wrap;padding:.5rem;--menu-active-fg:var(--color-neutral-content);--menu-active-bg:var(--color-neutral);font-size:.875rem}.menu :where(li ul){position:relative;margin-inline-start:1rem;padding-inline-start:.5rem;white-space:nowrap}.menu :where(li ul):before{position:absolute;inset-inline-start:0;top:.75rem;bottom:.75rem;background-color:var(--color-base-content);opacity:10%;width:var(--border);content:""}.menu :where(li>.menu-dropdown:not(.menu-dropdown-show)){display:none}.menu :where(li:not(.menu-title)>:not(ul,details,.menu-title,.btn)),.menu :where(li:not(.menu-title)>details>summary:not(.menu-title)){display:grid;grid-auto-flow:column;align-content:flex-start;align-items:center;gap:.5rem;border-radius:var(--radius-field);padding-inline:.75rem;padding-block:.375rem;text-align:start;transition-property:color,background-color,box-shadow;transition-duration:.2s;transition-timing-function:cubic-bezier(0,0,.2,1);grid-auto-columns:minmax(auto,max-content) auto max-content;text-wrap:balance;-webkit-user-select:none;-moz-user-select:none;user-select:none}.menu :where(li>details>summary){--tw-outline-style:none;outline-style:none}@media (forced-colors:active){.menu :where(li>details>summary){outline:2px solid #0000;outline-offset:2px}}.menu :where(li>details>summary)::-webkit-details-marker{display:none}.menu :where(li>.menu-dropdown-toggle):after,.menu :where(li>details>summary):after{justify-self:flex-end;display:block;height:.375rem;width:.375rem;rotate:-135deg;translate:0 -1px;transition-property:rotate,translate;transition-duration:.2s;content:"";transform-origin:50% 50%;box-shadow:inset 2px 2px;pointer-events:none}.menu details{overflow:hidden;interpolate-size:allow-keywords}.menu details::details-content{block-size:0}@media (prefers-reduced-motion:no-preference){.menu details::details-content{transition-behavior:allow-discrete;transition-property:block-size,content-visibility;transition-duration:.2s;transition-timing-function:cubic-bezier(0,0,.2,1)}}.menu details[open]::details-content{block-size:auto}.menu :where(li>.menu-dropdown-toggle.menu-dropdown-show):after,.menu :where(li>details[open]>summary):after{rotate:45deg;translate:0 1px}.menu :where(li:not(.menu-title,.disabled)>:not(ul,details,.menu-title),li:not(.menu-title,.disabled)>details>summary:not(.menu-title)):not(.menu-active,:active,.btn).menu-focus,.menu :where(li:not(.menu-title,.disabled)>:not(ul,details,.menu-title),li:not(.menu-title,.disabled)>details>summary:not(.menu-title)):not(.menu-active,:active,.btn):focus-visible{cursor:pointer;background-color:color-mix(in oklab,var(--color-base-content) 10%,#0000);color:var(--color-base-content);--tw-outline-style:none;outline-style:none}@media (forced-colors:active){.menu :where(li:not(.menu-title,.disabled)>:not(ul,details,.menu-title),li:not(.menu-title,.disabled)>details>summary:not(.menu-title)):not(.menu-active,:active,.btn).menu-focus,.menu :where(li:not(.menu-title,.disabled)>:not(ul,details,.menu-title),li:not(.menu-title,.disabled)>details>summary:not(.menu-title)):not(.menu-active,:active,.btn):focus-visible{outline:2px solid #0000;outline-offset:2px}}.menu :where(li:not(.menu-title,.disabled)>:not(ul,details,.menu-title):not(.menu-active,:active,.btn):hover,li:not(.menu-title,.disabled)>details>summary:not(.menu-title):not(.menu-active,:active,.btn):hover){cursor:pointer;background-color:color-mix(in oklab,var(--color-base-content) 10%,#0000);--tw-outline-style:none;outline-style:none}@media (forced-colors:active){.menu :where(li:not(.menu-title,.disabled)>:not(ul,details,.menu-title):not(.menu-active,:active,.btn):hover,li:not(.menu-title,.disabled)>details>summary:not(.menu-title):not(.menu-active,:active,.btn):hover){outline:2px solid #0000;outline-offset:2px}}.menu :where(li:not(.menu-title,.disabled)>:not(ul,details,.menu-title):not(.menu-active,:active,.btn):hover,li:not(.menu-title,.disabled)>details>summary:not(.menu-title):not(.menu-active,:active,.btn):hover){box-shadow:inset 0 1px oklch(0 0 0/.01),inset 0 -1px oklch(100% 0 0/.01)}.menu :where(li:empty){background-color:var(--color-base-content);opacity:10%;margin:.5rem 1rem;height:1px}.menu :where(li){position:relative;display:flex;flex-shrink:0;flex-direction:column;flex-wrap:wrap;align-items:stretch}.menu :where(li) .badge{justify-self:flex-end}.menu :where(li)>:not(ul,.menu-title,details,.btn).menu-active,.menu :where(li)>:not(ul,.menu-title,details,.btn):active,.menu :where(li)>details>summary:active{--tw-outline-style:none;outline-style:none}@media (forced-colors:active){.menu :where(li)>:not(ul,.menu-title,details,.btn).menu-active,.menu :where(li)>:not(ul,.menu-title,details,.btn):active,.menu :where(li)>details>summary:active{outline:2px solid #0000;outline-offset:2px}}.menu :where(li)>:not(ul,.menu-title,details,.btn).menu-active,.menu :where(li)>:not(ul,.menu-title,details,.btn):active,.menu :where(li)>details>summary: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)}.menu :where(li)>:not(ul,.menu-title,details,.btn).menu-active:not(.menu :where(li)>:not(ul,.menu-title,details,.btn).menu-active:active),.menu :where(li)>:not(ul,.menu-title,details,.btn):active:not(.menu :where(li)>:not(ul,.menu-title,details,.btn):active:active),.menu :where(li)>details>summary:active:not(.menu :where(li)>details>summary:active:active){box-shadow:0 2px calc(var(--depth)*3px) -2px var(--menu-active-bg)}.menu :where(li).menu-disabled{pointer-events:none;color:color-mix(in oklab,var(--color-base-content) 20%,#0000)}.menu .dropdown:focus-within .menu-dropdown-toggle:after{rotate:45deg;translate:0 1px}.menu .dropdown-content{margin-top:.5rem;padding:.5rem}.menu .dropdown-content:before{display:none}}@keyframes menu{0%{opacity:0}}@layer daisyui.l1.l2.l3{.toggle{border:var(--border) solid;color:var(--input-color);position:relative;display:inline-grid;flex-shrink:0;cursor:pointer;-webkit-appearance:none;-moz-appearance:none;appearance:none;place-content:center;vertical-align:middle;webkit-user-select:none;-webkit-user-select:none;-moz-user-select:none;user-select:none;grid-template-columns:0fr 1fr 1fr;--radius-selector-max:calc(var(--radius-selector) + var(--radius-selector) + var(--radius-selector));border-radius:calc(var(--radius-selector) + min(var(--toggle-p), var(--radius-selector-max)) + min(var(--border), var(--radius-selector-max)));padding:var(--toggle-p);box-shadow:0 1px color-mix(in oklab,currentColor calc(var(--depth)*10%),#0000) inset;transition:color .3s,grid-template-columns .2s;--input-color:color-mix(in oklab,var(--color-base-content) 50%,#0000);--toggle-p:calc(var(--size)*0.125);--size:calc(var(--size-selector, 0.25rem)*6);width:calc(var(--size)*2 - (var(--border) + var(--toggle-p))*2);height:var(--size)}.toggle>*{z-index:1;grid-column:span 1/span 1;grid-column-start:2;grid-row-start:1;height:100%;cursor:pointer;-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:initial;padding:.125rem;transition:opacity .2s,rotate .4s;border:none}.toggle>:focus{--tw-outline-style:none;outline-style:none}@media (forced-colors:active){.toggle>:focus{outline:2px solid #0000;outline-offset:2px}}.toggle>:nth-child(2){color:var(--color-base-100);rotate:0deg}.toggle>:nth-child(3){color:var(--color-base-100);opacity:0;rotate:-15deg}.toggle:has(:checked)>:nth-child(2){opacity:0;rotate:15deg}.toggle:has(:checked)>:nth-child(3){opacity:100%;rotate:0deg}.toggle:before{position:relative;inset-inline-start:0;grid-column-start:2;grid-row-start:1;aspect-ratio:1/1;height:100%;border-radius:var(--radius-selector);background-color:currentcolor;translate:0;--tw-content:"";content:var(--tw-content);transition:background-color .1s,translate .2s,inset-inline-start .2s;box-shadow:0 -1px oklch(0 0 0/calc(var(--depth)*.1)) inset,0 8px 0 -4px oklch(100% 0 0/calc(var(--depth)*.1)) inset,0 1px color-mix(in oklab,currentColor calc(var(--depth)*10%),#0000);background-size:auto,calc(var(--noise)*100%);background-image:none,var(--fx-noise)}@media (forced-colors:active){.toggle:before{outline-style:var(--tw-outline-style);outline-width:1px;outline-offset:-1px}}@media print{.toggle:before{outline:.25rem solid;outline-offset:-1rem}}.toggle:focus-visible,.toggle:has(:focus-visible){outline:2px solid currentColor;outline-offset:2px}.toggle:checked,.toggle:has(>input:checked),.toggle[aria-checked=true]{grid-template-columns:1fr 1fr 0fr;background-color:var(--color-base-100);--input-color:var(--color-base-content)}.toggle:checked:before,.toggle:has(>input:checked):before,.toggle[aria-checked=true]:before{background-color:currentcolor}.toggle:checked,.toggle:has(>input:checked),.toggle[aria-checked=true]{@starting-style{&:before{opacity:0}}}.toggle:indeterminate{grid-template-columns:.5fr 1fr .5fr}.toggle:disabled{cursor:not-allowed;opacity:30%}.toggle:disabled:before{background-color:initial;border:var(--border) solid}.badge{display:inline-flex;align-items:center;justify-content:center;gap:.5rem;border-radius:var(--radius-selector);vertical-align:middle;color:var(--badge-fg);border:var(--border) solid var(--badge-color,var(--color-base-200));font-size:.875rem;width:-moz-fit-content;width:fit-content;padding-inline:calc(.75rem - var(--border));background-size:auto,calc(var(--noise)*100%);background-image:none,var(--fx-noise);background-color:var(--badge-bg);--badge-bg:var(--badge-color,var(--color-base-100));--badge-fg:var(--color-base-content);--size:calc(var(--size-selector, 0.25rem)*6);height:var(--size)}.link{cursor:pointer;text-decoration-line:underline}.link:focus{--tw-outline-style:none;outline-style:none}@media (forced-colors:active){.link:focus{outline:2px solid #0000;outline-offset:2px}}.link:focus-visible{outline:2px solid currentColor;outline-offset:2px}.filter{display:flex;flex-wrap:wrap}.filter input[type=radio]{width:auto}.filter input{overflow:hidden;opacity:100%;scale:1;transition:margin .1s,opacity .3s,padding .3s,border-width .1s}.filter input:not(:last-child){margin-inline-end:.25rem}.filter input.filter-reset{aspect-ratio:1/1}.filter input.filter-reset:after{--tw-content:"×";content:var(--tw-content)}.filter:not(:has(input:checked:not(.filter-reset))) .filter-reset,.filter:not(:has(input:checked:not(.filter-reset))) input[type=reset]{scale:0;border-width:0;margin-inline:0;width:0;padding-inline:0;opacity:0}.filter:has(input:checked:not(.filter-reset)) input:not(:checked,.filter-reset,input[type=reset]){scale:0;border-width:0;margin-inline:0;width:0;padding-inline:0;opacity:0}.mask{display:inline-block;vertical-align:middle;-webkit-mask-size:contain;mask-size:contain;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-position:center;mask-position:center}.label{display:inline-flex;align-items:center;gap:.375rem;white-space:nowrap;color:color-mix(in oklab,currentcolor 60%,#0000)}.label:has(input){cursor:pointer}.label:is(.input>*,.select>*){display:flex;height:calc(100% - .5rem);align-items:center;padding-inline:.75rem;white-space:nowrap;font-size:inherit}.label:is(.input>*,.select>*):first-child{margin-inline-start:-.75rem;margin-inline-end:.75rem;border-inline-end:var(--border) solid color-mix(in oklab,currentColor 10%,#0000)}.label:is(.input>*,.select>*):last-child{margin-inline-start:.75rem;margin-inline-end:-.75rem;border-inline-start:var(--border) solid color-mix(in oklab,currentColor 10%,#0000)}.status{display:inline-block;aspect-ratio:1/1;width:.5rem;height:.5rem;border-radius:var(--radius-selector);background-color:color-mix(in oklab,var(--color-base-content) 20%,#0000);background-position:50%;background-repeat:no-repeat;color:color-mix(in oklab,var(--color-black) 30%,#0000);background-image:radial-gradient(circle at 35% 30%,oklch(1 0 0/calc(var(--depth)*.5)),#0000);box-shadow:0 2px 3px -1px color-mix(in oklab,currentColor calc(var(--depth)*100%),#0000)}.input,.status{vertical-align:middle}.input{cursor:text;border:var(--border) solid #0000;position:relative;display:inline-flex;flex-shrink:1;-webkit-appearance:none;-moz-appearance:none;appearance:none;align-items:center;gap:.5rem;background-color:var(--color-base-100);padding-inline:.75rem;white-space:nowrap;width:clamp(3rem,20rem,100%);height:var(--size);font-size:max(var(--font-size,.875rem),.875rem);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);box-shadow:0 1px color-mix(in oklab,var(--input-color) calc(var(--depth)*10%),#0000) inset,0 -1px oklch(100% 0 0/calc(var(--depth)*.1)) inset;--size:calc(var(--size-field, 0.25rem)*10);--input-color:color-mix(in oklab,var(--color-base-content) 20%,#0000)}.input:where(input){display:inline-flex}.input :where(input){display:inline-flex;height:100%;width:100%;-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:initial;border:none}.input :where(input):focus,.input :where(input):focus-within{--tw-outline-style:none;outline-style:none}@media (forced-colors:active){.input :where(input):focus,.input :where(input):focus-within{outline:2px solid #0000;outline-offset:2px}}.input :where(input[type=email]),.input :where(input[type=url]){direction:ltr}.input :where(input[type=date]){display:inline-flex}.input:focus,.input:focus-within{--input-color:var(--color-base-content);box-shadow:0 1px color-mix(in oklab,var(--input-color) calc(var(--depth)*10%),#0000);outline:2px solid var(--input-color);outline-offset:2px;isolation:isolate;z-index:1}@media (pointer:coarse){@supports (-webkit-touch-callout:none){.input:focus,.input:focus-within{--font-size:1rem}}}.input:has(>input[disabled]),.input:is(:disabled,[disabled]),fieldset:disabled .input{cursor:not-allowed;border-color:var(--color-base-200);background-color:var(--color-base-200);color:color-mix(in oklab,var(--color-base-content) 40%,#0000)}.input:has(>input[disabled])::-moz-placeholder,.input:is(:disabled,[disabled])::-moz-placeholder,fieldset:disabled .input::-moz-placeholder{color:color-mix(in oklab,var(--color-base-content) 20%,#0000)}.input:has(>input[disabled])::placeholder,.input:is(:disabled,[disabled])::placeholder,fieldset:disabled .input::placeholder{color:color-mix(in oklab,var(--color-base-content) 20%,#0000)}.input:has(>input[disabled]),.input:is(:disabled,[disabled]),fieldset:disabled .input{box-shadow:none}.input:has(>input[disabled])>input[disabled]{cursor:not-allowed}.input::-webkit-date-and-time-value{text-align:inherit}.input[type=number]::-webkit-inner-spin-button{margin-block:-.75rem;margin-inline-end:-.75rem}.input::-webkit-calendar-picker-indicator{position:absolute;inset-inline-end:.75em}.input:has(>input[type=date]) :where(input[type=date]){display:inline-flex;webkit-appearance:none;-webkit-appearance:none;-moz-appearance:none;appearance:none}.input:has(>input[type=date]) input[type=date]::-webkit-calendar-picker-indicator{position:absolute;inset-inline-end:.75em;width:1em;height:1em;cursor:pointer}.timeline{position:relative;display:flex}.timeline>li{position:relative;display:grid;flex-shrink:0;align-items:center;grid-template-rows:var(--timeline-row-start,minmax(0,1fr)) auto var( --timeline-row-end,minmax(0,1fr) );grid-template-columns:var(--timeline-col-start,minmax(0,1fr)) auto var( --timeline-col-end,minmax(0,1fr) )}.timeline>li>hr{border:none;width:100%}.timeline>li>hr:first-child{grid-column-start:1;grid-row-start:2}.timeline>li>hr:last-child{grid-column-start:3;grid-column-end:none;grid-row-start:2;grid-row-end:auto}@media print{.timeline>li>hr{border:.1px solid var(--color-base-300)}}.timeline :where(hr){height:.25rem;background-color:var(--color-base-300)}.timeline:has(.timeline-middle hr):first-child{border-start-start-radius:0;border-end-start-radius:0;border-start-end-radius:var(--radius-selector);border-end-end-radius:var(--radius-selector)}.timeline:has(.timeline-middle hr):last-child{border-start-start-radius:var(--radius-selector);border-end-start-radius:var(--radius-selector);border-start-end-radius:0;border-end-end-radius:0}.timeline:not(:has(.timeline-middle)) :first-child hr:last-child{border-start-start-radius:var(--radius-selector);border-end-start-radius:var(--radius-selector);border-start-end-radius:0;border-end-end-radius:0}.timeline:not(:has(.timeline-middle)) :last-child hr:first-child{border-start-start-radius:0;border-end-start-radius:0;border-start-end-radius:var(--radius-selector);border-end-end-radius:var(--radius-selector)}.progress{position:relative;height:.5rem;width:100%;-webkit-appearance:none;-moz-appearance:none;appearance:none;overflow:hidden;border-radius:var(--radius-box);background-color:color-mix(in oklab,currentcolor 20%,#0000);color:var(--color-base-content)}.progress:indeterminate{background-image:repeating-linear-gradient(90deg,currentColor -1%,currentColor 10%,#0000 0,#0000 90%);background-size:200%;background-position-x:15%}@media (prefers-reduced-motion:no-preference){.progress:indeterminate{animation:progress 5s ease-in-out infinite}}@supports (-moz-appearance:none){.progress:indeterminate::-moz-progress-bar{background-color:initial}@media (prefers-reduced-motion:no-preference){.progress:indeterminate::-moz-progress-bar{animation:progress 5s ease-in-out infinite;background-image:repeating-linear-gradient(90deg,currentColor -1%,currentColor 10%,#0000 0,#0000 90%);background-size:200%;background-position-x:15%}}.progress::-moz-progress-bar{border-radius:var(--radius-box);background-color:currentcolor}}@supports (-webkit-appearance:none){.progress::-webkit-progress-bar{border-radius:var(--radius-box);background-color:initial}.progress::-webkit-progress-value{border-radius:var(--radius-box);background-color:currentColor}}}@keyframes progress{50%{background-position-x:-115%}}.visible{visibility:visible}.static{position:static}.absolute{position:absolute}.relative{position:relative}.inset-y-0{top:0;bottom:0}.left-0{left:0}.m-3{margin:.75rem}.mx-2{margin-left:.5rem;margin-right:.5rem}.my-2{margin-top:.5rem;margin-bottom:.5rem}.mb-1{margin-bottom:.25rem}.mb-1\.5{margin-bottom:.375rem}.mb-2{margin-bottom:.5rem}.mb-2\.5{margin-bottom:.625rem}.mb-4{margin-bottom:1rem}.mb-5{margin-bottom:1.25rem}.mb-6{margin-bottom:1.5rem}.ml-auto{margin-left:auto}.mt-0{margin-top:0}.mt-0\.5{margin-top:.125rem}.mt-1{margin-top:.25rem}.mt-4{margin-top:1rem}.block{display:block}.inline{display:inline}.flex{display:flex}.inline-flex{display:inline-flex}.grid{display:grid}.hidden{display:none}.h-1{height:.25rem}.h-1\.5{height:.375rem}.h-12{height:3rem}.h-2{height:.5rem}.h-2\.5{height:.625rem}.h-3{height:.75rem}.h-3\.5{height:.875rem}.h-5{height:1.25rem}.h-8{height:2rem}.h-full{height:100%}.h-px{height:1px}.max-h-\[40vh\]{max-height:40vh}.w-10{width:2.5rem}.w-12{width:3rem}.w-2{width:.5rem}.w-2\.5{width:.625rem}.w-3{width:.75rem}.w-3\.5{width:.875rem}.w-5{width:1.25rem}.w-8{width:2rem}.w-full{width:100%}.min-w-0{min-width:0}.max-w-\[280px\]{max-width:280px}.flex-1{flex:1 1 0%}.flex-shrink-0,.shrink-0{flex-shrink:0}.transform{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}@keyframes spin{to{transform:rotate(1turn)}}.animate-spin{animation:spin 1s linear infinite}.cursor-default{cursor:default}.cursor-pointer{cursor:pointer}.grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.flex-row{flex-direction:row}.flex-col{flex-direction:column}.items-start{align-items:flex-start}.items-end{align-items:flex-end}.items-center{align-items:center}.items-baseline{align-items:baseline}.justify-end{justify-content:flex-end}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.gap-1{gap:.25rem}.gap-1\.5{gap:.375rem}.gap-2{gap:.5rem}.gap-3{gap:.75rem}.overflow-hidden{overflow:hidden}.overflow-y-auto{overflow-y:auto}.truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.break-words{overflow-wrap:break-word}.rounded{border-radius:.25rem}.rounded-full{border-radius:9999px}.rounded-lg{border-radius:.5rem}.rounded-md{border-radius:.375rem}.rounded-xl{border-radius:.75rem}.border{border-width:1px}.border-\[1\.5px\]{border-width:1.5px}.border-b{border-bottom-width:1px}.border-t{border-top-width:1px}.border-dashed{border-style:dashed}.border-gray-700{border-color:oklch(37.3% .034 259.733)}.border-teal-400{border-color:oklch(77.7% .152 181.912)}.border-t-transparent{border-top-color:#0000}.bg-teal-950{background-color:oklch(27.7% .046 192.524)}.bg-gradient-to-br{background-image:linear-gradient(to bottom right,var(--tw-gradient-stops))}.from-teal-500{--tw-gradient-from:oklch(70.4% 0.14 182.503) var(--tw-gradient-from-position);--tw-gradient-to:#fff0 var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-from),var(--tw-gradient-to)}.to-teal-600{--tw-gradient-to:oklch(60% 0.118 184.704) var(--tw-gradient-to-position)}.p-0{padding:0}.p-0\.5{padding:.125rem}.p-1{padding:.25rem}.p-2{padding:.5rem}.p-3{padding:.75rem}.px-1{padding-left:.25rem;padding-right:.25rem}.px-1\.5{padding-left:.375rem;padding-right:.375rem}.px-2{padding-left:.5rem;padding-right:.5rem}.px-2\.5{padding-left:.625rem;padding-right:.625rem}.px-3{padding-left:.75rem;padding-right:.75rem}.px-4{padding-left:1rem;padding-right:1rem}.px-6{padding-left:1.5rem;padding-right:1.5rem}.py-0{padding-top:0;padding-bottom:0}.py-0\.5{padding-top:.125rem;padding-bottom:.125rem}.py-1{padding-top:.25rem;padding-bottom:.25rem}.py-2{padding-top:.5rem;padding-bottom:.5rem}.py-2\.5{padding-top:.625rem;padding-bottom:.625rem}.py-3{padding-top:.75rem;padding-bottom:.75rem}.py-6{padding-top:1.5rem;padding-bottom:1.5rem}.pt-1{padding-top:.25rem}.pt-1\.5{padding-top:.375rem}.text-center{text-align:center}.text-2xl{font-size:1.5rem;line-height:2rem}.text-\[10px\]{font-size:10px}.text-\[11px\]{font-size:11px}.text-\[8px\]{font-size:8px}.text-\[9px\]{font-size:9px}.text-base{font-size:1rem;line-height:1.5rem}.text-sm{font-size:.875rem;line-height:1.25rem}.text-xs{font-size:.75rem;line-height:1rem}.font-bold{font-weight:700}.font-medium{font-weight:500}.font-semibold{font-weight:600}.uppercase{text-transform:uppercase}.tabular-nums{--tw-numeric-spacing:tabular-nums;font-variant-numeric:var(--tw-ordinal) var(--tw-slashed-zero) var(--tw-numeric-figure) var(--tw-numeric-spacing) var(--tw-numeric-fraction)}.leading-none{line-height:1}.leading-relaxed{line-height:1.625}.leading-tight{line-height:1.25}.tracking-wide{letter-spacing:.025em}.tracking-wider{letter-spacing:.05em}.text-amber-400{color:oklch(82.8% .189 84.429)}.text-gray-300{color:oklch(87.2% .01 258.338)}.text-gray-400{color:oklch(70.7% .022 261.325)}.text-gray-500{color:oklch(55.1% .027 264.364)}.text-green-400{color:oklch(79.2% .209 151.711)}.text-red-200{color:oklch(88.5% .062 18.334)}.text-red-400{color:oklch(70.4% .191 22.216)}.text-slate-100{color:oklch(96.8% .007 247.896)}.text-slate-300{color:oklch(86.9% .022 252.894)}.text-slate-400{color:oklch(70.4% .04 256.788)}.text-slate-500{color:oklch(55.4% .046 257.417)}.text-slate-600{color:oklch(44.6% .043 257.281)}.text-teal-300{color:oklch(85.5% .138 181.071)}.text-teal-400{color:oklch(77.7% .152 181.912)}.text-teal-500{color:oklch(70.4% .14 182.503)}.text-teal-600{color:oklch(60% .118 184.704)}.text-teal-800{color:oklch(43.7% .078 188.216)}.text-white{--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity))}.underline{text-decoration-line:underline}.no-underline{text-decoration-line:none}.underline-offset-2{text-underline-offset:2px}.shadow-lg{--tw-shadow:0 10px 15px -3px #0000001a,0 4px 6px -4px #0000001a;--tw-shadow-colored:0 10px 15px -3px var(--tw-shadow-color),0 4px 6px -4px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.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)}.backdrop-blur{--tw-backdrop-blur:blur(8px);-webkit-backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia)}.transition{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,-webkit-backdrop-filter;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter,-webkit-backdrop-filter;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-all{transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-colors{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1)}.duration-150,.transition-colors{transition-duration:.15s}.duration-700{transition-duration:.7s}.ease-in-out{transition-timing-function:cubic-bezier(.4,0,.2,1)}.ease-out{transition-timing-function:cubic-bezier(0,0,.2,1)}.join{display:inline-flex;align-items:stretch;--join-ss:0;--join-se:0;--join-es:0;--join-ee:0}.join :where(.join-item){border-start-start-radius:var(--join-ss,0);border-start-end-radius:var(--join-se,0);border-end-start-radius:var(--join-es,0);border-end-end-radius:var(--join-ee,0)}.join :where(.join-item) *{--join-ss:var(--radius-field);--join-se:var(--radius-field);--join-es:var(--radius-field);--join-ee:var(--radius-field)}.join>.join-item:where(:first-child){--join-ss:var(--radius-field);--join-se:0;--join-es:var(--radius-field);--join-ee:0}.join :first-child:not(:last-child) :where(.join-item){--join-ss:var(--radius-field);--join-se:0;--join-es:var(--radius-field);--join-ee:0}.join>.join-item:where(:last-child){--join-ss:0;--join-se:var(--radius-field);--join-es:0;--join-ee:var(--radius-field)}.join :last-child:not(:first-child) :where(.join-item){--join-ss:0;--join-se:var(--radius-field);--join-es:0;--join-ee:var(--radius-field)}.join>.join-item:where(:only-child){--join-ss:var(--radius-field);--join-se:var(--radius-field);--join-es:var(--radius-field);--join-ee:var(--radius-field)}.join :only-child :where(.join-item){--join-ss:var(--radius-field);--join-se:var(--radius-field);--join-es:var(--radius-field);--join-ee:var(--radius-field)}.hover\:bg-gray-600:hover{background-color:oklch(44.6% .03 256.802)}.hover\:bg-red-600:hover{background-color:oklch(57.7% .245 27.325)}.hover\:text-gray-200:hover{color:oklch(92.8% .006 264.531)}.hover\:text-slate-200:hover{color:oklch(92.9% .013 255.508)}.hover\:text-teal-400:hover{color:oklch(77.7% .152 181.912)}.hover\:text-white:hover{--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity))}.hover\:underline:hover{text-decoration-line:underline}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:opacity-30:disabled{opacity:.3}.group:hover .group-hover\:text-gray-400{color:oklch(70.7% .022 261.325)}.group:hover .group-hover\:text-teal-200{color:oklch(91% .096 180.426)}.group:hover .group-hover\:text-teal-300{color:oklch(85.5% .138 181.071)} \ No newline at end of file +/*! tailwindcss v4.2.2 | MIT License | https://tailwindcss.com */ +@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-gradient-position:initial;--tw-gradient-from:#0000;--tw-gradient-via:#0000;--tw-gradient-to:#0000;--tw-gradient-stops:initial;--tw-gradient-via-stops:initial;--tw-gradient-from-position:0%;--tw-gradient-via-position:50%;--tw-gradient-to-position:100%;--tw-leading:initial;--tw-font-weight:initial;--tw-tracking:initial;--tw-ordinal:initial;--tw-slashed-zero:initial;--tw-numeric-figure:initial;--tw-numeric-spacing:initial;--tw-numeric-fraction:initial;--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-backdrop-blur:initial;--tw-backdrop-brightness:initial;--tw-backdrop-contrast:initial;--tw-backdrop-grayscale:initial;--tw-backdrop-hue-rotate:initial;--tw-backdrop-invert:initial;--tw-backdrop-opacity:initial;--tw-backdrop-saturate:initial;--tw-backdrop-sepia:initial;--tw-duration:initial;--tw-ease:initial}}}@layer theme{:root,:host{--font-sans:"Graphik", sans-serif;--font-mono:ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;--color-red-200:oklch(88.5% .062 18.334);--color-red-300:oklch(80.8% .114 19.571);--color-red-400:oklch(70.4% .191 22.216);--color-red-500:oklch(63.7% .237 25.331);--color-red-600:oklch(57.7% .245 27.325);--color-red-700:oklch(50.5% .213 27.518);--color-red-800:oklch(44.4% .177 26.899);--color-red-900:oklch(39.6% .141 25.723);--color-amber-300:oklch(87.9% .169 91.605);--color-amber-400:oklch(82.8% .189 84.429);--color-amber-500:oklch(76.9% .188 70.08);--color-amber-700:oklch(55.5% .163 48.998);--color-amber-900:oklch(41.4% .112 45.904);--color-green-400:oklch(79.2% .209 151.711);--color-green-500:oklch(72.3% .219 149.579);--color-teal-200:oklch(91% .096 180.426);--color-teal-300:oklch(85.5% .138 181.071);--color-teal-400:oklch(77.7% .152 181.912);--color-teal-500:oklch(70.4% .14 182.503);--color-teal-600:oklch(60% .118 184.704);--color-teal-700:oklch(51.1% .096 186.391);--color-teal-800:oklch(43.7% .078 188.216);--color-teal-900:oklch(38.6% .063 188.416);--color-teal-950:oklch(27.7% .046 192.524);--color-slate-100:oklch(96.8% .007 247.896);--color-slate-200:oklch(92.9% .013 255.508);--color-slate-300:oklch(86.9% .022 252.894);--color-slate-400:oklch(70.4% .04 256.788);--color-slate-500:oklch(55.4% .046 257.417);--color-slate-600:oklch(44.6% .043 257.281);--color-gray-200:oklch(92.8% .006 264.531);--color-gray-300:oklch(87.2% .01 258.338);--color-gray-400:oklch(70.7% .022 261.325);--color-gray-500:oklch(55.1% .027 264.364);--color-gray-600:oklch(44.6% .03 256.802);--color-gray-700:oklch(37.3% .034 259.733);--color-gray-800:oklch(27.8% .033 256.848);--color-gray-900:oklch(21% .034 264.665);--color-black:#000;--color-white:#fff;--spacing:.25rem;--text-xs:.75rem;--text-xs--line-height:calc(1 / .75);--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--text-base:1rem;--text-base--line-height:calc(1.5 / 1);--text-2xl:1.5rem;--text-2xl--line-height:calc(2 / 1.5);--font-weight-medium:500;--font-weight-semibold:600;--font-weight-bold:700;--tracking-wide:.025em;--tracking-wider:.05em;--leading-tight:1.25;--leading-relaxed:1.625;--radius-md:.375rem;--radius-lg:.5rem;--radius-xl:.75rem;--ease-out:cubic-bezier(0, 0, .2, 1);--ease-in-out:cubic-bezier(.4, 0, .2, 1);--animate-spin:spin 1s linear infinite;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono)}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab, red, red)){::placeholder{color:color-mix(in oklab, currentcolor 50%, transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}: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(98% 0 0);--color-base-300:oklch(95% 0 0);--color-base-content:oklch(21% .006 285.885);--color-primary:oklch(45% .24 277.023);--color-primary-content:oklch(93% .034 272.788);--color-secondary:oklch(65% .241 354.308);--color-secondary-content:oklch(94% .028 342.258);--color-accent:oklch(77% .152 181.912);--color-accent-content:oklch(38% .063 188.416);--color-neutral:oklch(14% .005 285.823);--color-neutral-content:oklch(92% .004 286.32);--color-info:oklch(74% .16 232.661);--color-info-content:oklch(29% .066 243.157);--color-success:oklch(76% .177 163.223);--color-success-content:oklch(37% .077 168.94);--color-warning:oklch(82% .189 84.429);--color-warning-content:oklch(41% .112 45.904);--color-error:oklch(71% .194 13.428);--color-error-content:oklch(27% .105 12.094);--radius-selector:.5rem;--radius-field:.25rem;--radius-box:.5rem;--size-selector:.25rem;--size-field:.25rem;--border:1px;--depth:1;--noise:0}@media (prefers-color-scheme:dark){:root:not([data-theme]){color-scheme:dark;--color-base-100:oklch(25.33% .016 252.42);--color-base-200:oklch(23.26% .014 253.1);--color-base-300:oklch(21.15% .012 254.09);--color-base-content:oklch(97.807% .029 256.847);--color-primary:oklch(58% .233 277.117);--color-primary-content:oklch(96% .018 272.314);--color-secondary:oklch(65% .241 354.308);--color-secondary-content:oklch(94% .028 342.258);--color-accent:oklch(77% .152 181.912);--color-accent-content:oklch(38% .063 188.416);--color-neutral:oklch(14% .005 285.823);--color-neutral-content:oklch(92% .004 286.32);--color-info:oklch(74% .16 232.661);--color-info-content:oklch(29% .066 243.157);--color-success:oklch(76% .177 163.223);--color-success-content:oklch(37% .077 168.94);--color-warning:oklch(82% .189 84.429);--color-warning-content:oklch(41% .112 45.904);--color-error:oklch(71% .194 13.428);--color-error-content:oklch(27% .105 12.094);--radius-selector:.5rem;--radius-field:.25rem;--radius-box:.5rem;--size-selector:.25rem;--size-field:.25rem;--border:1px;--depth:1;--noise:0}}: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(98% 0 0);--color-base-300:oklch(95% 0 0);--color-base-content:oklch(21% .006 285.885);--color-primary:oklch(45% .24 277.023);--color-primary-content:oklch(93% .034 272.788);--color-secondary:oklch(65% .241 354.308);--color-secondary-content:oklch(94% .028 342.258);--color-accent:oklch(77% .152 181.912);--color-accent-content:oklch(38% .063 188.416);--color-neutral:oklch(14% .005 285.823);--color-neutral-content:oklch(92% .004 286.32);--color-info:oklch(74% .16 232.661);--color-info-content:oklch(29% .066 243.157);--color-success:oklch(76% .177 163.223);--color-success-content:oklch(37% .077 168.94);--color-warning:oklch(82% .189 84.429);--color-warning-content:oklch(41% .112 45.904);--color-error:oklch(71% .194 13.428);--color-error-content:oklch(27% .105 12.094);--radius-selector:.5rem;--radius-field:.25rem;--radius-box:.5rem;--size-selector:.25rem;--size-field:.25rem;--border:1px;--depth:1;--noise:0}:root:has(input.theme-controller[value=dark]:checked),[data-theme=dark]{color-scheme:dark;--color-base-100:oklch(25.33% .016 252.42);--color-base-200:oklch(23.26% .014 253.1);--color-base-300:oklch(21.15% .012 254.09);--color-base-content:oklch(97.807% .029 256.847);--color-primary:oklch(58% .233 277.117);--color-primary-content:oklch(96% .018 272.314);--color-secondary:oklch(65% .241 354.308);--color-secondary-content:oklch(94% .028 342.258);--color-accent:oklch(77% .152 181.912);--color-accent-content:oklch(38% .063 188.416);--color-neutral:oklch(14% .005 285.823);--color-neutral-content:oklch(92% .004 286.32);--color-info:oklch(74% .16 232.661);--color-info-content:oklch(29% .066 243.157);--color-success:oklch(76% .177 163.223);--color-success-content:oklch(37% .077 168.94);--color-warning:oklch(82% .189 84.429);--color-warning-content:oklch(41% .112 45.904);--color-error:oklch(71% .194 13.428);--color-error-content:oklch(27% .105 12.094);--radius-selector:.5rem;--radius-field:.25rem;--radius-box:.5rem;--size-selector:.25rem;--size-field:.25rem;--border:1px;--depth:1;--noise:0}:root{--fx-noise:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 200 200'%3E%3Cfilter id='a'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='1.34' numOctaves='4' stitchTiles='stitch'%3E%3C/feTurbulence%3E%3C/filter%3E%3Crect width='200' height='200' filter='url(%23a)' opacity='0.2'%3E%3C/rect%3E%3C/svg%3E");scrollbar-color:currentColor #0000}@supports (color:color-mix(in lab, red, red)){:root{scrollbar-color:color-mix(in oklch, currentColor 35%, #0000) #0000}}@property --radialprogress{syntax:"";inherits:true;initial-value:0%}:root:not(span){overflow:var(--page-overflow)}:root{--page-scroll-bg-on:linear-gradient(var(--root-bg), var(--root-bg)) var(--root-bg)}@supports (color:color-mix(in lab, red, red)){:root{--page-scroll-bg-on:linear-gradient(var(--root-bg), var(--root-bg)) color-mix(in srgb, var(--root-bg), oklch(0% 0 0) calc(var(--page-has-backdrop,0) * 40%))}}:root{--page-scroll-transition-on:background-color .3s ease-out;transition:var(--page-scroll-transition);scrollbar-gutter:var(--page-scroll-gutter,unset);scrollbar-gutter:if(style(--page-has-scroll: 1): var(--page-scroll-gutter,unset) ; else: unset)}:root:root{background:var(--page-scroll-bg,var(--root-bg,var(--color-base-100)))}@keyframes set-page-has-scroll{0%,to{--page-has-scroll:1}}:root,[data-theme]{background-color:var(--root-bg,var(--color-base-100));color:var(--color-base-content)}:where(:root,[data-theme]){--root-bg:var(--color-base-100)}}@layer components;@layer utilities{@layer daisyui.l1.l2.l3{.modal{pointer-events:none;visibility:hidden;width:100%;max-width:none;height:100%;max-height:none;color:inherit;transition:visibility .3s allow-discrete, background-color .3s ease-out, opacity .1s ease-out;overscroll-behavior:contain;z-index:999;scrollbar-gutter:auto;background-color:#0000;place-items:center;margin:0;padding:0;display:grid;position:fixed;inset:0;overflow:clip}.modal::backdrop{display:none}.tab{cursor:pointer;appearance:none;text-align:center;webkit-user-select:none;-webkit-user-select:none;user-select:none;flex-wrap:wrap;justify-content:center;align-items:center;display:inline-flex;position:relative}@media (hover:hover){.tab:hover{color:var(--color-base-content)}}.tab{--tab-p:.75rem;--tab-bg:var(--color-base-100);--tab-border-color:var(--color-base-300);--tab-radius-ss:0;--tab-radius-se:0;--tab-radius-es:0;--tab-radius-ee:0;--tab-order:0;--tab-radius-min:calc(.75rem - var(--border));--tab-radius-limit:min(var(--radius-field), var(--tab-radius-min));--tab-radius-grad:#0000 calc(69% - var(--border)), var(--tab-border-color) calc(calc(69% - var(--border)) + .25px), var(--tab-border-color) calc(calc(69% - var(--border)) + var(--border)), var(--tab-bg) calc(calc(69% - var(--border)) + var(--border) + .25px);order:var(--tab-order);height:var(--tab-height);border-color:#0000;padding-inline-start:var(--tab-p);padding-inline-end:var(--tab-p);font-size:.875rem}.tab:is(input[type=radio]){min-width:fit-content}.tab:is(input[type=radio]):after{--tw-content:attr(aria-label);content:var(--tw-content)}.tab:is(label){position:relative}.tab:is(label) input{cursor:pointer;appearance:none;opacity:0;position:absolute;inset:0}:is(.tab:checked,.tab:is(label:has(:checked)),.tab:is(.tab-active,[aria-selected=true],[aria-current=true],[aria-current=page]))+.tab-content{display:block}.tab:not(:checked,label:has(:checked),:hover,.tab-active,[aria-selected=true],[aria-current=true],[aria-current=page]){color:var(--color-base-content)}@supports (color:color-mix(in lab, red, red)){.tab:not(:checked,label:has(:checked),:hover,.tab-active,[aria-selected=true],[aria-current=true],[aria-current=page]){color:color-mix(in oklab, var(--color-base-content) 50%, transparent)}}.tab:not(input):empty{cursor:default;flex-grow:1}.tab:focus{--tw-outline-style:none;outline-style:none}@media (forced-colors:active){.tab:focus{outline-offset:2px;outline:2px solid #0000}}.tab:focus-visible,.tab:is(label:has(:checked:focus-visible)){outline-offset:-5px;outline:2px solid}.tab[disabled]{pointer-events:none;opacity:.4}:where(.btn){width:unset}.btn{cursor:pointer;text-align:center;vertical-align:middle;outline-offset:2px;webkit-user-select:none;-webkit-user-select:none;user-select:none;padding-inline:var(--btn-p);color:var(--btn-fg);--tw-prose-links:var(--btn-fg);height:var(--size);font-size:var(--fontsize,.875rem);outline-color:var(--btn-color,var(--color-base-content));background-color:var(--btn-bg);background-size:auto, calc(var(--noise) * 100%);background-image:none, var(--btn-noise);border-width:var(--border);border-style:solid;border-color:var(--btn-border);text-shadow:0 .5px oklch(100% 0 0 / calc(var(--depth) * .15));touch-action:manipulation;box-shadow:0 .5px 0 .5px oklch(100% 0 0 / calc(var(--depth) * 6%)) inset, var(--btn-shadow);--size:calc(var(--size-field,.25rem) * 10);--btn-bg:var(--btn-color,var(--color-base-200));--btn-fg:var(--color-base-content);--btn-p:1rem;--btn-border:var(--btn-bg);border-start-start-radius:var(--join-ss,var(--radius-field));border-start-end-radius:var(--join-se,var(--radius-field));border-end-end-radius:var(--join-ee,var(--radius-field));border-end-start-radius:var(--join-es,var(--radius-field));flex-wrap:nowrap;flex-shrink:0;justify-content:center;align-items:center;gap:.375rem;font-weight:600;transition-property:color,background-color,border-color,box-shadow;transition-duration:.2s;transition-timing-function:cubic-bezier(0,0,.2,1);display:inline-flex}@supports (color:color-mix(in lab, red, red)){.btn{--btn-border:color-mix(in oklab, var(--btn-bg), #000 calc(var(--depth) * 5%))}}.btn{--btn-shadow:0 3px 2px -2px var(--btn-bg), 0 4px 3px -2px var(--btn-bg)}@supports (color:color-mix(in lab, red, red)){.btn{--btn-shadow:0 3px 2px -2px color-mix(in oklab, var(--btn-bg) calc(var(--depth) * 30%), #0000), 0 4px 3px -2px color-mix(in oklab, var(--btn-bg) calc(var(--depth) * 30%), #0000)}}.btn{--btn-noise:var(--fx-noise)}@media (hover:hover){.btn:hover{--btn-bg:var(--btn-color,var(--color-base-200))}@supports (color:color-mix(in lab, red, red)){.btn:hover{--btn-bg:color-mix(in oklab, var(--btn-color,var(--color-base-200)), #000 7%)}}}.btn:focus-visible,.btn:has(:focus-visible){isolation:isolate;outline-width:2px;outline-style:solid}.btn:active:not(.btn-active){--btn-bg:var(--btn-color,var(--color-base-200));translate:0 .5px}@supports (color:color-mix(in lab, red, red)){.btn:active:not(.btn-active){--btn-bg:color-mix(in oklab, var(--btn-color,var(--color-base-200)), #000 5%)}}.btn:active:not(.btn-active){--btn-border:var(--btn-color,var(--color-base-200))}@supports (color:color-mix(in lab, red, red)){.btn:active:not(.btn-active){--btn-border:color-mix(in oklab, var(--btn-color,var(--color-base-200)), #000 7%)}}.btn:active:not(.btn-active){--btn-shadow:0 0 0 0 oklch(0% 0 0/0), 0 0 0 0 oklch(0% 0 0/0)}.btn:is(input[type=checkbox],input[type=radio]){appearance:none}.btn:is(input[type=checkbox],input[type=radio])[aria-label]:after{--tw-content:attr(aria-label);content:var(--tw-content)}.btn:where(input:checked:not(.filter .btn)){--btn-color:var(--color-primary);--btn-fg:var(--color-primary-content);isolation:isolate}.loading{pointer-events:none;aspect-ratio:1;vertical-align:middle;width:calc(var(--size-selector,.25rem) * 6);background-color:currentColor;display:inline-block;-webkit-mask-image:url("data:image/svg+xml,%3Csvg width='24' height='24' stroke='black' viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cg transform-origin='center'%3E%3Ccircle cx='12' cy='12' r='9.5' fill='none' stroke-width='3' stroke-linecap='round'%3E%3CanimateTransform attributeName='transform' type='rotate' from='0 12 12' to='360 12 12' dur='2s' repeatCount='indefinite'/%3E%3Canimate attributeName='stroke-dasharray' values='0,150;42,150;42,150' keyTimes='0;0.475;1' dur='1.5s' repeatCount='indefinite'/%3E%3Canimate attributeName='stroke-dashoffset' values='0;-16;-59' keyTimes='0;0.475;1' dur='1.5s' repeatCount='indefinite'/%3E%3C/circle%3E%3C/g%3E%3C/svg%3E");mask-image:url("data:image/svg+xml,%3Csvg width='24' height='24' stroke='black' viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cg transform-origin='center'%3E%3Ccircle cx='12' cy='12' r='9.5' fill='none' stroke-width='3' stroke-linecap='round'%3E%3CanimateTransform attributeName='transform' type='rotate' from='0 12 12' to='360 12 12' dur='2s' repeatCount='indefinite'/%3E%3Canimate attributeName='stroke-dasharray' values='0,150;42,150;42,150' keyTimes='0;0.475;1' dur='1.5s' repeatCount='indefinite'/%3E%3Canimate attributeName='stroke-dashoffset' values='0;-16;-59' keyTimes='0;0.475;1' dur='1.5s' repeatCount='indefinite'/%3E%3C/circle%3E%3C/g%3E%3C/svg%3E");-webkit-mask-position:50%;mask-position:50%;-webkit-mask-size:100%;mask-size:100%;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat}.input{cursor:text;border:var(--border) solid #0000;appearance:none;background-color:var(--color-base-100);vertical-align:middle;white-space:nowrap;width:clamp(3rem,20rem,100%);height:var(--size);font-size:max(var(--font-size,.875rem), .875rem);touch-action:manipulation;border-color:var(--input-color);box-shadow:0 1px var(--input-color) inset, 0 -1px oklch(100% 0 0 / calc(var(--depth) * .1)) inset;border-start-start-radius:var(--join-ss,var(--radius-field));border-start-end-radius:var(--join-se,var(--radius-field));border-end-end-radius:var(--join-ee,var(--radius-field));border-end-start-radius:var(--join-es,var(--radius-field));flex-shrink:1;align-items:center;gap:.5rem;padding-inline:.75rem;display:inline-flex;position:relative}@supports (color:color-mix(in lab, red, red)){.input{box-shadow:0 1px color-mix(in oklab, var(--input-color) calc(var(--depth) * 10%), #0000) inset, 0 -1px oklch(100% 0 0 / calc(var(--depth) * .1)) inset}}.input{--size:calc(var(--size-field,.25rem) * 10);--input-color:var(--color-base-content)}@supports (color:color-mix(in lab, red, red)){.input{--input-color:color-mix(in oklab, var(--color-base-content) 20%, #0000)}}.input:where(input){display:inline-flex}.input :where(input){appearance:none;background-color:#0000;border:none;width:100%;height:100%;display:inline-flex}.input :where(input):focus,.input :where(input):focus-within{--tw-outline-style:none;outline-style:none}@media (forced-colors:active){.input :where(input):focus,.input :where(input):focus-within{outline-offset:2px;outline:2px solid #0000}}.input :where(input[type=url]),.input :where(input[type=email]){direction:ltr}.input :where(input[type=date]){display:inline-flex}.input:focus,.input:focus-within{--input-color:var(--color-base-content);box-shadow:0 1px var(--input-color)}@supports (color:color-mix(in lab, red, red)){.input:focus,.input:focus-within{box-shadow:0 1px color-mix(in oklab, var(--input-color) calc(var(--depth) * 10%), #0000)}}.input:focus,.input:focus-within{outline:2px solid var(--input-color);outline-offset:2px;isolation:isolate;z-index:1}@media (pointer:coarse){@supports (-webkit-touch-callout:none){.input:focus,.input:focus-within{--font-size:1rem}}}.input:has(>input[disabled]),.input:is(:disabled,[disabled]),fieldset:disabled .input{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)){.input:has(>input[disabled]),.input:is(:disabled,[disabled]),fieldset:disabled .input{color:color-mix(in oklab, var(--color-base-content) 40%, transparent)}}:is(.input:has(>input[disabled]),.input:is(:disabled,[disabled]),fieldset:disabled .input)::placeholder{color:var(--color-base-content)}@supports (color:color-mix(in lab, red, red)){:is(.input:has(>input[disabled]),.input:is(:disabled,[disabled]),fieldset:disabled .input)::placeholder{color:color-mix(in oklab, var(--color-base-content) 20%, transparent)}}.input:has(>input[disabled]),.input:is(:disabled,[disabled]),fieldset:disabled .input{box-shadow:none}.input:has(>input[disabled])>input[disabled]{cursor:not-allowed}.input::-webkit-date-and-time-value{text-align:inherit}.input[type=number]::-webkit-inner-spin-button{margin-block:-.75rem;margin-inline-end:-.75rem}.input::-webkit-calendar-picker-indicator{position:absolute;inset-inline-end:.75em}.input:has(>input[type=date]) :where(input[type=date]){webkit-appearance:none;appearance:none;display:inline-flex}.input:has(>input[type=date]) input[type=date]::-webkit-calendar-picker-indicator{cursor:pointer;width:1em;height:1em;position:absolute;inset-inline-end:.75em}.indicator{width:max-content;display:inline-flex;position:relative}.indicator :where(.indicator-item){z-index:1;white-space:nowrap;top:var(--indicator-t,0);bottom:var(--indicator-b,auto);left:var(--indicator-s,auto);right:var(--indicator-e,0);translate:var(--indicator-x,50%) var(--indicator-y,-50%);position:absolute}.steps{counter-reset:step;grid-auto-columns:1fr;grid-auto-flow:column;display:inline-grid;overflow:auto hidden}.steps .step{text-align:center;--step-bg:var(--color-base-300);--step-fg:var(--color-base-content);grid-template-rows:40px 1fr;grid-template-columns:auto;place-items:center;min-width:4rem;display:grid}.steps .step:before{width:100%;height:.5rem;color:var(--step-bg);background-color:var(--step-bg);content:"";border:1px solid;grid-row-start:1;grid-column-start:1;margin-inline-start:-100%;top:0}.steps .step>.step-icon,.steps .step:not(:has(.step-icon)):after{--tw-content:counter(step);content:var(--tw-content);counter-increment:step;z-index:1;color:var(--step-fg);background-color:var(--step-bg);border:1px solid var(--step-bg);border-radius:3.40282e38px;grid-row-start:1;grid-column-start:1;place-self:center;place-items:center;width:2rem;height:2rem;display:grid;position:relative}.steps .step:first-child:before{--tw-content:none;content:var(--tw-content)}.steps .step[data-content]:after{--tw-content:attr(data-content);content:var(--tw-content)}.timeline{display:flex;position:relative}.timeline>li{grid-template-rows:var(--timeline-row-start,minmax(0, 1fr)) auto var(--timeline-row-end,minmax(0, 1fr));grid-template-columns:var(--timeline-col-start,minmax(0, 1fr)) auto var(--timeline-col-end,minmax(0, 1fr));flex-shrink:0;align-items:center;display:grid;position:relative}.timeline>li>hr{border:none;width:100%}.timeline>li>hr:first-child{grid-row-start:2;grid-column-start:1}.timeline>li>hr:last-child{grid-area:2/3/auto/none}@media print{.timeline>li>hr{border:.1px solid var(--color-base-300)}}.timeline :where(hr){background-color:var(--color-base-300);height:.25rem}.timeline:has(.timeline-middle hr):first-child{border-start-start-radius:0;border-start-end-radius:var(--radius-selector);border-end-end-radius:var(--radius-selector);border-end-start-radius:0}.timeline:has(.timeline-middle hr):last-child,.timeline:not(:has(.timeline-middle)) :first-child hr:last-child{border-start-start-radius:var(--radius-selector);border-start-end-radius:0;border-end-end-radius:0;border-end-start-radius:var(--radius-selector)}.timeline:not(:has(.timeline-middle)) :last-child hr:first-child{border-start-start-radius:0;border-start-end-radius:var(--radius-selector);border-end-end-radius:var(--radius-selector);border-end-start-radius:0}.checkbox{border:var(--border) solid var(--input-color,var(--color-base-content))}@supports (color:color-mix(in lab, red, red)){.checkbox{border:var(--border) solid var(--input-color,color-mix(in oklab, var(--color-base-content) 20%, #0000))}}.checkbox{cursor:pointer;appearance:none;border-radius:var(--radius-selector);vertical-align:middle;color:var(--color-base-content);box-shadow:0 1px oklch(0% 0 0 / calc(var(--depth) * .1)) inset, 0 0 #0000 inset, 0 0 #0000;--size:calc(var(--size-selector,.25rem) * 6);width:var(--size);height:var(--size);background-size:auto, calc(var(--noise) * 100%);background-image:none, var(--fx-noise);flex-shrink:0;padding:.25rem;transition:background-color .2s,box-shadow .2s;display:inline-block;position:relative}.checkbox:before{--tw-content:"";content:var(--tw-content);opacity:0;clip-path:polygon(20% 100%,20% 80%,50% 80%,50% 80%,70% 80%,70% 100%);width:100%;height:100%;box-shadow:0px 3px 0 0px oklch(100% 0 0 / calc(var(--depth) * .1)) inset;background-color:currentColor;font-size:1rem;line-height:.75;transition:clip-path .3s .1s,opacity .1s .1s,rotate .3s .1s,translate .3s .1s;display:block;rotate:45deg}.checkbox:focus-visible{outline:2px solid var(--input-color,currentColor);outline-offset:2px}.checkbox:checked,.checkbox[aria-checked=true]{background-color:var(--input-color,#0000);box-shadow:0 0 #0000 inset, 0 8px 0 -4px oklch(100% 0 0 / calc(var(--depth) * .1)) inset, 0 1px oklch(0% 0 0 / calc(var(--depth) * .1))}:is(.checkbox:checked,.checkbox[aria-checked=true]):before{clip-path:polygon(20% 100%,20% 80%,50% 80%,50% 0%,70% 0%,70% 100%);opacity:1}@media (forced-colors:active){:is(.checkbox:checked,.checkbox[aria-checked=true]):before{--tw-content:"✔︎";clip-path:none;background-color:#0000;rotate:0deg}}@media print{:is(.checkbox:checked,.checkbox[aria-checked=true]):before{--tw-content:"✔︎";clip-path:none;background-color:#0000;rotate:0deg}}.checkbox:indeterminate{background-color:var(--input-color,var(--color-base-content))}@supports (color:color-mix(in lab, red, red)){.checkbox:indeterminate{background-color:var(--input-color,color-mix(in oklab, var(--color-base-content) 20%, #0000))}}.checkbox:indeterminate:before{opacity:1;clip-path:polygon(20% 100%,20% 80%,50% 80%,50% 80%,80% 80%,80% 100%);translate:0 -35%;rotate:0deg}.stats{border-radius:var(--radius-box);grid-auto-flow:column;display:inline-grid;position:relative;overflow-x:auto}.progress{appearance:none;border-radius:var(--radius-box);background-color:currentColor;width:100%;height:.5rem;position:relative;overflow:hidden}@supports (color:color-mix(in lab, red, red)){.progress{background-color:color-mix(in oklab, currentcolor 20%, transparent)}}.progress{color:var(--color-base-content)}.progress:indeterminate{background-image:repeating-linear-gradient(90deg,currentColor -1% 10%,#0000 10% 90%);background-position-x:15%;background-size:200%}@media (prefers-reduced-motion:no-preference){.progress:indeterminate{animation:5s ease-in-out infinite progress}}@supports ((-moz-appearance:none)){.progress:indeterminate::-moz-progress-bar{background-color:#0000}@media (prefers-reduced-motion:no-preference){.progress:indeterminate::-moz-progress-bar{background-image:repeating-linear-gradient(90deg,currentColor -1% 10%,#0000 10% 90%);background-position-x:15%;background-size:200%;animation:5s ease-in-out infinite progress}}.progress::-moz-progress-bar{border-radius:var(--radius-box);background-color:currentColor}}@supports ((-webkit-appearance:none)){.progress::-webkit-progress-bar{border-radius:var(--radius-box);background-color:#0000}.progress::-webkit-progress-value{border-radius:var(--radius-box);background-color:currentColor}}.label{white-space:nowrap;color:currentColor;align-items:center;gap:.375rem;display:inline-flex}@supports (color:color-mix(in lab, red, red)){.label{color:color-mix(in oklab, currentcolor 60%, transparent)}}.label:has(input){cursor:pointer}.label:is(.input>*,.select>*){white-space:nowrap;height:calc(100% - .5rem);font-size:inherit;align-items:center;padding-inline:.75rem;display:flex}.label:is(.input>*,.select>*):first-child{border-inline-end:var(--border) solid currentColor;margin-inline:-.75rem .75rem}@supports (color:color-mix(in lab, red, red)){.label:is(.input>*,.select>*):first-child{border-inline-end:var(--border) solid color-mix(in oklab, currentColor 10%, #0000)}}.label:is(.input>*,.select>*):last-child{border-inline-start:var(--border) solid currentColor;margin-inline:.75rem -.75rem}@supports (color:color-mix(in lab, red, red)){.label:is(.input>*,.select>*):last-child{border-inline-start:var(--border) solid color-mix(in oklab, currentColor 10%, #0000)}}.status{aspect-ratio:1;border-radius:var(--radius-selector);background-color:var(--color-base-content);width:.5rem;height:.5rem;display:inline-block}@supports (color:color-mix(in lab, red, red)){.status{background-color:color-mix(in oklab, var(--color-base-content) 20%, transparent)}}.status{vertical-align:middle;color:#0000004d;background-position:50%;background-repeat:no-repeat}@supports (color:color-mix(in lab, red, red)){.status{color:color-mix(in oklab, var(--color-black) 30%, transparent)}}.status{background-image:radial-gradient(circle at 35% 30%, oklch(1 0 0 / calc(var(--depth) * .5)), #0000);box-shadow:0 2px 3px -1px}@supports (color:color-mix(in lab, red, red)){.status{box-shadow:0 2px 3px -1px color-mix(in oklab, currentColor calc(var(--depth) * 100%), #0000)}}.badge{border-radius:var(--radius-selector);vertical-align:middle;color:var(--badge-fg);border:var(--border) solid var(--badge-color,var(--color-base-200));width:fit-content;padding-inline:calc(.25rem * 3 - var(--border));background-size:auto, calc(var(--noise) * 100%);background-image:none, var(--fx-noise);background-color:var(--badge-bg);--badge-bg:var(--badge-color,var(--color-base-100));--badge-fg:var(--color-base-content);--size:calc(var(--size-selector,.25rem) * 6);height:var(--size);justify-content:center;align-items:center;gap:.5rem;font-size:.875rem;display:inline-flex}.tabs{--tabs-height:auto;--tabs-direction:row;--tab-height:calc(var(--size-field,.25rem) * 10);height:var(--tabs-height);flex-wrap:wrap;flex-direction:var(--tabs-direction);display:flex}.mask{vertical-align:middle;display:inline-block;-webkit-mask-position:50%;mask-position:50%;-webkit-mask-size:contain;mask-size:contain;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat}.link{cursor:pointer;text-decoration-line:underline}.link:focus{--tw-outline-style:none;outline-style:none}@media (forced-colors:active){.link:focus{outline-offset:2px;outline:2px solid #0000}}.link:focus-visible{outline-offset:2px;outline:2px solid}.btn-primary{--btn-color:var(--color-primary);--btn-fg:var(--color-primary-content)}}@layer daisyui.l1.l2{.modal.modal-open,.modal[open],.modal:target,.modal-toggle:checked+.modal{pointer-events:auto;visibility:visible;opacity:1;transition:visibility 0s allow-discrete, background-color .3s ease-out, opacity .1s ease-out;background-color:oklch(0% 0 0/.4)}:is(.modal.modal-open,.modal[open],.modal:target,.modal-toggle:checked+.modal) .modal-box{opacity:1;translate:0;scale:1}:root:has(:is(.modal.modal-open,.modal[open],.modal:target,.modal-toggle:checked+.modal)){--page-has-backdrop:1;--page-overflow:hidden;--page-scroll-bg:var(--page-scroll-bg-on);--page-scroll-gutter:stable;--page-scroll-transition:var(--page-scroll-transition-on);animation:forwards set-page-has-scroll;animation-timeline:scroll()}@starting-style{.modal.modal-open,.modal[open],.modal:target,.modal-toggle:checked+.modal{opacity:0}}.btn:disabled:not(.btn-link,.btn-ghost){background-color:var(--color-base-content)}@supports (color:color-mix(in lab, red, red)){.btn:disabled:not(.btn-link,.btn-ghost){background-color:color-mix(in oklab, var(--color-base-content) 10%, transparent)}}.btn:disabled:not(.btn-link,.btn-ghost){box-shadow:none}.btn:disabled{pointer-events:none;--btn-border:#0000;--btn-noise:none;--btn-fg:var(--color-base-content)}@supports (color:color-mix(in lab, red, red)){.btn:disabled{--btn-fg:color-mix(in oklch, var(--color-base-content) 20%, #0000)}}.btn[disabled]:not(.btn-link,.btn-ghost){background-color:var(--color-base-content)}@supports (color:color-mix(in lab, red, red)){.btn[disabled]:not(.btn-link,.btn-ghost){background-color:color-mix(in oklab, var(--color-base-content) 10%, transparent)}}.btn[disabled]:not(.btn-link,.btn-ghost){box-shadow:none}.btn[disabled]{pointer-events:none;--btn-border:#0000;--btn-noise:none;--btn-fg:var(--color-base-content)}@supports (color:color-mix(in lab, red, red)){.btn[disabled]{--btn-fg:color-mix(in oklch, var(--color-base-content) 20%, #0000)}}.steps .step-neutral+.step-neutral:before,.steps .step-neutral:after,.steps .step-neutral>.step-icon{--step-bg:var(--color-neutral);--step-fg:var(--color-neutral-content)}.steps .step-primary+.step-primary:before,.steps .step-primary:after,.steps .step-primary>.step-icon{--step-bg:var(--color-primary);--step-fg:var(--color-primary-content)}.steps .step-secondary+.step-secondary:before,.steps .step-secondary:after,.steps .step-secondary>.step-icon{--step-bg:var(--color-secondary);--step-fg:var(--color-secondary-content)}.steps .step-accent+.step-accent:before,.steps .step-accent:after,.steps .step-accent>.step-icon{--step-bg:var(--color-accent);--step-fg:var(--color-accent-content)}.steps .step-info+.step-info:before,.steps .step-info:after,.steps .step-info>.step-icon{--step-bg:var(--color-info);--step-fg:var(--color-info-content)}.steps .step-success+.step-success:before,.steps .step-success:after,.steps .step-success>.step-icon{--step-bg:var(--color-success);--step-fg:var(--color-success-content)}.steps .step-warning+.step-warning:before,.steps .step-warning:after,.steps .step-warning>.step-icon{--step-bg:var(--color-warning);--step-fg:var(--color-warning-content)}.steps .step-error+.step-error:before,.steps .step-error:after,.steps .step-error>.step-icon{--step-bg:var(--color-error);--step-fg:var(--color-error-content)}.checkbox:disabled{cursor:not-allowed;opacity:.2}}.visible{visibility:visible}.absolute{position:absolute}.relative{position:relative}.static{position:static}.inset-y-0{inset-block:calc(var(--spacing) * 0)}.start{inset-inline-start:var(--spacing)}.end{inset-inline-end:var(--spacing)}.left-0{left:calc(var(--spacing) * 0)}.container{width:100%}@media (min-width:40rem){.container{max-width:40rem}}@media (min-width:48rem){.container{max-width:48rem}}@media (min-width:64rem){.container{max-width:64rem}}@media (min-width:80rem){.container{max-width:80rem}}@media (min-width:96rem){.container{max-width:96rem}}.m-3{margin:calc(var(--spacing) * 3)}.mx-2{margin-inline:calc(var(--spacing) * 2)}.my-2{margin-block:calc(var(--spacing) * 2)}.mt-0\.5{margin-top:calc(var(--spacing) * .5)}.mt-1{margin-top:calc(var(--spacing) * 1)}.mt-4{margin-top:calc(var(--spacing) * 4)}.mb-1{margin-bottom:calc(var(--spacing) * 1)}.mb-1\.5{margin-bottom:calc(var(--spacing) * 1.5)}.mb-2{margin-bottom:calc(var(--spacing) * 2)}.mb-2\.5{margin-bottom:calc(var(--spacing) * 2.5)}.mb-4{margin-bottom:calc(var(--spacing) * 4)}.mb-5{margin-bottom:calc(var(--spacing) * 5)}.mb-6{margin-bottom:calc(var(--spacing) * 6)}.ml-auto{margin-left:auto}.join{--join-ss:0;--join-se:0;--join-es:0;--join-ee:0;align-items:stretch;display:inline-flex}.join :where(.join-item){border-start-start-radius:var(--join-ss,0);border-start-end-radius:var(--join-se,0);border-end-end-radius:var(--join-ee,0);border-end-start-radius:var(--join-es,0)}.join :where(.join-item) *{--join-ss:var(--radius-field);--join-se:var(--radius-field);--join-es:var(--radius-field);--join-ee:var(--radius-field)}.join>.join-item:where(:first-child),.join :first-child:not(:last-child) :where(.join-item){--join-ss:var(--radius-field);--join-se:0;--join-es:var(--radius-field);--join-ee:0}.join>.join-item:where(:last-child),.join :last-child:not(:first-child) :where(.join-item){--join-ss:0;--join-se:var(--radius-field);--join-es:0;--join-ee:var(--radius-field)}.join>.join-item:where(:only-child),.join :only-child :where(.join-item){--join-ss:var(--radius-field);--join-se:var(--radius-field);--join-es:var(--radius-field);--join-ee:var(--radius-field)}.block{display:block}.contents{display:contents}.flex{display:flex}.grid{display:grid}.hidden{display:none}.inline-flex{display:inline-flex}.h-1\.5{height:calc(var(--spacing) * 1.5)}.h-2\.5{height:calc(var(--spacing) * 2.5)}.h-3{height:calc(var(--spacing) * 3)}.h-3\.5{height:calc(var(--spacing) * 3.5)}.h-5{height:calc(var(--spacing) * 5)}.h-8{height:calc(var(--spacing) * 8)}.h-12{height:calc(var(--spacing) * 12)}.h-full{height:100%}.h-px{height:1px}.max-h-\[40vh\]{max-height:40vh}.w-2\.5{width:calc(var(--spacing) * 2.5)}.w-3{width:calc(var(--spacing) * 3)}.w-3\.5{width:calc(var(--spacing) * 3.5)}.w-5{width:calc(var(--spacing) * 5)}.w-8{width:calc(var(--spacing) * 8)}.w-10{width:calc(var(--spacing) * 10)}.w-12{width:calc(var(--spacing) * 12)}.w-full{width:100%}.max-w-\[280px\]{max-width:280px}.min-w-0{min-width:calc(var(--spacing) * 0)}.flex-1{flex:1}.flex-shrink-0,.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,)}.animate-spin{animation:var(--animate-spin)}.cursor-default{cursor:default}.cursor-pointer{cursor:pointer}.grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.flex-col{flex-direction:column}.flex-row{flex-direction:row}.items-baseline{align-items:baseline}.items-center{align-items:center}.items-end{align-items:flex-end}.items-start{align-items:flex-start}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.justify-end{justify-content:flex-end}.gap-1{gap:calc(var(--spacing) * 1)}.gap-1\.5{gap:calc(var(--spacing) * 1.5)}.gap-2{gap:calc(var(--spacing) * 2)}.gap-3{gap:calc(var(--spacing) * 3)}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-hidden{overflow:hidden}.overflow-y-auto{overflow-y:auto}.rounded{border-radius:.25rem}.rounded-full{border-radius:3.40282e38px}.rounded-lg{border-radius:var(--radius-lg)}.rounded-md{border-radius:var(--radius-md)}.rounded-xl{border-radius:var(--radius-xl)}.border{border-style:var(--tw-border-style);border-width:1px}.border-\[1\.5px\]{border-style:var(--tw-border-style);border-width:1.5px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-dashed{--tw-border-style:dashed;border-style:dashed}.border-amber-700\/30{border-color:#b750004d}@supports (color:color-mix(in lab, red, red)){.border-amber-700\/30{border-color:color-mix(in oklab, var(--color-amber-700) 30%, transparent)}}.border-gray-700{border-color:var(--color-gray-700)}.border-red-800\/30{border-color:#9f07124d}@supports (color:color-mix(in lab, red, red)){.border-red-800\/30{border-color:color-mix(in oklab, var(--color-red-800) 30%, transparent)}}.border-teal-400{border-color:var(--color-teal-400)}.border-teal-800\/15{border-color:#005f5a26}@supports (color:color-mix(in lab, red, red)){.border-teal-800\/15{border-color:color-mix(in oklab, var(--color-teal-800) 15%, transparent)}}.border-teal-800\/20{border-color:#005f5a33}@supports (color:color-mix(in lab, red, red)){.border-teal-800\/20{border-color:color-mix(in oklab, var(--color-teal-800) 20%, transparent)}}.border-teal-800\/25{border-color:#005f5a40}@supports (color:color-mix(in lab, red, red)){.border-teal-800\/25{border-color:color-mix(in oklab, var(--color-teal-800) 25%, transparent)}}.border-teal-800\/30{border-color:#005f5a4d}@supports (color:color-mix(in lab, red, red)){.border-teal-800\/30{border-color:color-mix(in oklab, var(--color-teal-800) 30%, transparent)}}.border-teal-800\/40{border-color:#005f5a66}@supports (color:color-mix(in lab, red, red)){.border-teal-800\/40{border-color:color-mix(in oklab, var(--color-teal-800) 40%, transparent)}}.border-teal-800\/50{border-color:#005f5a80}@supports (color:color-mix(in lab, red, red)){.border-teal-800\/50{border-color:color-mix(in oklab, var(--color-teal-800) 50%, transparent)}}.border-t-transparent{border-top-color:#0000}.bg-amber-500\/15{background-color:#f99c0026}@supports (color:color-mix(in lab, red, red)){.bg-amber-500\/15{background-color:color-mix(in oklab, var(--color-amber-500) 15%, transparent)}}.bg-amber-900\/20{background-color:#7b330633}@supports (color:color-mix(in lab, red, red)){.bg-amber-900\/20{background-color:color-mix(in oklab, var(--color-amber-900) 20%, transparent)}}.bg-gray-800\/95{background-color:#1e2939f2}@supports (color:color-mix(in lab, red, red)){.bg-gray-800\/95{background-color:color-mix(in oklab, var(--color-gray-800) 95%, transparent)}}.bg-gray-900\/60{background-color:#10182899}@supports (color:color-mix(in lab, red, red)){.bg-gray-900\/60{background-color:color-mix(in oklab, var(--color-gray-900) 60%, transparent)}}.bg-green-500\/15{background-color:#00c75826}@supports (color:color-mix(in lab, red, red)){.bg-green-500\/15{background-color:color-mix(in oklab, var(--color-green-500) 15%, transparent)}}.bg-red-500\/15{background-color:#fb2c3626}@supports (color:color-mix(in lab, red, red)){.bg-red-500\/15{background-color:color-mix(in oklab, var(--color-red-500) 15%, transparent)}}.bg-red-600\/70{background-color:#e40014b3}@supports (color:color-mix(in lab, red, red)){.bg-red-600\/70{background-color:color-mix(in oklab, var(--color-red-600) 70%, transparent)}}.bg-red-700\/60{background-color:#bf000f99}@supports (color:color-mix(in lab, red, red)){.bg-red-700\/60{background-color:color-mix(in oklab, var(--color-red-700) 60%, transparent)}}.bg-red-900\/20{background-color:#82181a33}@supports (color:color-mix(in lab, red, red)){.bg-red-900\/20{background-color:color-mix(in oklab, var(--color-red-900) 20%, transparent)}}.bg-slate-500\/10{background-color:#62748e1a}@supports (color:color-mix(in lab, red, red)){.bg-slate-500\/10{background-color:color-mix(in oklab, var(--color-slate-500) 10%, transparent)}}.bg-teal-400\/10{background-color:#00d3bd1a}@supports (color:color-mix(in lab, red, red)){.bg-teal-400\/10{background-color:color-mix(in oklab, var(--color-teal-400) 10%, transparent)}}.bg-teal-500\/15{background-color:#00baa726}@supports (color:color-mix(in lab, red, red)){.bg-teal-500\/15{background-color:color-mix(in oklab, var(--color-teal-500) 15%, transparent)}}.bg-teal-500\/50{background-color:#00baa780}@supports (color:color-mix(in lab, red, red)){.bg-teal-500\/50{background-color:color-mix(in oklab, var(--color-teal-500) 50%, transparent)}}.bg-teal-800\/40{background-color:#005f5a66}@supports (color:color-mix(in lab, red, red)){.bg-teal-800\/40{background-color:color-mix(in oklab, var(--color-teal-800) 40%, transparent)}}.bg-teal-800\/50{background-color:#005f5a80}@supports (color:color-mix(in lab, red, red)){.bg-teal-800\/50{background-color:color-mix(in oklab, var(--color-teal-800) 50%, transparent)}}.bg-teal-900\/20{background-color:#0b4f4a33}@supports (color:color-mix(in lab, red, red)){.bg-teal-900\/20{background-color:color-mix(in oklab, var(--color-teal-900) 20%, transparent)}}.bg-teal-900\/25{background-color:#0b4f4a40}@supports (color:color-mix(in lab, red, red)){.bg-teal-900\/25{background-color:color-mix(in oklab, var(--color-teal-900) 25%, transparent)}}.bg-teal-900\/30{background-color:#0b4f4a4d}@supports (color:color-mix(in lab, red, red)){.bg-teal-900\/30{background-color:color-mix(in oklab, var(--color-teal-900) 30%, transparent)}}.bg-teal-900\/50{background-color:#0b4f4a80}@supports (color:color-mix(in lab, red, red)){.bg-teal-900\/50{background-color:color-mix(in oklab, var(--color-teal-900) 50%, transparent)}}.bg-teal-900\/80{background-color:#0b4f4acc}@supports (color:color-mix(in lab, red, red)){.bg-teal-900\/80{background-color:color-mix(in oklab, var(--color-teal-900) 80%, transparent)}}.bg-teal-950{background-color:var(--color-teal-950)}.bg-teal-950\/40{background-color:#022f2e66}@supports (color:color-mix(in lab, red, red)){.bg-teal-950\/40{background-color:color-mix(in oklab, var(--color-teal-950) 40%, transparent)}}.bg-teal-950\/60{background-color:#022f2e99}@supports (color:color-mix(in lab, red, red)){.bg-teal-950\/60{background-color:color-mix(in oklab, var(--color-teal-950) 60%, transparent)}}.bg-gradient-to-br{--tw-gradient-position:to bottom right in oklab;background-image:linear-gradient(var(--tw-gradient-stops))}.from-teal-500{--tw-gradient-from:var(--color-teal-500);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position))}.to-teal-600{--tw-gradient-to:var(--color-teal-600);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position))}.p-0\.5{padding:calc(var(--spacing) * .5)}.p-1{padding:calc(var(--spacing) * 1)}.p-2{padding:calc(var(--spacing) * 2)}.p-3{padding:calc(var(--spacing) * 3)}.px-1\.5{padding-inline:calc(var(--spacing) * 1.5)}.px-2{padding-inline:calc(var(--spacing) * 2)}.px-2\.5{padding-inline:calc(var(--spacing) * 2.5)}.px-3{padding-inline:calc(var(--spacing) * 3)}.px-4{padding-inline:calc(var(--spacing) * 4)}.px-6{padding-inline:calc(var(--spacing) * 6)}.py-0\.5{padding-block:calc(var(--spacing) * .5)}.py-1{padding-block:calc(var(--spacing) * 1)}.py-2{padding-block:calc(var(--spacing) * 2)}.py-2\.5{padding-block:calc(var(--spacing) * 2.5)}.py-3{padding-block:calc(var(--spacing) * 3)}.py-6{padding-block:calc(var(--spacing) * 6)}.pt-1\.5{padding-top:calc(var(--spacing) * 1.5)}.text-center{text-align:center}.font-mono{font-family:var(--font-mono)}.text-2xl{font-size:var(--text-2xl);line-height:var(--tw-leading,var(--text-2xl--line-height))}.text-base{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.text-\[8px\]{font-size:8px}.text-\[9px\]{font-size:9px}.text-\[10px\]{font-size:10px}.text-\[11px\]{font-size:11px}.leading-none{--tw-leading:1;line-height:1}.leading-relaxed{--tw-leading:var(--leading-relaxed);line-height:var(--leading-relaxed)}.leading-tight{--tw-leading:var(--leading-tight);line-height:var(--leading-tight)}.font-bold{--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.tracking-wide{--tw-tracking:var(--tracking-wide);letter-spacing:var(--tracking-wide)}.tracking-wider{--tw-tracking:var(--tracking-wider);letter-spacing:var(--tracking-wider)}.break-words{overflow-wrap:break-word}.text-amber-300\/90{color:#ffd236e6}@supports (color:color-mix(in lab, red, red)){.text-amber-300\/90{color:color-mix(in oklab, var(--color-amber-300) 90%, transparent)}}.text-amber-400{color:var(--color-amber-400)}.text-gray-300{color:var(--color-gray-300)}.text-gray-400{color:var(--color-gray-400)}.text-gray-500{color:var(--color-gray-500)}.text-green-400{color:var(--color-green-400)}.text-red-200{color:var(--color-red-200)}.text-red-300\/90{color:#ffa3a3e6}@supports (color:color-mix(in lab, red, red)){.text-red-300\/90{color:color-mix(in oklab, var(--color-red-300) 90%, transparent)}}.text-red-400{color:var(--color-red-400)}.text-slate-100{color:var(--color-slate-100)}.text-slate-300{color:var(--color-slate-300)}.text-slate-400{color:var(--color-slate-400)}.text-slate-500{color:var(--color-slate-500)}.text-slate-600{color:var(--color-slate-600)}.text-teal-300{color:var(--color-teal-300)}.text-teal-400{color:var(--color-teal-400)}.text-teal-500{color:var(--color-teal-500)}.text-teal-600{color:var(--color-teal-600)}.text-teal-800{color:var(--color-teal-800)}.text-teal-800\/60{color:#005f5a99}@supports (color:color-mix(in lab, red, red)){.text-teal-800\/60{color:color-mix(in oklab, var(--color-teal-800) 60%, transparent)}}.text-white{color:var(--color-white)}.uppercase{text-transform:uppercase}.tabular-nums{--tw-numeric-spacing:tabular-nums;font-variant-numeric:var(--tw-ordinal,) var(--tw-slashed-zero,) var(--tw-numeric-figure,) var(--tw-numeric-spacing,) var(--tw-numeric-fraction,)}.no-underline{text-decoration-line:none}.underline{text-decoration-line:underline}.underline-offset-2{text-underline-offset:2px}.shadow-lg{--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a), 0 4px 6px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-teal-600\/30{--tw-shadow-color:#0095884d}@supports (color:color-mix(in lab, red, red)){.shadow-teal-600\/30{--tw-shadow-color:color-mix(in oklab, color-mix(in oklab, var(--color-teal-600) 30%, transparent) var(--tw-shadow-alpha), transparent)}}.shadow-teal-900\/40{--tw-shadow-color:#0b4f4a66}@supports (color:color-mix(in lab, red, red)){.shadow-teal-900\/40{--tw-shadow-color:color-mix(in oklab, color-mix(in oklab, var(--color-teal-900) 40%, transparent) var(--tw-shadow-alpha), transparent)}}.backdrop-blur{--tw-backdrop-blur:blur(8px);-webkit-backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,)}.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,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-all{transition-property:all;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.duration-150{--tw-duration:.15s;transition-duration:.15s}.duration-700{--tw-duration:.7s;transition-duration:.7s}.ease-in-out{--tw-ease:var(--ease-in-out);transition-timing-function:var(--ease-in-out)}.ease-out{--tw-ease:var(--ease-out);transition-timing-function:var(--ease-out)}@media (hover:hover){.group-hover\:bg-teal-700\/40:is(:where(.group):hover *){background-color:#00776e66}@supports (color:color-mix(in lab, red, red)){.group-hover\:bg-teal-700\/40:is(:where(.group):hover *){background-color:color-mix(in oklab, var(--color-teal-700) 40%, transparent)}}.group-hover\:text-gray-400:is(:where(.group):hover *){color:var(--color-gray-400)}.group-hover\:text-teal-200:is(:where(.group):hover *){color:var(--color-teal-200)}.group-hover\:text-teal-300:is(:where(.group):hover *){color:var(--color-teal-300)}.hover\:border-teal-700\/25:hover{border-color:#00776e40}@supports (color:color-mix(in lab, red, red)){.hover\:border-teal-700\/25:hover{border-color:color-mix(in oklab, var(--color-teal-700) 25%, transparent)}}.hover\:border-teal-700\/50:hover{border-color:#00776e80}@supports (color:color-mix(in lab, red, red)){.hover\:border-teal-700\/50:hover{border-color:color-mix(in oklab, var(--color-teal-700) 50%, transparent)}}.hover\:bg-gray-600:hover{background-color:var(--color-gray-600)}.hover\:bg-red-600:hover{background-color:var(--color-red-600)}.hover\:bg-teal-800\/30:hover{background-color:#005f5a4d}@supports (color:color-mix(in lab, red, red)){.hover\:bg-teal-800\/30:hover{background-color:color-mix(in oklab, var(--color-teal-800) 30%, transparent)}}.hover\:bg-teal-800\/40:hover{background-color:#005f5a66}@supports (color:color-mix(in lab, red, red)){.hover\:bg-teal-800\/40:hover{background-color:color-mix(in oklab, var(--color-teal-800) 40%, transparent)}}.hover\:bg-teal-900\/50:hover{background-color:#0b4f4a80}@supports (color:color-mix(in lab, red, red)){.hover\:bg-teal-900\/50:hover{background-color:color-mix(in oklab, var(--color-teal-900) 50%, transparent)}}.hover\:text-gray-200:hover{color:var(--color-gray-200)}.hover\:text-slate-200:hover{color:var(--color-slate-200)}.hover\:text-teal-400:hover{color:var(--color-teal-400)}.hover\:text-white:hover{color:var(--color-white)}.hover\:underline:hover{text-decoration-line:underline}}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:opacity-30:disabled{opacity:.3}}@keyframes rating{0%,40%{filter:brightness(1.05)contrast(1.05);scale:1.1}}@keyframes dropdown{0%{opacity:0}}@keyframes radio{0%{padding:5px}50%{padding:3px}}@keyframes toast{0%{opacity:0;scale:.9}to{opacity:1;scale:1}}@keyframes rotator{89.9999%,to{--first-item-position:0 0%}90%,99.9999%{--first-item-position:0 calc(var(--items) * 100%)}to{translate:0 -100%}}@keyframes skeleton{0%{background-position:150%}to{background-position:-50%}}@keyframes menu{0%{opacity:0}}@keyframes progress{50%{background-position-x:-115%}}@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-gradient-position{syntax:"*";inherits:false}@property --tw-gradient-from{syntax:"";inherits:false;initial-value:#0000}@property --tw-gradient-via{syntax:"";inherits:false;initial-value:#0000}@property --tw-gradient-to{syntax:"";inherits:false;initial-value:#0000}@property --tw-gradient-stops{syntax:"*";inherits:false}@property --tw-gradient-via-stops{syntax:"*";inherits:false}@property --tw-gradient-from-position{syntax:"";inherits:false;initial-value:0%}@property --tw-gradient-via-position{syntax:"";inherits:false;initial-value:50%}@property --tw-gradient-to-position{syntax:"";inherits:false;initial-value:100%}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-tracking{syntax:"*";inherits:false}@property --tw-ordinal{syntax:"*";inherits:false}@property --tw-slashed-zero{syntax:"*";inherits:false}@property --tw-numeric-figure{syntax:"*";inherits:false}@property --tw-numeric-spacing{syntax:"*";inherits:false}@property --tw-numeric-fraction{syntax:"*";inherits:false}@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:0}@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-backdrop-blur{syntax:"*";inherits:false}@property --tw-backdrop-brightness{syntax:"*";inherits:false}@property --tw-backdrop-contrast{syntax:"*";inherits:false}@property --tw-backdrop-grayscale{syntax:"*";inherits:false}@property --tw-backdrop-hue-rotate{syntax:"*";inherits:false}@property --tw-backdrop-invert{syntax:"*";inherits:false}@property --tw-backdrop-opacity{syntax:"*";inherits:false}@property --tw-backdrop-saturate{syntax:"*";inherits:false}@property --tw-backdrop-sepia{syntax:"*";inherits:false}@property --tw-duration{syntax:"*";inherits:false}@property --tw-ease{syntax:"*";inherits:false}@keyframes spin{to{transform:rotate(360deg)}} \ No newline at end of file diff --git a/tailwind.config.js b/tailwind.config.js index 337f806..3fda58a 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -4,7 +4,8 @@ const colors = require("tailwindcss/colors"); /** @type {import('tailwindcss').Config} */ module.exports = { content: [ - "./src/**/*.{html,ts}" // scan popup.html, other HTML + TS files + "./src/popup.html", // scan popup.html for class names + "./src/**/*.{html,ts}" // other HTML + TS files ], theme: { colors, diff --git a/webpack.config.js b/webpack.config.js index 589620c..8992d48 100755 --- a/webpack.config.js +++ b/webpack.config.js @@ -23,6 +23,13 @@ var fileExtensions = [ const isDevelopment = process.env.NODE_ENV !== "production"; +// --------------------------------------------------------------------------- +// Browser target: "chrome" (default) or "firefox" +// --------------------------------------------------------------------------- +const BROWSER = process.env.BROWSER || "chrome"; +const isFirefox = BROWSER === "firefox"; +const isChrome = BROWSER === "chrome"; + // Environment-specific config for CSTRADEUP const ENV_CONFIG = { development: { @@ -54,6 +61,9 @@ var options = { "inject-api": path.join(__dirname, "src", "content", "inject-api.ts"), relay: path.join(__dirname, "src", "content", "relay.ts"), intercept: path.join(__dirname, "src", "content", "intercept.ts"), + // Offscreen is used on both browsers: + // Chrome: loaded via chrome.offscreen.createDocument() + // Firefox: loaded directly in background_ff.html (background page) offscreen: path.join(__dirname, "src", "background", "offscreen", "offscreen.ts"), }, // chromeExtensionBoilerplate: { @@ -138,6 +148,7 @@ var options = { __CSTRADEUP_HOSTNAME__: JSON.stringify(currentEnv.HOSTNAME), __CSTRADEUP_DOMAIN__: JSON.stringify(currentEnv.DOMAIN), __IS_DEV__: JSON.stringify(isDevelopment), + __BROWSER__: JSON.stringify(BROWSER), }), // new ExtReloader({ // manifest: path.resolve(__dirname, "src/manifest.json") @@ -177,6 +188,41 @@ var options = { } } + // ── Firefox-specific manifest transformations ────────────────── + if (isFirefox) { + // 1. Add gecko addon id (required for Firefox extensions) + // Override with FIREFOX_ADDON_ID env var or use default. + manifest.browser_specific_settings = { + gecko: { + id: process.env.FIREFOX_ADDON_ID || "extension@cstradeup.net", + strict_min_version: "128.0", + }, + }; + + // 2. Firefox MV3 uses background.scripts (not service_worker). + // Firefox creates an auto-generated background page and loads + // each script via