diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..6c599c8 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,24 @@ +version: 2 +updates: + - package-ecosystem: npm + directory: "/" + schedule: + interval: weekly + open-pull-requests-limit: 5 + groups: + npm-minor-patch: + patterns: + - "*" + update-types: + - minor + - patch + + - package-ecosystem: github-actions + directory: "/" + schedule: + interval: weekly + open-pull-requests-limit: 5 + groups: + github-actions: + patterns: + - "*" diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index c9e31f3..2b82a9e 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -11,8 +11,6 @@ on: permissions: contents: read - pages: write - id-token: write concurrency: group: pages @@ -21,9 +19,14 @@ concurrency: jobs: build: runs-on: ubuntu-latest + # configure-pages reads the Pages site through the API, which needs + # `pages: read`. Deployment/OIDC permissions live only on the deploy job. + permissions: + contents: read + pages: read steps: - - uses: actions/checkout@v4 - - uses: actions/setup-node@v4 + - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0 + - uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 with: node-version: 20 cache: npm @@ -32,17 +35,20 @@ jobs: env: NEXT_PUBLIC_BASE_PATH: /web - run: touch out/.nojekyll - - uses: actions/configure-pages@v5 - - uses: actions/upload-pages-artifact@v3 + - uses: actions/configure-pages@983d7736d9b0ae728b81ab479565c72886d7745b # v5.0.0 + - uses: actions/upload-pages-artifact@56afc609e74202658d3ffba0e8f6dda462b719fa # v3.0.1 with: path: out deploy: needs: build runs-on: ubuntu-latest + permissions: + pages: write + id-token: write environment: name: github-pages url: ${{ steps.deployment.outputs.page_url }} steps: - id: deployment - uses: actions/deploy-pages@v4 + uses: actions/deploy-pages@d6db90164ac5ed86f2b6aed7e0febac5b3c0c03e # v4.0.5 diff --git a/.github/workflows/security-audit.yml b/.github/workflows/security-audit.yml new file mode 100644 index 0000000..78beead --- /dev/null +++ b/.github/workflows/security-audit.yml @@ -0,0 +1,33 @@ +name: Security Audit + +on: + push: + pull_request: + schedule: + # Weekly, Mondays at 06:23 UTC (off the top of the hour to reduce runner contention). + - cron: '23 6 * * 1' + +permissions: + contents: read + +jobs: + audit: + name: npm audit + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0 + with: + persist-credentials: false + + - name: Set up Node.js + uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 + with: + node-version: 20 + cache: npm + + - name: Install dependencies + run: npm ci --ignore-scripts + + - name: Audit dependencies + run: npm audit --audit-level=high diff --git a/CHANGELOG.md b/CHANGELOG.md index fb5d59b..10a7450 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,13 @@ # Changelog +## 2026-10-24 — Security update + +- Updated Next.js from 16.3.1 to 16.4.3 and aligned `eslint-config-next` to 16.4.3, closing the critical Next.js advisories (including the unauthenticated RCE and cache-poisoning/SSRF reports). +- Updated the sharp override to 0.35.5 (libheif/librsvg fixes) and resolved the remaining transitive advisories: source-map-js 1.2.2, zod 4.6.7, js-yaml 4.3.2 and brace-expansion 1.1.21/5.0.12. +- `npm audit` now reports 0 vulnerabilities, including with `--omit=dev`. The static export still builds successfully (142 pages) and no site content or layout changed. +- Added `security-audit.yml` running `npm ci --ignore-scripts` and `npm audit --audit-level=high` on push, pull request and weekly schedules. +- Added weekly Dependabot updates for npm and GitHub Actions, pinned all workflow actions by commit SHA, disabled persisted checkout credentials, and moved Pages write/OIDC permissions to the deploy job only. + ## 2026-09-12 — WebAssembly docs and home demo fix - Added wiki pages for the WebAssembly runtime, the four wasm plugins and the three wasm extensions in English, Spanish and German; plugin index, presets and summary updated diff --git a/docs/de/SUMMARY.md b/docs/de/SUMMARY.md index eeb627f..ebd5cca 100644 --- a/docs/de/SUMMARY.md +++ b/docs/de/SUMMARY.md @@ -2,7 +2,7 @@ Ein plattformunabhangiges Systeminformations-Tool geschrieben in Rust. -- **Version:** 1.0.0 +- **Version:** 1.0.1 - **Lizenz:** MIT - **Autor:** xscriptor - **Repository:** github.com/xfetch-cli/xfetch diff --git a/docs/de/changelog.md b/docs/de/changelog.md index 55002f4..41c5809 100644 --- a/docs/de/changelog.md +++ b/docs/de/changelog.md @@ -1,6 +1,16 @@ # Anderungsprotokoll # Anderungsprotokoll +## v1.0.1 · Sicherheitsrelease: gepatchte Abhängigkeiten, signierte Releases und sicherere Installer · 2026-10-24 + +- **Alle RustSec-Hinweise im Abhängigkeitsgraph von v1.0.0 sind geschlossen:** `wasmtime` und `wasmtime-wasi` 48.0.7, `rustls` 0.23.46, `rustls-webpki` 0.103.16, `webpki-roots` 1.0.11, `tokio` 1.54.1 und `yoke-derive` 0.8.4. `cargo audit --deny warnings` meldet 0 Schwachstellen und 0 Warnungen. +- **Die Binaries von v1.0.0 sind weiterhin betroffen; auf v1.0.1 aktualisieren.** +- **Wasm-Artefakte pinnen:** Manifeste akzeptieren ein optionales `sha256`, und Plugins, Effekte und Erweiterungen akzeptieren `--sha256`. Der Digest wird bei heruntergeladenen, eingecheckten, gebauten und lokalen Artefakten geprüft; eine Abweichung bricht ab, bevor etwas geschrieben wird. Remote-Installationen ohne Digest funktionieren weiter, warnen aber deutlich. +- **Härtung von Remote-Installationen:** validierte Guest-Namen, private temporäre Verzeichnisse, `git clone --depth 1 -- ` und explizite Warnungen, wenn Manifest-`build`-Befehle oder native Gäste ohne Sandbox laufen. +- **Prebuilt-Installer:** portables SHA-256 über `sha256sum`, `shasum` oder `openssl`; `SHA256SUMS` ist Pflicht; ab v1.0.1 wird zusätzlich ein signiertes `SHA256SUMS.bundle` verlangt. `--require-signature` macht cosign Pflicht, `--allow-unsigned` ist ein explizites Opt-out, und Version sowie Asset stammen aus dem Tag und dem exakten erwarteten Dateinamen. +- **Signierte Releases:** Keyless-cosign-Signatur für `SHA256SUMS`, GitHub-Build-Provenance-Attestations und ein Gate, das prüft, dass der Tag auf `main` liegt, zu `Cargo.toml` passt, Tests und `cargo audit` ausführt und Signatur sowie Checksums vor dem Veröffentlichen erneut verifiziert. +- **Supply Chain:** CI mit `cargo audit`/`npm audit`, Dependabot, per SHA gepinnte GitHub Actions und Release-Builds mit Rust 1.98.1 und `--locked`. + ## v1.0.0 · Native Windows-Probes, Daemons unter Windows und Abhängigkeits-Refresh · 2026-09-18 - **Native Windows-Probes:** CPU, Datum, Akku und GPU werden über die Win32-API (`platform/windows/`) gelesen statt über sysinfos PDH-Zähler und PowerShell/`wmic`-Subprozesse — der Standard-Fetch ging auf einem 16-Thread-Rechner von ~575 ms auf ~33 ms (warm), mit identischen Werten diff --git a/docs/en/SUMMARY.md b/docs/en/SUMMARY.md index a274446..3dcb42a 100644 --- a/docs/en/SUMMARY.md +++ b/docs/en/SUMMARY.md @@ -2,7 +2,7 @@ A cross-platform system information fetching tool written in Rust. -- **Version:** 1.0.0 +- **Version:** 1.0.1 - **License:** MIT - **Author:** xscriptor - **Repository:** github.com/xfetch-cli/xfetch diff --git a/docs/en/changelog.md b/docs/en/changelog.md index c6ce93a..f214f71 100644 --- a/docs/en/changelog.md +++ b/docs/en/changelog.md @@ -1,6 +1,16 @@ # Changelog # Changelog +## v1.0.1 · Security release: patched dependencies, signed releases & safer installers · 2026-10-24 + +- **Every RustSec advisory in the v1.0.0 dependency graph is closed:** `wasmtime` and `wasmtime-wasi` 48.0.7, `rustls` 0.23.46, `rustls-webpki` 0.103.16, `webpki-roots` 1.0.11, `tokio` 1.54.1 and `yoke-derive` 0.8.4. `cargo audit --deny warnings` reports 0 vulnerabilities and 0 warnings. +- **v1.0.0 binaries remain affected by these advisories; upgrade to v1.0.1.** +- **Wasm artifact pinning:** manifests accept an optional `sha256` and plugins, effects and extensions accept `--sha256`. The digest is enforced on downloaded, checked-in, built and direct-file artifacts; a mismatch aborts before anything is written. Remote installs without a digest still work but print a prominent warning. +- **Remote install hardening:** validated guest names, private temporary directories, `git clone --depth 1 -- `, and explicit warnings when manifest build commands or native guests run unsandboxed. +- **Prebuilt installer:** portable SHA-256 via `sha256sum`, `shasum` or `openssl`; `SHA256SUMS` is mandatory; v1.0.1+ also requires a signed `SHA256SUMS.bundle`. `--require-signature` makes cosign mandatory, `--allow-unsigned` is an explicit opt-out, and the version/assets come from the release tag and exact expected filename. +- **Signed releases:** keyless cosign signature for `SHA256SUMS`, GitHub build provenance attestations, and a release gate that checks the tag is on `main`, matches `Cargo.toml`, runs the tests and `cargo audit`, and re-verifies the signature and checksums before publishing. +- **Supply chain:** added `cargo audit`/`npm audit` CI, Dependabot, SHA-pinned GitHub Actions, and Rust 1.98.1 with `--locked` release builds. + ## v1.0.0 · Windows Native Probes, Daemons on Windows & Dependency Refresh · 2026-09-18 - **Windows native probes:** CPU, datetime, battery and GPU are read through the Win32 API (`platform/windows/`) instead of sysinfo's PDH counters and PowerShell/`wmic` subprocesses — the default fetch went from ~575 ms to ~33 ms warm on a 16-thread machine, with identical rendered values diff --git a/docs/es/SUMMARY.md b/docs/es/SUMMARY.md index 3a19399..a04bf2b 100644 --- a/docs/es/SUMMARY.md +++ b/docs/es/SUMMARY.md @@ -2,7 +2,7 @@ Una herramienta de obtención de información del sistema multiplataforma escrita en Rust. -- **Versión:** 1.0.0 +- **Versión:** 1.0.1 - **Licencia:** MIT - **Autor:** xscriptor - **Repositorio:** github.com/xfetch-cli/xfetch diff --git a/docs/es/changelog.md b/docs/es/changelog.md index 1b49b81..315a2ae 100644 --- a/docs/es/changelog.md +++ b/docs/es/changelog.md @@ -1,6 +1,16 @@ # Registro de Cambios # Registro de Cambios +## v1.0.1 · Release de seguridad: dependencias parchadas, releases firmadas e instaladores más seguros · 2026-10-24 + +- **Cerrados todos los avisos de RustSec del grafo de v1.0.0:** `wasmtime` y `wasmtime-wasi` 48.0.7, `rustls` 0.23.46, `rustls-webpki` 0.103.16, `webpki-roots` 1.0.11, `tokio` 1.54.1 y `yoke-derive` 0.8.4. `cargo audit --deny warnings` reporta 0 vulnerabilidades y 0 warnings. +- **Los binarios de v1.0.0 siguen afectados por estos avisos; actualiza a v1.0.1.** +- **Fijado de artefactos wasm:** los manifiestos aceptan un `sha256` opcional y los comandos de plugins, efectos y extensiones aceptan `--sha256`. El digest se verifica en artefactos descargados, versionados, generados por build y archivos locales; una discrepancia aborta antes de escribir nada. Las instalaciones remotas sin digest siguen funcionando, pero muestran un aviso claro. +- **Endurecimiento de instalaciones remotas:** nombres de invitado validados, directorios temporales privados, `git clone --depth 1 -- ` y avisos explícitos cuando un comando `build` del manifiesto o un plugin nativo se ejecuta sin sandbox. +- **Instalador prebuilt:** SHA-256 portable con `sha256sum`, `shasum` u `openssl`; `SHA256SUMS` es obligatorio; desde v1.0.1 también se exige `SHA256SUMS.bundle` firmado. `--require-signature` hace obligatorio cosign, `--allow-unsigned` es una excepción explícita, y la versión y el asset se derivan del tag y del nombre exacto esperado. +- **Releases firmadas:** firma keyless de cosign para `SHA256SUMS`, attestations de procedencia de GitHub y un gate que comprueba que el tag está en `main`, coincide con `Cargo.toml`, ejecuta tests y `cargo audit`, y re-verifica firma y checksums antes de publicar. +- **Cadena de suministro:** CI con `cargo audit`/`npm audit`, Dependabot, GitHub Actions pineadas por SHA y builds de release con Rust 1.98.1 y `--locked`. + ## v1.0.0 · Sondas nativas en Windows, daemons en Windows y actualización de dependencias · 2026-09-18 - **Sondas nativas en Windows:** CPU, fecha, batería y GPU se leen por la API Win32 (`platform/windows/`) en vez de los contadores PDH de sysinfo y los subprocesos de PowerShell/`wmic` — el fetch por defecto pasó de ~575 ms a ~33 ms en caliente en una máquina de 16 hilos, con valores idénticos diff --git a/package-lock.json b/package-lock.json index 7341dad..756a1ee 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,7 +11,7 @@ "dependencies": { "@xscriptor/xcomponents": "^0.2.3", "framer-motion": "^12.42.2", - "next": "^16.2.11", + "next": "^16.4.3", "react": "19.2.4", "react-dom": "19.2.4", "react-markdown": "^10.1.0", @@ -23,7 +23,7 @@ "@types/react": "^19", "@types/react-dom": "^19", "eslint": "^9", - "eslint-config-next": "16.2.10", + "eslint-config-next": "16.4.3", "tailwindcss": "^4", "typescript": "^5" } @@ -535,9 +535,9 @@ } }, "node_modules/@img/sharp-darwin-arm64": { - "version": "0.35.3", - "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.35.3.tgz", - "integrity": "sha512-RMnFX7YQsMoh7lWfcM4NEHHymBX/rLuKNPVM84XE9ONPcaSCDgE7CHIHpSgPcO2xcRthgBy1HfNO319mwhIAkg==", + "version": "0.35.5", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.35.5.tgz", + "integrity": "sha512-QRUlFQ0WxvdWyqqG/WtI3iupfD5rBzmCHXSdPsY91sAtVtTo7Q4cb6zOccZ3gqEqkr0f1As1ehLqmEpDsRf+lg==", "cpu": [ "arm64" ], @@ -553,13 +553,13 @@ "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-libvips-darwin-arm64": "1.3.2" + "@img/sharp-libvips-darwin-arm64": "1.3.4" } }, "node_modules/@img/sharp-darwin-x64": { - "version": "0.35.3", - "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.35.3.tgz", - "integrity": "sha512-Xo+5uFBtLN0BKqieTxiFzFPQAUlBbbH5iBKyRX/z1JrbnYsHTfKJnUfL8+p2TPXr1pXqao4eeL4Rl144uDpK9w==", + "version": "0.35.5", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.35.5.tgz", + "integrity": "sha512-+BR255RhDlpygUpOc/Jdt1nT6DQ3XG/ERo5wbcdOf5Q320dKtPCKPLR1LJs9VGXRaMa8l1uUa0tkCNOXiAxZUw==", "cpu": [ "x64" ], @@ -575,20 +575,20 @@ "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-libvips-darwin-x64": "1.3.2" + "@img/sharp-libvips-darwin-x64": "1.3.4" } }, "node_modules/@img/sharp-freebsd-wasm32": { - "version": "0.35.3", - "resolved": "https://registry.npmjs.org/@img/sharp-freebsd-wasm32/-/sharp-freebsd-wasm32-0.35.3.tgz", - "integrity": "sha512-lUxcqWIj2wMQ9BrwNjngcr1gWUr5xgaGThBRqPPalIC2n67Cqj1uPh8NnA/ZhAg8hUbKl+kVHKwgUIwe6ZYPrg==", + "version": "0.35.5", + "resolved": "https://registry.npmjs.org/@img/sharp-freebsd-wasm32/-/sharp-freebsd-wasm32-0.35.5.tgz", + "integrity": "sha512-Y/z91nEZ4uIBX5X3nfTovjU9lHNKFYbL2lpHCLVNmXQK03VIZvXBBt0KxbPGp2SdGSF+2mQU4e+hQaWOt86iAw==", "license": "Apache-2.0", "optional": true, "os": [ "freebsd" ], "dependencies": { - "@img/sharp-wasm32": "0.35.3" + "@img/sharp-wasm32": "0.35.5" }, "engines": { "node": ">=20.9.0" @@ -598,9 +598,9 @@ } }, "node_modules/@img/sharp-libvips-darwin-arm64": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.3.2.tgz", - "integrity": "sha512-9J6ypZFpQBj4YnePGoq/S38w6nz+vqg5WZLrLGY4YuSemdMq47GMLBPO42MzwdGwpg/agZ7xzZcFHa48xlywfg==", + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.3.4.tgz", + "integrity": "sha512-5R89nBYiRdUlSWJxPhO+GVtaXzXSxKnRu/xqMn3KTA3L9EB9Oy/P+Nn2f2vlhPuUdy/Zusb2DarbyTpGCfEDuw==", "cpu": [ "arm64" ], @@ -614,9 +614,9 @@ } }, "node_modules/@img/sharp-libvips-darwin-x64": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.3.2.tgz", - "integrity": "sha512-m2pW1n6cns9VaubNwsZ+c3CRYjxNQWgJ5gPlnL1nbBcpkBvFm6SCFN5o0psFHI8w9n11NKhFkeEDns98tiqbEw==", + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.3.4.tgz", + "integrity": "sha512-iR2OKH80yi0U+dUplyh3/xdpFvps6YkCwsXenIJxqxR1v9o+xtKTGbS9H7cps+2Vxjc8B1j96p75NmTGjIhtpQ==", "cpu": [ "x64" ], @@ -630,12 +630,15 @@ } }, "node_modules/@img/sharp-libvips-linux-arm": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.3.2.tgz", - "integrity": "sha512-1eMLzy92I4J6rmi4mAT8yC3HxOtniyGELlzGbNMLLeqe052ahFQ0h6LFq+lh5DsDIdYViIDst08abvSbcEdLXQ==", + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.3.4.tgz", + "integrity": "sha512-LmRtTsOHuvM2+wlO2Db37dx5MiZhB0FvSunciw48YjdOkZz9KAiRbm8ujeMOA1INqmei5NapFxYEK1D1ZSidmw==", "cpu": [ "arm" ], + "libc": [ + "glibc" + ], "license": "LGPL-3.0-or-later", "optional": true, "os": [ @@ -646,12 +649,15 @@ } }, "node_modules/@img/sharp-libvips-linux-arm64": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.3.2.tgz", - "integrity": "sha512-dqVSFynCox4C/J8kT16V7SIFAns0IjgLwkvYT7p8LQVmJ5OS5b6tI9IGflxTeuBS//zXeFIUbwt5dwxyZ17cnA==", + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.3.4.tgz", + "integrity": "sha512-Y3dgX/6lE2QhQb+Gxy0WZxfg9MEm/JBjamZpS2IklP7xIQoKN4hzAm7KcMVGtaVDt3neE9OKBC7vAfonA/Lr1A==", "cpu": [ "arm64" ], + "libc": [ + "glibc" + ], "license": "LGPL-3.0-or-later", "optional": true, "os": [ @@ -662,12 +668,15 @@ } }, "node_modules/@img/sharp-libvips-linux-ppc64": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-ppc64/-/sharp-libvips-linux-ppc64-1.3.2.tgz", - "integrity": "sha512-3z0NHDxD6n5I9gc05U1eW1AyRm+Gznzq3naMrthPNqE6oYykcogW0l/jfpJdjYnuNl8R7yI9pNbE1XiUeyq0Aw==", + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-ppc64/-/sharp-libvips-linux-ppc64-1.3.4.tgz", + "integrity": "sha512-Le6boB8Tai0Nis+gIxIpKx68UDVVIqdR8Tin5Yf1z2LJJQLDJvCDRqRu+jC2qCoD+eIomonmOwB4smBRxfVpYQ==", "cpu": [ "ppc64" ], + "libc": [ + "glibc" + ], "license": "LGPL-3.0-or-later", "optional": true, "os": [ @@ -678,12 +687,15 @@ } }, "node_modules/@img/sharp-libvips-linux-riscv64": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-riscv64/-/sharp-libvips-linux-riscv64-1.3.2.tgz", - "integrity": "sha512-bsb4rI+NldGOsXuej2r8OdSS8+zXDVaCWxyWrcv6kneTOlgAHtZABRzBBCwdsPiD90J4myNJuHpg6kA20ImW/w==", + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-riscv64/-/sharp-libvips-linux-riscv64-1.3.4.tgz", + "integrity": "sha512-aHkkIEHPRdQEegJN20MLmGtxYD9R2wQr3Cwpddnu5+YKMt6Uzax7S9h5gpZTo8wyrGuZSlfQ63OevL5mTyOC7Q==", "cpu": [ "riscv64" ], + "libc": [ + "glibc" + ], "license": "LGPL-3.0-or-later", "optional": true, "os": [ @@ -694,12 +706,15 @@ } }, "node_modules/@img/sharp-libvips-linux-s390x": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.3.2.tgz", - "integrity": "sha512-/ABshyj8gCpyIrNXnHn4LorDJ0HHm1VhXPBlxZ8zAtfVPAaSafXPGn+sUSIRiwaSBy0mmFjSjiXI5mkcwdChKQ==", + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.3.4.tgz", + "integrity": "sha512-ra/mB6MikESDUO7Yg+Mi95bFBb9GsObURuhnOv3OqknjGe9sZrG8tCe9q0xSIGrtLgvgw0gKnFWcK4blSgQOuQ==", "cpu": [ "s390x" ], + "libc": [ + "glibc" + ], "license": "LGPL-3.0-or-later", "optional": true, "os": [ @@ -710,12 +725,15 @@ } }, "node_modules/@img/sharp-libvips-linux-x64": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.3.2.tgz", - "integrity": "sha512-ITPEtgffGJ0S6G9dRyw/366tJQqFRcHWPHhC+Stpg3Z8AEMrDrTr2lhdz4f/Y/HMbRh//7Z5mBzEpVdi62Oc3w==", + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.3.4.tgz", + "integrity": "sha512-GJ//SSXbnwSDes02umB3nDJLFcQzw8a18V8fyhqr6tV515tOEMdImjjxj1AoafMRz56F3PHgftnj1QEKSU1zkw==", "cpu": [ "x64" ], + "libc": [ + "glibc" + ], "license": "LGPL-3.0-or-later", "optional": true, "os": [ @@ -726,12 +744,15 @@ } }, "node_modules/@img/sharp-libvips-linuxmusl-arm64": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.3.2.tgz", - "integrity": "sha512-zE9EdiUzUmg5mDT5a1rk5fYJ6GWPloTwWBYDS14naqHsL+EaMpDj1AWnpLgh3u0YCORv2Tt50wrcrpYqkP97Kw==", + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.3.4.tgz", + "integrity": "sha512-hvulFwtjUcagsis6BBxHwGFwWoNZjgYmULGVrZcyfNbjA8hKILbRxGg15/7w5HDyXHXUos/j6baAWqnCyQ2DWA==", "cpu": [ "arm64" ], + "libc": [ + "musl" + ], "license": "LGPL-3.0-or-later", "optional": true, "os": [ @@ -742,12 +763,15 @@ } }, "node_modules/@img/sharp-libvips-linuxmusl-x64": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.3.2.tgz", - "integrity": "sha512-m0lrLiUt+lBYnCFr8qV/65yMR4E/c7/wf78I5eKTdkEakFAlZ9QlzEM3QIhhAwVeUhLAHLcCq7a7Vszq/oFNZQ==", + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.3.4.tgz", + "integrity": "sha512-6zXKeE/p39I1AmA3cJG35eyBGNqNddLnUXjhwBnsGjFPWqf5VKkDBEqaEkPDoTEtkxwi2vv8Tcr2mDyP4So7Fg==", "cpu": [ "x64" ], + "libc": [ + "musl" + ], "license": "LGPL-3.0-or-later", "optional": true, "os": [ @@ -758,12 +782,15 @@ } }, "node_modules/@img/sharp-linux-arm": { - "version": "0.35.3", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.35.3.tgz", - "integrity": "sha512-affVWCTLooy8TSxbDx2qkzuDeaWLNVBA+P//FNBirHsXpP2fuBhk5AuboYUnrDnzoXes8GFjpTx0SBFOCRg+FA==", + "version": "0.35.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.35.5.tgz", + "integrity": "sha512-LEaXK2WdXVK5ykcw0buWyPMsmLLL2vpHLD6yrNSW+JGEL3BZPA4tpKN6iaMc4AxTTAoaX/sU1rOL51lcIz48ZQ==", "cpu": [ "arm" ], + "libc": [ + "glibc" + ], "license": "Apache-2.0", "optional": true, "os": [ @@ -776,16 +803,19 @@ "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-libvips-linux-arm": "1.3.2" + "@img/sharp-libvips-linux-arm": "1.3.4" } }, "node_modules/@img/sharp-linux-arm64": { - "version": "0.35.3", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.35.3.tgz", - "integrity": "sha512-QgKDspHPnrU+GQ55XPhGwyhC8acLVOOSyAvo1oVfFmrIXLkDNmGWzAfDZ4xK8oSA1qBQrALcHX0G5UZni/SuFQ==", + "version": "0.35.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.35.5.tgz", + "integrity": "sha512-LYVx5JTsOM2CBzmxreh+nl64/3H6Xb09iSLknqH47z2T2DFFxDeFLP5y4dJwe6H7uGQlHPyEEtIqyo3DYsRwdQ==", "cpu": [ "arm64" ], + "libc": [ + "glibc" + ], "license": "Apache-2.0", "optional": true, "os": [ @@ -798,16 +828,19 @@ "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-libvips-linux-arm64": "1.3.2" + "@img/sharp-libvips-linux-arm64": "1.3.4" } }, "node_modules/@img/sharp-linux-ppc64": { - "version": "0.35.3", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-ppc64/-/sharp-linux-ppc64-0.35.3.tgz", - "integrity": "sha512-sMd8rDxmpLOwv/7N44klFjOD5DUO7FLdjiXDI0hoxYaf7Ar262dQIEkosE98bps+5HPLtp/EvNqeqQtOycP/IA==", + "version": "0.35.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-ppc64/-/sharp-linux-ppc64-0.35.5.tgz", + "integrity": "sha512-QVxAAq8evVRI9ia2vqgwrmWucn5Dfv+JdWzj75pD8omHLPSP7f8p20O8jxzjCcuCEQEOtYOZUmX1hkiZ0kdevA==", "cpu": [ "ppc64" ], + "libc": [ + "glibc" + ], "license": "Apache-2.0", "optional": true, "os": [ @@ -820,16 +853,19 @@ "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-libvips-linux-ppc64": "1.3.2" + "@img/sharp-libvips-linux-ppc64": "1.3.4" } }, "node_modules/@img/sharp-linux-riscv64": { - "version": "0.35.3", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-riscv64/-/sharp-linux-riscv64-0.35.3.tgz", - "integrity": "sha512-0Eob78yjlYPfL5vMNWAW55l3R9Y6BQS/gOfe0ZcP9mEz9ohhKSt4im1hayiknXgf8AWrFqMvJcKIdmLmEe7yeQ==", + "version": "0.35.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-riscv64/-/sharp-linux-riscv64-0.35.5.tgz", + "integrity": "sha512-LtdreXguaavKODPIfzJ4kffx7UNt1omwtK0rch4EBbbSTXPnxWmYSayXdLJw0fJzQ97kHt1gL/yh4tvU+nCyRQ==", "cpu": [ "riscv64" ], + "libc": [ + "glibc" + ], "license": "Apache-2.0", "optional": true, "os": [ @@ -842,16 +878,19 @@ "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-libvips-linux-riscv64": "1.3.2" + "@img/sharp-libvips-linux-riscv64": "1.3.4" } }, "node_modules/@img/sharp-linux-s390x": { - "version": "0.35.3", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.35.3.tgz", - "integrity": "sha512-KgAxQ0DxpNOq1rG2t5cgTgShJFGSuU7XO45cqC+1NVOuZnP6tlgZRuSYOfNupGkHID0o3cJOsw4DVeJpMovcGw==", + "version": "0.35.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.35.5.tgz", + "integrity": "sha512-UZasTOFiYzotTsGOCu42BfUzP6Tu6Do/947iRm1RsLKvlllxwGcn4RN27LibGWceix4Y+Pmw3jsnTcCQIgWjqA==", "cpu": [ "s390x" ], + "libc": [ + "glibc" + ], "license": "Apache-2.0", "optional": true, "os": [ @@ -864,16 +903,19 @@ "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-libvips-linux-s390x": "1.3.2" + "@img/sharp-libvips-linux-s390x": "1.3.4" } }, "node_modules/@img/sharp-linux-x64": { - "version": "0.35.3", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.35.3.tgz", - "integrity": "sha512-8pqvxubL2PGdhlPy6GLqzDYMUjyRmKAwKHYKixpdJYBUK7PJ0C029XdsnpFIdgRZG68fZiGdHVWcKPvtiPB4cA==", + "version": "0.35.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.35.5.tgz", + "integrity": "sha512-SxFtLTeJInhAA9Q836kux2vZNeOBQEx658qvbboZScr0wIARym3IcGmW7KpVD5sbVg0Ojy+udFQdayYIZyoNog==", "cpu": [ "x64" ], + "libc": [ + "glibc" + ], "license": "Apache-2.0", "optional": true, "os": [ @@ -886,16 +928,19 @@ "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-libvips-linux-x64": "1.3.2" + "@img/sharp-libvips-linux-x64": "1.3.4" } }, "node_modules/@img/sharp-linuxmusl-arm64": { - "version": "0.35.3", - "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.35.3.tgz", - "integrity": "sha512-Vz0iQjzzcSX3HCbfwFfCSG/9SCIqyO0mH2sXyiHaAYfBk0cRsCWXRyQYX0ovCK/PAQBbTzQ0dsPQHh5MAFL59w==", + "version": "0.35.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.35.5.tgz", + "integrity": "sha512-9HbMclmI1zlNkFRs3z9/eBtDjfD0sGlrX1z6b1qwmiFY5ElDLh4BC0LPBdVp7z1DXFiKlIcznf+ZlsuZzLxQqg==", "cpu": [ "arm64" ], + "libc": [ + "musl" + ], "license": "Apache-2.0", "optional": true, "os": [ @@ -908,16 +953,19 @@ "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-libvips-linuxmusl-arm64": "1.3.2" + "@img/sharp-libvips-linuxmusl-arm64": "1.3.4" } }, "node_modules/@img/sharp-linuxmusl-x64": { - "version": "0.35.3", - "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.35.3.tgz", - "integrity": "sha512-6O1NPKcDVj9QEdg7Hx549EX8U0rp6yXQERqru6yRN7fGBn32UvIRJUlWnk+8xDCiG76hXVBbX82NZ/ZKr0euIg==", + "version": "0.35.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.35.5.tgz", + "integrity": "sha512-4KOphqB035HrVdqLZfCgMzzERrQkkzOwRhl4OAkRO1YCldbaFjySXMaK534Mo0V+LndnlJk+sbUyLeU0ULyD1A==", "cpu": [ "x64" ], + "libc": [ + "musl" + ], "license": "Apache-2.0", "optional": true, "os": [ @@ -930,17 +978,17 @@ "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-libvips-linuxmusl-x64": "1.3.2" + "@img/sharp-libvips-linuxmusl-x64": "1.3.4" } }, "node_modules/@img/sharp-wasm32": { - "version": "0.35.3", - "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.35.3.tgz", - "integrity": "sha512-cZ0XkcYGpHZkqW6iCkqTcmUC0CD9DhD5d/qeZlZkfRBn6GnHniZXLUo5+9xw8Iv76YE6LQFN9YNBlKREcCG76w==", + "version": "0.35.5", + "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.35.5.tgz", + "integrity": "sha512-Ptsga1su4tQx+LLF1ECS9U6nz5kmrXKo6XVbtR48Ke3ZRxxgaWBu7IDtEe1quo8hiupwm6WFqxVlXaSf7IINGQ==", "license": "Apache-2.0 AND LGPL-3.0-or-later AND MIT", "optional": true, "dependencies": { - "@emnapi/runtime": "^1.11.1" + "@emnapi/runtime": "^1.11.3" }, "engines": { "node": ">=20.9.0" @@ -950,16 +998,16 @@ } }, "node_modules/@img/sharp-webcontainers-wasm32": { - "version": "0.35.3", - "resolved": "https://registry.npmjs.org/@img/sharp-webcontainers-wasm32/-/sharp-webcontainers-wasm32-0.35.3.tgz", - "integrity": "sha512-2rnq7bX3NzeR2T4YWgz8qiG4h3TSdMe+vN1iQXpJleSJ3SM5zQ8Fy2SyyXAWlbxpEZ2Y+Z4u1BePgJEYbSy80Q==", + "version": "0.35.5", + "resolved": "https://registry.npmjs.org/@img/sharp-webcontainers-wasm32/-/sharp-webcontainers-wasm32-0.35.5.tgz", + "integrity": "sha512-hfhF/FmoQyTUkA0bIKFOtw536BQSeBMe6BF6QyWlrPxT754+TFLaZ7sKKTfvvM0yJgKgaYTwnFCIZ/GuDw5SUA==", "cpu": [ "wasm32" ], "license": "Apache-2.0", "optional": true, "dependencies": { - "@img/sharp-wasm32": "0.35.3" + "@img/sharp-wasm32": "0.35.5" }, "engines": { "node": ">=20.9.0" @@ -969,9 +1017,9 @@ } }, "node_modules/@img/sharp-win32-arm64": { - "version": "0.35.3", - "resolved": "https://registry.npmjs.org/@img/sharp-win32-arm64/-/sharp-win32-arm64-0.35.3.tgz", - "integrity": "sha512-4bPwFdMbeC4JQ8L8LOyWp6nsHcboP5fxkp6iPOXz2Vg49R42TuMs2whkJ5OAP4/Ul035qOzy0AecOF9VOscn4w==", + "version": "0.35.5", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-arm64/-/sharp-win32-arm64-0.35.5.tgz", + "integrity": "sha512-X4t7g+7ZA5DKblCBEXGjUqqemj4vczING/5viFwAL8h4N3qYeyjwdCvRLHi4EdOUI+2Z7UFlp1VM+p/AuEtm6Q==", "cpu": [ "arm64" ], @@ -988,9 +1036,9 @@ } }, "node_modules/@img/sharp-win32-ia32": { - "version": "0.35.3", - "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.35.3.tgz", - "integrity": "sha512-r53mXsBN6lFUDiST764SvgwUdHAqM4rPAiDzAmf4fLoB6X/rkfyTrLCg6+g17wJJiCmB3JYgHuUldCWUIRFSXw==", + "version": "0.35.5", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.35.5.tgz", + "integrity": "sha512-5Zm82LoBc43nhwNybZlG7Y1KO//Zhsn306fQl29ZOuStHLGTo3BWL83q3cznX0poxSAMuYL1On/BHBxkBeKr6A==", "cpu": [ "ia32" ], @@ -1007,9 +1055,9 @@ } }, "node_modules/@img/sharp-win32-x64": { - "version": "0.35.3", - "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.35.3.tgz", - "integrity": "sha512-D4y1vNeZrIIJCN+uHaWVtH86B+aCrdMYYjicy9pXHvbGZeGYLLSd3wdVuC37FxVXlU1ARsk84eKWfWMXGYEqvA==", + "version": "0.35.5", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.35.5.tgz", + "integrity": "sha512-x76eH0vEiHlcMQu8Y8IenntaACtddpT6W0wmXtWrnKcnKI7ME5DdgqhAD6SEWOEl1v2zDvkZDhFA9KnURwpfqg==", "cpu": [ "x64" ], @@ -1098,25 +1146,58 @@ } }, "node_modules/@next/env": { - "version": "16.3.1", - "resolved": "https://registry.npmjs.org/@next/env/-/env-16.3.1.tgz", - "integrity": "sha512-35G3xwkQUb2oETSDjFXGrVugknoayLFBh7vSE+yAcl9IP2zT9wyGwq7297AYHR11kJld807t5f8AJBs6WBzXsQ==", + "version": "16.4.3", + "resolved": "https://registry.npmjs.org/@next/env/-/env-16.4.3.tgz", + "integrity": "sha512-a7tz1QCcWWkwC/rPJcPMJk/UNRu9CFhDd3OHYE5hddbJrs8BqRTalxI6GlKCWEGzRLHN+S/B7a4PAHCtm25aBQ==", "license": "MIT" }, "node_modules/@next/eslint-plugin-next": { - "version": "16.2.10", - "resolved": "https://registry.npmjs.org/@next/eslint-plugin-next/-/eslint-plugin-next-16.2.10.tgz", - "integrity": "sha512-Gs8D2m21VnJeFo9qvYIIqJH94frWerWYu41BprU1pLtRVF7PCQNLiFZZ3fG+iPuj3K83Cwv/rt+msLOy8Qgu3Q==", + "version": "16.4.3", + "resolved": "https://registry.npmjs.org/@next/eslint-plugin-next/-/eslint-plugin-next-16.4.3.tgz", + "integrity": "sha512-oxuC06wt/71h6ACYCV9GbKOfnf5a7VlRe/p80YHTut15TNgDEmynDnaq8t/xhy5rlvk7dhItIPs6H3rvIM4kyw==", "dev": true, "license": "MIT", "dependencies": { + "@eslint-community/eslint-utils": "4.9.1", "fast-glob": "3.3.1" } }, + "node_modules/@next/eslint-plugin-next/node_modules/@eslint-community/eslint-utils": { + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.1.tgz", + "integrity": "sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@next/eslint-plugin-next/node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, "node_modules/@next/swc-darwin-arm64": { - "version": "16.3.1", - "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-16.3.1.tgz", - "integrity": "sha512-ABMIu2zQ7cnNIHm5ivKGwZwUrm0pAai3yiJ/gK/rF1c1VP9UOnj7XECbMKFdVKp9I9eMYq9NoDs1WXOoowxzJw==", + "version": "16.4.3", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-16.4.3.tgz", + "integrity": "sha512-4yq5EXBt+VDtAZwTyfijaFp5D2C5oz3Ikw5a2kiX2K9nw72vrZX2q5UuAlkPtUMO1tQz6JTKpaKWjS7OOefTDQ==", "cpu": [ "arm64" ], @@ -1130,9 +1211,9 @@ } }, "node_modules/@next/swc-darwin-x64": { - "version": "16.3.1", - "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-16.3.1.tgz", - "integrity": "sha512-gNG21e/UnrroeScbY/QndUEdl0mF1FRibW7BBeYUz/5ABCepjqDdEdgr592vpzMtCn/m7FTjYq3TN4TpyDnutw==", + "version": "16.4.3", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-16.4.3.tgz", + "integrity": "sha512-1Rvkn/LUhnEF8WxnRkOrqGhbwXui1bkWFxONKIbN+r7C+9KHDSZ+iUoj4CzymVMWUyZIyx9szcb9+kbKhD500A==", "cpu": [ "x64" ], @@ -1146,12 +1227,15 @@ } }, "node_modules/@next/swc-linux-arm64-gnu": { - "version": "16.3.1", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-16.3.1.tgz", - "integrity": "sha512-6B6Lw016iwNUQuaJoraMMTLh6TwHzFUtxipSScD1F3YyymcrRWkobodRS2ftIOkF5vrs4zNlyUrTC5YZQ9Lz5w==", + "version": "16.4.3", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-16.4.3.tgz", + "integrity": "sha512-dCKpXErGg3abUM6t5JTJV/ottVBTStJB5lRJTbgdUdQaQ+jNHiK56Hsc0YAEg/rinSh42hYG3HWiYmEMdilnxg==", "cpu": [ "arm64" ], + "libc": [ + "glibc" + ], "license": "MIT", "optional": true, "os": [ @@ -1162,12 +1246,15 @@ } }, "node_modules/@next/swc-linux-arm64-musl": { - "version": "16.3.1", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-16.3.1.tgz", - "integrity": "sha512-JUiPXZKK9wOhjf4MgDiH29GZLxfqOesbLtHq2pDxwH/WwscTRV2ToymnOTh1egzaZf0ueUf8T2+CeYTGHjW0Iw==", + "version": "16.4.3", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-16.4.3.tgz", + "integrity": "sha512-WwYbhWkhYBvBtib1K4W0kL8MW2snBD2A5b3SN4vPpqalZbZs5+bQ1yzAdepVoOqrFfEW3dmREy4Zs1MrWcrFbw==", "cpu": [ "arm64" ], + "libc": [ + "musl" + ], "license": "MIT", "optional": true, "os": [ @@ -1178,12 +1265,15 @@ } }, "node_modules/@next/swc-linux-x64-gnu": { - "version": "16.3.1", - "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-16.3.1.tgz", - "integrity": "sha512-Uog9jsrmIRIL/lfvIp9htmskSNC7JcQsMVucXL2V2YY1y/D9IUN3LPEafqy0zRJ2cIU1SQ0V6F6TlffQ+pLAGg==", + "version": "16.4.3", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-16.4.3.tgz", + "integrity": "sha512-QymWvfUwDEC5/lpJOsxX5VAbyoR2D13+2Jsjz4be7gT4LPqEgdpkeLIR/HFfCLgKzoMhpJbp6I/JnogyNZHcaA==", "cpu": [ "x64" ], + "libc": [ + "glibc" + ], "license": "MIT", "optional": true, "os": [ @@ -1194,12 +1284,15 @@ } }, "node_modules/@next/swc-linux-x64-musl": { - "version": "16.3.1", - "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-16.3.1.tgz", - "integrity": "sha512-6yy3FT13KgUFOj5H8bl8w/6nKiJwHIvbtwh1V+1acsu+7y4tJjnemSa6mhsh53BeoVrlozE+fMgZhXH46WmjMA==", + "version": "16.4.3", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-16.4.3.tgz", + "integrity": "sha512-Vmjd9D7DpA4Vv3cUlr82QWgJD/BQZmns801vtC5VWHg6jCIA4a5vMKpQnfrM2pyCrp2eV0ENdUg4PlN3bAc2Yw==", "cpu": [ "x64" ], + "libc": [ + "musl" + ], "license": "MIT", "optional": true, "os": [ @@ -1210,9 +1303,9 @@ } }, "node_modules/@next/swc-win32-arm64-msvc": { - "version": "16.3.1", - "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-16.3.1.tgz", - "integrity": "sha512-iOoN1QecUoGNZik536U/vtK43YwgyrCsGIkth52yIkl612n+0C9MjSnJbQAikISpb+WYRooBVhaDlUW7iZoKog==", + "version": "16.4.3", + "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-16.4.3.tgz", + "integrity": "sha512-lG1pPdPLk7gTyGb00n5JIMLdBJgjb+UEhSdZvFbhUMg0DyC6z4B7RnpSKF9VCd4imkLObVbXOFA0kFCpw7yFow==", "cpu": [ "arm64" ], @@ -1226,9 +1319,9 @@ } }, "node_modules/@next/swc-win32-x64-msvc": { - "version": "16.3.1", - "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-16.3.1.tgz", - "integrity": "sha512-d/k+PpAriUPaeMJJOG7HUSdqfEX46FEPWU1p3/nm2ACmXhj9hFEWdFODUBIpkuijXYkfL90qZzTqVPRp4BW/hw==", + "version": "16.4.3", + "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-16.4.3.tgz", + "integrity": "sha512-NmQC9RkJdnPXRaMxtkCzobB3teVjqF33oSOnwDfi+XYGWWYpt+xlGK3mtktSKLbdjwaWbJu2OkkMiRFGUUncKg==", "cpu": [ "x64" ], @@ -1883,9 +1976,9 @@ } }, "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { - "version": "5.0.9", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.9.tgz", - "integrity": "sha512-ScQ4IuvIEF1TMlP7Zt+vjJ//9zlPb2SDcxWxM3bk8s6t6GGdJ7KO1dCcTidOPJKePW30LE/2cT7wCyPho9/Wxg==", + "version": "5.0.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.12.tgz", + "integrity": "sha512-YovQ3rzhaLMIrDjNDMkNS01tea93qhEhG5xy8f6+R0l+dw3Ki+5sCoIoI942iuLZTHWogWktgwVDhU09iNEimQ==", "dev": true, "license": "MIT", "dependencies": { @@ -2637,9 +2730,9 @@ } }, "node_modules/brace-expansion": { - "version": "1.1.18", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.18.tgz", - "integrity": "sha512-Edep/X9fGqVNmzKBVsDYIOtD+z1tuezV70LBjdCst9Tqu76lsnvRiZ6oTic1n+/BIwX6QDGAO94PN4N2SADvtw==", + "version": "1.1.21", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.21.tgz", + "integrity": "sha512-9zeA+KLZNNzglF2TPKRQEDyx6Yby7daAkuy8MiPzpXPsYDWi/DRM8jmwUDxokQjYqBpv5DgPiwD4h4ZZSy1Ujw==", "dev": true, "license": "MIT", "dependencies": { @@ -3417,21 +3510,21 @@ } }, "node_modules/eslint-config-next": { - "version": "16.2.10", - "resolved": "https://registry.npmjs.org/eslint-config-next/-/eslint-config-next-16.2.10.tgz", - "integrity": "sha512-HSybLOY0QKf39i4FWUqPN0xWiNDi6A6UqJmZtgDkS3zMqjXTqULvj/sueXx3cdCG0mVG+qH6k5/qdegklH1d1w==", + "version": "16.4.3", + "resolved": "https://registry.npmjs.org/eslint-config-next/-/eslint-config-next-16.4.3.tgz", + "integrity": "sha512-j9IqBma6abp800frdUURaizYMgXOK+jNGyq6CsYcM9AxpSJs5D/TgMNGeAmRUilZvA7g9V1Tr71gNg9/SVTuMQ==", "dev": true, "license": "MIT", "dependencies": { - "@next/eslint-plugin-next": "16.2.10", + "@next/eslint-plugin-next": "16.4.3", "eslint-import-resolver-node": "^0.3.6", "eslint-import-resolver-typescript": "^3.5.2", "eslint-plugin-import": "^2.32.0", "eslint-plugin-jsx-a11y": "^6.10.0", "eslint-plugin-react": "^7.37.0", - "eslint-plugin-react-hooks": "^7.0.0", + "eslint-plugin-react-hooks": "^7.1.0", "globals": "16.4.0", - "typescript-eslint": "^8.46.0" + "typescript-eslint": "^8.56.0" }, "peerDependencies": { "eslint": ">=9.0.0", @@ -3830,9 +3923,9 @@ "license": "MIT" }, "node_modules/fastq": { - "version": "1.20.1", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.20.1.tgz", - "integrity": "sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==", + "version": "1.20.3", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.20.3.tgz", + "integrity": "sha512-XKv5nnLs6nLF71NgiKJLIZFLkPyIEuOselLG7ujZnGrRfQK8HpvY+WqKhAJUAdLomwVHErVS4LfxFlPq0/FTAw==", "dev": true, "license": "ISC", "dependencies": { @@ -4899,9 +4992,9 @@ "license": "MIT" }, "node_modules/js-yaml": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.3.1.tgz", - "integrity": "sha512-CY6crGq313MX8GkwvB7tzgp99vjQxY1++5y10/BKN/GUfHqWaOGQMNZkBvqSzsZKWk/ijwHlWzzkLulsGHhjWQ==", + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.3.2.tgz", + "integrity": "sha512-SFNOvSJ+Dgf/9An904Yx+CgSlIPCkIpao4qo51lpee25TIRejdH3rhR4EZMGoNx3/TP3O+wzWuiTFl4sqbltzA==", "dev": true, "funding": [ { @@ -6330,12 +6423,12 @@ "license": "MIT" }, "node_modules/next": { - "version": "16.3.1", - "resolved": "https://registry.npmjs.org/next/-/next-16.3.1.tgz", - "integrity": "sha512-hsAp0i7Rh+/dhe7DGIeN2YlpLM1DP4MNxti9EtDMtqcO612X81MvvEj388/oTce9U1EcEIOWDlGq0zRwrBKvuA==", + "version": "16.4.3", + "resolved": "https://registry.npmjs.org/next/-/next-16.4.3.tgz", + "integrity": "sha512-OqxKTGi9u80FydydsMNYNjnuje9Au+kvHlt2GZ//ftdpDHm1dxKqAaENoOOTX5wKzn+9vaKUNIfZeyZUuLhCnA==", "license": "MIT", "dependencies": { - "@next/env": "16.3.1", + "@next/env": "16.4.3", "@swc/helpers": "0.5.23", "baseline-browser-mapping": "^2.9.19", "caniuse-lite": "^1.0.30001579", @@ -6349,15 +6442,15 @@ "node": ">=20.9.0" }, "optionalDependencies": { - "@next/swc-darwin-arm64": "16.3.1", - "@next/swc-darwin-x64": "16.3.1", - "@next/swc-linux-arm64-gnu": "16.3.1", - "@next/swc-linux-arm64-musl": "16.3.1", - "@next/swc-linux-x64-gnu": "16.3.1", - "@next/swc-linux-x64-musl": "16.3.1", - "@next/swc-win32-arm64-msvc": "16.3.1", - "@next/swc-win32-x64-msvc": "16.3.1", - "sharp": "^0.35.3" + "@next/swc-darwin-arm64": "16.4.3", + "@next/swc-darwin-x64": "16.4.3", + "@next/swc-linux-arm64-gnu": "16.4.3", + "@next/swc-linux-arm64-musl": "16.4.3", + "@next/swc-linux-x64-gnu": "16.4.3", + "@next/swc-linux-x64-musl": "16.4.3", + "@next/swc-win32-arm64-msvc": "16.4.3", + "@next/swc-win32-x64-msvc": "16.4.3", + "sharp": "^0.35.5" }, "peerDependencies": { "@opentelemetry/api": "^1.1.0", @@ -7153,9 +7246,9 @@ } }, "node_modules/sharp": { - "version": "0.35.3", - "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.35.3.tgz", - "integrity": "sha512-ej0zVHuZGHCiABXcNxeYhpRnPNPAcvbG8RMdBAhDAxLKkCRVSpK3Iyu7qbqw3JMzoj0REeM6f3tJLtVwl0023Q==", + "version": "0.35.5", + "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.35.5.tgz", + "integrity": "sha512-Ywn4OnzGukp7CDMrp08RQ50YKmuwG47brZgIVPTvBaaAfQlRlygrRqSrxdCiL9M+LlzLBiJ68IR1QqvzHyjC7g==", "license": "Apache-2.0", "optional": true, "dependencies": { @@ -7170,31 +7263,31 @@ "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-darwin-arm64": "0.35.3", - "@img/sharp-darwin-x64": "0.35.3", - "@img/sharp-freebsd-wasm32": "0.35.3", - "@img/sharp-libvips-darwin-arm64": "1.3.2", - "@img/sharp-libvips-darwin-x64": "1.3.2", - "@img/sharp-libvips-linux-arm": "1.3.2", - "@img/sharp-libvips-linux-arm64": "1.3.2", - "@img/sharp-libvips-linux-ppc64": "1.3.2", - "@img/sharp-libvips-linux-riscv64": "1.3.2", - "@img/sharp-libvips-linux-s390x": "1.3.2", - "@img/sharp-libvips-linux-x64": "1.3.2", - "@img/sharp-libvips-linuxmusl-arm64": "1.3.2", - "@img/sharp-libvips-linuxmusl-x64": "1.3.2", - "@img/sharp-linux-arm": "0.35.3", - "@img/sharp-linux-arm64": "0.35.3", - "@img/sharp-linux-ppc64": "0.35.3", - "@img/sharp-linux-riscv64": "0.35.3", - "@img/sharp-linux-s390x": "0.35.3", - "@img/sharp-linux-x64": "0.35.3", - "@img/sharp-linuxmusl-arm64": "0.35.3", - "@img/sharp-linuxmusl-x64": "0.35.3", - "@img/sharp-webcontainers-wasm32": "0.35.3", - "@img/sharp-win32-arm64": "0.35.3", - "@img/sharp-win32-ia32": "0.35.3", - "@img/sharp-win32-x64": "0.35.3" + "@img/sharp-darwin-arm64": "0.35.5", + "@img/sharp-darwin-x64": "0.35.5", + "@img/sharp-freebsd-wasm32": "0.35.5", + "@img/sharp-libvips-darwin-arm64": "1.3.4", + "@img/sharp-libvips-darwin-x64": "1.3.4", + "@img/sharp-libvips-linux-arm": "1.3.4", + "@img/sharp-libvips-linux-arm64": "1.3.4", + "@img/sharp-libvips-linux-ppc64": "1.3.4", + "@img/sharp-libvips-linux-riscv64": "1.3.4", + "@img/sharp-libvips-linux-s390x": "1.3.4", + "@img/sharp-libvips-linux-x64": "1.3.4", + "@img/sharp-libvips-linuxmusl-arm64": "1.3.4", + "@img/sharp-libvips-linuxmusl-x64": "1.3.4", + "@img/sharp-linux-arm": "0.35.5", + "@img/sharp-linux-arm64": "0.35.5", + "@img/sharp-linux-ppc64": "0.35.5", + "@img/sharp-linux-riscv64": "0.35.5", + "@img/sharp-linux-s390x": "0.35.5", + "@img/sharp-linux-x64": "0.35.5", + "@img/sharp-linuxmusl-arm64": "0.35.5", + "@img/sharp-linuxmusl-x64": "0.35.5", + "@img/sharp-webcontainers-wasm32": "0.35.5", + "@img/sharp-win32-arm64": "0.35.5", + "@img/sharp-win32-ia32": "0.35.5", + "@img/sharp-win32-x64": "0.35.5" }, "peerDependenciesMeta": { "@types/node": { @@ -7315,9 +7408,9 @@ } }, "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==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.2.tgz", + "integrity": "sha512-KGj/8Y43x35aZVDtt+J4mK1hoLGHULMYfSkODJNQjNDC3oW1PqPoxMwo0pLUsWM/UEGzON/NxeHywEfNXNP3Vw==", "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" @@ -8204,9 +8297,9 @@ } }, "node_modules/zod": { - "version": "4.4.3", - "resolved": "https://registry.npmjs.org/zod/-/zod-4.4.3.tgz", - "integrity": "sha512-ytENFjIJFl2UwYglde2jchW2Hwm4GJFLDiSXWdTrJQBIN9Fcyp7n4DhxJEiWNAJMV1/BqWfW/kkg71UDcHJyTQ==", + "version": "4.6.7", + "resolved": "https://registry.npmjs.org/zod/-/zod-4.6.7.tgz", + "integrity": "sha512-g8W2D2kU6a8untc053fX1uVBKzM7yqAxW/3zwk83+6RyF2+SKOuV+c0wBDhUwzV1PaGapmZH+rmcUzPf+3CGwg==", "dev": true, "license": "MIT", "funding": { diff --git a/package.json b/package.json index 59f5f19..fec1e0f 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ "dependencies": { "@xscriptor/xcomponents": "^0.2.3", "framer-motion": "^12.42.2", - "next": "^16.2.11", + "next": "^16.4.3", "react": "19.2.4", "react-dom": "19.2.4", "react-markdown": "^10.1.0", @@ -20,7 +20,7 @@ }, "overrides": { "postcss": "^8.5.10", - "sharp": "^0.35.0" + "sharp": "^0.35.5" }, "devDependencies": { "@tailwindcss/postcss": "^4", @@ -28,7 +28,7 @@ "@types/react": "^19", "@types/react-dom": "^19", "eslint": "^9", - "eslint-config-next": "16.2.10", + "eslint-config-next": "16.4.3", "tailwindcss": "^4", "typescript": "^5" } diff --git a/src/app/globals.css b/src/app/globals.css index f69177c..8a60216 100644 --- a/src/app/globals.css +++ b/src/app/globals.css @@ -6,7 +6,7 @@ --color-bg3: #22263a; --color-fg: #e1e4ed; --color-fg2: #8b91a8; - --color-accent: #dea584; + --color-accent: #ffb27a; --color-accent2: #ffa500; --color-green: #78dba9; --color-cyan: #78dce8; @@ -30,7 +30,7 @@ --border: #22263a; --text: #e1e4ed; --text-muted: #8b91a8; - --accent: #dea584; + --accent: #ffb27a; } html:not([data-theme="dark"]) { @@ -40,7 +40,7 @@ html:not([data-theme="dark"]) { --color-bg3: #e0ddd5; --color-fg: #1e1e1e; --color-fg2: #6b7280; - --color-accent: #c8763a; + --color-accent: #a85122; --color-accent2: #ffa500; --color-green: #2ea043; --color-cyan: #0e8a9e; @@ -54,7 +54,7 @@ html:not([data-theme="dark"]) { --border: #e0ddd5; --text: #1e1e1e; --text-muted: #6b7280; - --accent: #c8763a; + --accent: #a85122; } body { @@ -107,18 +107,6 @@ body { .placeholder-fg2::placeholder { color: var(--color-fg2) !important; } .\[\&\:checked\:\:after\]\:text-bg:checked:after { color: var(--color-bg) !important; } -.xfetch-nav a, -.xfetch-nav button, -.XGlassNavbar_overlay a, -.XGlassNavbar_overlay button { - font-family: "Geist", ui-sans-serif, system-ui, sans-serif; -} - -header.XGlassNavbar_nav .XGlassNavbar_sectionLeft, -header.XGlassNavbar_nav .XGlassNavbar_sectionRight { - width: auto; - flex: 0 0 auto; -} .bg-paths-dark { display: block; } .bg-paths-light { display: none; } diff --git a/src/app/landing.css b/src/app/landing.css new file mode 100644 index 0000000..6e46dd5 --- /dev/null +++ b/src/app/landing.css @@ -0,0 +1,2977 @@ +/* ========================================================================== + xfetch landing — "precision terminal / isometric lab" + This file is additive. Everything is scoped to .xf-* selectors plus a small + set of html-level tokens so the global nav/footer work on docs/previews too. + ========================================================================== */ + +html { + --xf-bg: #07090f; + --xf-surface: #0d111a; + --xf-surface-2: #121826; + --xf-surface-3: #182033; + --xf-line: rgba(148, 163, 184, 0.16); + --xf-line-strong: rgba(148, 163, 184, 0.3); + --xf-text: #e8ecf5; + --xf-muted: #98a2b8; + --xf-accent: var(--color-accent, #ffb27a); + --xf-accent-strong: #ffc79e; + --xf-accent-ink: #26130a; + --xf-control-border: #6f7b90; + --xf-text-xs: 0.72rem; + --xf-text-2xs: 0.66rem; + --xf-radius-sm: 14px; + --xf-radius-lg: 20px; + --xf-space-1: 0.25rem; + --xf-space-2: 0.5rem; + --xf-space-3: 0.75rem; + --xf-space-4: 1rem; + --xf-space-5: 1.5rem; + --xf-space-6: 2rem; + --xf-space-7: 3rem; + --xf-shadow-soft: 0 18px 45px -28px rgba(0, 0, 0, 0.68); + --xf-cyan: #7dd3fc; + --xf-violet: #a78bfa; + --xf-success: #7ee2b8; + --xf-warning: #ffd28a; + --xf-danger: #ff8f9c; + --xf-glass-tint: rgba(13, 17, 26, 0.62); + --xf-glass-edge: rgba(255, 255, 255, 0.16); + --xf-glass-inner: rgba(255, 255, 255, 0.09); + --xf-grid-line: rgba(148, 163, 184, 0.075); + --xf-shadow: 0 30px 80px -34px rgba(0, 0, 0, 0.85); + --xf-code-bg: #080b12; + --xf-code-bg-2: #0d1220; + --xf-code-text: #dbe3f4; + --xf-code-muted: #8b97ad; + --xf-code-key: #7dd3fc; + --xf-code-accent: #ffb27a; + --xf-code-success: #7ee2b8; + --xf-radius: 18px; + color-scheme: dark; +} + +html:not([data-theme="dark"]) { + --xf-bg: #f7f4ee; + --xf-surface: #fffdf9; + --xf-surface-2: #f1ede5; + --xf-surface-3: #e8e2d8; + --xf-line: rgba(23, 26, 33, 0.13); + --xf-line-strong: rgba(23, 26, 33, 0.24); + --xf-text: #171a21; + --xf-muted: #5b6270; + --xf-accent-strong: #9d4a1e; + --xf-accent-ink: #fffdf9; + --xf-control-border: #8c8378; + --xf-cyan: #0e7490; + --xf-violet: #6d28d9; + --xf-success: #1f7a52; + --xf-warning: #8a5a00; + --xf-danger: #b42335; + --xf-glass-tint: rgba(255, 253, 249, 0.7); + --xf-glass-edge: rgba(23, 26, 33, 0.14); + --xf-glass-inner: rgba(255, 255, 255, 0.7); + --xf-grid-line: rgba(23, 26, 33, 0.065); + --xf-shadow: 0 30px 80px -38px rgba(44, 37, 27, 0.42); + color-scheme: light; +} + +html[data-theme="dark"] { + color-scheme: dark; +} + +/* ---------- shared primitives ---------- */ + +.xf-sr-only { + position: absolute !important; + width: 1px !important; + height: 1px !important; + padding: 0 !important; + margin: -1px !important; + overflow: hidden !important; + clip: rect(0, 0, 0, 0) !important; + white-space: nowrap !important; + border: 0 !important; +} + +.xf-skip { + position: fixed; + top: 0.6rem; + left: 0.6rem; + z-index: 200; + padding: 0.6rem 0.9rem; + border: 1px solid var(--xf-accent); + border-radius: 10px; + background: var(--xf-surface); + color: var(--xf-text); + font: 600 0.8rem/1 var(--font-sans); + text-decoration: none; + transform: translateY(-180%); + transition: transform 0.15s ease; +} +.xf-skip:focus-visible, +.xf-skip:focus { + transform: translateY(0); + outline: 2px solid var(--xf-accent); + outline-offset: 2px; +} + +.xf-container { + width: min(100% - clamp(1.5rem, 5vw, 3rem), 1200px); + margin-inline: auto; +} + +html:has(.xf-landing) { + scroll-padding-top: 88px; +} + +body:has(.xf-landing) { + background: var(--xf-bg); +} + +.xf-landing { + position: relative; + min-height: 100vh; + background: transparent; + color: var(--xf-text); + font-family: var(--font-sans); + font-size: 16px; + line-height: 1.6; +} + +.xf-landing a, +.xf-landing button, +.xf-nav a, +.xf-nav button, +.xf-footer a, +.xf-skip { + -webkit-tap-highlight-color: transparent; +} + +.xf-landing :focus-visible, +.xf-nav :focus-visible, +.xf-footer :focus-visible { + outline: 2px solid var(--xf-accent); + outline-offset: 3px; +} + +.xf-landing ::selection { + background: var(--xf-accent); + color: var(--xf-accent-ink); +} + +.xf-eyebrow { + margin: 0 0 0.7rem; + font-family: var(--font-mono); + font-size: var(--xf-text-xs); + font-weight: 600; + letter-spacing: 0.19em; + line-height: 1.4; + text-transform: uppercase; + color: var(--xf-accent); +} + +.xf-mini-label { + margin: 0; + font-family: var(--font-mono); + font-size: var(--xf-text-xs); + font-weight: 600; + letter-spacing: 0.14em; + text-transform: uppercase; + color: var(--xf-muted); +} + +.xf-hint { + margin: 0; + color: var(--xf-muted); + font-size: 0.78rem; + line-height: 1.5; +} + +.xf-glass { + position: relative; + background: var(--xf-glass-tint); + border: 1px solid var(--xf-glass-edge); + box-shadow: + inset 0 1px 0 var(--xf-glass-inner), + 0 24px 60px -30px rgba(0, 0, 0, 0.72); + -webkit-backdrop-filter: blur(18px) saturate(165%); + backdrop-filter: blur(18px) saturate(165%); +} + +@supports not ((backdrop-filter: blur(2px)) or (-webkit-backdrop-filter: blur(2px))) { + body .xf-nav .xf-nav-inner, + body .xf-nav.is-scrolled .xf-nav-inner, + .xf-glass { + background: var(--xf-surface); + } +} + +/* ---------- scroll reveal ---------- */ + +.xf-js [data-reveal] { + opacity: 0; + translate: 0 22px; + transition: + opacity 0.7s cubic-bezier(0.2, 0.72, 0.2, 1), + translate 0.7s cubic-bezier(0.2, 0.72, 0.2, 1); + transition-delay: var(--reveal-delay, 0ms); +} +.xf-js [data-reveal].is-in, +.xf-js [data-reveal]:focus-within { + opacity: 1; + translate: 0 0; +} + +/* ---------- ambient background ---------- */ + +.xf-bg { + position: fixed; + inset: 0; + z-index: 0; + overflow: hidden; + pointer-events: none; +} +.xf-bg-grid { + position: absolute; + inset: 0; + background-image: + linear-gradient(to right, var(--xf-grid-line) 1px, transparent 1px), + linear-gradient(to bottom, var(--xf-grid-line) 1px, transparent 1px); + background-size: 72px 72px; + -webkit-mask-image: radial-gradient(ellipse 95% 70% at 50% 18%, #000 20%, transparent 78%); + mask-image: radial-gradient(ellipse 95% 70% at 50% 18%, #000 20%, transparent 78%); +} +.xf-bg-glow { + position: absolute; + width: 46rem; + height: 46rem; + border-radius: 50%; + filter: blur(80px); + opacity: 0.4; +} +.xf-bg-glow--warm { + top: -20rem; + left: -14rem; + background: radial-gradient(circle, color-mix(in srgb, var(--xf-accent) 36%, transparent), transparent 68%); +} +.xf-bg-glow--cool { + top: -24rem; + right: -18rem; + background: radial-gradient(circle, color-mix(in srgb, var(--xf-cyan) 26%, transparent), transparent 68%); + opacity: 0.32; +} +.xf-bg-lines { + position: absolute; + inset: -10% -5%; + width: 110%; + height: 120%; + opacity: 0.5; +} +.xf-bg-drift { + transform-origin: center; + animation: xf-bg-drift 26s ease-in-out infinite alternate; +} +.xf-bg-noise { + position: absolute; + inset: 0; + opacity: 0.035; + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160' viewBox='0 0 160 160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)' opacity='0.55'/%3E%3C/svg%3E"); +} + +@keyframes xf-bg-drift { + from { transform: translate3d(-8px, 4px, 0); } + to { transform: translate3d(10px, -8px, 0); } +} + +/* ========================================================================== + NAV + ========================================================================== */ + +.xf-nav { + position: fixed; + top: 0; + left: 0; + right: 0; + z-index: 60; + padding: 0.6rem 0 0; +} +.xf-nav-inner { + display: flex; + align-items: center; + gap: 0.85rem; + width: min(100% - clamp(1.5rem, 5vw, 3rem), 1200px); + min-height: 58px; + margin-inline: auto; + padding: 0.38rem 0.5rem 0.38rem 0.7rem; + border: 1px solid var(--xf-glass-edge); + border-radius: 15px; + background: var(--xf-glass-tint); + box-shadow: + inset 0 1px 0 var(--xf-glass-inner), + 0 16px 44px -24px rgba(0, 0, 0, 0.72); + -webkit-backdrop-filter: blur(18px) saturate(175%); + backdrop-filter: blur(18px) saturate(175%); + transition: background 0.2s ease, box-shadow 0.2s ease, border-color 0.2s ease; +} +.xf-nav.is-scrolled .xf-nav-inner { + background: color-mix(in srgb, var(--xf-surface) 82%, transparent); + box-shadow: + inset 0 1px 0 var(--xf-glass-inner), + 0 20px 50px -26px rgba(0, 0, 0, 0.82); +} + +.xf-brand { + display: inline-flex; + align-items: center; + gap: 0.55rem; + padding: 0.2rem 0.35rem; + border-radius: 9px; + color: var(--xf-text); + text-decoration: none; + white-space: nowrap; +} +.xf-brand-mark { + display: grid; + place-items: center; + width: 28px; + height: 28px; + border: 1px solid color-mix(in srgb, var(--xf-accent) 55%, var(--xf-line)); + border-radius: 8px; + background: color-mix(in srgb, var(--xf-accent) 12%, transparent); + color: var(--xf-accent); + font-family: var(--font-mono); + font-size: 0.7rem; + font-weight: 700; + letter-spacing: -0.04em; +} +.xf-brand-word { + font-family: var(--font-mono); + font-size: 0.92rem; + font-weight: 700; + letter-spacing: -0.02em; +} + +.xf-nav-links { + display: flex; + align-items: center; + justify-content: center; + gap: 0.05rem; + flex: 1; + min-width: 0; +} +.xf-nav-link { + position: relative; + padding: 0.42rem 0.52rem; + border-radius: 8px; + color: var(--xf-muted); + font-size: 0.76rem; + font-weight: 550; + line-height: 1.2; + text-decoration: none; + white-space: nowrap; + transition: color 0.15s ease, background 0.15s ease; +} +.xf-nav-link:hover { + color: var(--xf-text); + background: color-mix(in srgb, var(--xf-surface-2) 72%, transparent); +} +.xf-nav-link.is-active { + color: var(--xf-text); + background: color-mix(in srgb, var(--xf-accent) 11%, transparent); +} +.xf-nav-link.is-active::after { + content: ""; + position: absolute; + left: 0.55rem; + right: 0.55rem; + bottom: 0.12rem; + height: 1px; + border-radius: 1px; + background: var(--xf-accent); +} + +.xf-nav-actions { + display: flex; + align-items: center; + gap: 0.35rem; +} +.xf-theme-toggle, +.xf-menu-btn { + display: inline-grid; + place-items: center; + width: 38px; + height: 38px; + padding: 0; + border: 1px solid var(--xf-control-border); + border-radius: 9px; + background: color-mix(in srgb, var(--xf-surface-2) 55%, transparent); + color: var(--xf-muted); + cursor: pointer; + transition: color 0.15s ease, border-color 0.15s ease, background 0.15s ease; +} +.xf-theme-toggle:hover, +.xf-menu-btn:hover { + color: var(--xf-accent); + border-color: color-mix(in srgb, var(--xf-accent) 45%, var(--xf-line)); + background: color-mix(in srgb, var(--xf-accent) 9%, transparent); +} +.xf-menu-btn { + display: none; +} +.xf-menu-icon { + position: relative; + display: flex; + flex-direction: column; + justify-content: space-between; + width: 16px; + height: 12px; +} +.xf-menu-icon span { + display: block; + width: 100%; + height: 1.5px; + border-radius: 2px; + background: currentColor; + transition: transform 0.18s ease, opacity 0.18s ease; + transform-origin: center; +} +.xf-menu-icon.is-open span:nth-child(1) { transform: translateY(5px) rotate(45deg); } +.xf-menu-icon.is-open span:nth-child(2) { opacity: 0; } +.xf-menu-icon.is-open span:nth-child(3) { transform: translateY(-5px) rotate(-45deg); } + +.xf-nav-progress { + position: absolute; + left: 50%; + bottom: -0.1rem; + width: min(100% - clamp(1.5rem, 5vw, 3rem), 1200px); + height: 2px; + transform: translateX(-50%); + border-radius: 2px; + overflow: hidden; + opacity: 0.8; +} +.xf-nav-progress span { + display: block; + width: 0; + height: 100%; + background: linear-gradient(90deg, var(--xf-accent), var(--xf-cyan)); +} + +.xf-mobile-menu { + position: absolute; + top: calc(100% + 0.45rem); + left: 50%; + width: min(100% - clamp(1.5rem, 5vw, 3rem), 1200px); + transform: translateX(-50%); + max-height: calc(100vh - 90px); + overflow-y: auto; + overscroll-behavior: contain; + padding: var(--xf-space-2); + border: 1px solid var(--xf-line-strong); + border-radius: var(--xf-radius-sm); + background: var(--xf-surface); + box-shadow: var(--xf-shadow); +} +.xf-mobile-head { + display: flex; + align-items: center; + justify-content: space-between; + gap: var(--xf-space-3); + padding: 0.2rem 0.2rem 0.55rem; + margin-bottom: 0.25rem; + border-bottom: 1px solid var(--xf-line); +} +.xf-mobile-title { + color: var(--xf-muted); + font-family: var(--font-mono); + font-size: var(--xf-text-xs); + font-weight: 600; + letter-spacing: 0.14em; + text-transform: uppercase; +} +.xf-mobile-close { + display: inline-grid; + place-items: center; + width: 32px; + height: 32px; + padding: 0; + border: 1px solid var(--xf-control-border); + border-radius: 8px; + background: color-mix(in srgb, var(--xf-surface-2) 55%, transparent); + color: var(--xf-muted); + cursor: pointer; +} +.xf-mobile-close:hover { + color: var(--xf-accent); + border-color: var(--xf-accent); +} +.xf-mobile-link { + display: flex; + align-items: center; + gap: 0.7rem; + padding: 0.7rem 0.75rem; + border-radius: 9px; + color: var(--xf-text); + font-size: 0.9rem; + font-weight: 550; + text-decoration: none; +} +.xf-mobile-link:hover { + color: var(--xf-accent); + background: color-mix(in srgb, var(--xf-accent) 9%, transparent); +} +.xf-mobile-link.is-active { + color: var(--xf-text); + background: color-mix(in srgb, var(--xf-accent) 9%, transparent); +} +.xf-mobile-index { + font-family: var(--font-mono); + font-size: var(--xf-text-xs); + color: var(--xf-muted); +} + +/* ========================================================================== + HERO + ========================================================================== */ + +.xf-hero { + position: relative; + padding-block: clamp(7.5rem, 12vw, 10.5rem) clamp(3.5rem, 7vw, 6.5rem); + overflow: clip; +} +.xf-hero-grid { + display: grid; + grid-template-columns: minmax(0, 1.08fr) minmax(0, 1fr); + align-items: center; + gap: clamp(2rem, 5vw, 4rem); +} +.xf-hero-copy { + min-width: 0; +} +.xf-hero-banner { + display: block; + width: min(100%, 16rem); + height: auto; + margin-bottom: clamp(1.2rem, 2.4vw, 2rem); +} +.xf-hero-eyebrow { + display: flex; + flex-wrap: wrap; + align-items: center; + gap: 0.5rem; +} +.xf-hero-title { + margin: 0; + font-size: clamp(2.8rem, 5.4vw, 5.15rem); + font-weight: 650; + line-height: 0.98; + letter-spacing: -0.048em; + text-wrap: balance; +} +.xf-hero-title-accent { + color: var(--xf-accent); +} +.xf-hero-lead { + max-width: 52ch; + margin: clamp(1.2rem, 2.4vw, 1.7rem) 0 0; + color: var(--xf-muted); + font-size: clamp(1rem, 1.4vw, 1.15rem); + line-height: 1.65; +} +.xf-hero-actions { + display: flex; + flex-wrap: wrap; + gap: 0.65rem; + margin-top: clamp(1.5rem, 3vw, 2.1rem); +} +.xf-btn { + display: inline-flex; + align-items: center; + justify-content: center; + gap: 0.55rem; + min-height: 44px; + padding: 0.68rem 1.05rem; + border: 1px solid transparent; + border-radius: 11px; + font-family: var(--font-sans); + font-size: 0.86rem; + font-weight: 650; + line-height: 1.2; + text-decoration: none; + cursor: pointer; + transition: transform 0.16s ease, background 0.16s ease, border-color 0.16s ease, color 0.16s ease, box-shadow 0.16s ease; +} +.xf-btn--primary { + background: var(--xf-accent); + color: var(--xf-accent-ink); + box-shadow: 0 14px 34px -16px color-mix(in srgb, var(--xf-accent) 70%, transparent); +} +.xf-btn--primary:hover { + background: var(--xf-accent-strong); + transform: translateY(-1px); +} +.xf-btn--ghost { + border-color: var(--xf-line-strong); + background: color-mix(in srgb, var(--xf-surface) 74%, transparent); + color: var(--xf-text); +} +.xf-btn--ghost:hover { + border-color: color-mix(in srgb, var(--xf-accent) 45%, var(--xf-line)); + background: color-mix(in srgb, var(--xf-accent) 8%, var(--xf-surface)); + transform: translateY(-1px); +} + +.xf-facts { + display: flex; + flex-wrap: wrap; + gap: 0.4rem; + margin: clamp(1.4rem, 2.8vw, 2rem) 0 0; + padding: 0; + list-style: none; +} +.xf-facts li { + padding: 0.28rem 0.58rem; + border: 1px solid var(--xf-line); + border-radius: 999px; + background: color-mix(in srgb, var(--xf-surface) 66%, transparent); + color: var(--xf-muted); + font-family: var(--font-mono); + font-size: var(--xf-text-xs); + letter-spacing: 0.02em; + white-space: nowrap; +} + +/* hero visual */ + +.xf-hero-visual { + position: relative; + width: 100%; + max-width: 100%; + min-width: 0; + margin: 0; +} +.xf-visual-stage { + position: relative; + display: grid; + place-items: center; + width: 100%; + max-width: 100%; + min-width: 0; + aspect-ratio: 1 / 0.92; + min-height: 420px; + perspective: 1200px; +} +.xf-hero-plinth { + position: absolute; + left: 12%; + right: 12%; + bottom: 7%; + height: 46%; + border: 1px solid var(--xf-line); + border-radius: 26px; + background-image: + linear-gradient(to right, var(--xf-grid-line) 1px, transparent 1px), + linear-gradient(to bottom, var(--xf-grid-line) 1px, transparent 1px); + background-size: 34px 34px; + background-color: color-mix(in srgb, var(--xf-surface) 55%, transparent); + box-shadow: 0 50px 90px -40px rgba(0, 0, 0, 0.8); + transform: rotateX(64deg) rotateZ(-36deg); + opacity: 0.55; +} +.xf-hero-glow { + position: absolute; + width: 70%; + height: 55%; + border-radius: 50%; + background: radial-gradient(circle, color-mix(in srgb, var(--xf-cyan) 20%, transparent), transparent 68%); + filter: blur(36px); + opacity: 0.7; +} +.xf-iso { + position: relative; + width: 90%; + max-width: 520px; + transform-style: preserve-3d; + transform: rotateX(calc(9deg + var(--rx, 0deg))) rotateY(calc(-14deg + var(--ry, 0deg))); + transition: transform 0.18s ease-out; +} +.xf-slab { + position: absolute; + inset: 0; + border: 1px solid var(--xf-line); + border-radius: var(--xf-radius); + background: var(--xf-surface); + box-shadow: 0 30px 70px -40px rgba(0, 0, 0, 0.8); + overflow: hidden; +} +.xf-slab--back { + transform: translate3d(-28px, 38px, -95px) scale(0.91); + opacity: 0.42; +} +.xf-slab--mid { + transform: translate3d(-14px, 19px, -46px) scale(0.955); + opacity: 0.66; +} +.xf-slab-logo { + padding: 1.2rem; + color: var(--xf-muted); + font-family: var(--font-mono); + font-size: 0.62rem; + line-height: 1.05; + white-space: pre; +} +.xf-slab-rows { + display: grid; + gap: 0.32rem; + padding: 1.2rem; + color: var(--xf-muted); + font-family: var(--font-mono); + font-size: 0.6rem; +} +.xf-slab-rows i { + color: var(--xf-cyan); + font-style: normal; +} +.xf-term { + position: relative; + z-index: 2; + display: flex; + flex-direction: column; + overflow: hidden; + border: 1px solid rgba(255, 255, 255, 0.14); + border-radius: var(--xf-radius); + background: linear-gradient(180deg, var(--xf-code-bg-2), var(--xf-code-bg)); + box-shadow: + 0 50px 110px -46px rgba(0, 0, 0, 0.92), + inset 0 1px 0 rgba(255, 255, 255, 0.07); + transform: translateZ(34px); +} +.xf-term-chrome { + display: flex; + align-items: center; + gap: 0.38rem; + padding: 0.58rem 0.75rem; + border-bottom: 1px solid rgba(148, 163, 184, 0.16); + background: var(--xf-code-bg-2); +} +.xf-term-dot { + width: 8px; + height: 8px; + border-radius: 50%; + flex: none; +} +.xf-term-dot.is-red { background: #ff5f56; } +.xf-term-dot.is-amber { background: #ffbd2e; } +.xf-term-dot.is-green { background: #27c93f; } +.xf-term-title { + margin-left: 0.35rem; + color: var(--xf-code-muted); + font-family: var(--font-mono); + font-size: 0.6rem; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} +.xf-term-badge { + margin-left: auto; + padding: 0.1rem 0.4rem; + border: 1px solid rgba(148, 163, 184, 0.22); + border-radius: 999px; + color: var(--xf-code-muted); + font-family: var(--font-mono); + font-size: 0.55rem; + white-space: nowrap; +} +.xf-term-body { + display: grid; + grid-template-columns: auto minmax(0, 1fr); + gap: 1.15rem; + padding: 1rem 1.05rem; +} +.xf-term-logo { + margin: 0; + color: var(--xf-code-accent); + font-family: var(--font-mono); + font-size: clamp(0.46rem, 0.72vw, 0.62rem); + line-height: 1.08; + white-space: pre; + opacity: 0.95; +} +.xf-term-rows { + display: grid; + align-content: start; + gap: 0.3rem; + min-width: 0; +} +.xf-term-row { + display: flex; + gap: 0.5rem; + margin: 0; + font-family: var(--font-mono); + font-size: clamp(0.5rem, 0.78vw, 0.66rem); + line-height: 1.35; + white-space: nowrap; +} +.xf-term-key { + flex: none; + width: 4.1em; + color: var(--xf-code-key); +} +.xf-term-value { + color: var(--xf-code-text); + overflow: hidden; + text-overflow: ellipsis; +} +.xf-term-palette { + display: flex; + gap: 0.18rem; + margin: 0.28rem 0 0; +} +.xf-term-palette span { + width: 8px; + height: 8px; + border-radius: 2px; +} +.xf-term-foot { + display: flex; + align-items: center; + gap: 0.35rem; + padding: 0.52rem 0.85rem 0.6rem; + border-top: 1px solid rgba(148, 163, 184, 0.16); + color: var(--xf-code-muted); + font-family: var(--font-mono); + font-size: 0.6rem; +} +.xf-term-prompt { + color: var(--xf-code-success); +} +.xf-term-cursor, +.xf-terminal-cursor { + display: inline-block; + width: 6px; + height: 0.9em; + background: var(--xf-code-success); + animation: xf-blink 1.1s step-end infinite; +} +.xf-term-cursor { + margin-left: 0.15rem; +} +@keyframes xf-blink { + 50% { opacity: 0; } +} + +.xf-chip { + position: absolute; + z-index: 3; + display: inline-flex; + align-items: baseline; + gap: 0.3rem; + padding: 0.34rem 0.55rem; + border: 1px solid var(--xf-control-border); + border-radius: 999px; + background: color-mix(in srgb, var(--xf-surface-2) 92%, transparent); + box-shadow: 0 16px 34px -20px rgba(0, 0, 0, 0.75); + color: var(--xf-muted); + font-family: var(--font-mono); + font-size: var(--xf-text-xs); + line-height: 1; + white-space: nowrap; + transform: translateZ(80px); +} +.xf-chip strong { + color: var(--xf-accent); + font-weight: 700; +} +.xf-chip--tl { top: 4%; left: -4%; } +.xf-chip--tr { top: 13%; right: -5%; } +.xf-chip--bl { bottom: 14%; left: -7%; } +.xf-chip--br { bottom: 3%; right: 1%; } +.xf-chip--tl { animation: xf-chip-a 7s ease-in-out infinite alternate; } +.xf-chip--tr { animation: xf-chip-b 8s ease-in-out infinite alternate; } +.xf-chip--bl { animation: xf-chip-b 7.5s ease-in-out infinite alternate-reverse; } +.xf-chip--br { animation: xf-chip-a 8.5s ease-in-out infinite alternate-reverse; } +@keyframes xf-chip-a { + from { transform: translate3d(0, 0, 80px); } + to { transform: translate3d(0, -7px, 80px); } +} +@keyframes xf-chip-b { + from { transform: translate3d(0, 0, 80px); } + to { transform: translate3d(0, 6px, 80px); } +} + +/* ========================================================================== + SECTION SCAFFOLD + ========================================================================== */ + +.xf-section { + position: relative; + padding-block: clamp(3.4rem, 7vw, 6.8rem); + border-top: 1px solid var(--xf-line); +} +.xf-sec-head { + max-width: 74ch; + margin-bottom: clamp(1.8rem, 3.6vw, 2.8rem); +} +.xf-sec-head h2 { + margin: 0; + font-size: clamp(1.9rem, 3.4vw, 2.85rem); + font-weight: 650; + line-height: 1.08; + letter-spacing: -0.035em; + text-wrap: balance; +} +.xf-sec-lead { + max-width: 68ch; + margin: 0.9rem 0 0; + color: var(--xf-muted); + font-size: clamp(0.94rem, 1.2vw, 1.04rem); + line-height: 1.7; +} + +/* ---------- code blocks ---------- */ + +.xf-code { + overflow: hidden; + border: 1px solid var(--xf-line); + border-radius: var(--xf-radius-sm); + background: var(--xf-code-bg); + color: var(--xf-code-text); +} +.xf-code-head { + display: flex; + align-items: center; + justify-content: space-between; + gap: 0.7rem; + padding: 0.5rem 0.7rem 0.5rem 0.9rem; + border-bottom: 1px solid rgba(148, 163, 184, 0.16); + background: var(--xf-code-bg-2); +} +.xf-code-label { + overflow: hidden; + color: var(--xf-code-muted); + font-family: var(--font-mono); + font-size: var(--xf-text-xs); + font-weight: 600; + letter-spacing: 0.13em; + text-overflow: ellipsis; + text-transform: uppercase; + white-space: nowrap; +} +.xf-copy { + display: inline-flex; + align-items: center; + gap: 0.3rem; + flex: none; + min-height: 26px; + padding: 0.28rem 0.5rem; + border: 1px solid rgba(148, 163, 184, 0.3); + border-radius: 7px; + background: rgba(255, 255, 255, 0.03); + color: var(--xf-code-muted); + font-family: var(--font-mono); + font-size: var(--xf-text-xs); + font-weight: 600; + cursor: pointer; + transition: color 0.15s ease, border-color 0.15s ease, background 0.15s ease; +} +.xf-copy:hover { + color: var(--xf-code-accent); + border-color: color-mix(in srgb, var(--xf-code-accent) 50%, transparent); + background: color-mix(in srgb, var(--xf-code-accent) 8%, transparent); +} +.xf-code-pre { + margin: 0; + padding: 0.95rem 1.05rem; + overflow-x: auto; + color: var(--xf-code-text); + font-family: var(--font-mono); + font-size: 0.78rem; + line-height: 1.7; + white-space: pre-wrap; + overflow-wrap: anywhere; + tab-size: 2; +} +.xf-code-comment { + color: var(--xf-code-muted); +} +.xf-code-prompt { + color: var(--xf-code-success); +} + +/* ========================================================================== + INSTALL + ========================================================================== */ + +.xf-install { + display: grid; + gap: 0.85rem; +} +.xf-tabs { + display: flex; + flex-wrap: wrap; + gap: 0.35rem; +} +.xf-tab { + display: inline-flex; + align-items: center; + min-height: 30px; + padding: 0.48rem 0.78rem; + border: 1px solid var(--xf-control-border); + border-radius: 999px; + background: color-mix(in srgb, var(--xf-surface) 78%, transparent); + color: var(--xf-muted); + font-family: var(--font-mono); + font-size: var(--xf-text-xs); + font-weight: 600; + cursor: pointer; + transition: color 0.15s ease, border-color 0.15s ease, background 0.15s ease; +} +.xf-tab:hover { + color: var(--xf-text); + border-color: var(--xf-line-strong); +} +.xf-tab.is-active { + color: var(--xf-text); + border-color: color-mix(in srgb, var(--xf-accent) 48%, var(--xf-line)); + background: color-mix(in srgb, var(--xf-accent) 10%, transparent); +} +.xf-install-after { + max-width: 680px; + margin-top: 0.5rem; +} +.xf-install-after .xf-mini-label { + margin-bottom: 0.5rem; +} + +/* ========================================================================== + DEMO GALLERY + ========================================================================== */ + +.xf-gallery { + display: grid; + gap: var(--xf-space-4); +} +.xf-gallery-bar { + display: flex; + flex-wrap: wrap; + align-items: center; + justify-content: space-between; + gap: var(--xf-space-3); +} +.xf-gallery-link { + display: inline-flex; + align-items: center; + gap: 0.4rem; + min-height: 24px; + color: var(--xf-accent); + font-family: var(--font-mono); + font-size: var(--xf-text-xs); + font-weight: 600; + text-decoration: none; +} +.xf-gallery-link:hover { + color: var(--xf-text); + text-decoration: underline; +} +.xf-gallery-panel { + min-width: 0; +} +.xf-gallery-grid { + display: grid; + grid-template-columns: repeat(2, minmax(0, 1fr)); + gap: var(--xf-space-3); + margin: 0; + padding: 0; + list-style: none; +} +.xf-gallery-item { + min-width: 0; +} +.xf-gallery-item:last-child:nth-child(odd) { + grid-column: 1 / -1; +} +.xf-gallery-item figure { + display: grid; + gap: 0.5rem; + height: 100%; + margin: 0; + padding: 0.55rem; + border: 1px solid var(--xf-line); + border-radius: var(--xf-radius-sm); + background: color-mix(in srgb, var(--xf-surface) 80%, transparent); + box-shadow: var(--xf-shadow-soft); +} +.xf-gallery-media { + position: relative; + aspect-ratio: 16 / 10; + overflow: hidden; + border: 1px solid var(--xf-line); + border-radius: 9px; + background: #05070c; +} +.xf-gallery-media img { + display: block; + width: 100%; + height: 100%; + object-fit: contain; +} +.xf-gallery-item figcaption { + color: var(--xf-muted); + font-size: var(--xf-text-xs); + line-height: 1.55; +} + +/* ========================================================================== + FEATURES — bento + ========================================================================== */ + +.xf-features { + display: grid; + grid-template-columns: repeat(6, minmax(0, 1fr)); + gap: 0.8rem; +} +.xf-feature { + position: relative; + grid-column: span 2; + display: flex; + flex-direction: column; + min-height: 11.5rem; + padding: 1.15rem 1.15rem 1.25rem; + overflow: hidden; + border: 1px solid var(--xf-line); + border-radius: var(--xf-radius); + background: + linear-gradient(150deg, color-mix(in srgb, var(--xf-surface-2) 74%, transparent), var(--xf-surface)); + transition: transform 0.18s ease, border-color 0.18s ease, background 0.18s ease; +} +.xf-feature:nth-child(1) { + grid-column: span 4; +} +.xf-feature:nth-child(6), +.xf-feature:nth-child(7), +.xf-feature:nth-child(8), +.xf-feature:nth-child(9) { + grid-column: span 3; +} +.xf-feature::before { + content: ""; + position: absolute; + inset: 0 0 auto; + height: 1px; + background: linear-gradient(90deg, transparent, color-mix(in srgb, var(--xf-accent) 70%, transparent), transparent); + opacity: 0; + transition: opacity 0.18s ease; +} +.xf-feature:hover { + transform: translateY(-3px); + border-color: color-mix(in srgb, var(--xf-accent) 36%, var(--xf-line)); +} +.xf-feature:hover::before { + opacity: 1; +} +.xf-feature-top { + display: flex; + align-items: flex-start; + justify-content: space-between; + gap: 0.7rem; + margin-bottom: 0.9rem; +} +.xf-feature-icon { + display: grid; + place-items: center; + width: 38px; + height: 38px; + border: 1px solid color-mix(in srgb, var(--xf-accent) 32%, var(--xf-line)); + border-radius: 10px; + background: color-mix(in srgb, var(--xf-accent) 9%, transparent); + color: var(--xf-accent); +} +.xf-feature-num { + color: color-mix(in srgb, var(--xf-muted) 62%, transparent); + font-family: var(--font-mono); + font-size: 0.62rem; + letter-spacing: 0.08em; +} +.xf-feature h3 { + margin: 0 0 0.4rem; + font-size: 0.98rem; + font-weight: 650; + line-height: 1.3; + letter-spacing: -0.01em; +} +.xf-feature p { + margin: 0; + color: var(--xf-muted); + font-size: 0.8rem; + line-height: 1.62; +} +.xf-feature-stats { + display: flex; + flex-wrap: wrap; + gap: var(--xf-space-4); + margin: auto 0 0; + padding: var(--xf-space-4) 0 0; + border-top: 1px solid var(--xf-line); + list-style: none; +} +.xf-feature-stats li { + display: grid; + gap: 0.05rem; +} +.xf-feature-stats strong { + color: var(--xf-accent); + font-family: var(--font-mono); + font-size: 1.05rem; + font-weight: 700; + line-height: 1; +} +.xf-feature-stats span { + color: var(--xf-muted); + font-family: var(--font-mono); + font-size: var(--xf-text-xs); + text-transform: uppercase; + letter-spacing: 0.06em; +} + +/* ========================================================================== + TERMINAL DEMO + ========================================================================== */ + +.xf-split { + display: grid; + grid-template-columns: minmax(0, 0.82fr) minmax(0, 1.18fr); + align-items: center; + gap: clamp(1.5rem, 4vw, 3.2rem); +} +.xf-terminal-copy .xf-sec-head { + margin-bottom: 1.5rem; +} +.xf-terminal-actions { + display: flex; + flex-wrap: wrap; + align-items: center; + gap: 0.8rem; +} +.xf-term-window { + overflow: hidden; + border: 1px solid var(--xf-line-strong); + border-radius: 16px; + background: var(--xf-code-bg); + box-shadow: var(--xf-shadow); +} +.xf-terminal-scroll { + height: 33rem; + overflow: auto; + overscroll-behavior: contain; + scrollbar-width: thin; + scrollbar-color: rgba(148, 163, 184, 0.3) transparent; +} +.xf-terminal-scroll:focus-visible { + outline: 2px solid var(--xf-accent); + outline-offset: -2px; +} +.xf-terminal-pre { + min-height: 100%; + margin: 0; + padding: 0.95rem 1.1rem 1.3rem; + color: var(--xf-code-text); + font-family: var(--font-mono); + font-size: 0.74rem; + line-height: 1.68; + white-space: pre; +} +.xf-line-empty { + display: block; + height: 1.68em; +} +.xf-line-prompt { + display: block; + color: var(--xf-code-success); +} +.xf-line-prompt span { + margin-right: 0.15rem; +} +.xf-line-dim { + display: block; + color: var(--xf-code-muted); + font-size: 0.68rem; +} +.xf-line-info { + display: flex; + flex-wrap: wrap; + gap: 0.5rem; +} +.xf-line-key { + min-width: 6.2rem; + color: var(--xf-code-key); +} +.xf-line-palette { + display: block; + letter-spacing: 0.02em; + white-space: nowrap; +} +.xf-terminal-cursor { + margin-left: 0.3rem; + vertical-align: -0.08em; +} + +/* ========================================================================== + SYSTEM MAP + ========================================================================== */ + +.xf-map-grid { + display: grid; + grid-template-columns: minmax(0, 1.32fr) minmax(0, 1fr); + align-items: start; + gap: clamp(1.2rem, 3vw, 2.2rem); +} +.xf-map-figure { + margin: 0; +} +.xf-map-canvas { + position: relative; + overflow: hidden; + border: 1px solid var(--xf-line); + border-radius: var(--xf-radius-lg); + background: + radial-gradient(ellipse at 30% 20%, color-mix(in srgb, var(--xf-cyan) 7%, transparent), transparent 55%), + linear-gradient(160deg, color-mix(in srgb, var(--xf-surface-2) 55%, transparent), var(--xf-surface)); + aspect-ratio: 800 / 620; +} +.xf-map-svg { + display: block; + width: 100%; + height: 100%; +} +.xf-map-connectors path { + fill: none; + stroke: var(--xf-cyan); + stroke-width: 1.2; + stroke-dasharray: 4 7; + opacity: 0.55; +} +.xf-map-top { + stroke: var(--xf-line-strong); + stroke-width: 1; +} +.xf-map-side { + stroke: var(--xf-line); + stroke-width: 1; +} +.xf-map-stop-top-a { stop-color: var(--xf-surface-2); } +.xf-map-stop-top-b { stop-color: color-mix(in srgb, var(--xf-surface-2) 72%, var(--xf-cyan)); } +.xf-map-stop-side-a { stop-color: color-mix(in srgb, var(--xf-surface) 82%, #000); } +.xf-map-stop-side-b { stop-color: var(--xf-surface); } +.xf-map-num { + fill: var(--xf-accent); + font-family: var(--font-mono); + font-size: 12px; + font-weight: 700; +} +.xf-map-name { + fill: var(--xf-text); + font-family: var(--font-sans); + font-size: 16px; + font-weight: 650; +} +.xf-map-sub { + fill: var(--xf-muted); + font-family: var(--font-mono); + font-size: 11px; +} +.xf-map-plane-face { + stroke: color-mix(in srgb, var(--xf-violet) 55%, transparent); + stroke-width: 1.2; + stroke-dasharray: 5 5; +} +.xf-map-plane-edge { + fill: none; + stroke: color-mix(in srgb, var(--xf-violet) 42%, transparent); + stroke-width: 1.2; +} +.xf-map-plane-title { + fill: var(--xf-violet); + font-family: var(--font-mono); + font-size: 16px; + font-weight: 700; + letter-spacing: 0.04em; +} +.xf-map-plane-sub { + fill: var(--xf-muted); + font-family: var(--font-mono); + font-size: 11px; + letter-spacing: 0.1em; + text-transform: uppercase; +} +.xf-map-node { + fill: var(--xf-cyan); +} +.xf-map-node-label { + fill: var(--xf-muted); + font-family: var(--font-mono); + font-size: 11px; +} +.xf-map-hotspot { + position: absolute; + z-index: 2; + border: 1px solid transparent; + border-radius: 12px; + background: transparent; + cursor: pointer; + transition: border-color 0.16s ease, background 0.16s ease; +} +.xf-map-hotspot > span { + position: absolute; + top: 0.3rem; + right: 0.4rem; + color: var(--xf-accent); + font-family: var(--font-mono); + font-size: 0.55rem; + opacity: 0; + transition: opacity 0.16s ease; +} +.xf-map-hotspot:hover, +.xf-map-hotspot:focus-visible, +.xf-map-hotspot.is-active { + border-color: color-mix(in srgb, var(--xf-accent) 55%, transparent); + background: color-mix(in srgb, var(--xf-accent) 7%, transparent); +} +.xf-map-hotspot:hover > span, +.xf-map-hotspot:focus-visible > span, +.xf-map-hotspot.is-active > span { + opacity: 1; +} +.xf-map-figure figcaption { + padding: 0.7rem 0.2rem 0; + color: var(--xf-muted); + font-family: var(--font-mono); + font-size: var(--xf-text-xs); + line-height: 1.6; +} + +.xf-map-mobile-stack { + display: none; + gap: 0.4rem; + margin-top: var(--xf-space-3); +} +.xf-map-mobile-layer { + display: flex; + align-items: center; + gap: var(--xf-space-3); + width: 100%; + min-height: 52px; + padding: 0.65rem 0.75rem; + border: 1px solid var(--xf-control-border); + border-radius: 11px; + background: color-mix(in srgb, var(--xf-surface) 78%, transparent); + color: var(--xf-text); + text-align: left; + cursor: pointer; +} +.xf-map-mobile-layer:hover, +.xf-map-mobile-layer.is-active { + border-color: color-mix(in srgb, var(--xf-accent) 55%, var(--xf-line)); + background: color-mix(in srgb, var(--xf-accent) 8%, var(--xf-surface)); +} +.xf-map-mobile-num { + color: var(--xf-accent); + font-family: var(--font-mono); + font-size: var(--xf-text-xs); + font-weight: 700; +} +.xf-map-mobile-text { + display: grid; + gap: 0.1rem; +} +.xf-map-mobile-text strong { + font-size: 0.88rem; + font-weight: 650; +} +.xf-map-mobile-text small { + color: var(--xf-muted); + font-family: var(--font-mono); + font-size: var(--xf-text-xs); +} +.xf-map-side { + display: grid; + gap: 0.85rem; +} +.xf-map-tabs { + display: grid; + gap: 0.22rem; +} +.xf-map-tab { + display: flex; + align-items: center; + gap: 0.65rem; + padding: 0.55rem 0.7rem; + border: 1px solid transparent; + border-radius: 9px; + background: transparent; + color: var(--xf-muted); + font-family: var(--font-sans); + font-size: 0.8rem; + font-weight: 600; + text-align: left; + cursor: pointer; + transition: color 0.15s ease, background 0.15s ease, border-color 0.15s ease; +} +.xf-map-tab:hover { + color: var(--xf-text); + background: color-mix(in srgb, var(--xf-surface-2) 60%, transparent); +} +.xf-map-tab.is-active { + color: var(--xf-text); + border-color: var(--xf-line); + background: color-mix(in srgb, var(--xf-surface-2) 78%, transparent); +} +.xf-map-tab-num { + color: var(--xf-accent); + font-family: var(--font-mono); + font-size: var(--xf-text-xs); +} +.xf-map-detail { + min-height: 15rem; + padding: 1.1rem 1.15rem; + border-radius: 15px; +} +.xf-map-detail .xf-eyebrow { + margin-bottom: 0.4rem; +} +.xf-map-detail h3 { + margin: 0 0 0.55rem; + font-size: 1.1rem; + font-weight: 650; + letter-spacing: -0.01em; +} +.xf-map-detail p { + margin: 0; + color: var(--xf-muted); + font-size: 0.82rem; + line-height: 1.65; +} +.xf-tag-list { + display: flex; + flex-wrap: wrap; + gap: 0.3rem; + margin: 0.85rem 0 0; + padding: 0; + list-style: none; +} +.xf-tag-list li { + padding: 0.16rem 0.46rem; + border: 1px solid var(--xf-line); + border-radius: 999px; + color: var(--xf-muted); + font-family: var(--font-mono); + font-size: var(--xf-text-xs); + line-height: 1.5; +} + +/* ========================================================================== + MODULE EXPLORER + ========================================================================== */ + +.xf-explorer { + display: grid; + grid-template-columns: minmax(0, 1fr) minmax(0, 1.35fr) auto; + align-items: end; + gap: 0.9rem; + margin-bottom: 1.2rem; +} +.xf-explorer-search { + min-width: 0; +} +.xf-explorer-search .xf-mini-label { + display: block; + margin-bottom: 0.42rem; +} +.xf-input-wrap { + display: flex; + align-items: center; + gap: 0.55rem; + padding: 0.55rem 0.65rem; + border: 1px solid var(--xf-control-border); + border-radius: 11px; + background: color-mix(in srgb, var(--xf-surface) 82%, transparent); + color: var(--xf-muted); + transition: border-color 0.15s ease, box-shadow 0.15s ease; +} +.xf-input-wrap:focus-within { + border-color: color-mix(in srgb, var(--xf-accent) 52%, var(--xf-line)); + box-shadow: 0 0 0 3px color-mix(in srgb, var(--xf-accent) 12%, transparent); +} +.xf-input-wrap > svg { + flex: none; + color: var(--xf-accent); +} +.xf-input-wrap input { + flex: 1; + min-width: 0; + border: 0; + background: none; + color: var(--xf-text); + font-family: var(--font-mono); + font-size: 0.78rem; + outline: none; +} +.xf-input-wrap input::placeholder { + color: var(--xf-muted); + opacity: 1; +} +.xf-input-wrap input[type="search"]::-webkit-search-cancel-button, +.xf-input-wrap input[type="search"]::-webkit-search-decoration { + -webkit-appearance: none; + appearance: none; + display: none; +} +.xf-input-clear { + display: inline-grid; + place-items: center; + flex: none; + width: 24px; + height: 24px; + padding: 0; + border: 0; + border-radius: 6px; + background: transparent; + color: var(--xf-muted); + cursor: pointer; +} +.xf-input-clear:hover { + color: var(--xf-accent); + background: color-mix(in srgb, var(--xf-accent) 10%, transparent); +} +.xf-filter-col .xf-mini-label { + display: block; + margin-bottom: 0.42rem; +} +.xf-chips { + display: flex; + flex-wrap: wrap; + gap: 0.28rem; +} +.xf-chip-btn { + display: inline-flex; + align-items: center; + min-height: 26px; + padding: 0.35rem 0.55rem; + border: 1px solid var(--xf-control-border); + border-radius: 999px; + background: transparent; + color: var(--xf-muted); + font-family: var(--font-mono); + font-size: var(--xf-text-xs); + font-weight: 600; + cursor: pointer; + transition: color 0.15s ease, border-color 0.15s ease, background 0.15s ease; +} +.xf-chip-btn:hover { + color: var(--xf-text); + border-color: var(--xf-line-strong); +} +.xf-chip-btn.is-active { + color: var(--xf-text); + border-color: color-mix(in srgb, var(--xf-accent) 48%, var(--xf-line)); + background: color-mix(in srgb, var(--xf-accent) 10%, transparent); +} +.xf-count { + margin: 0; + padding-bottom: 0.55rem; + color: var(--xf-muted); + font-family: var(--font-mono); + font-size: var(--xf-text-xs); + white-space: nowrap; +} +.xf-count strong { + color: var(--xf-accent); + font-weight: 700; +} + +.xf-module-grid { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(15.5rem, 1fr)); + gap: 0.6rem; + margin: 0; + padding: 0; + list-style: none; +} +.xf-module { + display: flex; + gap: 0.7rem; + padding: 0.8rem 0.85rem; + border: 1px solid var(--xf-line); + border-radius: 12px; + background: color-mix(in srgb, var(--xf-surface) 78%, transparent); + transition: border-color 0.15s ease, background 0.15s ease; +} +.xf-module:hover { + border-color: color-mix(in srgb, var(--xf-accent) 34%, var(--xf-line)); + background: var(--xf-surface); +} +.xf-module-icon { + display: grid; + place-items: center; + flex: none; + width: 30px; + height: 30px; + border: 1px solid var(--xf-line); + border-radius: 8px; + background: color-mix(in srgb, var(--xf-surface-2) 68%, transparent); + color: var(--xf-accent); +} +.xf-module-body { + min-width: 0; +} +.xf-module-head { + display: flex; + align-items: baseline; + justify-content: space-between; + gap: 0.5rem; +} +.xf-module-head h3 { + margin: 0; + min-width: 0; +} +.xf-module-head code { + color: var(--xf-accent); + font-family: var(--font-mono); + font-size: 0.78rem; + font-weight: 700; +} +.xf-module-cat { + flex: none; + color: var(--xf-muted); + font-family: var(--font-mono); + font-size: var(--xf-text-xs); + letter-spacing: 0.08em; + text-transform: uppercase; +} +.xf-module p { + margin: 0.18rem 0 0; + color: var(--xf-muted); + font-size: 0.74rem; + line-height: 1.5; +} +.xf-empty { + display: grid; + justify-items: start; + gap: 0.8rem; + margin-top: 1rem; + padding: 1.4rem; + border: 1px dashed var(--xf-line-strong); + border-radius: 14px; + color: var(--xf-muted); +} +.xf-empty p { + margin: 0; + font-size: 0.85rem; +} + +/* ========================================================================== + LAYOUT EXPLORER + ========================================================================== */ + +.xf-layout-grid { + display: grid; + grid-template-columns: minmax(0, 0.86fr) minmax(0, 1.14fr); + align-items: start; + gap: 1.1rem; +} +.xf-layout-tabs { + display: grid; + gap: 0.25rem; +} +.xf-layout-tab { + display: flex; + align-items: flex-start; + gap: 0.7rem; + width: 100%; + padding: 0.7rem 0.8rem; + border: 1px solid transparent; + border-radius: 11px; + background: transparent; + color: var(--xf-muted); + text-align: left; + cursor: pointer; + transition: color 0.15s ease, background 0.15s ease, border-color 0.15s ease; +} +.xf-layout-tab:hover { + color: var(--xf-text); + background: color-mix(in srgb, var(--xf-surface-2) 58%, transparent); +} +.xf-layout-tab.is-active { + border-color: color-mix(in srgb, var(--xf-accent) 38%, var(--xf-line)); + background: color-mix(in srgb, var(--xf-accent) 7%, var(--xf-surface)); +} +.xf-layout-tab-num { + flex: none; + padding-top: 0.08rem; + color: var(--xf-accent); + font-family: var(--font-mono); + font-size: var(--xf-text-xs); +} +.xf-layout-tab-body { + display: grid; + gap: 0.15rem; + min-width: 0; +} +.xf-layout-tab-title { + color: var(--xf-text); + font-size: 0.82rem; + font-weight: 650; + line-height: 1.3; +} +.xf-layout-tab-desc { + color: var(--xf-muted); + font-size: var(--xf-text-xs); + line-height: 1.5; +} +.xf-layout-panel { + padding: 0.8rem; + border: 1px solid var(--xf-line); + border-radius: 16px; + background: var(--xf-surface); +} +.xf-layout-preview-wrap { + position: relative; + overflow: hidden; + border: 1px solid var(--xf-line); + border-radius: 11px; + background: var(--xf-code-bg); +} +.xf-layout-preview-label { + position: absolute; + right: 0.55rem; + bottom: 0.45rem; + color: var(--xf-code-muted); + font-family: var(--font-mono); + font-size: var(--xf-text-xs); +} +.xf-layout-code { + margin-top: 0.7rem; +} +.xf-layout-note { + margin: 0.65rem 0 0; + color: var(--xf-muted); + font-family: var(--font-mono); + font-size: var(--xf-text-xs); + line-height: 1.6; +} +.xf-layout-note code { + color: var(--xf-accent); +} + +/* layout skeletons */ + +.xf-lp { + display: grid; + align-content: center; + min-height: 13.5rem; + padding: 1.1rem; + color: var(--xf-code-text); + font-family: var(--font-mono); + font-size: clamp(0.5rem, 0.82vw, 0.64rem); + line-height: 1.55; +} +.xf-lp span { + display: block; +} +.xf-lp i { + display: inline-block; + min-width: 3.3em; + color: var(--xf-code-key); + font-style: normal; +} +.xf-lp b { + color: var(--xf-code-text); + font-weight: 400; +} +.xf-lp--default { + grid-template-columns: auto minmax(0, 1fr); + gap: 1rem; + align-items: center; +} +.xf-lp-logo { + color: var(--xf-code-accent); + line-height: 1.08; + white-space: pre; +} +.xf-lp-logo--small { + font-size: 0.92em; +} +.xf-lp-rows { + display: grid; + gap: 0.24rem; +} +.xf-lp-rows span { + display: flex; + gap: 0.5rem; +} +.xf-lp-rows i { + min-width: 3em; +} +.xf-lp--pacman { + gap: 0.55rem; +} +.xf-lp-pacman { + border: 1px solid var(--xf-code-key); + border-radius: 4px; + padding: 0.6rem; +} +.xf-lp-pac-head { + color: var(--xf-code-accent); + text-align: center; + letter-spacing: 0.1em; +} +.xf-lp-pac-body { + display: grid; + grid-template-columns: auto minmax(0, 1fr); + gap: 0.8rem; + padding: 0.55rem 0; +} +.xf-lp-pac-foot { + color: var(--xf-code-key); + letter-spacing: 0.1em; + text-align: center; +} +.xf-lp--section .xf-lp-section { + display: grid; + gap: 0.26rem; +} +.xf-lp-sec-title { + color: var(--xf-code-accent); + letter-spacing: 0.04em; +} +.xf-lp--side-block .xf-lp-side { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 0.55rem; +} +.xf-lp-side-col { + display: grid; + gap: 0.24rem; + padding: 0.55rem; + border: 1px solid var(--xf-code-muted); + border-radius: 4px; +} +.xf-lp-side-col.is-values span { + color: var(--xf-code-text); +} +.xf-lp--tree .xf-lp-tree { + display: grid; + gap: 0.15rem; +} +.xf-lp-tree b { + color: var(--xf-code-accent); +} +.xf-lp-tree i { + color: var(--xf-code-key); + min-width: 0; +} +.xf-lp--box .xf-lp-box { + padding: 0.5rem; + border: 2px solid var(--xf-code-key); + border-radius: 8px; +} +.xf-lp-box-inner { + display: grid; + gap: 0.24rem; + padding: 0.6rem; + border: 1px solid var(--xf-code-muted); + border-radius: 4px; +} + +/* ========================================================================== + CONFIG BUILDER + ========================================================================== */ + +.xf-config-grid { + display: grid; + grid-template-columns: minmax(0, 0.95fr) minmax(0, 1.05fr); + align-items: start; + gap: 1.2rem; +} +.xf-config-controls { + display: grid; + gap: 0.90rem; +} +.xf-fieldset { + margin: 0; + padding: 0.9rem 1rem 1rem; + border: 1px solid var(--xf-line); + border-radius: 15px; + background: color-mix(in srgb, var(--xf-surface) 72%, transparent); +} +.xf-fieldset legend { + display: flex; + flex-wrap: wrap; + align-items: baseline; + gap: 0.5rem; + padding: 0 0.35rem; + color: var(--xf-text); + font-size: 0.8rem; + font-weight: 650; +} +.xf-fieldset-count { + color: var(--xf-muted); + font-family: var(--font-mono); + font-size: var(--xf-text-xs); + font-weight: 400; +} +.xf-config-actions { + display: flex; + flex-wrap: wrap; + gap: 0.65rem; + margin-bottom: 0.55rem; +} +.xf-link-btn { + display: inline-flex; + align-items: center; + min-height: 24px; + padding: 0.1rem 0.15rem; + border: 0; + background: none; + color: var(--xf-accent); + font-family: var(--font-mono); + font-size: var(--xf-text-xs); + font-weight: 600; + letter-spacing: 0.04em; + cursor: pointer; +} +.xf-link-btn:hover { + text-decoration: underline; +} +.xf-config-modules { + display: grid; + grid-template-columns: repeat(2, minmax(0, 1fr)); + gap: 0.12rem 0.4rem; +} +.xf-check { + position: relative; + display: flex; + align-items: center; + gap: 0.42rem; + min-height: 26px; + padding: 0.28rem 0.35rem; + border-radius: 7px; + cursor: pointer; + transition: background 0.14s ease; +} +.xf-check:hover { + background: color-mix(in srgb, var(--xf-surface-2) 68%, transparent); +} +.xf-check input { + position: absolute; + width: 1px; + height: 1px; + opacity: 0; +} +.xf-check-box { + display: grid; + place-items: center; + flex: none; + width: 15px; + height: 15px; + border: 1px solid var(--xf-control-border); + border-radius: 4px; + background: var(--xf-surface-2); + color: var(--xf-accent-ink); + transition: background 0.14s ease, border-color 0.14s ease; +} +.xf-check-box svg { + opacity: 0; + transition: opacity 0.12s ease; +} +.xf-check input:checked + .xf-check-box { + border-color: var(--xf-accent); + background: var(--xf-accent); +} +.xf-check input:checked + .xf-check-box svg { + opacity: 1; +} +.xf-check input:focus-visible + .xf-check-box { + outline: 2px solid var(--xf-accent); + outline-offset: 3px; +} +.xf-check-icon { + display: inline-flex; + flex: none; + color: var(--xf-accent); +} +.xf-check code { + overflow: hidden; + color: var(--xf-text); + font-family: var(--font-mono); + font-size: 0.7rem; + text-overflow: ellipsis; +} +.xf-select-field .xf-mini-label { + display: block; + margin-bottom: 0.42rem; +} +.xf-select-field select { + width: 100%; + padding: 0.6rem 0.7rem; + border: 1px solid var(--xf-control-border); + border-radius: 10px; + background: color-mix(in srgb, var(--xf-surface) 82%, transparent); + color: var(--xf-text); + font-family: var(--font-mono); + font-size: 0.78rem; + cursor: pointer; +} +.xf-select-field select:hover { + border-color: var(--xf-line-strong); +} +.xf-config-output { + display: grid; + gap: 0.7rem; +} +.xf-config-code .xf-code-pre { + min-height: 18rem; +} +.xf-config-hint { + margin: 0.15rem 0 0; + color: var(--xf-muted); + font-size: 0.78rem; +} + +/* ========================================================================== + PLUGINS + SANDBOX + ========================================================================== */ + +.xf-plugin-grid { + display: grid; + grid-template-columns: minmax(0, 1.08fr) minmax(0, 0.92fr); + align-items: start; + gap: clamp(1.2rem, 3vw, 2.2rem); +} +.xf-plugin-main { + display: grid; + gap: 0.85rem; +} +.xf-plugin-cards { + display: grid; + grid-template-columns: minmax(0, 1fr); + gap: 0.6rem; +} +@media (min-width: 700px) { + .xf-plugin-cards { + grid-template-columns: repeat(3, minmax(0, 1fr)); + } +} +.xf-plugin-card { + padding: 0.9rem; + border: 1px solid var(--xf-line); + border-radius: 13px; + background: color-mix(in srgb, var(--xf-surface) 78%, transparent); + transition: border-color 0.15s ease, background 0.15s ease; +} +.xf-plugin-card:hover { + border-color: color-mix(in srgb, var(--xf-violet) 40%, var(--xf-line)); + background: var(--xf-surface); +} +.xf-plugin-card-head { + display: flex; + align-items: center; + justify-content: space-between; + gap: 0.5rem; +} +.xf-plugin-card h3 { + margin: 0; +} +.xf-plugin-card h3 code { + color: var(--xf-accent); + font-family: var(--font-mono); + font-size: 0.8rem; + font-weight: 700; +} +.xf-plugin-dot { + width: 6px; + height: 6px; + border-radius: 50%; + background: var(--xf-violet); + box-shadow: 0 0 0 3px color-mix(in srgb, var(--xf-violet) 16%, transparent); +} +.xf-plugin-card p { + margin: 0.38rem 0 0.65rem; + color: var(--xf-muted); + font-size: 0.75rem; + line-height: 1.55; +} +.xf-plugin-card .xf-tag-list { + margin: 0; +} + +.xf-sandbox { + margin: 0; + padding: 0.8rem; + border: 1px solid var(--xf-line); + border-radius: var(--xf-radius-lg); + background: + radial-gradient(ellipse at 50% 38%, color-mix(in srgb, var(--xf-violet) 11%, transparent), transparent 62%), + color-mix(in srgb, var(--xf-surface) 76%, transparent); +} +.xf-sandbox-svg { + display: block; + width: 100%; + height: auto; +} +.xf-orbit { + transform-box: view-box; + transform-origin: 260px 220px; + animation: xf-orbit 24s linear infinite; +} +.xf-orbit--b { + animation-duration: 19s; + animation-direction: reverse; +} +.xf-orbit--c { + animation-duration: 28s; +} +@keyframes xf-orbit { + to { transform: rotate(360deg); } +} +.xf-orbit-ring { + fill: none; + stroke: color-mix(in srgb, var(--xf-cyan) 38%, transparent); + stroke-width: 1; + stroke-dasharray: 3 7; +} +.xf-orbit-node { + fill: var(--xf-violet); +} +.xf-orbit-node.is-cyan { fill: var(--xf-cyan); } +.xf-orbit-node.is-warm { fill: var(--xf-accent); } +.xf-sandbox-face { + stroke: color-mix(in srgb, var(--xf-violet) 55%, var(--xf-line)); + stroke-width: 1.1; +} +.xf-sandbox-top-a { stop-color: color-mix(in srgb, var(--xf-surface-2) 68%, var(--xf-violet)); } +.xf-sandbox-top-b { stop-color: color-mix(in srgb, var(--xf-surface-2) 88%, var(--xf-cyan)); } +.xf-sandbox-side-a { stop-color: color-mix(in srgb, var(--xf-surface) 84%, #000); } +.xf-sandbox-side-b { stop-color: var(--xf-surface); } +.xf-sandbox-title { + fill: var(--xf-text); + font-family: var(--font-mono); + font-size: 20px; + font-weight: 700; + letter-spacing: 0.06em; +} +.xf-sandbox-sub { + fill: var(--xf-muted); + font-family: var(--font-mono); + font-size: 11px; + letter-spacing: 0.18em; + text-transform: uppercase; +} +.xf-sandbox-caption { + fill: var(--xf-violet); + font-family: var(--font-mono); + font-size: 12px; + letter-spacing: 0.12em; +} +.xf-sandbox figcaption { + display: grid; + gap: 0.35rem; + padding: 0.35rem 0.35rem 0; + color: var(--xf-muted); + font-family: var(--font-mono); + font-size: var(--xf-text-xs); + line-height: 1.6; +} +.xf-sandbox-legend { + display: flex; + flex-wrap: wrap; + align-items: center; + gap: 0.35rem; +} +.xf-sandbox-legend i { + display: inline-block; + width: 7px; + height: 7px; + margin-left: 0.35rem; + border-radius: 50%; +} +.xf-sandbox-legend i:first-child { + margin-left: 0; +} +.xf-sandbox-legend .is-warm { background: var(--xf-accent); } +.xf-sandbox-legend .is-cyan { background: var(--xf-cyan); } +.xf-sandbox-legend .is-violet { background: var(--xf-violet); } +.xf-sandbox-note { + color: var(--xf-muted); +} +.xf-capabilities { + display: grid; + grid-template-columns: repeat(2, minmax(0, 1fr)); + gap: 0.3rem; + margin: 0.7rem 0 0.2rem; + padding: 0; + list-style: none; +} +.xf-capabilities li { + padding: 0.28rem 0.5rem; + border: 1px solid var(--xf-line); + border-radius: 7px; + color: var(--xf-muted); + font-family: var(--font-mono); + font-size: var(--xf-text-xs); + line-height: 1.45; +} +.xf-discovery { + margin: 1.4rem 0 0; + padding-top: 1rem; + border-top: 1px solid var(--xf-line); + color: var(--xf-muted); + font-size: 0.8rem; + line-height: 1.8; +} +.xf-discovery code { + padding: 0.08rem 0.3rem; + border: 1px solid var(--xf-line); + border-radius: 5px; + color: var(--xf-accent); + font-family: var(--font-mono); + font-size: 0.72rem; +} + +/* ========================================================================== + USAGE + ========================================================================== */ + +.xf-usage { + display: grid; + grid-template-columns: minmax(0, 1fr) minmax(0, 26rem); + align-items: end; + gap: clamp(1.2rem, 4vw, 3rem); +} +.xf-usage .xf-sec-head { + margin-bottom: 0; +} +.xf-usage-code .xf-code-pre { + font-size: 0.95rem; +} + +/* ========================================================================== + ROADMAP + ========================================================================== */ + +.xf-roadmap-legend { + display: flex; + flex-wrap: wrap; + gap: 1rem; + margin: -0.5rem 0 1.2rem; + color: var(--xf-muted); + font-family: var(--font-mono); + font-size: var(--xf-text-xs); +} +.xf-roadmap-legend span { + display: inline-flex; + align-items: center; + gap: 0.4rem; +} +.xf-roadmap-legend i { + width: 8px; + height: 8px; + border: 1px solid var(--xf-line-strong); + border-radius: 50%; +} +.xf-roadmap-legend .is-done { + background: var(--xf-success); + border-color: var(--xf-success); +} +.xf-roadmap-legend .is-partial { + background: var(--xf-warning); + border-color: var(--xf-warning); +} +.xf-timeline { + position: relative; + display: grid; + gap: 1.05rem; + margin: 0; + padding: 0 0 0 1.55rem; + border-left: 1px solid var(--xf-line); + list-style: none; +} +.xf-phase { + position: relative; +} +.xf-phase-marker { + position: absolute; + left: calc(-1.55rem - 5.5px); + top: 0.36rem; + width: 10px; + height: 10px; + border: 1px solid var(--xf-line-strong); + border-radius: 50%; + background: var(--xf-bg); +} +.xf-phase.is-done .xf-phase-marker { + border-color: var(--xf-success); + background: var(--xf-success); +} +.xf-phase.is-partial .xf-phase-marker { + border-color: var(--xf-warning); + background: var(--xf-warning); +} +.xf-phase-body { + padding: 0 0 0.15rem; +} +.xf-phase-head { + display: flex; + flex-wrap: wrap; + align-items: baseline; + justify-content: space-between; + gap: 0.4rem 0.8rem; +} +.xf-phase-head h3 { + margin: 0; + font-size: 0.9rem; + font-weight: 650; + line-height: 1.4; +} +.xf-status { + flex: none; + padding: 0.12rem 0.46rem; + border: 1px solid var(--xf-line); + border-radius: 999px; + color: var(--xf-muted); + font-family: var(--font-mono); + font-size: var(--xf-text-xs); + letter-spacing: 0.08em; + text-transform: uppercase; + white-space: nowrap; +} +.xf-phase.is-done .xf-status { + color: var(--xf-success); + border-color: color-mix(in srgb, var(--xf-success) 40%, var(--xf-line)); + background: color-mix(in srgb, var(--xf-success) 8%, transparent); +} +.xf-phase.is-partial .xf-status { + color: var(--xf-warning); + border-color: color-mix(in srgb, var(--xf-warning) 40%, var(--xf-line)); + background: color-mix(in srgb, var(--xf-warning) 8%, transparent); +} +.xf-phase-body p { + margin: 0.28rem 0 0; + color: var(--xf-muted); + font-size: 0.78rem; + line-height: 1.6; +} + +/* ========================================================================== + UNINSTALL + ========================================================================== */ + +.xf-uninstall-grid { + display: grid; + grid-template-columns: repeat(2, minmax(0, 1fr)); + gap: 1rem; +} +.xf-subhead { + margin: 0 0 0.5rem; + font-size: 0.9rem; + font-weight: 650; +} +.xf-caution { + margin: 1rem 0 0; + color: var(--xf-muted); + font-size: 0.76rem; + line-height: 1.6; +} +.xf-caution code { + color: var(--xf-accent); + font-family: var(--font-mono); +} + +/* ========================================================================== + FINAL CTA + ========================================================================== */ + +.xf-cta { + position: relative; + overflow: hidden; + padding-block: clamp(4.5rem, 9vw, 8rem); + border-top: 1px solid var(--xf-line); + background: + radial-gradient(ellipse at 50% 0%, color-mix(in srgb, var(--xf-accent) 12%, transparent), transparent 58%), + var(--xf-bg); +} +.xf-cta-grid { + position: absolute; + inset: 0; + background-image: + linear-gradient(to right, var(--xf-grid-line) 1px, transparent 1px), + linear-gradient(to bottom, var(--xf-grid-line) 1px, transparent 1px); + background-size: 42px 42px; + transform: perspective(600px) rotateX(55deg) translateY(35%); + transform-origin: bottom; + -webkit-mask-image: linear-gradient(to top, #000, transparent 72%); + mask-image: linear-gradient(to top, #000, transparent 72%); + opacity: 0.7; +} +.xf-cta-inner { + position: relative; + max-width: 780px; + text-align: center; +} +.xf-cta-inner h2 { + margin: 0; + font-size: clamp(2.2rem, 5vw, 3.7rem); + font-weight: 650; + line-height: 1.02; + letter-spacing: -0.045em; +} +.xf-cta-inner h2 span { + color: var(--xf-accent); +} +.xf-cta-lead { + max-width: 58ch; + margin: 1.1rem auto 0; + color: var(--xf-muted); + font-size: clamp(0.94rem, 1.2vw, 1.05rem); + line-height: 1.7; +} +.xf-cta-actions { + display: flex; + flex-wrap: wrap; + justify-content: center; + gap: 0.65rem; + margin-top: 1.6rem; +} + +/* ========================================================================== + FOOTER + ========================================================================== */ + +.xf-footer { + position: relative; + z-index: 1; + border-top: 1px solid var(--xf-line); + background: color-mix(in srgb, var(--xf-surface) 72%, var(--xf-bg)); +} +.xf-footer-inner { + display: grid; + grid-template-columns: auto minmax(0, 1fr) auto; + align-items: center; + gap: 1.2rem 2rem; + padding-block: 2.2rem; +} +.xf-footer-brand { + display: flex; + align-items: center; + gap: 0.7rem; +} +.xf-footer-mark { + display: grid; + place-items: center; + width: 34px; + height: 34px; + border: 1px solid color-mix(in srgb, var(--xf-accent) 50%, var(--xf-line)); + border-radius: 9px; + background: color-mix(in srgb, var(--xf-accent) 10%, transparent); + color: var(--xf-accent); + font-family: var(--font-mono); + font-size: 0.72rem; + font-weight: 700; +} +.xf-footer-title { + margin: 0; + color: var(--xf-text); + font-family: var(--font-mono); + font-size: 0.82rem; + font-weight: 700; +} +.xf-footer-made { + margin: 0.1rem 0 0; + color: var(--xf-muted); + font-size: 0.72rem; +} +.xf-footer-made strong { + color: var(--xf-text); +} +.xf-footer-links { + display: flex; + flex-wrap: wrap; + justify-content: center; + gap: 0.35rem 1.1rem; +} +.xf-footer-link { + display: inline-flex; + align-items: center; + min-height: 24px; + color: var(--xf-muted); + font-size: 0.74rem; + text-decoration: none; + transition: color 0.15s ease; +} +.xf-footer-link:hover { + color: var(--xf-accent); +} +.xf-footer-version { + margin: 0; + color: var(--xf-muted); + font-family: var(--font-mono); + font-size: var(--xf-text-xs); + text-align: right; + white-space: nowrap; +} + +/* ========================================================================== + RESPONSIVE + ========================================================================== */ + +@media (max-width: 1100px) { + .xf-map-grid, + .xf-plugin-grid { + grid-template-columns: minmax(0, 1fr); + } +} + +@media (max-width: 1080px) { + .xf-nav-link { + font-size: 0.7rem; + padding-inline: 0.4rem; + } + .xf-hero-grid { + grid-template-columns: minmax(0, 1fr) minmax(0, 0.95fr); + } + .xf-explorer { + grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); + } + .xf-count { + grid-column: 1 / -1; + padding-bottom: 0; + } +} + +@media (max-width: 920px) { + .xf-nav-links { + display: none; + } + .xf-menu-btn { + display: inline-grid; + } + .xf-nav-inner { + justify-content: space-between; + } + .xf-brand { + flex: 1; + } + + .xf-hero-grid, + .xf-split, + .xf-map-grid, + .xf-layout-grid, + .xf-config-grid, + .xf-plugin-grid, + .xf-usage { + grid-template-columns: minmax(0, 1fr); + } + .xf-hero { + padding-top: 7.2rem; + } + .xf-hero-copy { + max-width: 46rem; + } + .xf-hero-visual { + max-width: 36rem; + margin-inline: auto; + width: 100%; + } + .xf-visual-stage { + aspect-ratio: 1 / 0.88; + } + .xf-features { + grid-template-columns: repeat(2, minmax(0, 1fr)); + } + .xf-feature, + .xf-feature:nth-child(1), + .xf-feature:nth-child(2), + .xf-feature:nth-child(6), + .xf-feature:nth-child(7), + .xf-feature:nth-child(8), + .xf-feature:nth-child(9) { + grid-column: span 1; + } + .xf-feature:first-child { + grid-column: span 2; + } + .xf-usage { + align-items: start; + } + .xf-usage-code { + max-width: 26rem; + } + .xf-footer-inner { + grid-template-columns: minmax(0, 1fr) auto; + } + .xf-footer-links { + justify-content: flex-start; + grid-column: 1 / -1; + grid-row: 2; + } + .xf-footer-version { + text-align: right; + } + .xf-map-side { + max-width: 48rem; + } + .xf-map-detail { + min-height: 0; + } +} + +@media (max-width: 680px) { + .xf-bg-glow { + display: none; + } + .xf-gallery-grid { + grid-template-columns: minmax(0, 1fr); + } + .xf-gallery-bar { + align-items: flex-start; + } + .xf-map-canvas { + display: none; + } + .xf-map-mobile-stack { + display: grid; + } + .xf-map-tabs { + display: none; + } + .xf-map-side { + max-width: none; + } + .xf-section { + padding-block: 3.3rem; + } + .xf-hero { + padding-top: 6.8rem; + padding-bottom: 3rem; + } + .xf-hero-title { + font-size: clamp(2.45rem, 10.5vw, 3.4rem); + } + .xf-hero-actions .xf-btn { + flex: 1 1 auto; + } + .xf-visual-stage { + min-height: 350px; + } + .xf-slab--back, + .xf-slab--mid { + display: none; + } + .xf-term-body { + gap: 0.7rem; + padding: 0.8rem; + } + .xf-term-logo { + font-size: 0.42rem; + } + .xf-term-row { + font-size: 0.52rem; + } + .xf-chip--tl, + .xf-chip--bl { + display: none; + } + .xf-chip--tr { + top: 1%; + right: 0; + } + .xf-chip--br { + bottom: 0; + right: 3%; + } + .xf-features { + grid-template-columns: minmax(0, 1fr); + } + .xf-feature, + .xf-feature:nth-child(1), + .xf-feature:nth-child(2), + .xf-feature:nth-child(6), + .xf-feature:nth-child(7), + .xf-feature:nth-child(8), + .xf-feature:nth-child(9) { + grid-column: span 1; + min-height: 0; + } + .xf-explorer { + grid-template-columns: minmax(0, 1fr); + } + .xf-count { + grid-column: auto; + } + .xf-config-modules { + grid-template-columns: minmax(0, 1fr); + } + .xf-uninstall-grid, + .xf-capabilities { + grid-template-columns: minmax(0, 1fr); + } + .xf-footer-inner { + grid-template-columns: minmax(0, 1fr); + gap: 1rem; + } + .xf-footer-links { + grid-column: auto; + grid-row: auto; + } + .xf-footer-version { + text-align: left; + white-space: normal; + } + .xf-terminal-pre { + font-size: 0.66rem; + } + .xf-lp { + min-height: 12rem; + } +} + +@media (max-width: 440px) { + .xf-term-logo { + display: none; + } + .xf-term-body { + grid-template-columns: minmax(0, 1fr); + } + .xf-facts { + gap: 0.3rem; + } + .xf-facts li { + font-size: var(--xf-text-xs); + } + .xf-nav-inner { + min-height: 54px; + } +} + +/* ========================================================================== + MOTION / CONTRAST / TRANSPARENCY / FORCED COLORS + ========================================================================== */ + +@media (prefers-reduced-motion: reduce) { + html { + scroll-behavior: auto; + } + .xf-js [data-reveal] { + opacity: 1; + translate: none; + transition: none; + } + .xf-chip, + .xf-orbit, + .xf-bg-drift, + .xf-term-cursor, + .xf-terminal-cursor { + animation: none !important; + } + .xf-iso { + transition: none; + } + .xf-feature:hover, + .xf-btn:hover, + .xf-module:hover, + .xf-layout-tab:hover { + transform: none; + } +} + +@media (prefers-contrast: more) { + body .xf-nav .xf-nav-inner, + body .xf-nav.is-scrolled .xf-nav-inner, + .xf-glass { + background: var(--xf-surface); + border-color: var(--xf-text); + -webkit-backdrop-filter: none; + backdrop-filter: none; + } + .xf-feature, + .xf-module, + .xf-plugin-card, + .xf-layout-panel, + .xf-code, + .xf-gallery-item figure, + .xf-fieldset, + .xf-sandbox, + .xf-map-canvas { + border-color: color-mix(in srgb, var(--xf-text) 55%, transparent); + } + .xf-nav-link.is-active, + .xf-nav-link:hover { + text-decoration: underline; + } +} + +@media (prefers-reduced-transparency: reduce) { + body .xf-nav .xf-nav-inner, + body .xf-nav.is-scrolled .xf-nav-inner, + .xf-glass { + background: var(--xf-surface); + -webkit-backdrop-filter: none; + backdrop-filter: none; + } + .xf-hero-plinth, + .xf-hero-glow, + .xf-bg-glow, + .xf-bg-noise { + display: none; + } +} + +@media (forced-colors: active) { + body .xf-nav .xf-nav-inner, + body .xf-nav.is-scrolled .xf-nav-inner, + .xf-glass, + .xf-feature, + .xf-module, + .xf-plugin-card, + .xf-layout-panel, + .xf-fieldset, + .xf-sandbox, + .xf-map-canvas, + .xf-code, + .xf-gallery-item figure, + .xf-theme-toggle, + .xf-menu-btn, + .xf-btn, + .xf-chip, + .xf-tag-list li { + border: 1px solid CanvasText; + } + .xf-btn--primary { + background: ButtonFace; + color: ButtonText; + } + .xf-nav-progress span { + background: Highlight; + } + .xf-term-window, + .xf-code, + .xf-layout-preview-wrap { + background: Canvas; + color: CanvasText; + } + .xf-chip-btn.is-active, + .xf-nav-link.is-active, + .xf-map-tab.is-active, + .xf-layout-tab.is-active { + outline: 2px solid Highlight; + } +} + +/* One stable toggle button, two icons. No hydration-dependent state. */ +.xf-theme-icon { + display: grid; + place-items: center; +} +html[data-theme="dark"] .xf-theme-icon--moon, +html:not([data-theme="dark"]) .xf-theme-icon--sun { + display: none; +} diff --git a/src/app/layout.tsx b/src/app/layout.tsx index 9e53dff..67cba07 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -1,7 +1,7 @@ import type { Metadata } from "next"; import { Geist, Geist_Mono } from "next/font/google"; -import "@xscriptor/xcomponents/styles.css"; import "./globals.css"; +import "./landing.css"; import BgPaths from "@/components/BgPaths"; import SiteNav from "@/components/SiteNav"; @@ -19,13 +19,16 @@ export default function RootLayout({ children }: { children: React.ReactNode })