diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 45b5e31..e3c4369 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -156,6 +156,15 @@ jobs: - name: Cache cargo registry and target uses: Swatinem/rust-cache@v2 + - name: Install Node.js + uses: actions/setup-node@v4 + with: + node-version: "20" + cache: "npm" + + - name: Install npm dependencies (UnoCSS) + run: npm ci + - name: Install Trunk run: | wget -qO- https://github.com/trunk-rs/trunk/releases/download/v0.21.14/trunk-x86_64-unknown-linux-gnu.tar.gz \ @@ -195,10 +204,31 @@ jobs: fi } check 'odp-*_bg.wasm' 'wasm' 230 - check 'tailwind-*.css' 'tailwind CSS' 10 + check 'base-*.css' 'base CSS' 5 + check 'uno.generated-*.css' 'UnoCSS bundle' 10 check 'repo_graph.css' 'repo_graph CSS' 2 check 'odp-*.js' 'wasm-bindgen JS' 20 if [ "$fail" -ne 0 ]; then echo "::error::One or more assets exceeded their size budget." exit 1 fi + + - name: Critical icon classes present + # UnoCSS preset-icons silently emits nothing when an icon class + # cannot be resolved (missing iconify pack, typo, etc.), which + # would ship a working build with invisible buttons. Assert that + # the icons we actually rely on made it into the generated CSS. + run: | + set -euo pipefail + css=$(ls dist/uno.generated-*.css | head -n1) + required="i-lucide-moon i-lucide-sun i-lucide-menu i-lucide-x i-lucide-arrow-right i-lucide-github i-lucide-play" + missing="" + for cls in $required; do + grep -qF ".$cls" "$css" || missing="$missing $cls" + done + if [ -n "$missing" ]; then + echo "::error::UnoCSS did not emit rules for:$missing" + echo "::error::Likely cause: missing iconify pack in node_modules (run 'npm ci'), or class typo in src/." + exit 1 + fi + echo "OK: all required icon utilities present in $css" diff --git a/.github/workflows/cloudflare-pages-deploy.yaml b/.github/workflows/cloudflare-pages-deploy.yaml index bac3afc..692f6a5 100644 --- a/.github/workflows/cloudflare-pages-deploy.yaml +++ b/.github/workflows/cloudflare-pages-deploy.yaml @@ -44,6 +44,15 @@ jobs: # - name: Download and install tailwindcss binary # run: npm install -D tailwindcss && npx tailwindcss -i -o # run tailwind + - name: Install Node.js + uses: actions/setup-node@v4 + with: + node-version: "20" + cache: "npm" + + - name: Install npm dependencies (UnoCSS) + run: npm ci + - name: Download and install Trunk binary run: wget -qO- https://github.com/trunk-rs/trunk/releases/download/v0.21.14/trunk-x86_64-unknown-linux-gnu.tar.gz | tar -xzf- diff --git a/.gitignore b/.gitignore index 68863f0..a260c8f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,8 @@ /target /dist/ + +# UnoCSS pipeline -- generated stylesheet and Node tooling are not +# committed; consumers run `npm install` once and `trunk build` after. +/node_modules/ +/style/uno.generated.css + diff --git a/Cargo.lock b/Cargo.lock index 6dbab66..80a96c4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -132,6 +132,12 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "classes" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5603d514e43c7439b594a021fa63bf6bfde2b47b6af966023624fd777d4dd8b3" + [[package]] name = "codee" version = "0.3.2" @@ -1012,6 +1018,7 @@ dependencies = [ "leptos_meta", "leptos_router", "serde_json", + "unocss-classes", "wasm-bindgen", "wasm-bindgen-futures", "wasm-bindgen-test", @@ -1289,6 +1296,12 @@ dependencies = [ "regex-syntax", ] +[[package]] +name = "regex-lite" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cab834c73d247e67f4fae452806d17d3c7501756d98c8808d7c9c7aa7d18f973" + [[package]] name = "regex-syntax" version = "0.8.5" @@ -1714,6 +1727,38 @@ version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" +[[package]] +name = "unocss-classes" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "034c7e51f6e631ac4da2b365acd8f614f4ab6415db421f1ebbef8b579b2bfae4" +dependencies = [ + "classes", + "unocss-classes-macros", +] + +[[package]] +name = "unocss-classes-macros" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "878280153455c4801d3e33f268335f166cce60b92c22ce4ae83010d2f25cd160" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "unocss-classes-utils", +] + +[[package]] +name = "unocss-classes-utils" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a933cd049d632b1070477be454c2f9c49c1cf2e76b638094bb2e4df459c34a42" +dependencies = [ + "once_cell", + "regex-lite", +] + [[package]] name = "url" version = "2.5.4" diff --git a/Cargo.toml b/Cargo.toml index 1898377..8e1d95a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,13 +8,14 @@ console_error_panic_hook = "0.1.7" leptos = { version = "0.8.2", features = ["csr"] } leptos_meta = "0.8.2" leptos_router = "0.8.2" +unocss-classes = "2" wasm-bindgen = "0.2.100" # All the web-sys features we use directly (Window, Document, Console) # are already enabled transitively by leptos's `csr` feature, so we # don't need to opt into them again here. We still depend on web-sys # directly for the `web_sys::js_sys` re-export and `web_sys::window()` # in `repo_view.rs`. -web-sys = "0.3.77" +web-sys = { version = "0.3.77", features = ["Storage", "MediaQueryList"] } [dev-dependencies] js-sys = "0.3" diff --git a/README.md b/README.md new file mode 100644 index 0000000..cc74ca3 --- /dev/null +++ b/README.md @@ -0,0 +1,130 @@ +# OpenDevicePartnership.github.io + +Website for the Open Device Partnership, built with Rust, Leptos, and Trunk. + +## Prerequisites + +Install these once on your machine: + +1. **Rust** (nightly toolchain) — [https://rustup.rs/](https://rustup.rs/) + + ```cmd + rustup toolchain install nightly + rustup default nightly + ``` + +2. **WebAssembly target** + + ```cmd + rustup target add wasm32-unknown-unknown + ``` + +3. **Trunk** — bundles the Rust → WASM app and serves it. + + ```cmd + cargo binstall trunk + :: or + cargo install trunk + ``` + +4. **Node.js 20+** — needed by the UnoCSS pipeline that Trunk invokes as a + pre-build hook (see `Trunk.toml [[hooks]]`). Install from + [https://nodejs.org/](https://nodejs.org/) or via your package manager. + +## First-time setup + +After cloning, install the JavaScript dependencies that UnoCSS needs: + +```cmd +npm ci +``` + +> **Important:** use `npm ci` (not `npm install`) so the lockfile is honored +> exactly. The `@iconify-json/lucide` package is required for every icon on +> the site (theme toggle, mobile menu, card arrows, etc.). If it is missing, +> UnoCSS silently emits no CSS for icon utilities and buttons appear empty +> with **no build error**. CI guards against this with an explicit +> "Critical icon classes present" check, but locally you must keep +> `node_modules/` in sync with `package-lock.json`. + +If you ever see invisible icons or hit `i-lucide-*` classes that don't +render, the fix is almost always: + +```cmd +npm ci +trunk build +``` + +## Development + +Run the dev server: + +```cmd +trunk serve +``` + +This will: + +- Run the UnoCSS pre-build hook (`npm run build:css`) to regenerate + `style/uno.generated.css` from `src/**/*.rs` and `index.html` +- Build the project in debug mode +- Start a development server at +- Watch for file changes and auto-reload the browser + +If you are editing CSS classes heavily and want a tighter loop, run the +UnoCSS watcher alongside `trunk serve` in a second terminal: + +```cmd +npm run watch:css +``` + +## Production build + +```cmd +trunk build --release +``` + +The optimized output is written to `dist/`. This is exactly what the +Cloudflare Pages deploy workflow runs. + +## Tests and lint + +```cmd +cargo test --all-targets +cargo fmt --all -- --check +cargo clippy --target wasm32-unknown-unknown --all-targets -- -D warnings +leptosfmt --check src +``` + +Browser-side tests (requires `wasm-pack` and Firefox): + +```cmd +wasm-pack test --headless --firefox --test wasm +``` + +## Project structure + +- `src/` — Rust source code + - `components/` — reusable UI components + - `pages/` — page components + - `data/` — content modules (projects, announcements, etc.) +- `style/` — CSS files + - `base.css` — design tokens and reset (single source of truth for colors, + type, spacing). Uses `color-scheme: light dark` + `light-dark()` so + each token is defined once and the active theme is chosen automatically. + - `repo_graph.css` — styles for the lazy-loaded D3 dependency graph. + - `uno.generated.css` — generated by UnoCSS; do not edit by hand. +- `public/` — static assets (images, fonts). +- `index.html` — main HTML template (loaded by Trunk). +- `Trunk.toml` — Trunk configuration; declares the `npm run build:css` + pre-build hook. +- `unocss.config.ts` — UnoCSS configuration; declares the icon presets, + design-token aliases, and scan globs. +- `package.json` / `package-lock.json` — UnoCSS + iconify dependencies. +- `Cargo.toml` — Rust dependencies. + +## Technology stack + +- **Leptos** — reactive web framework for Rust (CSR build) +- **Trunk** — WASM web application bundler +- **UnoCSS** — atomic CSS engine (Wind3 preset + iconify lucide icons) diff --git a/Readme.md b/Readme.md deleted file mode 100644 index 3b7823b..0000000 --- a/Readme.md +++ /dev/null @@ -1,63 +0,0 @@ -# OpenDevicePartnership.github.io - -Website for the Open Device Partnership, built with Rust, Leptos, and Trunk. - -## Prerequisites - -Before running this project, ensure you have the following installed: - -1. **Rust** - Install from [https://rustup.rs/](https://rustup.rs/) - -2. **Trunk** - Build tool for Rust web applications - - ```cmd - cargo binstall trunk or - cargo install trunk - ``` - -3. **WebAssembly target** - Required for compiling to WASM - - ```cmd - rustup target add wasm32-unknown-unknown - ``` - -## Development - -To run the development server: - -```cmd -trunk serve -``` - -This will: - -- Build the project in debug mode -- Start a development server at -- Watch for file changes and auto-reload the browser - -## Production Build - -To build for production: - -```cmd -trunk build --release -``` - -The optimized output will be generated in the `dist/` directory. - -## Project Structure - -- `src/` - Rust source code - - `components/` - Reusable UI components - - `pages/` - Page components -- `style/` - CSS files (Tailwind) -- `public/` - Static assets (images, etc.) -- `index.html` - Main HTML template -- `Trunk.toml` - Trunk configuration -- `Cargo.toml` - Rust dependencies - -## Technology Stack - -- **Leptos** - Reactive web framework for Rust -- **Trunk** - WASM web application bundler -- **Tailwind CSS** - Utility-first CSS framework diff --git a/Trunk.toml b/Trunk.toml index 0b9b60f..95f44be 100644 --- a/Trunk.toml +++ b/Trunk.toml @@ -31,8 +31,12 @@ minify = "always" [watch] # Paths to watch. The `build.target`'s parent folder is watched by default. watch = [] -# Paths to ignore. -ignore = [] +# Paths to ignore. The UnoCSS pre-build hook writes +# `style/uno.generated.css`; without this, Trunk would see that write +# and immediately re-trigger another build, looping forever. Same for +# `node_modules` (npm install churns it on its own schedule) and +# `dist` (Trunk's own output). +ignore = ["style/uno.generated.css", "node_modules", "dist"] [serve] # The address to serve on. @@ -60,3 +64,18 @@ open = false # tls_cert_path = "self_signed_certs/cert.pem" # Additional headers to send. NOTE: header names must be valid HTTP headers. # headers = { "X-Foo" = "bar" } + +# UnoCSS pre-build hook. +# +# We use the `unocss-classes` Rust crate (`uno!` macro) to author +# class strings inline in `view!` blocks, then ask `@unocss/cli` to +# scan src/**/*.rs and emit `style/uno.generated.css`. Trunk runs the +# hook before compiling Rust, so the generated CSS is in place by the +# time the asset graph is built. +# +# The CLI is provided by `package.json`. Run `npm install` once after +# pulling, then Trunk handles the rest. +[[hooks]] +stage = "pre_build" +command = "npm" +command_arguments = ["run", "--silent", "build:css"] diff --git a/index.html b/index.html index d4fd670..36abf73 100644 --- a/index.html +++ b/index.html @@ -4,7 +4,8 @@ - + + diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..aac889a --- /dev/null +++ b/package-lock.json @@ -0,0 +1,2225 @@ +{ + "name": "odp-website-styles", + "version": "0.1.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "odp-website-styles", + "version": "0.1.0", + "devDependencies": { + "@iconify-json/lucide": "^1.2.0", + "@unocss/cli": "^66.6.8", + "@unocss/preset-icons": "^66.6.8", + "@unocss/preset-wind3": "^66.6.8", + "@unocss/transformer-directives": "^66.6.8", + "@unocss/transformer-variant-group": "^66.6.8", + "unocss": "^66.6.8" + } + }, + "node_modules/@antfu/install-pkg": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@antfu/install-pkg/-/install-pkg-1.1.0.tgz", + "integrity": "sha512-MGQsmw10ZyI+EJo45CdSER4zEb+p31LpDAFp2Z3gkSd1yqVZGi0Ebx++YTEMonJy4oChEMLsxZ64j8FH6sSqtQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "package-manager-detector": "^1.3.0", + "tinyexec": "^1.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/@emnapi/core": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.10.0.tgz", + "integrity": "sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@emnapi/wasi-threads": "1.2.1", + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/runtime": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.10.0.tgz", + "integrity": "sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/wasi-threads": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.1.tgz", + "integrity": "sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@iconify-json/lucide": { + "version": "1.2.107", + "resolved": "https://registry.npmjs.org/@iconify-json/lucide/-/lucide-1.2.107.tgz", + "integrity": "sha512-Q4JmCICVwHqaGhB3ugDFdb4uGXuU/o8OJrJuo1YjeZhGeT3jX5fc//7qMNsCb10VuL2PVDM/CkaqO9chnmI3gg==", + "dev": true, + "license": "ISC", + "dependencies": { + "@iconify/types": "*" + } + }, + "node_modules/@iconify/types": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@iconify/types/-/types-2.0.0.tgz", + "integrity": "sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@iconify/utils": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/@iconify/utils/-/utils-3.1.3.tgz", + "integrity": "sha512-LPKOXPn/zV+zis1oOfGWogaXVpqUybF3ZS6SCZIsz8vg0ivVp9+fVqyYB7xq0aiST/VhUQYGO1qo6uoYSiEJqw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@antfu/install-pkg": "^1.1.0", + "@iconify/types": "^2.0.0", + "import-meta-resolve": "^4.2.0" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/remapping": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", + "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "dev": true, + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@napi-rs/wasm-runtime": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.4.tgz", + "integrity": "sha512-3NQNNgA1YSlJb/kMH1ildASP9HW7/7kYnRI2szWJaofaS1hWmbGI4H+d3+22aGzXXN9IJ+n+GiFVcGipJP18ow==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@tybys/wasm-util": "^0.10.1" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Brooooooklyn" + }, + "peerDependencies": { + "@emnapi/core": "^1.7.1", + "@emnapi/runtime": "^1.7.1" + } + }, + "node_modules/@oxc-parser/binding-android-arm-eabi": { + "version": "0.124.0", + "resolved": "https://registry.npmjs.org/@oxc-parser/binding-android-arm-eabi/-/binding-android-arm-eabi-0.124.0.tgz", + "integrity": "sha512-+R9zCafSL8ovjokdPtorUp3sXrh8zQ2AC2L0ivXNvlLR0WS+5WdPkNVrnENq5UvzagM4Xgl0NPsJKz3Hv9+y8g==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@oxc-parser/binding-android-arm64": { + "version": "0.124.0", + "resolved": "https://registry.npmjs.org/@oxc-parser/binding-android-arm64/-/binding-android-arm64-0.124.0.tgz", + "integrity": "sha512-ULHC/gVZ+nP4pd3kNNQTYaQ/e066BW/KuY5qUsvwkVWwOUQGDg+WpfyVOmQ4xfxoue6cMlkKkJ+ntdzfDXpNlg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@oxc-parser/binding-darwin-arm64": { + "version": "0.124.0", + "resolved": "https://registry.npmjs.org/@oxc-parser/binding-darwin-arm64/-/binding-darwin-arm64-0.124.0.tgz", + "integrity": "sha512-fGJ2hw7bnbUYn6UvTjp0m4WJ9zXz3cohgcwcgeo7gUZehpPNpvcVEVeIVHNmHnAuAw/ysf4YJR8DA1E+xCA4Lw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@oxc-parser/binding-darwin-x64": { + "version": "0.124.0", + "resolved": "https://registry.npmjs.org/@oxc-parser/binding-darwin-x64/-/binding-darwin-x64-0.124.0.tgz", + "integrity": "sha512-j0+re9pgps5BH2Tk3fm59Hi3QuLP3C4KhqXi6A+wRHHHJWDFR8mc/KI9mBrfk2JRT+15doGo+zv1eN75/9DuOw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@oxc-parser/binding-freebsd-x64": { + "version": "0.124.0", + "resolved": "https://registry.npmjs.org/@oxc-parser/binding-freebsd-x64/-/binding-freebsd-x64-0.124.0.tgz", + "integrity": "sha512-0k5mS0npnrhKy72UfF51lpOZ2ESoPWn6gdFw+RdeRWcokraDW1O2kSx3laQ+yk7cCEavQdJSpWCYS/GvBbUCXQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@oxc-parser/binding-linux-arm-gnueabihf": { + "version": "0.124.0", + "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-0.124.0.tgz", + "integrity": "sha512-P/i4eguRWvAUfGdfhQYg1jpwYkyUV6D3gefIH7HhmRl1Ph6P4IqTIEVcyJr1i/3vr1V5OHU4wonH6/ue/Qzvrw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@oxc-parser/binding-linux-arm-musleabihf": { + "version": "0.124.0", + "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-arm-musleabihf/-/binding-linux-arm-musleabihf-0.124.0.tgz", + "integrity": "sha512-/ameqFQH5fFP+66Atr8Ynv/2rYe4utcU7L4MoWS5JtrFLVO78g4qDLavyIlJxa6caSwYOvG/eO3c/DXqY5/6Rw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@oxc-parser/binding-linux-arm64-gnu": { + "version": "0.124.0", + "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-0.124.0.tgz", + "integrity": "sha512-gNeyEcXTtfrRCbj2EfxWU85Fs0wIX3p44Y3twnvuMfkWlLrb9M1Z25AYNSKjJM+fdAjeeQCjw0on47zFuBYwQw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@oxc-parser/binding-linux-arm64-musl": { + "version": "0.124.0", + "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-arm64-musl/-/binding-linux-arm64-musl-0.124.0.tgz", + "integrity": "sha512-uvG7v4Tz9S8/PVqY0SP0DLHxo4hZGe+Pv2tGVnwcsjKCCUPjplbrFVvDzXq+kOaEoUkiCY0Kt1hlZ6FDJ1LKNQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@oxc-parser/binding-linux-ppc64-gnu": { + "version": "0.124.0", + "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-0.124.0.tgz", + "integrity": "sha512-t7KZaaUhfp2au0MRpoENEFqwLKYDdptEry6V7pTAVdPEcFG4P6ii8yeGU9m6p5vb+b8WEKmdpGMNXBEYy7iJdw==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@oxc-parser/binding-linux-riscv64-gnu": { + "version": "0.124.0", + "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-riscv64-gnu/-/binding-linux-riscv64-gnu-0.124.0.tgz", + "integrity": "sha512-eurGGaxHZiIQ+fBSageS8TAkRqZgdOiBeqNrWAqAPup9hXBTmQ0WcBjwsLElf+3jvDL9NhnX0dOgOqPfsjSjdg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@oxc-parser/binding-linux-riscv64-musl": { + "version": "0.124.0", + "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-riscv64-musl/-/binding-linux-riscv64-musl-0.124.0.tgz", + "integrity": "sha512-d1V7/ll1i/LhqE/gZy6Wbz6evlk0egh2XKkwMI3epiojtbtUwQSLIER0Y3yDBBocPuWOjJdvmjtEmPTTLXje/w==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@oxc-parser/binding-linux-s390x-gnu": { + "version": "0.124.0", + "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-0.124.0.tgz", + "integrity": "sha512-w1+cBvriUteOpox6ATqCFVkpGL47PFdcfCPGmgUZbd78Fw44U0gQkc+kVGvAOTvGrptMYgwomD1c6OTVvkrpGg==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@oxc-parser/binding-linux-x64-gnu": { + "version": "0.124.0", + "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-x64-gnu/-/binding-linux-x64-gnu-0.124.0.tgz", + "integrity": "sha512-RRB1evQiXRtMCsQQiAh9U0H3HzguLpE0ytfStuhRgmOj7tqUCOVxkHsvM9geZjAax6NqVRj7VXx32qjjkZPsBw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@oxc-parser/binding-linux-x64-musl": { + "version": "0.124.0", + "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-x64-musl/-/binding-linux-x64-musl-0.124.0.tgz", + "integrity": "sha512-asVYN0qmSHlCU8H9Q47SmeJ/Z5EG4IWCC+QGxkfFboI5qh15aLlJnHmnrV61MwQRPXGnVC/sC3qKhrUyqGxUqw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@oxc-parser/binding-openharmony-arm64": { + "version": "0.124.0", + "resolved": "https://registry.npmjs.org/@oxc-parser/binding-openharmony-arm64/-/binding-openharmony-arm64-0.124.0.tgz", + "integrity": "sha512-nhwuxm6B8pn9lzAzMUfa571L5hCXYwQo8C8cx5aGOuHWCzruR8gPJnRRXGBci+uGaIIQEZDyU/U6HDgrSp/JlQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@oxc-parser/binding-wasm32-wasi": { + "version": "0.124.0", + "resolved": "https://registry.npmjs.org/@oxc-parser/binding-wasm32-wasi/-/binding-wasm32-wasi-0.124.0.tgz", + "integrity": "sha512-LWuq4Dl9tff7n+HjJcqoBjDlVCtruc0shgtdtGM+rTUIE9aFxHA/P+wCYR+aWMjN8m9vNaRME/sKXErmhmeKrA==", + "cpu": [ + "wasm32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@napi-rs/wasm-runtime": "^1.1.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@oxc-parser/binding-win32-arm64-msvc": { + "version": "0.124.0", + "resolved": "https://registry.npmjs.org/@oxc-parser/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-0.124.0.tgz", + "integrity": "sha512-aOh3Lf3AeH0dgzT4yBXcArFZ8VhqNXwZ/xlN0GqBtgVaGoHOOqL2YHlcVIgT+ghsXPVR2PTtYgBiQ1CNK7jp5A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@oxc-parser/binding-win32-ia32-msvc": { + "version": "0.124.0", + "resolved": "https://registry.npmjs.org/@oxc-parser/binding-win32-ia32-msvc/-/binding-win32-ia32-msvc-0.124.0.tgz", + "integrity": "sha512-sib5xC0nz/+SCpaETBuHBz4SXS02KuG5HtyOcHsO/SK5ZvLRGhOZx0elDKawjb6adFkD7dQCqpXUS25wY6ELKQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@oxc-parser/binding-win32-x64-msvc": { + "version": "0.124.0", + "resolved": "https://registry.npmjs.org/@oxc-parser/binding-win32-x64-msvc/-/binding-win32-x64-msvc-0.124.0.tgz", + "integrity": "sha512-UgojtjGUgZgAZQYt7SC6VO65OVdxEkRe2q+2vbHJO//18qw3Hrk6UvHGQKldsQKgbVcIBT/YBrt85YberiYIPQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@oxc-project/types": { + "version": "0.124.0", + "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.124.0.tgz", + "integrity": "sha512-VBFWMTBvHxS11Z5Lvlr3IWgrwhMTXV+Md+EQF0Xf60+wAdsGFTBx7X7K/hP4pi8N7dcm1RvcHwDxZ16Qx8keUg==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/Boshen" + } + }, + "node_modules/@polka/url": { + "version": "1.0.0-next.29", + "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.29.tgz", + "integrity": "sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==", + "dev": true, + "license": "MIT" + }, + "node_modules/@quansync/fs": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@quansync/fs/-/fs-1.0.0.tgz", + "integrity": "sha512-4TJ3DFtlf1L5LDMaM6CanJ/0lckGNtJcMjQ1NAV6zDmA0tEHKZtxNKin8EgPaVX1YzljbxckyT2tJrpQKAtngQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "quansync": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sxzz" + } + }, + "node_modules/@rolldown/binding-android-arm64": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.0.1.tgz", + "integrity": "sha512-fJI3I0r3C3Oj/zdBCpaCmBRZYf07xpaq4yCfDDoSFm+beWNzbIl26puW8RraUdugoJw/95zerNOn6jasAhzSmg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "peer": true, + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-darwin-arm64": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.0.1.tgz", + "integrity": "sha512-cKnAhWEsV7TPcA/5EAteDp6KcJZBQ2G+BqE7zayMMi7kMvwRsbv7WT9aOnn0WNl4SKEIf43vjS31iUPu80nzXg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "peer": true, + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-darwin-x64": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.0.1.tgz", + "integrity": "sha512-YKrVwQjIRBPo+5G/u03wGjbdy4q7pyzCe93DK9VJ7zkVmeg8LJ7GbgsiHWdR4xSoe4CAXRD7Bcjgbtr64bkXNg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "peer": true, + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-freebsd-x64": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.0.1.tgz", + "integrity": "sha512-z/oBsREo46SsFqBwYtFe0kpJeBijAT48O/WXLI4suiCLBkr03RTtTJMCzSdDd2znlh8VJizL09XVkQgk8IZonw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "peer": true, + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-arm-gnueabihf": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.0.1.tgz", + "integrity": "sha512-ik8q7GM11zxvYxFc2PeDcT6TBvhCQMaUxfph/M5l9sKuTs/Sjg3L+Byw0F7w0ZVLBZmx30P+gG0ECzzN+MFcmQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-arm64-gnu": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.0.1.tgz", + "integrity": "sha512-QoSx2EkyrrdZ6kcyE8stqZ62t0Yra8Fs5ia9lOxJrh6TMQJK7gQKmscdTHf7pOXKREKrVwOtJcQG3qVSfc866A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-arm64-musl": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.0.1.tgz", + "integrity": "sha512-uwNwFpwKeNiZawfAWBgg0VIztPTV3ihhh1vV334h9ivnNLorxnQMU6Fz8wG1Zb4Qh9LC1/MkcyT3YlDXG3Rsgg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-ppc64-gnu": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.0.1.tgz", + "integrity": "sha512-zY1bul7OWr7DFBiJ++wofXvnr8B45ce3QsQUhKrIhXsygAh7bTkwyeM1bi1a2g5C/yC/N8TZyGDEoMfm/l9mpg==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-s390x-gnu": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.0.1.tgz", + "integrity": "sha512-0frlsT/f4Ft6I7SMESTKnF3cZsdicQn1dCMkF/jT9wDLE+gGoiQfv1nmT9e+s7s/fekvvy6tZM2jHvI2tkbJDQ==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-x64-gnu": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.0.1.tgz", + "integrity": "sha512-XABVmGp9Tg0WspTVvwduTc4fpqy6JnAUrSQe6OuyqD/03nI7r0O9OWUkMIwFrjKAIqolvqoA4ZrJppgwE0Gxmw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-x64-musl": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.0.1.tgz", + "integrity": "sha512-bV4fzswuzVcKD90o/VM6QqKxnxlDq0g2BISDLNVmxrnhpv1DDbyPhCIjYfvzYLV+MvkKKnQt2Q6AO86SEBULUQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-openharmony-arm64": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.0.1.tgz", + "integrity": "sha512-/Mh0Zhq3OP7fVs0kcQHZP6lZEthMGTaSf8UBQYSFEZDWGXXlEC+nJ6EqenaK2t4LBXMe3A+K/G2BVXXdtOr4PQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "peer": true, + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-wasm32-wasi": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.0.1.tgz", + "integrity": "sha512-+1xc9X45l8ufsBAm6Gjvx2qDRIY9lTVt0cgWNcJ+1gdhXvkbxePA60yRTwSTuXL09CMhyJmjpV7E3NoyxbqFQQ==", + "cpu": [ + "wasm32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@emnapi/core": "1.10.0", + "@emnapi/runtime": "1.10.0", + "@napi-rs/wasm-runtime": "^1.1.4" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-win32-arm64-msvc": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.0.1.tgz", + "integrity": "sha512-1D+UqZdfnuR+Jy1GgMJwi85bD40H21uNmOPRWQhw4oRSuolZ/B5rixZ45DK2KXOTCvmVCecauWgEhbw8bI7tOw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "peer": true, + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-win32-x64-msvc": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.0.1.tgz", + "integrity": "sha512-INAycaWuhlOK3wk4mRHGsdgwYWmd9cChdPdE9bwWmy6rn9VqVNYNFGhOdXrofXUxwHIncSiPNb8tNm8knDVIeQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "peer": true, + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/pluginutils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.1.tgz", + "integrity": "sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/@tybys/wasm-util": { + "version": "0.10.2", + "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.2.tgz", + "integrity": "sha512-RoBvJ2X0wuKlWFIjrwffGw1IqZHKQqzIchKaadZZfnNpsAYp2mM0h36JtPCjNDAHGgYez/15uMBpfGwchhiMgg==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@types/estree": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.9.tgz", + "integrity": "sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@unocss/cli": { + "version": "66.6.8", + "resolved": "https://registry.npmjs.org/@unocss/cli/-/cli-66.6.8.tgz", + "integrity": "sha512-dJ4AmrhCtQwEDJtpFG7AgJ4Qi4GWnNgWWlLWq4DhKBOCcvldr9k98mscdhs3MOwph25DIxU5MdLRAg/OS1JryQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/remapping": "^2.3.5", + "@unocss/config": "66.6.8", + "@unocss/core": "66.6.8", + "@unocss/preset-wind3": "66.6.8", + "@unocss/preset-wind4": "66.6.8", + "@unocss/transformer-directives": "66.6.8", + "cac": "^7.0.0", + "chokidar": "^5.0.0", + "colorette": "^2.0.20", + "consola": "^3.4.2", + "magic-string": "^0.30.21", + "pathe": "^2.0.3", + "perfect-debounce": "^2.1.0", + "tinyglobby": "^0.2.16", + "unplugin-utils": "^0.3.1" + }, + "bin": { + "unocss": "bin/unocss.mjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/@unocss/config": { + "version": "66.6.8", + "resolved": "https://registry.npmjs.org/@unocss/config/-/config-66.6.8.tgz", + "integrity": "sha512-f+a8OyhD7ZoK8Pa1b3Cbx1RQc3n5x+Qht/cHg3wh/g4DNQIjBI2EqwSLfBigWhdO96zIqFAdyTlO3onmrJwUOw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@unocss/core": "66.6.8", + "colorette": "^2.0.20", + "consola": "^3.4.2", + "unconfig": "^7.5.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/@unocss/core": { + "version": "66.6.8", + "resolved": "https://registry.npmjs.org/@unocss/core/-/core-66.6.8.tgz", + "integrity": "sha512-P9IlQfgms+8/nka7fBhiiWU4SPwrTNKbTdK0z1SLnttXMHHjsB2zpG+Vi1JQDpICfY9Y1/2pWtguPE+zeOVu9Q==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/@unocss/extractor-arbitrary-variants": { + "version": "66.6.8", + "resolved": "https://registry.npmjs.org/@unocss/extractor-arbitrary-variants/-/extractor-arbitrary-variants-66.6.8.tgz", + "integrity": "sha512-cOXstpPTOLt/HYcL0OsqFkNau0e8ktZ5Q8fgnXBZjmLGmi+VzdESNlwxZyCXLuamZGnbrZ8lDsKdsGG7P1pMKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@unocss/core": "66.6.8" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/@unocss/inspector": { + "version": "66.6.8", + "resolved": "https://registry.npmjs.org/@unocss/inspector/-/inspector-66.6.8.tgz", + "integrity": "sha512-g8uRzXDdmoNRjXX/mZP7m0rWXLtOimyOW7+VFK6FNxRWBmvIGYgTLHkutF6Wyh9lLPDYx3pkkEmfgL35BDT3Sg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@unocss/core": "66.6.8", + "@unocss/rule-utils": "66.6.8", + "colorette": "^2.0.20", + "gzip-size": "^6.0.0", + "sirv": "^3.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/@unocss/preset-attributify": { + "version": "66.6.8", + "resolved": "https://registry.npmjs.org/@unocss/preset-attributify/-/preset-attributify-66.6.8.tgz", + "integrity": "sha512-YxyRSF5rq0WbY8kCG0gpj3DSXPL89QGxZeqABmceCzPJbXJBBHEJz/pgBPmzSa2Ziulgs0AEkHzWFPfpb2uGTA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@unocss/core": "66.6.8" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/@unocss/preset-icons": { + "version": "66.6.8", + "resolved": "https://registry.npmjs.org/@unocss/preset-icons/-/preset-icons-66.6.8.tgz", + "integrity": "sha512-+zD5TNGZIXvVOMcvDIYaTXinffpDMERGj6Ch8WTtJluA6qHHBvRuFexoU2bY8nF1r0HZkYzNT9C+RujFSP+6TA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@iconify/utils": "^3.1.0", + "@unocss/core": "66.6.8", + "ofetch": "^1.5.1" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/@unocss/preset-mini": { + "version": "66.6.8", + "resolved": "https://registry.npmjs.org/@unocss/preset-mini/-/preset-mini-66.6.8.tgz", + "integrity": "sha512-vAechrReO7LtWzFAeF54P7CintG2m65SlVlBsi1x2Ru7IdgUNJEHII0MfXUvf9r1x8vsIlhATyaqqtBVT6ps/w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@unocss/core": "66.6.8", + "@unocss/extractor-arbitrary-variants": "66.6.8", + "@unocss/rule-utils": "66.6.8" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/@unocss/preset-tagify": { + "version": "66.6.8", + "resolved": "https://registry.npmjs.org/@unocss/preset-tagify/-/preset-tagify-66.6.8.tgz", + "integrity": "sha512-cG6zBYswtWTpeQe/Lb1Bh+IzU4Ck+VI8rpYvrnvSGl22rJjAsXd+buB1P0PjyDpoe924rq0bLTayZ8r6Ayyyvw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@unocss/core": "66.6.8" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/@unocss/preset-typography": { + "version": "66.6.8", + "resolved": "https://registry.npmjs.org/@unocss/preset-typography/-/preset-typography-66.6.8.tgz", + "integrity": "sha512-wOApJpE0QfeOTWN5RuQts8zS6PXhTZIfjpt6cBj8dmv7+GlIQlwopxL7wcDb2wVwdCByuMvUbWl7nC3kz/iFTA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@unocss/core": "66.6.8", + "@unocss/rule-utils": "66.6.8" + } + }, + "node_modules/@unocss/preset-uno": { + "version": "66.6.8", + "resolved": "https://registry.npmjs.org/@unocss/preset-uno/-/preset-uno-66.6.8.tgz", + "integrity": "sha512-z01Rw/rBuahRulwQRnobUFnGqyU+UenOLz72KGn4p0Yh8gBC44fPlNHsOWA0TNediHRJg33HptX4kx16HCVWDg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@unocss/core": "66.6.8", + "@unocss/preset-wind3": "66.6.8" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/@unocss/preset-web-fonts": { + "version": "66.6.8", + "resolved": "https://registry.npmjs.org/@unocss/preset-web-fonts/-/preset-web-fonts-66.6.8.tgz", + "integrity": "sha512-AgEHO8h0AkeOT57AOE9PS7dJOa5Rfr0gIyz/FxA7vJ/FwgQL70uX+bRW8kmoH81zcjo5xBP2IX3Z6A8VAOo3Vw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@unocss/core": "66.6.8", + "ofetch": "^1.5.1" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/@unocss/preset-wind": { + "version": "66.6.8", + "resolved": "https://registry.npmjs.org/@unocss/preset-wind/-/preset-wind-66.6.8.tgz", + "integrity": "sha512-F0mdmwK/HelYOgBRMHl+Yx/VyARCQJtPlcgPBejI3E9ZWOZlKS7hvPqPrgvS63WTGMHgM3/22cGuYYFjpi/ugA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@unocss/core": "66.6.8", + "@unocss/preset-wind3": "66.6.8" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/@unocss/preset-wind3": { + "version": "66.6.8", + "resolved": "https://registry.npmjs.org/@unocss/preset-wind3/-/preset-wind3-66.6.8.tgz", + "integrity": "sha512-WNTeDAYCatmEFjBJ4itUmz0TElBvNFqjh5i2/ianDJO/vkd+IYUb03jEPLUppVlvMhy8bN8AunP0AtW3Xf2psA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@unocss/core": "66.6.8", + "@unocss/preset-mini": "66.6.8", + "@unocss/rule-utils": "66.6.8" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/@unocss/preset-wind4": { + "version": "66.6.8", + "resolved": "https://registry.npmjs.org/@unocss/preset-wind4/-/preset-wind4-66.6.8.tgz", + "integrity": "sha512-CheOm7KXOsTI5t4RXgeYz95CO5p589F6jsyYp+inOCk4N0/d+DWiDHrQ+V0x0HWs3JXWlD+/Va/yXjlc3o2sIw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@unocss/core": "66.6.8", + "@unocss/extractor-arbitrary-variants": "66.6.8", + "@unocss/rule-utils": "66.6.8" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/@unocss/rule-utils": { + "version": "66.6.8", + "resolved": "https://registry.npmjs.org/@unocss/rule-utils/-/rule-utils-66.6.8.tgz", + "integrity": "sha512-WR35L07mLP6PElD4hlUHo5KbQ48uz2HT/XCuJyAsHP+15Gv6539hPWA5SresPuva9r8rl+PeGIgMSIKf4A5Ihw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@unocss/core": "^66.6.8", + "magic-string": "^0.30.21" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/@unocss/transformer-attributify-jsx": { + "version": "66.6.8", + "resolved": "https://registry.npmjs.org/@unocss/transformer-attributify-jsx/-/transformer-attributify-jsx-66.6.8.tgz", + "integrity": "sha512-g+7lvm+8V1MnJ21ialTxFBonCTtenn/KcZQbm0JfvQjgG+KuuSnt3BGEcXAHQZu3eBDGuJuasTHiXWwzCYIRBQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@unocss/core": "66.6.8", + "oxc-parser": "^0.124.0", + "oxc-walker": "^0.7.0" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/@unocss/transformer-compile-class": { + "version": "66.6.8", + "resolved": "https://registry.npmjs.org/@unocss/transformer-compile-class/-/transformer-compile-class-66.6.8.tgz", + "integrity": "sha512-37dFuzgYo8ki033KmuvyZXugQRVH1c3+/z5kcWLPhcMR8UJscAtjgRx80S1UvWup2q6TPxPpmy/rMbqWvs3jfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@unocss/core": "66.6.8" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/@unocss/transformer-directives": { + "version": "66.6.8", + "resolved": "https://registry.npmjs.org/@unocss/transformer-directives/-/transformer-directives-66.6.8.tgz", + "integrity": "sha512-9hC3mQ8eycliW/igI9le0LovTIMBKoL6crucTkr4MmWuNqICMvNxTmGj5Xh64olBPnascevFwam6xsy+J1lX4Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@unocss/core": "66.6.8", + "@unocss/rule-utils": "66.6.8", + "css-tree": "^3.2.1" + } + }, + "node_modules/@unocss/transformer-variant-group": { + "version": "66.6.8", + "resolved": "https://registry.npmjs.org/@unocss/transformer-variant-group/-/transformer-variant-group-66.6.8.tgz", + "integrity": "sha512-+t7gJDW3W3z3/f8zBf0DfV2UZyGyFOwG5CIsIj5ofu3VJ91mKD/5ZAH8fD3cryXCBSqslj4yv+8R+BLV07T5AA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@unocss/core": "66.6.8" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/@unocss/vite": { + "version": "66.6.8", + "resolved": "https://registry.npmjs.org/@unocss/vite/-/vite-66.6.8.tgz", + "integrity": "sha512-bXfEnEHdW7zTGLIYU16MsfKSFy3Q47Pevhrt5f9fOGzC4UI1JGkkoQSfoFpXZGliDrhoSFK4Msz9Jt43Ta4j+w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/remapping": "^2.3.5", + "@unocss/config": "66.6.8", + "@unocss/core": "66.6.8", + "@unocss/inspector": "66.6.8", + "chokidar": "^5.0.0", + "magic-string": "^0.30.21", + "pathe": "^2.0.3", + "tinyglobby": "^0.2.16", + "unplugin-utils": "^0.3.1" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + }, + "peerDependencies": { + "vite": "^2.9.0 || ^3.0.0-0 || ^4.0.0 || ^5.0.0-0 || ^6.0.0-0 || ^7.0.0-0 || ^8.0.0-0" + } + }, + "node_modules/acorn": { + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz", + "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/cac": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/cac/-/cac-7.0.0.tgz", + "integrity": "sha512-tixWYgm5ZoOD+3g6UTea91eow5z6AAHaho3g0V9CNSNb45gM8SmflpAc+GRd1InC4AqN/07Unrgp56Y94N9hJQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=20.19.0" + } + }, + "node_modules/chokidar": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-5.0.0.tgz", + "integrity": "sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw==", + "dev": true, + "license": "MIT", + "dependencies": { + "readdirp": "^5.0.0" + }, + "engines": { + "node": ">= 20.19.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/colorette": { + "version": "2.0.20", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", + "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", + "dev": true, + "license": "MIT" + }, + "node_modules/confbox": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.1.8.tgz", + "integrity": "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==", + "dev": true, + "license": "MIT" + }, + "node_modules/consola": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/consola/-/consola-3.4.2.tgz", + "integrity": "sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^14.18.0 || >=16.10.0" + } + }, + "node_modules/css-tree": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-3.2.1.tgz", + "integrity": "sha512-X7sjQzceUhu1u7Y/ylrRZFU2FS6LRiFVp6rKLPg23y3x3c3DOKAwuXGDp+PAGjh6CSnCjYeAul8pcT8bAl+lSA==", + "dev": true, + "license": "MIT", + "dependencies": { + "mdn-data": "2.27.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0" + } + }, + "node_modules/defu": { + "version": "6.1.7", + "resolved": "https://registry.npmjs.org/defu/-/defu-6.1.7.tgz", + "integrity": "sha512-7z22QmUWiQ/2d0KkdYmANbRUVABpZ9SNYyH5vx6PZ+nE5bcC0l7uFvEfHlyld/HcGBFTL536ClDt3DEcSlEJAQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/destr": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/destr/-/destr-2.0.5.tgz", + "integrity": "sha512-ugFTXCtDZunbzasqBxrK93Ik/DRYsO6S/fedkWEMKqt04xZ4csmnmwGDBAb07QWNaGMAmnTIemsYZCksjATwsA==", + "dev": true, + "license": "MIT" + }, + "node_modules/detect-libc": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", + "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", + "dev": true, + "license": "Apache-2.0", + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/duplexer": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", + "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==", + "dev": true, + "license": "MIT" + }, + "node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0" + } + }, + "node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "peer": true, + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/gzip-size": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-6.0.0.tgz", + "integrity": "sha512-ax7ZYomf6jqPTQ4+XCpUGyXKHk5WweS+e05MBO4/y3WJ5RkmPXNKvX+bx1behVILVwr6JSQvZAku021CHPXG3Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "duplexer": "^0.1.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/import-meta-resolve": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/import-meta-resolve/-/import-meta-resolve-4.2.0.tgz", + "integrity": "sha512-Iqv2fzaTQN28s/FwZAoFq0ZSs/7hMAHJVX+w8PZl3cY19Pxk6jFFalxQoIfW2826i/fDLXv8IiEZRIT0lDuWcg==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/jiti": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.7.0.tgz", + "integrity": "sha512-AC/7JofJvZGrrneWNaEnJeOLUx+JlGt7tNa0wZiRPT4MY1wmfKjt2+6O2p2uz2+skll8OZZmJMNqeke7kKbNgQ==", + "dev": true, + "license": "MIT", + "bin": { + "jiti": "lib/jiti-cli.mjs" + } + }, + "node_modules/lightningcss": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.32.0.tgz", + "integrity": "sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==", + "dev": true, + "license": "MPL-2.0", + "peer": true, + "dependencies": { + "detect-libc": "^2.0.3" + }, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "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" + } + }, + "node_modules/lightningcss-android-arm64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.32.0.tgz", + "integrity": "sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "android" + ], + "peer": true, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-arm64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.32.0.tgz", + "integrity": "sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "peer": true, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-x64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.32.0.tgz", + "integrity": "sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "peer": true, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-freebsd-x64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.32.0.tgz", + "integrity": "sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "freebsd" + ], + "peer": true, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm-gnueabihf": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.32.0.tgz", + "integrity": "sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-gnu": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.32.0.tgz", + "integrity": "sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-musl": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.32.0.tgz", + "integrity": "sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-gnu": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.32.0.tgz", + "integrity": "sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-musl": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.32.0.tgz", + "integrity": "sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-arm64-msvc": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.32.0.tgz", + "integrity": "sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "peer": true, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-x64-msvc": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.32.0.tgz", + "integrity": "sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "peer": true, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/magic-regexp": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/magic-regexp/-/magic-regexp-0.10.0.tgz", + "integrity": "sha512-Uly1Bu4lO1hwHUW0CQeSWuRtzCMNO00CmXtS8N6fyvB3B979GOEEeAkiTUDsmbYLAbvpUS/Kt5c4ibosAzVyVg==", + "dev": true, + "license": "MIT", + "dependencies": { + "estree-walker": "^3.0.3", + "magic-string": "^0.30.12", + "mlly": "^1.7.2", + "regexp-tree": "^0.1.27", + "type-level-regexp": "~0.1.17", + "ufo": "^1.5.4", + "unplugin": "^2.0.0" + } + }, + "node_modules/magic-string": { + "version": "0.30.21", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", + "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.5" + } + }, + "node_modules/mdn-data": { + "version": "2.27.1", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.27.1.tgz", + "integrity": "sha512-9Yubnt3e8A0OKwxYSXyhLymGW4sCufcLG6VdiDdUGVkPhpqLxlvP5vl1983gQjJl3tqbrM731mjaZaP68AgosQ==", + "dev": true, + "license": "CC0-1.0" + }, + "node_modules/mlly": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.8.2.tgz", + "integrity": "sha512-d+ObxMQFmbt10sretNDytwt85VrbkhhUA/JBGm1MPaWJ65Cl4wOgLaB1NYvJSZ0Ef03MMEU/0xpPMXUIQ29UfA==", + "dev": true, + "license": "MIT", + "dependencies": { + "acorn": "^8.16.0", + "pathe": "^2.0.3", + "pkg-types": "^1.3.1", + "ufo": "^1.6.3" + } + }, + "node_modules/mrmime": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.1.tgz", + "integrity": "sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/nanoid": { + "version": "3.3.12", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.12.tgz", + "integrity": "sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "peer": true, + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/node-fetch-native": { + "version": "1.6.7", + "resolved": "https://registry.npmjs.org/node-fetch-native/-/node-fetch-native-1.6.7.tgz", + "integrity": "sha512-g9yhqoedzIUm0nTnTqAQvueMPVOuIY16bqgAJJC8XOOubYFNwz6IER9qs0Gq2Xd0+CecCKFjtdDTMA4u4xG06Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/ofetch": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/ofetch/-/ofetch-1.5.1.tgz", + "integrity": "sha512-2W4oUZlVaqAPAil6FUg/difl6YhqhUR7x2eZY4bQCko22UXg3hptq9KLQdqFClV+Wu85UX7hNtdGTngi/1BxcA==", + "dev": true, + "license": "MIT", + "dependencies": { + "destr": "^2.0.5", + "node-fetch-native": "^1.6.7", + "ufo": "^1.6.1" + } + }, + "node_modules/oxc-parser": { + "version": "0.124.0", + "resolved": "https://registry.npmjs.org/oxc-parser/-/oxc-parser-0.124.0.tgz", + "integrity": "sha512-h07SFj/tp2U3cf3+LFX6MmOguQiM9ahwpGs0ZK5CGhgL8p4kk24etrJKsEzhXAvo7mfvoKTZooZ5MLKAPRmJ1g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@oxc-project/types": "^0.124.0" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "funding": { + "url": "https://github.com/sponsors/Boshen" + }, + "optionalDependencies": { + "@oxc-parser/binding-android-arm-eabi": "0.124.0", + "@oxc-parser/binding-android-arm64": "0.124.0", + "@oxc-parser/binding-darwin-arm64": "0.124.0", + "@oxc-parser/binding-darwin-x64": "0.124.0", + "@oxc-parser/binding-freebsd-x64": "0.124.0", + "@oxc-parser/binding-linux-arm-gnueabihf": "0.124.0", + "@oxc-parser/binding-linux-arm-musleabihf": "0.124.0", + "@oxc-parser/binding-linux-arm64-gnu": "0.124.0", + "@oxc-parser/binding-linux-arm64-musl": "0.124.0", + "@oxc-parser/binding-linux-ppc64-gnu": "0.124.0", + "@oxc-parser/binding-linux-riscv64-gnu": "0.124.0", + "@oxc-parser/binding-linux-riscv64-musl": "0.124.0", + "@oxc-parser/binding-linux-s390x-gnu": "0.124.0", + "@oxc-parser/binding-linux-x64-gnu": "0.124.0", + "@oxc-parser/binding-linux-x64-musl": "0.124.0", + "@oxc-parser/binding-openharmony-arm64": "0.124.0", + "@oxc-parser/binding-wasm32-wasi": "0.124.0", + "@oxc-parser/binding-win32-arm64-msvc": "0.124.0", + "@oxc-parser/binding-win32-ia32-msvc": "0.124.0", + "@oxc-parser/binding-win32-x64-msvc": "0.124.0" + } + }, + "node_modules/oxc-walker": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/oxc-walker/-/oxc-walker-0.7.0.tgz", + "integrity": "sha512-54B4KUhrzbzc4sKvKwVYm7E2PgeROpGba0/2nlNZMqfDyca+yOor5IMb4WLGBatGDT0nkzYdYuzylg7n3YfB7A==", + "dev": true, + "license": "MIT", + "dependencies": { + "magic-regexp": "^0.10.0" + }, + "peerDependencies": { + "oxc-parser": ">=0.98.0" + } + }, + "node_modules/package-manager-detector": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/package-manager-detector/-/package-manager-detector-1.6.0.tgz", + "integrity": "sha512-61A5ThoTiDG/C8s8UMZwSorAGwMJ0ERVGj2OjoW5pAalsNOg15+iQiPzrLJ4jhZ1HJzmC2PIHT2oEiH3R5fzNA==", + "dev": true, + "license": "MIT" + }, + "node_modules/pathe": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", + "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", + "dev": true, + "license": "MIT" + }, + "node_modules/perfect-debounce": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/perfect-debounce/-/perfect-debounce-2.1.0.tgz", + "integrity": "sha512-LjgdTytVFXeUgtHZr9WYViYSM/g8MkcTPYDlPa3cDqMirHjKiSZPYd6DoL7pK8AJQr+uWkQvCjHNdiMqsrJs+g==", + "dev": true, + "license": "MIT" + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC", + "peer": true + }, + "node_modules/picomatch": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", + "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pkg-types": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.3.1.tgz", + "integrity": "sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "confbox": "^0.1.8", + "mlly": "^1.7.4", + "pathe": "^2.0.1" + } + }, + "node_modules/postcss": { + "version": "8.5.14", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.14.tgz", + "integrity": "sha512-SoSL4+OSEtR99LHFZQiJLkT59C5B1amGO1NzTwj7TT1qCUgUO6hxOvzkOYxD+vMrXBM3XJIKzokoERdqQq/Zmg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "peer": true, + "dependencies": { + "nanoid": "^3.3.11", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/quansync": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/quansync/-/quansync-1.0.0.tgz", + "integrity": "sha512-5xZacEEufv3HSTPQuchrvV6soaiACMFnq1H8wkVioctoH3TRha9Sz66lOxRwPK/qZj7HPiSveih9yAyh98gvqA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/antfu" + }, + { + "type": "individual", + "url": "https://github.com/sponsors/sxzz" + } + ], + "license": "MIT" + }, + "node_modules/readdirp": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-5.0.0.tgz", + "integrity": "sha512-9u/XQ1pvrQtYyMpZe7DXKv2p5CNvyVwzUB6uhLAnQwHMSgKMBR62lc7AHljaeteeHXn11XTAaLLUVZYVZyuRBQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 20.19.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/regexp-tree": { + "version": "0.1.27", + "resolved": "https://registry.npmjs.org/regexp-tree/-/regexp-tree-0.1.27.tgz", + "integrity": "sha512-iETxpjK6YoRWJG5o6hXLwvjYAoW+FEZn9os0PD/b6AP6xQwsa/Y7lCVgIixBbUPMfhu+i2LtdeAqVTgGlQarfA==", + "dev": true, + "license": "MIT", + "bin": { + "regexp-tree": "bin/regexp-tree" + } + }, + "node_modules/rolldown": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.0.1.tgz", + "integrity": "sha512-X0KQHljNnEkWNqqiz9zJrGunh1B0HgOxLXvnFpCOcadzcy5qohZ3tqMEUg00vncoRovXuK3ZqCT9KnnKzoInFQ==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@oxc-project/types": "=0.130.0", + "@rolldown/pluginutils": "^1.0.0" + }, + "bin": { + "rolldown": "bin/cli.mjs" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "optionalDependencies": { + "@rolldown/binding-android-arm64": "1.0.1", + "@rolldown/binding-darwin-arm64": "1.0.1", + "@rolldown/binding-darwin-x64": "1.0.1", + "@rolldown/binding-freebsd-x64": "1.0.1", + "@rolldown/binding-linux-arm-gnueabihf": "1.0.1", + "@rolldown/binding-linux-arm64-gnu": "1.0.1", + "@rolldown/binding-linux-arm64-musl": "1.0.1", + "@rolldown/binding-linux-ppc64-gnu": "1.0.1", + "@rolldown/binding-linux-s390x-gnu": "1.0.1", + "@rolldown/binding-linux-x64-gnu": "1.0.1", + "@rolldown/binding-linux-x64-musl": "1.0.1", + "@rolldown/binding-openharmony-arm64": "1.0.1", + "@rolldown/binding-wasm32-wasi": "1.0.1", + "@rolldown/binding-win32-arm64-msvc": "1.0.1", + "@rolldown/binding-win32-x64-msvc": "1.0.1" + } + }, + "node_modules/rolldown/node_modules/@oxc-project/types": { + "version": "0.130.0", + "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.130.0.tgz", + "integrity": "sha512-ibD2usx9JRu7f5pu2tMKMI4cpA4NgXJQoYRP4pQ7Pxmn1l6k/53qWtQWZayhYy3X4QZkt90Ot+mJEaeXouio6Q==", + "dev": true, + "license": "MIT", + "peer": true, + "funding": { + "url": "https://github.com/sponsors/Boshen" + } + }, + "node_modules/sirv": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/sirv/-/sirv-3.0.2.tgz", + "integrity": "sha512-2wcC/oGxHis/BoHkkPwldgiPSYcpZK3JU28WoMVv55yHJgcZ8rlXvuG9iZggz+sU1d4bRgIGASwyWqjxu3FM0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@polka/url": "^1.0.0-next.24", + "mrmime": "^2.0.0", + "totalist": "^3.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/tinyexec": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.1.2.tgz", + "integrity": "sha512-dAqSqE/RabpBKI8+h26GfLq6Vb3JVXs30XYQjdMjaj/c2tS8IYYMbIzP599KtRj7c57/wYApb3QjgRgXmrCukA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/tinyglobby": { + "version": "0.2.16", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.16.tgz", + "integrity": "sha512-pn99VhoACYR8nFHhxqix+uvsbXineAasWm5ojXoN8xEwK5Kd3/TrhNn1wByuD52UxWRLy8pu+kRMniEi6Eq9Zg==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.4" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/totalist": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.1.tgz", + "integrity": "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "dev": true, + "license": "0BSD", + "optional": true + }, + "node_modules/type-level-regexp": { + "version": "0.1.17", + "resolved": "https://registry.npmjs.org/type-level-regexp/-/type-level-regexp-0.1.17.tgz", + "integrity": "sha512-wTk4DH3cxwk196uGLK/E9pE45aLfeKJacKmcEgEOA/q5dnPGNxXt0cfYdFxb57L+sEpf1oJH4Dnx/pnRcku9jg==", + "dev": true, + "license": "MIT" + }, + "node_modules/ufo": { + "version": "1.6.4", + "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.6.4.tgz", + "integrity": "sha512-JFNbkD1Svwe0KvGi8GOeLcP4kAWQ609twvCdcHxq1oSL8svv39ZuSvajcD8B+5D0eL4+s1Is2D/O6KN3qcTeRA==", + "dev": true, + "license": "MIT" + }, + "node_modules/unconfig": { + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/unconfig/-/unconfig-7.5.0.tgz", + "integrity": "sha512-oi8Qy2JV4D3UQ0PsopR28CzdQ3S/5A1zwsUwp/rosSbfhJ5z7b90bIyTwi/F7hCLD4SGcZVjDzd4XoUQcEanvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@quansync/fs": "^1.0.0", + "defu": "^6.1.4", + "jiti": "^2.6.1", + "quansync": "^1.0.0", + "unconfig-core": "7.5.0" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/unconfig-core": { + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/unconfig-core/-/unconfig-core-7.5.0.tgz", + "integrity": "sha512-Su3FauozOGP44ZmKdHy2oE6LPjk51M/TRRjHv2HNCWiDvfvCoxC2lno6jevMA91MYAdCdwP05QnWdWpSbncX/w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@quansync/fs": "^1.0.0", + "quansync": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/unocss": { + "version": "66.6.8", + "resolved": "https://registry.npmjs.org/unocss/-/unocss-66.6.8.tgz", + "integrity": "sha512-stq9FbxedTDkoWrxnNQNnPQXOaM6L2Lobq8HzjXdR2tMc55gtfqDArqL7TESfnN7qeZsIocNYCHLNA4DXq50YQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@unocss/cli": "66.6.8", + "@unocss/core": "66.6.8", + "@unocss/preset-attributify": "66.6.8", + "@unocss/preset-icons": "66.6.8", + "@unocss/preset-mini": "66.6.8", + "@unocss/preset-tagify": "66.6.8", + "@unocss/preset-typography": "66.6.8", + "@unocss/preset-uno": "66.6.8", + "@unocss/preset-web-fonts": "66.6.8", + "@unocss/preset-wind": "66.6.8", + "@unocss/preset-wind3": "66.6.8", + "@unocss/preset-wind4": "66.6.8", + "@unocss/transformer-attributify-jsx": "66.6.8", + "@unocss/transformer-compile-class": "66.6.8", + "@unocss/transformer-directives": "66.6.8", + "@unocss/transformer-variant-group": "66.6.8", + "@unocss/vite": "66.6.8" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + }, + "peerDependencies": { + "@unocss/astro": "66.6.8", + "@unocss/postcss": "66.6.8", + "@unocss/webpack": "66.6.8" + }, + "peerDependenciesMeta": { + "@unocss/astro": { + "optional": true + }, + "@unocss/postcss": { + "optional": true + }, + "@unocss/webpack": { + "optional": true + } + } + }, + "node_modules/unplugin": { + "version": "2.3.11", + "resolved": "https://registry.npmjs.org/unplugin/-/unplugin-2.3.11.tgz", + "integrity": "sha512-5uKD0nqiYVzlmCRs01Fhs2BdkEgBS3SAVP6ndrBsuK42iC2+JHyxM05Rm9G8+5mkmRtzMZGY8Ct5+mliZxU/Ww==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/remapping": "^2.3.5", + "acorn": "^8.15.0", + "picomatch": "^4.0.3", + "webpack-virtual-modules": "^0.6.2" + }, + "engines": { + "node": ">=18.12.0" + } + }, + "node_modules/unplugin-utils": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/unplugin-utils/-/unplugin-utils-0.3.1.tgz", + "integrity": "sha512-5lWVjgi6vuHhJ526bI4nlCOmkCIF3nnfXkCMDeMJrtdvxTs6ZFCM8oNufGTsDbKv/tJ/xj8RpvXjRuPBZJuJog==", + "dev": true, + "license": "MIT", + "dependencies": { + "pathe": "^2.0.3", + "picomatch": "^4.0.3" + }, + "engines": { + "node": ">=20.19.0" + }, + "funding": { + "url": "https://github.com/sponsors/sxzz" + } + }, + "node_modules/vite": { + "version": "8.0.13", + "resolved": "https://registry.npmjs.org/vite/-/vite-8.0.13.tgz", + "integrity": "sha512-MFtjBYgzmSxmgA4RAfjIyXWpGe1oALnjgUTzzV7QLx/TKxCzjtMH6Fd9/eVK+5Fg1qNoz5VAwsmMs/NofrmJvw==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "lightningcss": "^1.32.0", + "picomatch": "^4.0.4", + "postcss": "^8.5.14", + "rolldown": "1.0.1", + "tinyglobby": "^0.2.16" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^20.19.0 || >=22.12.0", + "@vitejs/devtools": "^0.1.18", + "esbuild": "^0.27.0 || ^0.28.0", + "jiti": ">=1.21.0", + "less": "^4.0.0", + "sass": "^1.70.0", + "sass-embedded": "^1.70.0", + "stylus": ">=0.54.8", + "sugarss": "^5.0.0", + "terser": "^5.16.0", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "@vitejs/devtools": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "jiti": { + "optional": true + }, + "less": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } + } + }, + "node_modules/webpack-virtual-modules": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/webpack-virtual-modules/-/webpack-virtual-modules-0.6.2.tgz", + "integrity": "sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==", + "dev": true, + "license": "MIT" + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..31d8149 --- /dev/null +++ b/package.json @@ -0,0 +1,19 @@ +{ + "name": "odp-website-styles", + "version": "0.1.0", + "private": true, + "description": "UnoCSS build pipeline for the ODP website. Trunk's pre-build hook (see Trunk.toml [[hooks]]) runs `npm run build:css` to scan src/**/*.rs for uno![...] macro invocations and emit style/uno.generated.css.", + "scripts": { + "build:css": "unocss --config unocss.config.ts --out-file style/uno.generated.css \"src/**/*.rs\" \"index.html\"", + "watch:css": "unocss --config unocss.config.ts --out-file style/uno.generated.css --watch \"src/**/*.rs\" \"index.html\"" + }, + "devDependencies": { + "@iconify-json/lucide": "^1.2.0", + "@unocss/cli": "^66.6.8", + "@unocss/preset-icons": "^66.6.8", + "@unocss/preset-wind3": "^66.6.8", + "@unocss/transformer-directives": "^66.6.8", + "@unocss/transformer-variant-group": "^66.6.8", + "unocss": "^66.6.8" + } +} diff --git a/public/images/dark/backbutton.svg b/public/images/dark/backbutton.svg deleted file mode 100644 index 00c08a1..0000000 --- a/public/images/dark/backbutton.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/public/images/dark/checkcircle.svg b/public/images/dark/checkcircle.svg deleted file mode 100644 index a1633c3..0000000 --- a/public/images/dark/checkcircle.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/public/images/dark/computer.svg b/public/images/dark/computer.svg deleted file mode 100644 index 55e9c90..0000000 --- a/public/images/dark/computer.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/public/images/dark/discord.svg b/public/images/dark/discord.svg deleted file mode 100644 index ff1af49..0000000 --- a/public/images/dark/discord.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/public/images/dark/documentation.svg b/public/images/dark/documentation.svg deleted file mode 100644 index d593225..0000000 --- a/public/images/dark/documentation.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/public/images/dark/fastforward.svg b/public/images/dark/fastforward.svg deleted file mode 100644 index 4ca6f0e..0000000 --- a/public/images/dark/fastforward.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/public/images/dark/github.svg b/public/images/dark/github.svg deleted file mode 100644 index 54bb248..0000000 --- a/public/images/dark/github.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/public/images/dark/lock.svg b/public/images/dark/lock.svg deleted file mode 100644 index 83010ab..0000000 --- a/public/images/dark/lock.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/public/images/dark/teams.svg b/public/images/dark/teams.svg deleted file mode 100644 index 53868da..0000000 --- a/public/images/dark/teams.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/public/images/dark/video.svg b/public/images/dark/video.svg deleted file mode 100644 index cdc49ea..0000000 --- a/public/images/dark/video.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/public/images/dark/zulip.svg b/public/images/dark/zulip.svg deleted file mode 100644 index 3d7923e..0000000 --- a/public/images/dark/zulip.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/public/images/ec.webp b/public/images/ec.webp deleted file mode 100644 index 3fa0ef5..0000000 Binary files a/public/images/ec.webp and /dev/null differ diff --git a/public/images/ec_services.webp b/public/images/ec_services.webp deleted file mode 100644 index 520099c..0000000 Binary files a/public/images/ec_services.webp and /dev/null differ diff --git a/public/images/flag.svg b/public/images/flag.svg deleted file mode 100644 index 2822da1..0000000 --- a/public/images/flag.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/public/images/laptop.png b/public/images/laptop.png deleted file mode 100644 index adeae29..0000000 Binary files a/public/images/laptop.png and /dev/null differ diff --git a/public/images/light/backbutton.svg b/public/images/light/backbutton.svg deleted file mode 100644 index d603d4c..0000000 --- a/public/images/light/backbutton.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/public/images/light/checkcircle.svg b/public/images/light/checkcircle.svg deleted file mode 100644 index 10dccfb..0000000 --- a/public/images/light/checkcircle.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/public/images/light/computer.svg b/public/images/light/computer.svg deleted file mode 100644 index ff3f03a..0000000 --- a/public/images/light/computer.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/public/images/light/discord.svg b/public/images/light/discord.svg deleted file mode 100644 index 1e6f0a2..0000000 --- a/public/images/light/discord.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/public/images/light/documentation.svg b/public/images/light/documentation.svg deleted file mode 100644 index 16a4d82..0000000 --- a/public/images/light/documentation.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/public/images/light/fastforward.svg b/public/images/light/fastforward.svg deleted file mode 100644 index 08b5c41..0000000 --- a/public/images/light/fastforward.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/public/images/light/github.svg b/public/images/light/github.svg deleted file mode 100644 index 66d0a93..0000000 --- a/public/images/light/github.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - diff --git a/public/images/light/lock.svg b/public/images/light/lock.svg deleted file mode 100644 index a238741..0000000 --- a/public/images/light/lock.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/public/images/light/teams.svg b/public/images/light/teams.svg deleted file mode 100644 index de80dd7..0000000 --- a/public/images/light/teams.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/public/images/light/video.svg b/public/images/light/video.svg deleted file mode 100644 index e63b7c4..0000000 --- a/public/images/light/video.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/public/images/light/zulip.svg b/public/images/light/zulip.svg deleted file mode 100644 index 674ada7..0000000 --- a/public/images/light/zulip.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/public/images/patina.webp b/public/images/patina.webp deleted file mode 100644 index c7d7ef5..0000000 Binary files a/public/images/patina.webp and /dev/null differ diff --git a/src/components/announce_banner.rs b/src/components/announce_banner.rs deleted file mode 100644 index 9ae7cd3..0000000 --- a/src/components/announce_banner.rs +++ /dev/null @@ -1,25 +0,0 @@ -use leptos::prelude::*; - -#[component] -pub fn AnnounceBanner() -> impl IntoView { - view! { -
- Flag Icon - - {"UPDATE: "} - {"Open Device Partnership Expands Open-Source Efforts; "} - - {"Patina Project to Launch at UEFI 2025 Developer Conference & Plugfest - read more!"} - - -
- } -} diff --git a/src/components/cards.rs b/src/components/cards.rs new file mode 100644 index 0000000..e2a7b6f --- /dev/null +++ b/src/components/cards.rs @@ -0,0 +1,309 @@ +//! Content cards used across pages. + +use crate::components::controls::{Tag, TagTone}; +use crate::components::layout::{Cluster, Stack, StackGap, Surface, SurfaceElevation, SurfaceTone}; +use crate::components::media::Icon; +use crate::components::typography::{Body, BodyTone, Eyebrow, Heading, HeadingLevel}; +use crate::data::partners::PARTNERS; +use crate::data::projects::ProjectCopy; +use crate::data::teams::TeamMember; +use leptos::prelude::*; +use leptos_router::components::A; +use unocss_classes::uno; + +/// A project card used on `/` and `/projects`. +/// +/// The square media slot keeps every project icon visually +/// consistent regardless of the source image's intrinsic ratio. +#[component] +pub fn ProjectCard(project: &'static ProjectCopy, tone: TagTone) -> impl IntoView { + let monogram_class = match tone { + TagTone::Patina => "bg-[var(--color-project-patina)] text-[var(--color-project-patina-ink)]", + TagTone::Ec => "bg-[var(--color-project-ec)] text-[var(--color-project-ec-ink)]", + TagTone::Services => "bg-[var(--color-project-services)] text-[var(--color-project-services-ink)]", + _ => "bg-surface-sunken text-ink-primary", + }; + view! { + + +
+ +
+
+ {project.short_label} + {project.title} + {project.summary} +
+ + "Explore project" + + +
+
+ } +} + +/// A condensed value-proposition card (icon + title + body). +#[component] +pub fn ValueCard(#[prop(into)] icon: String, #[prop(into)] title: String, #[prop(into)] body: String) -> impl IntoView { + view! { + + + + + {title} + {body} + + } +} + +/// A small team-member card with avatar, name, role, and GitHub +/// handle. +#[component] +pub fn TeamCard(member: TeamMember) -> impl IntoView { + let full_name = format!("{} {}", member.first_name, member.last_name); + view! { + + full_name.clone() +
+

{full_name}

+

{member.role}

+
+ + + {member.github_username} + +
+ } +} + +/// Small grouping card for a documentation/training link. +#[component] +pub fn DocCard( + #[prop(into)] href: String, + #[prop(into)] title: String, + #[prop(into)] description: String, + #[prop(optional, default = false)] external: bool, +) -> impl IntoView { + let inner = view! { + +
+ + {title} + + +
+ + {description} + +
+ }; + if external { + view! { + + {inner} + + } + .into_any() + } else { + view! { + + {inner} + + } + .into_any() + } +} + +/// Slim trust strip rendered in the footer. +#[component] +pub fn TrustStrip() -> impl IntoView { + view! { +
+

"Built with our partners"

+ + {PARTNERS + .iter() + .map(|p| { + view! { + + p.name + + } + }) + .collect_view()} + +
+ } +} + +/// Announcement detail card. Used on `/announcements/`. +#[component] +pub fn AnnouncementDetail( + announcement: &'static crate::data::announcements::Announcement, + children: Children, +) -> impl IntoView { + let date_long = announcement.published_at.long(); + let date_iso = announcement.published_at.iso(); + let kind_label = announcement.kind.label(); + let location = announcement.location; + view! { +
+ + {kind_label} + {announcement.title} +

+ + {location + .map(|loc| { + view! { + " · " + {loc} + } + })} +

+
p]:mb-5 [&_a]:underline [&_a]:underline-offset-4 [&_a]:text-ink-accent", + "[&_strong]:font-semibold [&_ul]:list-disc [&_ul]:pl-6 [&_ul]:mb-5 [&_li]:mb-2" + ]>{children()}
+
+
+ } +} + +/// A blog-list card for the announcements index. +/// +/// Renders the eyebrow (kind + date + optional location), the title, +/// an excerpt, and a "Read more →" affordance. The entire card is a +/// single anchor to the permalink so the click target is generous. +#[component] +pub fn AnnouncementCard(announcement: &'static crate::data::announcements::Announcement) -> impl IntoView { + let href = format!("/announcements/{}", announcement.slug); + let date_long = announcement.published_at.long(); + let date_iso = announcement.published_at.iso(); + let kind_label = announcement.kind.label(); + let location = announcement.location; + view! { + + +
+ {kind_label} + "·" + + {location + .map(|loc| { + view! { + "·" + {loc} + } + })} +
+ + {announcement.title} + + {announcement.excerpt} + + "Read more" + + +
+
+ } +} diff --git a/src/components/community_teams.rs b/src/components/community_teams.rs deleted file mode 100644 index abd3491..0000000 --- a/src/components/community_teams.rs +++ /dev/null @@ -1,107 +0,0 @@ -use crate::components::section::Section; -use crate::components::team_grid::TeamGrid; -use crate::components::themed_icon::ThemedIcon; -use crate::components::ui::{Heading, HeadingLevel, Text, TextSize}; -use crate::data::teams::steering_committee; -use leptos::prelude::*; - -#[component] -pub fn CommunityTeams() -> impl IntoView { - let steering_committee = steering_committee(); - - view! { -
-
-
- - {"How ODP is built by its community"} - -
-
- - - {"The Open Device Partnership (ODP) is a collaborative open-source initiative designed to promote cooperative innovation in firmware development through contribution and transparency."} -
-
- {"To support this vision, ODP has adopted a lightweight yet formal governance model that clarifies how decisions are made, how contributions are recognized, and how the community remains focused on shared goals."} -
-
- {"Like most open-source communities, the ODP governance model consists of a group of core maintainers that are responsible for guiding the technical direction of the project known as the \"Technical Steering Committee\" (TSC). Members are typically industry-experienced contributors nominated by the community members or its sponsors."} -
- {"The model also provides for certain \"Working Groups\", which are task-focused teams that handle the development or specification within a particular area of concern (for example, Patina, EC Services)."} -
- {"Decisions are made via public discussion followed by majority vote among TSC members."} -
- {"All official actions, road maps, and meeting notes are transparently published, and all project materials are hosted openly on GitHub."} -
-
- {"For more information, see the complete governance policies at the "} - - {"ODP Governance Repository"} - - {", or join the discussion on our public chat on "} - - {"Zulip"} - - {"."} -
-
-
-
- - - {"Steering Committee"} - -
- -
- - {"Teams"} - -
-
- - - -
-
- } -} - -#[component] -fn TeamCard(title: &'static str, description: &'static str, href: &'static str) -> impl IntoView { - view! { -
- - {title} - - - {description} - -
- - {"Members + Contacts"} - -
- } -} diff --git a/src/components/controls.rs b/src/components/controls.rs new file mode 100644 index 0000000..35f7112 --- /dev/null +++ b/src/components/controls.rs @@ -0,0 +1,202 @@ +//! Interactive controls: `Button`, `LinkButton`, `Tag`, `Badge`, +//! and `ArrowLink`. + +use leptos::ev; +use leptos::prelude::*; +use leptos_router::components::A; +use unocss_classes::uno; + +#[derive(Clone, Copy, Default, PartialEq, Eq)] +pub enum ButtonVariant { + #[default] + Primary, +} + +#[derive(Clone, Copy, Default, PartialEq, Eq)] +pub enum ButtonSize { + #[default] + Md, +} + +fn button_classes(variant: ButtonVariant, size: ButtonSize) -> String { + let variant_class = match variant { + ButtonVariant::Primary => { + uno!( + "bg-accent text-accent-ink border border-accent", + "hover:(bg-accent-strong border-accent-strong)", + "shadow-elev-1" + ) + } + }; + let size_class = match size { + ButtonSize::Md => uno!("px-5 py-3 text-body"), + }; + format!( + "{} {} {} {}", + uno!("inline-flex items-center justify-center gap-2 rounded-md font-medium"), + uno!("transition-colors duration-200 cursor-pointer"), + variant_class, + size_class + ) +} + +/// Imperative ` + } +} + +/// `` styled like a `Button`. Used for CTAs that navigate. +#[component] +pub fn LinkButton( + #[prop(into)] href: String, + #[prop(optional)] variant: ButtonVariant, + #[prop(optional)] size: ButtonSize, + #[prop(optional, default = false)] external: bool, + #[prop(into, optional)] class: String, + children: Children, +) -> impl IntoView { + let final_class = format!("{} {class}", button_classes(variant, size)); + if external { + view! { + + {children()} + + } + .into_any() + } else { + view! { + + {children()} + + } + .into_any() + } +} + +#[derive(Clone, Copy, Default, PartialEq, Eq)] +pub enum TagTone { + #[default] + Neutral, + Accent, + Trust, + Patina, + Ec, + Services, +} + +/// Pill-shaped label. Used as project tags and section eyebrows. +#[component] +pub fn Tag( + #[prop(optional)] tone: TagTone, + #[prop(into, optional)] class: String, + children: Children, +) -> impl IntoView { + let tone_class = match tone { + TagTone::Neutral => uno!("bg-surface-sunken text-ink-secondary"), + TagTone::Accent => uno!("bg-accent-soft text-ink-accent"), + TagTone::Trust => uno!("bg-trust-soft text-trust"), + TagTone::Patina => "bg-[var(--color-project-patina)]/15 text-[var(--color-project-patina-ink)]".to_string(), + TagTone::Ec => "bg-[var(--color-project-ec)]/15 text-[var(--color-project-ec-ink)]".to_string(), + TagTone::Services => { + "bg-[var(--color-project-services)]/15 text-[var(--color-project-services-ink)]".to_string() + } + }; + let final_class = format!( + "{} {tone_class} {class}", + uno!("inline-flex items-center px-3 py-1 rounded-pill text-caption font-mono uppercase tracking-wider") + ); + view! { {children()} } +} + +/// Inline link with an arrow affordance and underline-on-hover. +#[component] +pub fn ArrowLink( + #[prop(into)] href: String, + #[prop(optional, default = false)] external: bool, + #[prop(into, optional)] class: String, + children: Children, +) -> impl IntoView { + let final_class = format!( + "{} {class}", + uno!( + "group inline-flex items-baseline gap-2 text-ink-primary", + "border-b border-transparent hover:border-current", + "transition-colors duration-200" + ) + ); + let inner = view! { + {children()} + + }; + if external { + view! { + + {inner} + + } + .into_any() + } else { + view! { + + {inner} + + } + .into_any() + } +} + +/// Plain inline link (underline on hover). +#[component] +pub fn InlineLink( + #[prop(into)] href: String, + #[prop(optional, default = false)] external: bool, + #[prop(into, optional)] class: String, + children: Children, +) -> impl IntoView { + let final_class = format!( + "{} {class}", + uno!("text-ink-accent underline decoration-from-font underline-offset-4 hover:decoration-2") + ); + if external { + view! { + + {children()} + + } + .into_any() + } else { + view! { + + {children()} + + } + .into_any() + } +} diff --git a/src/components/documentation_training.rs b/src/components/documentation_training.rs deleted file mode 100644 index 5a02001..0000000 --- a/src/components/documentation_training.rs +++ /dev/null @@ -1,69 +0,0 @@ -use crate::components::ui::{DocLinkItem, Heading, HeadingLevel, IconBlock, IconBlockSize, Text, TextSize}; -use leptos::prelude::*; - -#[derive(Clone)] -pub struct DocLink { - pub href: &'static str, - pub title: &'static str, - pub external: bool, -} - -/// Canonical "Documentation" link list shown at the bottom of every -/// content page. Pages typically render `` -/// with no `links` prop so they pick up this default; pass an explicit -/// `links=...` only when a page needs a different set. -pub const DEFAULT_DOC_LINKS: &[DocLink] = &[ - DocLink { - href: "https://opendevicepartnership.github.io/documentation/guide/why/why.html", - title: "Why ODP?", - external: true, - }, - DocLink { - href: "https://opendevicepartnership.github.io/documentation/guide/intro/getting_started.html", - title: "Getting Started with ODP", - external: true, - }, - DocLink { - href: "https://opendevicepartnership.github.io/documentation/guide/intro/welcome.html", - title: "Tutorials", - external: true, - }, - DocLink { - href: "https://opendevicepartnership.github.io/documentation/guide/specs/specifications.html", - title: "Specifications", - external: true, - }, - DocLink { - href: "/community", - title: "Contributing to ODP", - external: false, - }, -]; - -#[component] -pub fn DocumentationTraining(#[prop(default = DEFAULT_DOC_LINKS.to_vec())] links: Vec) -> impl IntoView { - view! { -
- - - "Documentation" - -
- - "Start developing with ODP" - -
- -
    - {links - .into_iter() - .map(|link| { - view! { - - } - }) - .collect_view()} -
-
- } -} diff --git a/src/components/footer.rs b/src/components/footer.rs deleted file mode 100644 index 87e75c6..0000000 --- a/src/components/footer.rs +++ /dev/null @@ -1,58 +0,0 @@ -use crate::components::themed_icon::ThemedIcon; -use leptos::prelude::*; - -#[component] -pub fn Footer() -> impl IntoView { - view! { -
-
-
- -

- {"© 2025 Open Device Partnership"} -

-
- - -
-
- } -} diff --git a/src/components/header.rs b/src/components/header.rs deleted file mode 100644 index c427a50..0000000 --- a/src/components/header.rs +++ /dev/null @@ -1,144 +0,0 @@ -use crate::components::themed_icon::ThemedIcon; -use leptos::ev; -use leptos::prelude::RwSignal; -use leptos::prelude::*; -use leptos_router::components::A; - -#[component] -pub fn Header(#[prop(optional, default = "header_background")] background_class: &'static str) -> impl IntoView { - let menu_open = RwSignal::new(false); - let close_menu = move || menu_open.set(false); - - // ESC closes the mobile menu when it is open. - window_event_listener(ev::keydown, move |e| { - if e.key() == "Escape" && menu_open.get_untracked() { - menu_open.set(false); - } - }); - - view! { -
-
- - - -
- - - - - - // Backdrop: catches clicks outside the open mobile menu and dismisses it. - - - -
- } -} - -#[component] -fn NavButton( - href: &'static str, - label: &'static str, - #[prop(optional)] mobile: bool, - #[prop(optional, into)] on_navigate: Option>, -) -> impl IntoView { - let location = leptos_router::hooks::use_location(); - let is_active = move || location.pathname.get().starts_with(href); - - view! { - - {label} - - } -} - -#[component] -fn ExternalNavButton( - href: &'static str, - label: &'static str, - #[prop(optional)] mobile: bool, - #[prop(optional, into)] on_navigate: Option>, -) -> impl IntoView { - view! { - - {label} - - } -} diff --git a/src/components/image_button.rs b/src/components/image_button.rs deleted file mode 100644 index 9bb4a27..0000000 --- a/src/components/image_button.rs +++ /dev/null @@ -1,23 +0,0 @@ -use leptos::prelude::*; - -/// Rounded image rendered as a link. -/// -/// Sizing is purely declarative via Tailwind utilities passed in `class`. -/// The default `aspect-square max-w-[350px]` matches the landing-page -/// tiles; call sites override the cap when the surrounding layout calls -/// for a larger image. There is no per-instance `