diff --git a/.github/workflows/deploy-site.yml b/.github/workflows/deploy-site.yml
index fa7f8da..43356f4 100644
--- a/.github/workflows/deploy-site.yml
+++ b/.github/workflows/deploy-site.yml
@@ -5,6 +5,7 @@ on:
branches: [main]
paths:
- 'site/**'
+ - 'site-internal/**'
- '.github/workflows/deploy-site.yml'
workflow_dispatch:
@@ -26,8 +27,12 @@ jobs:
with:
node-version: 20
cache: npm
- cache-dependency-path: site/package-lock.json
+ cache-dependency-path: |
+ site/package-lock.json
+ site-internal/package-lock.json
- run: cd site && npm install && VITE_BASE=/multi-casual-android/ npm run build
+ - run: cd site-internal && npm install && VITE_BASE=/multi-casual-android/xiaomi/ npm run build
+ - run: mkdir -p site/dist/xiaomi && cp -R site-internal/dist/. site/dist/xiaomi/
- uses: actions/upload-pages-artifact@v3
with:
path: site/dist
diff --git a/site-internal/.gitignore b/site-internal/.gitignore
new file mode 100644
index 0000000..5a3597b
--- /dev/null
+++ b/site-internal/.gitignore
@@ -0,0 +1,5 @@
+node_modules/
+dist/
+.edgeone/
+*.tsbuildinfo
+public/downloads/*.apk
diff --git a/site-internal/README.md b/site-internal/README.md
new file mode 100644
index 0000000..f7114c3
--- /dev/null
+++ b/site-internal/README.md
@@ -0,0 +1,78 @@
+# site-internal — Multica Xiaomi internal landing page
+
+A separate Vite + React landing page for the **Multica Xiaomi** internal
+Android build. The public site at [`../site/`](../site/) targets the
+Multi-Casual public release; this directory is a sibling project
+published under the same GitHub Pages site at `/xiaomi/`.
+
+## Visual scope
+
+This page is a near-clone of the public site (`site/src/`) with three
+intentional differences:
+
+1. The "Relationship to Multica" section is removed.
+2. The source link points to the private company GitLab project.
+ The signed APK download points to a separate artifact-only GitHub
+ release repository.
+3. The iOS App button is left untouched and still points at the
+ public iOS repo — the same `github.com/park0er/multi-casual-ios-app`
+ source-of-truth is reused on purpose.
+
+All screenshots, the promo video, the journey / workspace interactions,
+the language toggle, and the layout are reused from `site/src/assets/`
+so the visual stays in sync with the public site.
+
+## Release metadata
+
+`src/App.tsx` points the primary APK download button at the static
+GitHub release asset:
+
+```text
+https://github.com/park0er/multica-xiaomi-apk/releases/download/v0.1.5-xiaomi/Multica-Xiaomi-v0.1.5.apk
+```
+
+The APK is copied from `app/build/outputs/apk/xiaomi/release/` into
+`site-internal/public/downloads/` before deployment. Current metadata:
+
+| Field | Value |
+|---|---|
+| `release.sha256` | `13e004472d33e66aa40aa7ebd58f75e22cfde8cce3a153729481f1be4d2d1414` |
+| `release.gitlabUrl` | `https://git.n.xiaomi.com/zhaoxisheng/multica-xiaomi-android` |
+| `release.releasesUrl` | `https://github.com/park0er/multica-xiaomi-apk/releases/download/v0.1.5-xiaomi/Multica-Xiaomi-v0.1.5.apk` |
+
+Also confirm the `release.apiUrl` matches the staging or production
+Xiaomi Multica endpoint you want this build to talk to
+(`http://staging-multica.ad.xiaomi.srv` is the build.gradle default).
+
+## Build
+
+```bash
+cd site-internal
+npm install
+npm run build
+```
+
+Output goes to `site-internal/dist/` and is gitignored.
+
+## Deploy
+
+The site is hosted as a subdirectory of the public GitHub Pages site:
+
+```
+https://park0er.github.io/multi-casual-android/xiaomi/
+```
+
+GitHub Actions builds the public site into the Pages root and this
+internal Xiaomi site into `dist/xiaomi/` before deploying.
+
+### Publish flow
+
+1. Copy `site-internal/` into the public repo.
+2. Commit and push the public repo.
+3. GitHub Actions deploys both `site/` and `site-internal/`.
+
+### EdgeOne status
+
+Tencent EdgeOne hosting was attempted first but proved unreliable for
+this internal distribution. The current source of truth for downloads is
+GitHub Pages.
diff --git a/site-internal/index.html b/site-internal/index.html
new file mode 100644
index 0000000..6184260
--- /dev/null
+++ b/site-internal/index.html
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+ Multica Xiaomi · Internal Build
+
+
+
+
+
+
diff --git a/site-internal/package-lock.json b/site-internal/package-lock.json
new file mode 100644
index 0000000..7c1d4f0
--- /dev/null
+++ b/site-internal/package-lock.json
@@ -0,0 +1,1001 @@
+{
+ "name": "multica-xiaomi-internal-site",
+ "version": "0.1.0",
+ "lockfileVersion": 3,
+ "requires": true,
+ "packages": {
+ "": {
+ "name": "multica-xiaomi-internal-site",
+ "version": "0.1.0",
+ "dependencies": {
+ "@vitejs/plugin-react": "latest",
+ "motion": "latest",
+ "react": "latest",
+ "react-dom": "latest",
+ "typescript": "latest",
+ "vite": "latest"
+ },
+ "devDependencies": {
+ "@types/react": "^19.2.16",
+ "@types/react-dom": "^19.2.3"
+ }
+ },
+ "node_modules/@emnapi/core": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.11.1.tgz",
+ "integrity": "sha512-RSvbQmHzdKzNsLYa/wHrbc3KN4sYLKAdPZxqiM2HATqv/SBk2/ENSHpvXGaLOMcsAyz0poEGqkmmKYG3OWiJEQ==",
+ "license": "MIT",
+ "optional": true,
+ "peer": true,
+ "dependencies": {
+ "@emnapi/wasi-threads": "1.2.2",
+ "tslib": "^2.4.0"
+ }
+ },
+ "node_modules/@emnapi/runtime": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.11.1.tgz",
+ "integrity": "sha512-vgj7R3y3Wgx24IQaGPA/R6YFXLHVMOZ0uVEyIQPaWs+rd1AzfEMXlAC22FYwO1XkKR6NPsq7mUandH8oIRdZFw==",
+ "license": "MIT",
+ "optional": true,
+ "peer": true,
+ "dependencies": {
+ "tslib": "^2.4.0"
+ }
+ },
+ "node_modules/@emnapi/wasi-threads": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.2.tgz",
+ "integrity": "sha512-c95qOXkHdydNKhscBTebqEC1CVAZpyqOfVfBzQ1qgzyl3gfeldUjIggDbIZgDKsHLgnsM+igH7TJ/eAasaVuMA==",
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "tslib": "^2.4.0"
+ }
+ },
+ "node_modules/@napi-rs/wasm-runtime": {
+ "version": "1.1.6",
+ "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.6.tgz",
+ "integrity": "sha512-ZLv/JdUfkvOy9eCnnBaGfiO+XimbjebAeO+MRQqD/B+FR1tnRN0tpKSJHRbE8sFfS6aqsXZ67TQjfwfsxULVbg==",
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "@tybys/wasm-util": "^0.10.3"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/Brooooooklyn"
+ },
+ "peerDependencies": {
+ "@emnapi/core": "^1.7.1",
+ "@emnapi/runtime": "^1.7.1"
+ }
+ },
+ "node_modules/@oxc-project/types": {
+ "version": "0.137.0",
+ "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.137.0.tgz",
+ "integrity": "sha512-WT+Gb24i8hmvo85AIv2oEYouEXkRlKAlT9WaCa3TfLgNCN+GhrJOGZuIlMouAh38Qe4QOx26eUOVsq70qXrywA==",
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/Boshen"
+ }
+ },
+ "node_modules/@rolldown/binding-android-arm64": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.1.3.tgz",
+ "integrity": "sha512-DT6Z3PhvioeHMvxo+xHc3KtqggrI7CCTXCmC2h/5zUlp5jVitv7XEy+9q5/7v8IolhlioawpMo8Kg0EEBy7J0g==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@rolldown/binding-darwin-arm64": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.1.3.tgz",
+ "integrity": "sha512-0NwgwsjM7LrsuVnXMK3koTpagBNOhloc/BNjKqZjv4V5zI5r13qx69uVhRx+o5Z0yy4Hzq+lpy7TAgUG/ocvrw==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@rolldown/binding-darwin-x64": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.1.3.tgz",
+ "integrity": "sha512-YtiBp4disu6V560loT6PjMdiRaWmVvDNrUunAalbiFx2ggeJwxdAsgZMcoGP17uyAsTwAj5V1niksxlHnVQ1Sw==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@rolldown/binding-freebsd-x64": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.1.3.tgz",
+ "integrity": "sha512-yD3EkEdXk2LypPxnf/kSZHirarsI8gcPzc62SukhR9VJTyvV+F9Q/GxWNuCojc7sXyuVC4DxRGhdDK4X8VSsbw==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@rolldown/binding-linux-arm-gnueabihf": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.1.3.tgz",
+ "integrity": "sha512-c+8vieQbsD7HNAHKIA34w0GJ9FedFFuJGD+7E6vz7Q3uqAIugL5p45fhlsj4UaAsHpcmlqugBWMhA0/j7o0sIg==",
+ "cpu": [
+ "arm"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@rolldown/binding-linux-arm64-gnu": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.1.3.tgz",
+ "integrity": "sha512-50jD0uUwLvur7Zz9LHz17kaAdTPjn5wN93hEgjvmYFRZwiR7ZJYovTd5ipyWJDAnXKvZ+wgc+/Ika6dwSF5OcA==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@rolldown/binding-linux-arm64-musl": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.1.3.tgz",
+ "integrity": "sha512-BO9+oPL8K9poZJBfYPsXNtYjPE5uM3qeehT3aFcW4LITOl+iSqhp0abzjR2nWBUNjIZeKXjAEWBZ64WjNoHd6w==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@rolldown/binding-linux-ppc64-gnu": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.1.3.tgz",
+ "integrity": "sha512-f3VpLB1vQ0Eo6ecr/6cekLnvYMFF4YBFoVGkfkvPLq1bAkbAwHYQPZKoAmG6OJyTcxxoC+AvezGx/S1obNC0Mw==",
+ "cpu": [
+ "ppc64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@rolldown/binding-linux-s390x-gnu": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.1.3.tgz",
+ "integrity": "sha512-AmurZ26Pqx/RI9N1gzEOCklkKXl927yjfXWUUS0O7Puh8ARM/Ob8qfrD3qnWksScdw6cSrW5PSHE9DyLu7+PtA==",
+ "cpu": [
+ "s390x"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@rolldown/binding-linux-x64-gnu": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.1.3.tgz",
+ "integrity": "sha512-JJpqs8bRGITDOdbkNKnlojzBabbOHrqjSvDr0IVsZObE1lBcPjxItUEY9eWIDbxaJ3cGrXPWGfGkIxFijg/URg==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@rolldown/binding-linux-x64-musl": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.1.3.tgz",
+ "integrity": "sha512-rSJcdjPxzA/by/6/rYs+v+bXU7UjvnbUWz8MJb6kh6+knqB1dCrtHg0uu7C/4haqJvqdkYHQ5IGn+tCH9GLW/g==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@rolldown/binding-openharmony-arm64": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.1.3.tgz",
+ "integrity": "sha512-hQ3/PYkDJICgevvyNcVrihVeqq7k1Pp3VZ9lY+dauAYUJKO+auqApvANhvR1An9BhmqYKvW2Mu1F9u4DXSMLxQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openharmony"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@rolldown/binding-wasm32-wasi": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.1.3.tgz",
+ "integrity": "sha512-Elcv/BtML9lXrV6JuKITc/grN2kYV9gjsQpW8Jfw4ioK0TOkjBjye0nnyqQNy9STNaI20lXNaQBRrD5gSgR0Yg==",
+ "cpu": [
+ "wasm32"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "@emnapi/core": "1.11.1",
+ "@emnapi/runtime": "1.11.1",
+ "@napi-rs/wasm-runtime": "^1.1.6"
+ },
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@rolldown/binding-win32-arm64-msvc": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.1.3.tgz",
+ "integrity": "sha512-2DrEfhluH9yhiaFApmsjsjwrSYbNcY1oFTzYSP1a535jDbV98zCFanA/96TBUd0iDFcxGmw9QRExwGCXz3U+/g==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@rolldown/binding-win32-x64-msvc": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.1.3.tgz",
+ "integrity": "sha512-OL4OMk7UPXOeVGGd3qo5zJyPIljf4AFgk5QAkPPS+OoLuOOozhuaQGC18MxVTnw/06q93gShAJzlwnSCY9YtqA==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@rolldown/pluginutils": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.1.tgz",
+ "integrity": "sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw==",
+ "license": "MIT"
+ },
+ "node_modules/@tybys/wasm-util": {
+ "version": "0.10.3",
+ "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.3.tgz",
+ "integrity": "sha512-F3fo1MYrRJYL3zER0OUOmkutjr1Vp23m7OsSgp7nq4SP6OqX6C/56XFIPAl5bt3zaBRjmW7SGz3u/6LwFpYcOg==",
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "tslib": "^2.4.0"
+ }
+ },
+ "node_modules/@types/react": {
+ "version": "19.2.17",
+ "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.17.tgz",
+ "integrity": "sha512-MXfmqaVPEVgkBT/aY0aGCkRWWtByiYQXo3xdQ8r5RzuFrPiRn8Gar2tQdXSUQ2GKV3bkXckek89V8wQBY2Q/Aw==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "csstype": "^3.2.2"
+ }
+ },
+ "node_modules/@types/react-dom": {
+ "version": "19.2.3",
+ "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.2.3.tgz",
+ "integrity": "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==",
+ "dev": true,
+ "license": "MIT",
+ "peerDependencies": {
+ "@types/react": "^19.2.0"
+ }
+ },
+ "node_modules/@vitejs/plugin-react": {
+ "version": "6.0.3",
+ "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-6.0.3.tgz",
+ "integrity": "sha512-vmFvco5/QuC2f9Oj+wTk0+9XeDFkHxSamwZKYc7MxYwKICfvUvlMhqKI0VuICPltGqh1neqBKDvO4kes1ya8vg==",
+ "license": "MIT",
+ "dependencies": {
+ "@rolldown/pluginutils": "^1.0.1"
+ },
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ },
+ "peerDependencies": {
+ "@rolldown/plugin-babel": "^0.1.7 || ^0.2.0",
+ "babel-plugin-react-compiler": "^1.0.0",
+ "vite": "^8.0.0"
+ },
+ "peerDependenciesMeta": {
+ "@rolldown/plugin-babel": {
+ "optional": true
+ },
+ "babel-plugin-react-compiler": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/csstype": {
+ "version": "3.2.3",
+ "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz",
+ "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/detect-libc": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz",
+ "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==",
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/fdir": {
+ "version": "6.5.0",
+ "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz",
+ "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=12.0.0"
+ },
+ "peerDependencies": {
+ "picomatch": "^3 || ^4"
+ },
+ "peerDependenciesMeta": {
+ "picomatch": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/framer-motion": {
+ "version": "12.42.0",
+ "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-12.42.0.tgz",
+ "integrity": "sha512-wp7EJnfWaaEScVygKv3e20udoRz+LbtxScsuTkakAxfXmt+ReC6WyPW2nINRAGvd+hG9odwcjBLyOTPjH5pBRA==",
+ "license": "MIT",
+ "dependencies": {
+ "motion-dom": "^12.42.0",
+ "motion-utils": "^12.39.0",
+ "tslib": "^2.4.0"
+ },
+ "peerDependencies": {
+ "@emotion/is-prop-valid": "*",
+ "react": "^18.0.0 || ^19.0.0",
+ "react-dom": "^18.0.0 || ^19.0.0"
+ },
+ "peerDependenciesMeta": {
+ "@emotion/is-prop-valid": {
+ "optional": true
+ },
+ "react": {
+ "optional": true
+ },
+ "react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/fsevents": {
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
+ "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
+ "hasInstallScript": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
+ }
+ },
+ "node_modules/lightningcss": {
+ "version": "1.32.0",
+ "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.32.0.tgz",
+ "integrity": "sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==",
+ "license": "MPL-2.0",
+ "dependencies": {
+ "detect-libc": "^2.0.3"
+ },
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ },
+ "optionalDependencies": {
+ "lightningcss-android-arm64": "1.32.0",
+ "lightningcss-darwin-arm64": "1.32.0",
+ "lightningcss-darwin-x64": "1.32.0",
+ "lightningcss-freebsd-x64": "1.32.0",
+ "lightningcss-linux-arm-gnueabihf": "1.32.0",
+ "lightningcss-linux-arm64-gnu": "1.32.0",
+ "lightningcss-linux-arm64-musl": "1.32.0",
+ "lightningcss-linux-x64-gnu": "1.32.0",
+ "lightningcss-linux-x64-musl": "1.32.0",
+ "lightningcss-win32-arm64-msvc": "1.32.0",
+ "lightningcss-win32-x64-msvc": "1.32.0"
+ }
+ },
+ "node_modules/lightningcss-android-arm64": {
+ "version": "1.32.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.32.0.tgz",
+ "integrity": "sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-darwin-arm64": {
+ "version": "1.32.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.32.0.tgz",
+ "integrity": "sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-darwin-x64": {
+ "version": "1.32.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.32.0.tgz",
+ "integrity": "sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-freebsd-x64": {
+ "version": "1.32.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.32.0.tgz",
+ "integrity": "sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-linux-arm-gnueabihf": {
+ "version": "1.32.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.32.0.tgz",
+ "integrity": "sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw==",
+ "cpu": [
+ "arm"
+ ],
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-linux-arm64-gnu": {
+ "version": "1.32.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.32.0.tgz",
+ "integrity": "sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-linux-arm64-musl": {
+ "version": "1.32.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.32.0.tgz",
+ "integrity": "sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-linux-x64-gnu": {
+ "version": "1.32.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.32.0.tgz",
+ "integrity": "sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-linux-x64-musl": {
+ "version": "1.32.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.32.0.tgz",
+ "integrity": "sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-win32-arm64-msvc": {
+ "version": "1.32.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.32.0.tgz",
+ "integrity": "sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-win32-x64-msvc": {
+ "version": "1.32.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.32.0.tgz",
+ "integrity": "sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/motion": {
+ "version": "12.42.0",
+ "resolved": "https://registry.npmjs.org/motion/-/motion-12.42.0.tgz",
+ "integrity": "sha512-Qhwvu9sVl5/URSq5CNzwMCpSKK8Uhnrwb6VO977kZyj/wOCS7mWebJUnBoHx5cZU1Zv8a9BD5CSICWKAlrLJgA==",
+ "license": "MIT",
+ "dependencies": {
+ "framer-motion": "^12.42.0",
+ "tslib": "^2.4.0"
+ },
+ "peerDependencies": {
+ "@emotion/is-prop-valid": "*",
+ "react": "^18.0.0 || ^19.0.0",
+ "react-dom": "^18.0.0 || ^19.0.0"
+ },
+ "peerDependenciesMeta": {
+ "@emotion/is-prop-valid": {
+ "optional": true
+ },
+ "react": {
+ "optional": true
+ },
+ "react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/motion-dom": {
+ "version": "12.42.0",
+ "resolved": "https://registry.npmjs.org/motion-dom/-/motion-dom-12.42.0.tgz",
+ "integrity": "sha512-M63h4n8R+quJdNhBwuLlgxM+OLYa9+I/T2pzDRboB9fLXRdbou+Gw7Zury+SkpaCyACP1JHSjHgZ1EgTkBr30w==",
+ "license": "MIT",
+ "dependencies": {
+ "motion-utils": "^12.39.0"
+ }
+ },
+ "node_modules/motion-utils": {
+ "version": "12.39.0",
+ "resolved": "https://registry.npmjs.org/motion-utils/-/motion-utils-12.39.0.tgz",
+ "integrity": "sha512-8nadJAJjTtqRkmRF36FoJTrywK9nnFmnPwnSMyxaOCU7GDjN9RTMJIxx9De8ErM+vpPhMccr/6fo5WciyQLnMQ==",
+ "license": "MIT"
+ },
+ "node_modules/nanoid": {
+ "version": "3.3.15",
+ "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.15.tgz",
+ "integrity": "sha512-y7Wygv/7mEOvxTuEQDB8StXdMRBWf1kR/tlhAzBRUFkB2jfcLOAxO/SHmOO2zgz1pVgK29/kyupn059/bCHdjA==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "bin": {
+ "nanoid": "bin/nanoid.cjs"
+ },
+ "engines": {
+ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
+ }
+ },
+ "node_modules/picocolors": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
+ "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
+ "license": "ISC"
+ },
+ "node_modules/picomatch": {
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz",
+ "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==",
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
+ "node_modules/postcss": {
+ "version": "8.5.15",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.15.tgz",
+ "integrity": "sha512-FfR8sjd4em2T6fb3I2MwAJU7HWVMr9zba+enmQeeWFfCbm+UOC/0X4DS8XtpUTMwWMGbjKYP7xjfNekzyGmB3A==",
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/postcss/"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/postcss"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "nanoid": "^3.3.12",
+ "picocolors": "^1.1.1",
+ "source-map-js": "^1.2.1"
+ },
+ "engines": {
+ "node": "^10 || ^12 || >=14"
+ }
+ },
+ "node_modules/react": {
+ "version": "19.2.7",
+ "resolved": "https://registry.npmjs.org/react/-/react-19.2.7.tgz",
+ "integrity": "sha512-HNe9WslTbXmFK8o8cmwgAeJFSBvt1bPdHCVKtaaV+WlAN36mpT4hcRpwbf3fY56ar2oIXzsBpOAiIRHAdY0OlQ==",
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/react-dom": {
+ "version": "19.2.7",
+ "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.7.tgz",
+ "integrity": "sha512-t0BRVXvbiE/o20Hfw669rLbMCDWtYZLvmJigy2f0MxsXF+71pxhR3xOkspmsO8h3ZlNzyibAmtCa3l4lYKk6gQ==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "scheduler": "^0.27.0"
+ },
+ "peerDependencies": {
+ "react": "^19.2.7"
+ }
+ },
+ "node_modules/rolldown": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.1.3.tgz",
+ "integrity": "sha512-1F1eEtUBtFvcGm1HQ9TiUIUHPQG7mSAODrhIzjxoUEFuo8OcbrGLiVLkevNgj84TE4lnHvnumwFjhJO5Eu135g==",
+ "license": "MIT",
+ "dependencies": {
+ "@oxc-project/types": "=0.137.0",
+ "@rolldown/pluginutils": "^1.0.0"
+ },
+ "bin": {
+ "rolldown": "bin/cli.mjs"
+ },
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ },
+ "optionalDependencies": {
+ "@rolldown/binding-android-arm64": "1.1.3",
+ "@rolldown/binding-darwin-arm64": "1.1.3",
+ "@rolldown/binding-darwin-x64": "1.1.3",
+ "@rolldown/binding-freebsd-x64": "1.1.3",
+ "@rolldown/binding-linux-arm-gnueabihf": "1.1.3",
+ "@rolldown/binding-linux-arm64-gnu": "1.1.3",
+ "@rolldown/binding-linux-arm64-musl": "1.1.3",
+ "@rolldown/binding-linux-ppc64-gnu": "1.1.3",
+ "@rolldown/binding-linux-s390x-gnu": "1.1.3",
+ "@rolldown/binding-linux-x64-gnu": "1.1.3",
+ "@rolldown/binding-linux-x64-musl": "1.1.3",
+ "@rolldown/binding-openharmony-arm64": "1.1.3",
+ "@rolldown/binding-wasm32-wasi": "1.1.3",
+ "@rolldown/binding-win32-arm64-msvc": "1.1.3",
+ "@rolldown/binding-win32-x64-msvc": "1.1.3"
+ }
+ },
+ "node_modules/scheduler": {
+ "version": "0.27.0",
+ "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.27.0.tgz",
+ "integrity": "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==",
+ "license": "MIT"
+ },
+ "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==",
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/tinyglobby": {
+ "version": "0.2.17",
+ "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.17.tgz",
+ "integrity": "sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==",
+ "license": "MIT",
+ "dependencies": {
+ "fdir": "^6.5.0",
+ "picomatch": "^4.0.4"
+ },
+ "engines": {
+ "node": ">=12.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/SuperchupuDev"
+ }
+ },
+ "node_modules/tslib": {
+ "version": "2.8.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
+ "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
+ "license": "0BSD"
+ },
+ "node_modules/typescript": {
+ "version": "6.0.3",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-6.0.3.tgz",
+ "integrity": "sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw==",
+ "license": "Apache-2.0",
+ "bin": {
+ "tsc": "bin/tsc",
+ "tsserver": "bin/tsserver"
+ },
+ "engines": {
+ "node": ">=14.17"
+ }
+ },
+ "node_modules/vite": {
+ "version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/vite/-/vite-8.1.0.tgz",
+ "integrity": "sha512-BuJcQK/56NQTWDGn4ABea3q4SSBdNPWwNZKTkkUpcMPnLoquSYH8llRtSUIgoL1KSCpHt5eghLShn50mH36y7Q==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "lightningcss": "^1.32.0",
+ "picomatch": "^4.0.4",
+ "postcss": "^8.5.15",
+ "rolldown": "~1.1.2",
+ "tinyglobby": "^0.2.17"
+ },
+ "bin": {
+ "vite": "bin/vite.js"
+ },
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ },
+ "funding": {
+ "url": "https://github.com/vitejs/vite?sponsor=1"
+ },
+ "optionalDependencies": {
+ "fsevents": "~2.3.3"
+ },
+ "peerDependencies": {
+ "@types/node": "^20.19.0 || >=22.12.0",
+ "@vitejs/devtools": "^0.3.0",
+ "esbuild": "^0.27.0 || ^0.28.0",
+ "jiti": ">=1.21.0",
+ "less": "^4.0.0",
+ "sass": "^1.70.0",
+ "sass-embedded": "^1.70.0",
+ "stylus": ">=0.54.8",
+ "sugarss": "^5.0.0",
+ "terser": "^5.16.0",
+ "tsx": "^4.8.1",
+ "yaml": "^2.4.2"
+ },
+ "peerDependenciesMeta": {
+ "@types/node": {
+ "optional": true
+ },
+ "@vitejs/devtools": {
+ "optional": true
+ },
+ "esbuild": {
+ "optional": true
+ },
+ "jiti": {
+ "optional": true
+ },
+ "less": {
+ "optional": true
+ },
+ "sass": {
+ "optional": true
+ },
+ "sass-embedded": {
+ "optional": true
+ },
+ "stylus": {
+ "optional": true
+ },
+ "sugarss": {
+ "optional": true
+ },
+ "terser": {
+ "optional": true
+ },
+ "tsx": {
+ "optional": true
+ },
+ "yaml": {
+ "optional": true
+ }
+ }
+ }
+ }
+}
diff --git a/site-internal/package.json b/site-internal/package.json
new file mode 100644
index 0000000..ab4cc68
--- /dev/null
+++ b/site-internal/package.json
@@ -0,0 +1,22 @@
+{
+ "name": "multica-xiaomi-internal-site",
+ "private": true,
+ "version": "0.1.0",
+ "scripts": {
+ "dev": "vite --host 127.0.0.1",
+ "build": "tsc -b && vite build",
+ "preview": "vite preview --host 127.0.0.1"
+ },
+ "dependencies": {
+ "@vitejs/plugin-react": "latest",
+ "motion": "latest",
+ "react": "latest",
+ "react-dom": "latest",
+ "typescript": "latest",
+ "vite": "latest"
+ },
+ "devDependencies": {
+ "@types/react": "^19.2.16",
+ "@types/react-dom": "^19.2.3"
+ }
+}
diff --git a/site-internal/protofly-redirect.html b/site-internal/protofly-redirect.html
new file mode 100644
index 0000000..cca52fc
--- /dev/null
+++ b/site-internal/protofly-redirect.html
@@ -0,0 +1,77 @@
+
+
+
+
+
+
+ 跳转到 Multica Xiaomi
+
+
+
+
+ 正在跳转到 Multica Xiaomi
+ 这是小米内网入口,目标页面托管在 GitHub Pages。
+ 立即打开
+ https://park0er.github.io/multi-casual-android/xiaomi/
+
+
+
diff --git a/site-internal/public/favicon.png b/site-internal/public/favicon.png
new file mode 100644
index 0000000..b249e4f
Binary files /dev/null and b/site-internal/public/favicon.png differ
diff --git a/site-internal/src/App.tsx b/site-internal/src/App.tsx
new file mode 100644
index 0000000..00feae7
--- /dev/null
+++ b/site-internal/src/App.tsx
@@ -0,0 +1,662 @@
+import logoImg from "./assets/logo.png";
+import { useState, useEffect, useRef, useCallback, useMemo } from "react";
+import { motion, AnimatePresence, useMotionValue, useTransform, useReducedMotion } from "motion/react";
+import inboxImg from "./assets/screenshots/01-inbox.jpg";
+import issuesListImg from "./assets/screenshots/02-issues-list.jpg";
+import issuesBoardImg from "./assets/screenshots/03-issues-board.jpg";
+import issueDetailImg from "./assets/screenshots/04-issue-detail.jpg";
+import issueSubImg from "./assets/screenshots/05-issue-detail-subissues.jpg";
+import commentImg from "./assets/screenshots/06-comment-composer.jpg";
+import mentionImg from "./assets/screenshots/07-mention-picker.jpg";
+import projectsImg from "./assets/screenshots/08-projects-list.jpg";
+import projectDetailImg from "./assets/screenshots/09-project-detail.jpg";
+import agentsImg from "./assets/screenshots/10-agents-list.jpg";
+import runtimesImg from "./assets/screenshots/11-runtimes-list.jpg";
+import skillsImg from "./assets/screenshots/12-skills-list.jpg";
+import skillDetailImg from "./assets/screenshots/13-skill-detail.jpg";
+import settingsImg from "./assets/screenshots/14-settings.jpg";
+import promoVideo from "./assets/video/multica-android-promo-draft.mp4";
+
+const release = {
+ packageName: "ai.multica.app.xiaomi",
+ sha256: "13e004472d33e66aa40aa7ebd58f75e22cfde8cce3a153729481f1be4d2d1414",
+ gitlabUrl: "https://git.n.xiaomi.com/zhaoxisheng/multica-xiaomi-android",
+ releasesUrl: "https://github.com/park0er/multica-xiaomi-apk/releases/download/v0.1.5-xiaomi/Multica-Xiaomi-v0.1.5.apk",
+ iosUrl: "https://github.com/park0er/multi-casual-ios-app",
+ multicaUrl: "https://multica.ai",
+ apiUrl: "http://staging-multica.ad.xiaomi.srv",
+};
+
+type Locale = "en" | "zh";
+
+const copy: Record };
+ workspace: { kicker: string; title: string; subtitle: string; items: Array<{ title: string; subtitle: string }> };
+ video: { kicker: string; title: string; body: string };
+ download: { kicker: string; title: string; package: string; api: string; sha: string; latest: string; source: string; note: string };
+ trust: { kicker: string; items: string[] };
+ footer: { tagline: string; multica: string; gitlab: string; ios: string; download: string };
+}> = {
+ en: {
+ nav: { brand: "Multica Xiaomi", download: "Download", trust: "Scope", language: "中文" },
+ hero: {
+ eyebrow: "Internal Xiaomi build · Company-only distribution",
+ title: "Multica Xiaomi for the Xiaomi workspace.",
+ subtitle: "An Android app independently built from scratch by Zhao Xisheng in Xiaomi's Commercial Platform Department. Multica has not provided an official Android app to date; this internal build gives Xiaomi users a native path today.",
+ download: "Download APK",
+ gitlab: "GitLab",
+ multica: "Visit Multica",
+ ios: "iOS App",
+ },
+ journey: {
+ kicker: "Interactive walkthrough",
+ title: "Try the flow.",
+ subtitle: "Click each step or scroll to see the app in action.",
+ cta: "Start the walkthrough",
+ steps: [
+ { title: "Inbox notifications", subtitle: "Stay on top of activity — new issues, comments, and agent progress show up as they happen." },
+ { title: "Browse issues", subtitle: "See all tasks in a clean list view, ready for triage. Filter, search, and tap into any issue." },
+ { title: "Switch to board view", subtitle: "Tap the view toggle to switch to a kanban board that shows status flow at a glance." },
+ { title: "Open issue detail", subtitle: "Tap an issue card to see the full detail: title, status, labels, assignee, and body text." },
+ { title: "Explore context", subtitle: "Context guide points zoom into focus areas — title and status, body content, then subtasks and comments — and return to the full view between each." },
+ { title: "Scroll for more", subtitle: "Keep scrolling to see subtasks, subscribers, and the comment thread — all the structured context stays on one page." },
+ { title: "Draft a comment", subtitle: "Tap the comment box. The keyboard appears and a comment types out character by character." },
+ { title: "Mention anyone", subtitle: "Type @ and a picker appears with people, agents, and squads. Choose who to notify." },
+ { title: "Workspace overview", subtitle: "Switch between Projects, Agents, Runtimes, Skills, and Settings with workspace chips." },
+ ],
+ },
+ workspace: {
+ kicker: "Workspace assets",
+ title: "Projects, agents, and everything in between.",
+ subtitle: "Switch between workspace views to see the full picture.",
+ items: [
+ { title: "Projects", subtitle: "Browse projects with progress tracking" },
+ { title: "Project detail", subtitle: "Task stats, status fields, and resources" },
+ { title: "Agents", subtitle: "View agent status and recent activity" },
+ { title: "Runtimes", subtitle: "Check runtime availability and versions" },
+ { title: "Skills", subtitle: "Browse the workspace agent skill library" },
+ { title: "Skill detail", subtitle: "Inspect skill structure and documentation" },
+ { title: "Settings", subtitle: "Account, workspace, and preference controls" },
+ ],
+ },
+ video: { kicker: "Product demo", title: "See it in 30 seconds.", body: "A fast walkthrough of inbox, issues, context, comments, mentions, and workspace views." },
+ download: { kicker: "Internal build", title: "Download the Xiaomi internal APK from GitHub Pages.", package: "Package", api: "Service API", sha: "APK SHA256", latest: "Download APK", source: "View source", note: "Internal distribution only — not for external release." },
+ trust: {
+ kicker: "Internal build scope",
+ items: [
+ "Designed and implemented from scratch by Zhao Xisheng of Xiaomi's Commercial Platform Department, with no upstream Android app to inherit from.",
+ "Multica has not provided an official Android app to date; this project is an independent Xiaomi internal Android client for Multica workflows.",
+ "Company-internal distribution only. APK download is served from a separate GitHub release artifact repository after EdgeOne proved unreliable.",
+ "Connects to the Xiaomi Multica service endpoint, with analytics routed through OneTrack and disabled for Umeng / PostHog.",
+ "Source is kept in the private company GitLab project; the signed APK is distributed from GitHub Pages.",
+ ],
+ },
+ footer: { tagline: "Built from scratch by Zhao Xisheng for the Xiaomi workspace. APK served via GitHub Pages.", multica: "Multica website", gitlab: "GitLab", ios: "iOS App", download: "Download APK" },
+ },
+ zh: {
+ nav: { brand: "Multica Xiaomi", download: "下载", trust: "分发说明", language: "English" },
+ hero: {
+ eyebrow: "小米内部构建 · 仅限公司内部分发",
+ title: "面向小米工作区的 Multica Xiaomi 内部版。",
+ subtitle: "由小米商业平台部赵锡盛完全从头自研的 Android App。Multica 官方到目前为止还没有提供 Android App;这套内部构建先为小米用户补上原生移动端入口。",
+ download: "下载 APK",
+ gitlab: "GitLab",
+ multica: "访问 Multica",
+ ios: "iOS App",
+ },
+ journey: {
+ kicker: "交互式演示",
+ title: "试试这个流程。",
+ subtitle: "点击每个步骤,或滚动页面查看 app 实际操作。",
+ cta: "开始演示",
+ steps: [
+ { title: "Inbox 通知", subtitle: "新 issues、评论和 agent 进展会实时出现在收件箱,不错过任何动态。" },
+ { title: "浏览 Issues", subtitle: "在列表视图中查看所有任务,快速筛选和进入任意 issue。" },
+ { title: "切换看板视图", subtitle: "点击视图切换按钮,看板视图让你一眼看到任务状态流。" },
+ { title: "打开 Issue 详情", subtitle: "点击 issue 卡片查看完整详情:标题、状态、标签、负责人和正文。" },
+ { title: "探索上下文", subtitle: "Context 引导点依次放大标题与状态、正文内容、子任务与评论,然后缩回全貌。" },
+ { title: "滚动查看更多", subtitle: "继续下滑查看子任务、订阅者和评论线程 —— 结构化上下文都在同一页。" },
+ { title: "草拟评论", subtitle: "点击评论框,键盘出现,评论逐字输入。" },
+ { title: "@ 提及任何人", subtitle: "输入 @ 弹出选择器,可选人、agent 或小队。" },
+ { title: "Workspace 总览", subtitle: "通过 workspace chips 切换查看 Projects、Agents、Runtimes、Skills 和 Settings。" },
+ ],
+ },
+ workspace: {
+ kicker: "Workspace 资产",
+ title: "项目、agents,以及它们之间的一切。",
+ subtitle: "切换 workspace 视图,掌握全貌。",
+ items: [
+ { title: "Projects", subtitle: "浏览项目和进度追踪" },
+ { title: "项目详情", subtitle: "任务统计、状态字段和资源入口" },
+ { title: "Agents", subtitle: "查看 agent 状态和最近活动" },
+ { title: "Runtimes", subtitle: "检查运行时可用性和版本" },
+ { title: "Skills", subtitle: "浏览 workspace agent 技能库" },
+ { title: "技能详情", subtitle: "查看技能结构和文档" },
+ { title: "Settings", subtitle: "账号、工作区和偏好控制" },
+ ],
+ },
+ video: { kicker: "产品演示", title: "30 秒看完核心流程。", body: "快速演示 inbox 通知、issues 看板、上下文探索、评论回复、@ 提及和 workspace 视图切换。" },
+ download: { kicker: "内部构建", title: "从 GitHub Pages 下载小米内部 APK。", package: "Package", api: "Service API", sha: "APK SHA256", latest: "下载 APK", source: "查看源码", note: "仅供公司内部分发,不对外发布。" },
+ trust: {
+ kicker: "内部构建说明",
+ items: [
+ "由小米商业平台部赵锡盛完全从头设计和实现,不是基于 Multica 官方 Android 客户端改造。",
+ "Multica 官方到目前为止还没有提供 Android App;本项目是面向小米内部 Multica 工作流的独立 Android 客户端。",
+ "仅供公司内部分发;由于腾讯云 EdgeOne 访问不稳定,APK 下载改由单独的 GitHub Release 产物仓库托管提供。",
+ "连接小米 Multica 服务端点,统计走 OneTrack,Umeng / PostHog 已关闭。",
+ "源码保存在私有公司 GitLab 项目中;签名 APK 从 GitHub Pages 分发。",
+ ],
+ },
+ footer: { tagline: "商业平台部赵锡盛从头自研,APK 由 GitHub Pages 分发。", multica: "Multica 官网", gitlab: "GitLab", ios: "iOS App", download: "下载 APK" },
+ },
+};
+
+const JOURNEY_STEPS = 9;
+const TYPING_TEXT = "Looks good. I'll ask the agent to check the failing case and post a follow-up.";
+const MENTION_ITEMS = [
+ { name: "codex", color: "#1647ff" },
+ { name: "Opus", color: "#7c3aed" },
+ { name: "RollieOC", color: "#059669" },
+];
+
+const WORKSPACE_SCREENSHOTS = [projectsImg, projectDetailImg, agentsImg, runtimesImg, skillsImg, skillDetailImg, settingsImg];
+
+const fade = (reduced: boolean, delay = 0) => ({
+ initial: reduced ? {} : { opacity: 0, y: 18 },
+ whileInView: { opacity: 1, y: 0 },
+ viewport: { once: true, margin: "-60px" },
+ transition: { duration: 0.65, delay, ease: [0.25, 0.1, 0.25, 1] as const },
+});
+
+const reveal = (reduced: boolean) => ({
+ initial: reduced ? {} : { opacity: 0, y: 20 },
+ whileInView: { opacity: 1, y: 0 },
+ viewport: { once: true, margin: "-80px" },
+ transition: { duration: 0.7, ease: [0.25, 0.1, 0.25, 1] as const },
+});
+
+/* ── PhoneDemo ── */
+function PhoneDemo({
+ src,
+ reduced,
+ zoomScale = 1,
+ zoomX = 0,
+ zoomY = 0,
+ children,
+}: {
+ src: string;
+ reduced: boolean;
+ zoomScale?: number;
+ zoomX?: number;
+ zoomY?: number;
+ children?: React.ReactNode;
+}) {
+ return (
+
+ );
+}
+
+/* ── Typewriter effect ── */
+function TypewriterEffect({ active, text, reduced }: { active: boolean; text: string; reduced: boolean }) {
+ const charCount = useMotionValue(0);
+ const chars = useMemo(() => text.split(""), [text]);
+ const charRefs = useRef<(HTMLSpanElement | null)[]>([]);
+ const intervalRef = useRef | null>(null);
+
+ // Imperatively update char opacity from motion value (no hooks in loops)
+ useEffect(() => {
+ const unsubscribe = charCount.on("change", (v) => {
+ const count = Math.round(v);
+ charRefs.current.forEach((el, i) => {
+ if (el) el.style.opacity = i < count ? "1" : "0";
+ });
+ });
+ return unsubscribe;
+ }, [charCount]);
+
+ useEffect(() => {
+ if (intervalRef.current) clearInterval(intervalRef.current);
+ if (!active) { charCount.set(0); charRefs.current.forEach((el) => { if (el) el.style.opacity = "0"; }); return; }
+ if (reduced) {
+ charCount.set(chars.length);
+ charRefs.current.forEach((el, i) => { if (el) el.style.opacity = i < chars.length ? "1" : "0"; });
+ return;
+ }
+ let i = 0;
+ const interval = setInterval(() => {
+ i++;
+ charCount.set(i);
+ if (i >= chars.length) clearInterval(interval);
+ }, 42);
+ intervalRef.current = interval;
+ return () => clearInterval(interval);
+ }, [active, reduced, chars.length]);
+
+ return (
+
+ {chars.map((char, i) => (
+ { charRefs.current[i] = el; }}
+ style={{ opacity: 0 }}
+ >
+ {char === " " ? "\u00A0" : char}
+
+ ))}
+
+
+ );
+}
+
+/* ── PhoneMockup (hero) ── */
+function PhoneMockup({ reduced }: { reduced: boolean }) {
+ return (
+
+
+
+
+
+ );
+}
+
+/* ── Main App ── */
+export default function App() {
+ const reduced = useReducedMotion() ?? false;
+ const [lang, setLang] = useState("en");
+ const [step, setStep] = useState(0);
+ const [activeWs, setActiveWs] = useState(0);
+ const [hasInteracted, setHasInteracted] = useState(false);
+ const completedRef = useRef>(new Set());
+ const journeyRef = useRef(null);
+ const hasAutoPlayedRef = useRef(false);
+ const t = copy[lang];
+
+ // Auto-play journey on first scroll into view
+ useEffect(() => {
+ if (hasInteracted || hasAutoPlayedRef.current) return;
+ const el = journeyRef.current;
+ if (!el) return;
+
+ const observer = new IntersectionObserver(
+ ([entry]) => {
+ if (entry.isIntersecting && entry.intersectionRatio > 0.3 && !hasAutoPlayedRef.current) {
+ hasAutoPlayedRef.current = true;
+ let currentStep = 0;
+ const advance = () => {
+ currentStep++;
+ if (currentStep < JOURNEY_STEPS) {
+ setStep(currentStep);
+ setTimeout(advance, 2200);
+ }
+ };
+ setTimeout(advance, 2200);
+ }
+ },
+ { threshold: 0.3 }
+ );
+ observer.observe(el);
+ return () => observer.disconnect();
+ }, [hasInteracted]);
+
+ const handleStepClick = useCallback((index: number) => {
+ setHasInteracted(true);
+ setStep(index);
+ }, []);
+
+ const handleWorkspaceClick = useCallback((index: number) => {
+ setActiveWs(index);
+ }, []);
+
+ // Phone screen source based on journey step
+ const phoneScreenSrc = useMemo(() => {
+ if (step <= 1) return step === 0 ? inboxImg : issuesListImg;
+ if (step === 2) return issuesBoardImg;
+ if (step <= 5) return step === 3 ? issueDetailImg : issueSubImg;
+ if (step === 6) return commentImg;
+ if (step === 7) return mentionImg;
+ return projectsImg;
+ }, [step]);
+
+ // Focus zoom transform for step 4 (context explore)
+ const focusZones = [
+ { scale: 1.6, x: 0, y: -120 }, // title/status
+ { scale: 1.45, x: 0, y: -40 }, // body
+ { scale: 1.5, x: 0, y: 80 }, // subtasks/comments
+ ];
+ const focusIdx = step === 4 ? 0 : -1; // simple: show first zone; cycle handled by auto-play
+ const zoom = step === 4 ? focusZones[focusIdx] || focusZones[0] : { scale: 1, x: 0, y: 0 };
+
+ return (
+
+ {/* Hero */}
+
+
+
+
+
+
{t.nav.brand}
+
+
+
+
+
+
{t.hero.eyebrow}
+
{t.hero.title}
+
{t.hero.subtitle}
+
+ {t.hero.download}
+ {t.hero.gitlab}
+ {t.hero.multica}
+ {t.hero.ios}
+
+
+
+
+
+
+ {/* (Relationship section removed for the internal build.) */}
+
+ {/* Interactive Product Journey */}
+
+
+ {t.journey.kicker}
+ {t.journey.title}
+ {t.journey.subtitle}
+
+
+
+
+ {t.journey.steps.map((s, i) => (
+
handleStepClick(i)}
+ initial={reduced ? {} : { opacity: 0, x: -16 }}
+ whileInView={{ opacity: 1, x: 0 }}
+ viewport={{ once: true }}
+ transition={{ duration: 0.5, delay: i * 0.06 }}
+ >
+ {i < step ? "✓" : i + 1}
+
+
{s.title}
+
{s.subtitle}
+
+
+ ))}
+
+
+
+
+
+ {/* Hand + tap ripple for interactive steps */}
+ {step >= 1 && step <= 3 && (
+ <>
+ 👆
+
+ >
+ )}
+
+ {/* Typing effect for step 6 */}
+ {step === 6 && }
+
+ {/* Mention picker overlay for step 7 */}
+
+ {step === 7 && (
+
+
+ @ cod
+
+
+ {MENTION_ITEMS.map((m, i) => (
+
+ {m.name[0].toUpperCase()}
+
+
{m.name}
+
{i === 0 ? "agent" : i === 1 ? "agent" : "squad"}
+
+
+ ))}
+
+
+ )}
+
+
+ {/* Workspace chips overlay for step 8 */}
+ {step === 8 && (
+
+ {["Projects", "Agents", "Runtimes", "Skills", "Settings"].map((label, i) => (
+
+ {label}
+
+ ))}
+
+ )}
+
+
+
+
+
+
+ {/* Workspace Assets Grid */}
+
+
+
{t.workspace.kicker}
+
{t.workspace.title}
+
{t.workspace.subtitle}
+
+
+
+ {t.workspace.items.map((item, i) => (
+ handleWorkspaceClick(i)}
+ >
+ {item.title}
+
+ ))}
+
+
+
+
+
+ {t.workspace.items.map((item, i) => (
+ handleWorkspaceClick(i)}
+ initial={reduced ? {} : { opacity: 0, y: 16 }}
+ whileInView={{ opacity: 1, y: 0 }}
+ viewport={{ once: true }}
+ transition={{ duration: 0.5, delay: i * 0.06 }}
+ >
+
+
+ {item.title}
+ {item.subtitle}
+
+
+ ))}
+
+
+
+ {/* Video Demo */}
+
+ {t.video.kicker}
+
+
{t.video.title}
+
{t.video.body}
+
+
+
+
+ {/* Download */}
+
+
+ {t.download.kicker}
+ {t.download.title}
+
+
+ {t.download.package}
+ {release.packageName}
+
+
+ {t.download.api}
+ {release.apiUrl}
+
+
+ {t.download.sha}
+ {release.sha256}
+
+
+ {`adb install -r Multica-Xiaomi-v0.1.5.apk`}
+
+
+ {lang === "en"
+ ? <>APK downloads are served by a separate GitHub release artifact repository; source lives on the company GitLab .>
+ : <>APK 由单独的 GitHub Release 产物仓库分发;源码保存在公司 GitLab 。>
+ }
+
+
+
+
+ {/* Trust */}
+
+ {t.trust.kicker}
+
+ {t.trust.items.map((item) => (
+
+ ✓
+ {item}
+
+ ))}
+
+
+
+ {/* Footer */}
+
+
+
Multica Xiaomi
+
{t.footer.tagline}
+
+
+
+
+ );
+}
diff --git a/site-internal/src/assets/logo.png b/site-internal/src/assets/logo.png
new file mode 100644
index 0000000..8fa30f0
Binary files /dev/null and b/site-internal/src/assets/logo.png differ
diff --git a/site-internal/src/assets/screenshots/01-inbox.jpg b/site-internal/src/assets/screenshots/01-inbox.jpg
new file mode 100644
index 0000000..a8ace20
Binary files /dev/null and b/site-internal/src/assets/screenshots/01-inbox.jpg differ
diff --git a/site-internal/src/assets/screenshots/02-issues-list.jpg b/site-internal/src/assets/screenshots/02-issues-list.jpg
new file mode 100644
index 0000000..6bede1e
Binary files /dev/null and b/site-internal/src/assets/screenshots/02-issues-list.jpg differ
diff --git a/site-internal/src/assets/screenshots/03-issues-board.jpg b/site-internal/src/assets/screenshots/03-issues-board.jpg
new file mode 100644
index 0000000..54b6fda
Binary files /dev/null and b/site-internal/src/assets/screenshots/03-issues-board.jpg differ
diff --git a/site-internal/src/assets/screenshots/04-issue-detail.jpg b/site-internal/src/assets/screenshots/04-issue-detail.jpg
new file mode 100644
index 0000000..9ffb4d9
Binary files /dev/null and b/site-internal/src/assets/screenshots/04-issue-detail.jpg differ
diff --git a/site-internal/src/assets/screenshots/05-issue-detail-subissues.jpg b/site-internal/src/assets/screenshots/05-issue-detail-subissues.jpg
new file mode 100644
index 0000000..09de083
Binary files /dev/null and b/site-internal/src/assets/screenshots/05-issue-detail-subissues.jpg differ
diff --git a/site-internal/src/assets/screenshots/06-comment-composer.jpg b/site-internal/src/assets/screenshots/06-comment-composer.jpg
new file mode 100644
index 0000000..46551d9
Binary files /dev/null and b/site-internal/src/assets/screenshots/06-comment-composer.jpg differ
diff --git a/site-internal/src/assets/screenshots/07-mention-picker.jpg b/site-internal/src/assets/screenshots/07-mention-picker.jpg
new file mode 100644
index 0000000..0ab61a5
Binary files /dev/null and b/site-internal/src/assets/screenshots/07-mention-picker.jpg differ
diff --git a/site-internal/src/assets/screenshots/08-projects-list.jpg b/site-internal/src/assets/screenshots/08-projects-list.jpg
new file mode 100644
index 0000000..03710d6
Binary files /dev/null and b/site-internal/src/assets/screenshots/08-projects-list.jpg differ
diff --git a/site-internal/src/assets/screenshots/09-project-detail.jpg b/site-internal/src/assets/screenshots/09-project-detail.jpg
new file mode 100644
index 0000000..69398ae
Binary files /dev/null and b/site-internal/src/assets/screenshots/09-project-detail.jpg differ
diff --git a/site-internal/src/assets/screenshots/10-agents-list.jpg b/site-internal/src/assets/screenshots/10-agents-list.jpg
new file mode 100644
index 0000000..5b1a631
Binary files /dev/null and b/site-internal/src/assets/screenshots/10-agents-list.jpg differ
diff --git a/site-internal/src/assets/screenshots/11-runtimes-list.jpg b/site-internal/src/assets/screenshots/11-runtimes-list.jpg
new file mode 100644
index 0000000..9b6cf4f
Binary files /dev/null and b/site-internal/src/assets/screenshots/11-runtimes-list.jpg differ
diff --git a/site-internal/src/assets/screenshots/12-skills-list.jpg b/site-internal/src/assets/screenshots/12-skills-list.jpg
new file mode 100644
index 0000000..79b73c0
Binary files /dev/null and b/site-internal/src/assets/screenshots/12-skills-list.jpg differ
diff --git a/site-internal/src/assets/screenshots/13-skill-detail.jpg b/site-internal/src/assets/screenshots/13-skill-detail.jpg
new file mode 100644
index 0000000..a6a827b
Binary files /dev/null and b/site-internal/src/assets/screenshots/13-skill-detail.jpg differ
diff --git a/site-internal/src/assets/screenshots/14-settings.jpg b/site-internal/src/assets/screenshots/14-settings.jpg
new file mode 100644
index 0000000..244035e
Binary files /dev/null and b/site-internal/src/assets/screenshots/14-settings.jpg differ
diff --git a/site-internal/src/assets/video/multica-android-promo-draft.mp4 b/site-internal/src/assets/video/multica-android-promo-draft.mp4
new file mode 100644
index 0000000..f36d193
Binary files /dev/null and b/site-internal/src/assets/video/multica-android-promo-draft.mp4 differ
diff --git a/site-internal/src/main.tsx b/site-internal/src/main.tsx
new file mode 100644
index 0000000..3589701
--- /dev/null
+++ b/site-internal/src/main.tsx
@@ -0,0 +1,10 @@
+import React from "react";
+import ReactDOM from "react-dom/client";
+import App from "./App";
+import "./styles.css";
+
+ReactDOM.createRoot(document.getElementById("root")!).render(
+
+
+ ,
+);
diff --git a/site-internal/src/styles.css b/site-internal/src/styles.css
new file mode 100644
index 0000000..8887020
--- /dev/null
+++ b/site-internal/src/styles.css
@@ -0,0 +1,971 @@
+:root {
+ --blue: #1647ff;
+ --blue-2: #0f33c8;
+ --yellow: #ffe45c;
+ --ink: #101218;
+ --muted: #687080;
+ --paper: #f6f8fc;
+ --card: #ffffff;
+ --line: rgba(16, 18, 24, 0.1);
+ --shadow: 0 24px 70px rgba(16, 18, 24, 0.14);
+ font-family: -apple-system, BlinkMacSystemFont, "SF Pro Display", "Noto Sans SC", "PingFang SC", "Microsoft YaHei", sans-serif;
+ color: var(--ink);
+ background: var(--paper);
+}
+
+* { box-sizing: border-box; }
+
+html { scroll-behavior: smooth; }
+
+body {
+ margin: 0;
+ min-width: 320px;
+ overflow-x: hidden;
+ background:
+ radial-gradient(circle at 82% 5%, rgba(255, 228, 92, 0.4), transparent 31%),
+ radial-gradient(circle at 10% 30%, rgba(22, 71, 255, 0.16), transparent 30%),
+ linear-gradient(180deg, #fbfcff 0%, #e8eeff 55%, #d4dff9 85%, #c4d4f5 100%);
+}
+
+body, button, input { font: inherit; }
+
+button { cursor: pointer; }
+
+a { color: inherit; text-decoration: none; }
+
+.section-pad { padding: 80px clamp(22px, 5vw, 76px); }
+
+.hero {
+ min-height: 100vh;
+ position: relative;
+ overflow: hidden;
+ padding-top: 26px;
+ padding-left: clamp(16px, 5vw, 76px);
+ padding-right: clamp(16px, 5vw, 76px);
+}
+
+.hero-bg {
+ position: absolute;
+ inset: 0;
+ background-image:
+ linear-gradient(rgba(16, 18, 24, 0.045) 1px, transparent 1px),
+ linear-gradient(90deg, rgba(16, 18, 24, 0.045) 1px, transparent 1px);
+ background-size: 56px 56px;
+ mask-image: linear-gradient(to bottom, black 0%, transparent 88%);
+ pointer-events: none;
+}
+
+.topbar {
+ width: min(1160px, 100%);
+ margin: 0 auto 70px;
+ position: relative;
+ z-index: 2;
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ gap: 24px;
+ padding: 12px;
+ border: 1px solid var(--line);
+ border-radius: 999px;
+ background: rgba(255, 255, 255, 0.72);
+ backdrop-filter: blur(18px);
+ box-shadow: 0 12px 36px rgba(16, 18, 24, 0.06);
+}
+
+.brand, .nav-links { display: flex; align-items: center; gap: 10px; }
+
+.brand { font-weight: 850; letter-spacing: -0.02em; }
+
+.brand-mark {
+ width: 34px;
+ height: 34px;
+ border-radius: 10px;
+ object-fit: cover;
+ display: block;
+}
+
+.nav-links a {
+ color: var(--muted);
+ font-size: 14px;
+ font-weight: 700;
+ padding: 8px 10px;
+}
+
+.nav-links a:hover { color: var(--ink); }
+
+.language-toggle {
+ color: var(--blue);
+ font-size: 14px;
+ font-weight: 850;
+ padding: 8px 12px;
+ border: 1px solid rgba(22, 71, 255, 0.18);
+ border-radius: 999px;
+ background: rgba(22, 71, 255, 0.07);
+}
+
+.language-toggle:hover { background: rgba(22, 71, 255, 0.12); }
+
+.hero-grid {
+ width: min(1160px, 100%);
+ margin: 0 auto;
+ position: relative;
+ z-index: 1;
+ display: grid;
+ grid-template-columns: minmax(0, 1.06fr) minmax(320px, 0.72fr);
+ gap: clamp(28px, 7vw, 96px);
+ align-items: center;
+}
+
+.eyebrow, .section-kicker {
+ margin: 0 0 16px;
+ color: var(--blue);
+ font-size: 12px;
+ font-weight: 900;
+ letter-spacing: 0.15em;
+ text-transform: uppercase;
+}
+
+h1, h2, h3, p { margin-top: 0; }
+
+h1 {
+ max-width: 780px;
+ margin-bottom: 24px;
+ font-size: clamp(54px, 8.2vw, 112px);
+ line-height: 0.9;
+ letter-spacing: -0.075em;
+}
+
+h2 {
+ font-size: clamp(36px, 5vw, 72px);
+ line-height: 0.94;
+ letter-spacing: -0.065em;
+ margin-bottom: 22px;
+}
+
+main[lang="zh-CN"] h1 {
+ max-width: 700px;
+ font-size: clamp(42px, 6.8vw, 86px);
+ line-height: 0.98;
+ letter-spacing: -0.07em;
+}
+
+main[lang="zh-CN"] h2 {
+ font-size: clamp(34px, 4.6vw, 62px);
+ line-height: 1;
+}
+
+h3 {
+ font-size: 24px;
+ line-height: 1.08;
+ letter-spacing: -0.035em;
+}
+
+.hero-subtitle, .relationship p, .demo p, .journey-desc {
+ max-width: 650px;
+ color: #343b4a;
+ font-size: clamp(18px, 2vw, 23px);
+ line-height: 1.48;
+}
+
+.cta-row { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 32px; }
+.cta-row.compact { margin-top: 22px; }
+
+.button {
+ font-size: 15px;
+ display: inline-flex;
+ min-height: 48px;
+ align-items: center;
+ justify-content: center;
+ border-radius: 999px;
+ padding: 0 20px;
+ font-weight: 850;
+ border: 1px solid transparent;
+ transition: color 0.18s ease, background 0.18s ease, border-color 0.18s ease;
+}
+
+.button.primary { color: white; background: var(--blue); box-shadow: 0 14px 34px rgba(22, 71, 255, 0.32); }
+.button.secondary { background: white; border-color: var(--line); }
+.button.ghost { color: var(--muted); background: rgba(255, 255, 255, 0.54); border-color: var(--line); }
+
+/* Phone mockup */
+.phone-wrap {
+ width: min(390px, 82vw);
+ margin: 0 auto;
+ position: relative;
+ transform-origin: center;
+}
+
+.hero-phone-stack {
+ min-height: 720px;
+ position: relative;
+ perspective: 1200px;
+}
+
+.hero-phone-stack img {
+ position: absolute;
+ width: min(310px, 54vw);
+ height: 676px;
+ border-radius: 46px;
+ border: 12px solid #11141d;
+ background: white;
+ object-fit: cover;
+ object-position: top center;
+ box-shadow: var(--shadow);
+}
+
+.hero-phone-stack img:nth-child(1) { left: 2%; top: 48px; transform: rotate(-8deg) translateZ(-20px); }
+.hero-phone-stack img:nth-child(2) { left: 28%; top: 0; transform: rotate(4deg) translateZ(40px); }
+.hero-phone-stack img:nth-child(3) { right: 0; top: 132px; transform: rotate(10deg) translateZ(10px); }
+
+.phone-shell {
+ position: relative;
+ padding: 14px;
+ border-radius: 54px;
+ background: #11141d;
+ box-shadow: var(--shadow), inset 0 0 0 2px rgba(255,255,255,0.1);
+}
+
+.phone-shell-compact {
+ position: relative;
+ padding: 12px;
+ border-radius: 48px;
+ background: #11141d;
+ box-shadow: 0 20px 56px rgba(16, 18, 24, 0.22);
+}
+
+.speaker {
+ position: absolute;
+ top: 18px;
+ left: 50%;
+ width: 72px;
+ height: 8px;
+ transform: translateX(-50%);
+ border-radius: 999px;
+ background: rgba(255,255,255,0.18);
+ z-index: 2;
+}
+
+.phone-screen {
+ position: relative;
+ overflow: hidden;
+ border-radius: 40px;
+ background: white;
+ aspect-ratio: 9 / 19.7;
+}
+
+.phone-screen-compact {
+ position: relative;
+ overflow: hidden;
+ border-radius: 36px;
+ background: white;
+ aspect-ratio: 9 / 19.7;
+}
+
+.phone-screen img,
+.phone-screen-compact img {
+ width: 100%;
+ height: 100%;
+ object-fit: cover;
+ object-position: top center;
+ display: block;
+}
+
+.phone-screen-shot {
+ position: absolute;
+ inset: 0;
+ width: 100%;
+ height: 100%;
+ object-fit: cover;
+ object-position: top center;
+}
+
+
+
+.tap-ring {
+ position: absolute;
+ right: -8px;
+ bottom: 158px;
+ width: 76px;
+ height: 76px;
+ border-radius: 999px;
+ border: 2px solid var(--blue);
+ background: rgba(255, 228, 92, 0.7);
+ box-shadow: 0 0 0 16px rgba(255, 228, 92, 0.22);
+}
+
+/* Shared content sections */
+.relationship, .features, .demo, .video-demo, .download, .trust, .footer {
+ width: min(1160px, calc(100% - 44px));
+ margin: 0 auto;
+ padding-left: 0;
+ padding-right: 0;
+}
+
+.two-col, .demo-grid {
+ display: grid;
+ grid-template-columns: minmax(0, 0.85fr) minmax(320px, 1fr);
+ gap: clamp(24px, 5vw, 76px);
+ align-items: center;
+}
+
+/* Relationship section */
+.relationship-card {
+ border: 1px solid var(--line);
+ border-radius: 30px;
+ background: rgba(255,255,255,0.76);
+ box-shadow: 0 18px 48px rgba(16,18,24,0.08);
+ padding: clamp(28px, 5vw, 48px);
+}
+
+.relationship-card p {
+ max-width: 800px;
+ margin: 0 0 16px;
+ font-size: clamp(16px, 1.8vw, 20px);
+ line-height: 1.65;
+ color: #343b4a;
+}
+
+.relationship-card p:last-child { margin-bottom: 0; }
+
+.relationship-card a {
+ color: var(--blue);
+ text-decoration: underline;
+ text-decoration-color: rgba(22, 71, 255, 0.25);
+}
+
+.relationship-card a:hover { text-decoration-color: var(--blue); }
+
+/* Interactive product journey */
+.journey {
+ width: min(1160px, calc(100% - 44px));
+ margin: 0 auto;
+ padding: 40px 0;
+}
+
+.journey-header {
+ text-align: center;
+ margin-bottom: 48px;
+}
+
+.journey-header h2 {
+ max-width: 800px;
+ margin: 0 auto 16px;
+}
+
+.journey-header p {
+ max-width: 600px;
+ margin: 0 auto;
+ color: var(--muted);
+ font-size: 16px;
+}
+
+.journey-layout {
+ display: grid;
+ grid-template-columns: minmax(0, 1fr) minmax(280px, 440px);
+ gap: clamp(24px, 5vw, 64px);
+ align-items: start;
+}
+
+.journey-steps {
+ display: flex;
+ flex-direction: column;
+ gap: 16px;
+}
+
+.journey-step {
+ display: flex;
+ gap: 18px;
+ padding: 20px 24px;
+ border-radius: 20px;
+ border: 1px solid var(--line);
+ background: rgba(255,255,255,0.68);
+ cursor: pointer;
+ transition: background 0.2s ease, border-color 0.2s ease, box-shadow 0.2s ease;
+}
+
+.journey-step:hover {
+ background: rgba(255,255,255,0.92);
+ border-color: rgba(22, 71, 255, 0.18);
+}
+
+.journey-step-active {
+ background: white;
+ border-color: var(--blue);
+ box-shadow: 0 12px 36px rgba(22, 71, 255, 0.12);
+}
+
+.journey-step-completed {
+ opacity: 0.65;
+ cursor: default;
+}
+
+.journey-step-number {
+ width: 32px;
+ height: 32px;
+ border-radius: 999px;
+ background: rgba(22, 71, 255, 0.08);
+ color: var(--blue);
+ font-size: 14px;
+ font-weight: 900;
+ display: grid;
+ place-items: center;
+ flex: none;
+ margin-top: 2px;
+}
+
+.journey-step-active .journey-step-number {
+ background: var(--blue);
+ color: white;
+}
+
+.journey-step-completed .journey-step-number {
+ background: var(--blue);
+ color: white;
+}
+
+.journey-step-content h3 {
+ font-size: 18px;
+ margin-bottom: 6px;
+ letter-spacing: -0.02em;
+}
+
+.journey-step-content p {
+ font-size: 18px;
+ line-height: 1.55;
+ color: var(--muted);
+ margin: 0;
+}
+
+.journey-phone-area {
+ position: sticky;
+ top: 40px;
+}
+
+.journey-phone-container {
+ position: relative;
+ display: flex;
+ justify-content: center;
+}
+
+/* Journey phone overlays */
+.journey-overlay {
+ position: absolute;
+ inset: 0;
+ z-index: 6;
+ border-radius: 36px;
+ overflow: hidden;
+}
+
+.journey-hand {
+ position: absolute;
+ z-index: 8;
+ font-size: 28px;
+ filter: drop-shadow(0 4px 8px rgba(0,0,0,0.2));
+ pointer-events: none;
+}
+
+.journey-tap-ripple {
+ position: absolute;
+ z-index: 7;
+ width: 52px;
+ height: 52px;
+ border-radius: 999px;
+ border: 2px solid var(--blue);
+ background: rgba(255, 228, 92, 0.55);
+ box-shadow: 0 0 0 12px rgba(255, 228, 92, 0.18);
+ pointer-events: none;
+}
+
+/* Focus zoom */
+.focus-zoom {
+ position: absolute;
+ z-index: 5;
+ border-radius: 20px;
+ border: 3px solid var(--blue);
+ background: rgba(22, 71, 255, 0.06);
+ pointer-events: none;
+}
+
+/* Workspace assets grid */
+.workspace-section {
+ width: min(1160px, calc(100% - 44px));
+ margin: 0 auto;
+}
+
+.workspace-header {
+ text-align: center;
+ margin-bottom: 48px;
+}
+
+.workspace-header h2 {
+ max-width: 700px;
+ margin: 0 auto 16px;
+}
+
+.workspace-header p {
+ max-width: 560px;
+ margin: 0 auto;
+ color: var(--muted);
+ font-size: 16px;
+}
+
+.workspace-chips {
+ display: flex;
+ justify-content: center;
+ flex-wrap: wrap;
+ gap: 10px;
+ margin-bottom: 36px;
+}
+
+.workspace-chip {
+ padding: 10px 18px;
+ border-radius: 999px;
+ font-size: 14px;
+ font-weight: 850;
+ border: 1px solid var(--line);
+ background: rgba(255,255,255,0.72);
+ color: var(--muted);
+ transition: background 0.18s, color 0.18s, border-color 0.18s, box-shadow 0.18s;
+}
+
+.workspace-chip:hover {
+ background: white;
+ color: var(--ink);
+}
+
+.workspace-chip-active {
+ background: var(--blue);
+ color: white;
+ border-color: var(--blue);
+ box-shadow: 0 10px 24px rgba(22, 71, 255, 0.28);
+}
+
+.workspace-phone-wrap {
+ display: flex;
+ justify-content: center;
+ margin-bottom: 48px;
+}
+
+.workspace-phone-wrap .phone-shell-compact {
+ width: min(260px, 60vw);
+}
+
+/* Mention picker overlay */
+.mention-overlay {
+ position: absolute;
+ bottom: 0;
+ left: 0;
+ right: 0;
+ z-index: 10;
+ background: rgba(255,255,255,0.97);
+ backdrop-filter: blur(12px);
+ border-top: 1px solid var(--line);
+ border-radius: 24px 24px 36px 36px;
+ padding: 16px 14px;
+ box-shadow: 0 -12px 36px rgba(16, 18, 24, 0.1);
+}
+
+.mention-search {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ padding: 10px 14px;
+ border-radius: 14px;
+ background: #f4f6fa;
+ margin-bottom: 14px;
+ font-size: 14px;
+ color: var(--muted);
+}
+
+.mention-search span {
+ color: var(--blue);
+ font-weight: 800;
+}
+
+.mention-list {
+ display: flex;
+ flex-direction: column;
+ gap: 4px;
+}
+
+.mention-item {
+ display: flex;
+ align-items: center;
+ gap: 12px;
+ padding: 10px 12px;
+ border-radius: 14px;
+ transition: background 0.12s;
+}
+
+.mention-item-active {
+ background: rgba(22, 71, 255, 0.07);
+}
+
+.mention-avatar {
+ width: 32px;
+ height: 32px;
+ border-radius: 999px;
+ display: grid;
+ place-items: center;
+ font-size: 13px;
+ font-weight: 900;
+ color: white;
+ flex: none;
+}
+
+.mention-name {
+ font-size: 14px;
+ font-weight: 800;
+}
+
+.mention-role {
+ font-size: 12px;
+ color: var(--muted);
+}
+
+.mention-highlight {
+ position: absolute;
+ z-index: 5;
+ border-radius: 16px;
+ border: 2px solid var(--blue);
+ background: rgba(22, 71, 255, 0.06);
+ pointer-events: none;
+}
+
+/* Typing demo */
+.typing-line {
+ position: absolute;
+ z-index: 6;
+ display: flex;
+ align-items: center;
+ gap: 2px;
+ font-size: 18px;
+ font-weight: 700;
+ color: var(--ink);
+ letter-spacing: -0.01em;
+ line-height: 1;
+ white-space: pre;
+ pointer-events: none;
+}
+
+.typing-cursor {
+ display: inline-block;
+ width: 2px;
+ height: 18px;
+ background: var(--blue);
+ border-radius: 999px;
+ margin-left: 1px;
+}
+
+/* Features grid (legacy, kept for reference) */
+.feature-grid, .trust-grid, .release-grid {
+ display: grid;
+ grid-template-columns: repeat(3, minmax(0, 1fr));
+ gap: 18px;
+}
+
+.feature-card, .trust-item, .release-card {
+ border: 1px solid var(--line);
+ border-radius: 30px;
+ background: rgba(255,255,255,0.76);
+ box-shadow: 0 18px 48px rgba(16,18,24,0.08);
+}
+
+.feature-card { padding: 28px; min-height: 250px; }
+.feature-card span { color: var(--blue); font-weight: 950; font-size: 13px; letter-spacing: 0.12em; }
+.feature-card p, .trust-item p { color: var(--muted); line-height: 1.65; }
+
+.demo { overflow: hidden; }
+.screenshot-stack { min-height: 560px; position: relative; overflow: hidden; border-radius: 42px; }
+.shot {
+ position: absolute;
+ width: min(310px, 52vw);
+ height: 620px;
+ border-radius: 34px;
+ border: 10px solid #11141d;
+ box-shadow: var(--shadow);
+ background: white;
+ object-fit: cover;
+ object-position: top center;
+}
+.shot.back { right: 210px; top: 40px; transform: rotate(-7deg); opacity: 0.78; }
+.shot.front { right: 12px; top: 0; transform: rotate(5deg); }
+
+.video-demo {
+ padding-top: 20px;
+}
+
+.video-copy {
+ display: grid;
+ grid-template-columns: minmax(0, 0.95fr) minmax(320px, 1fr);
+ gap: clamp(24px, 5vw, 76px);
+ align-items: end;
+ margin-bottom: 28px;
+}
+
+.video-copy p {
+ color: #343b4a;
+ font-size: clamp(17px, 1.7vw, 21px);
+ line-height: 1.55;
+}
+
+.promo-video, .video-placeholder {
+ display: block;
+ width: 100%;
+ aspect-ratio: 16 / 9;
+ border: 1px solid var(--line);
+ border-radius: 34px;
+ background: #0e1320;
+ box-shadow: var(--shadow);
+}
+
+.promo-video { object-fit: cover; z-index: 1; position: relative; }
+
+.video-placeholder {
+ display: grid;
+ place-items: center;
+ color: white;
+ background:
+ radial-gradient(circle at 70% 24%, rgba(255, 228, 92, 0.22), transparent 34%),
+ linear-gradient(135deg, #0e1320, #172453);
+}
+
+.video-placeholder span {
+ width: 86px;
+ height: 86px;
+ display: grid;
+ place-items: center;
+ margin-bottom: 18px;
+ border-radius: 999px;
+ color: var(--blue);
+ background: var(--yellow);
+ font-size: 44px;
+ font-weight: 950;
+ box-shadow: 0 18px 42px rgba(255, 228, 92, 0.24);
+}
+
+.video-placeholder strong {
+ display: block;
+ color: white;
+ font-size: clamp(22px, 3vw, 42px);
+ letter-spacing: -0.04em;
+}
+
+.download { padding-top: 40px; }
+.release-card { padding: clamp(28px, 5vw, 54px); }
+.release-grid { margin: 30px 0 22px; }
+.release-grid div {
+ min-width: 0;
+ padding: 18px;
+ border-radius: 20px;
+ background: #f7f9ff;
+ border: 1px solid rgba(22, 71, 255, 0.13);
+}
+.release-grid span { display: block; color: var(--muted); font-size: 12px; font-weight: 900; text-transform: uppercase; letter-spacing: 0.12em; margin-bottom: 8px; }
+.release-grid code, pre code { font-family: "SFMono-Regular", ui-monospace, Menlo, Consolas, "PingFang SC", monospace; }
+.release-grid code { display: block; overflow-wrap: anywhere; color: var(--ink); font-size: 14px; }
+.hash-cell { grid-column: span 3; }
+pre {
+ overflow: auto;
+ margin: 0;
+ padding: 18px 20px;
+ border-radius: 20px;
+ color: #eef4ff;
+ background: #0e1320;
+}
+
+.trust-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
+.trust-item { display: flex; gap: 14px; padding: 22px; align-items: flex-start; }
+.check {
+ width: 30px;
+ height: 30px;
+ display: grid;
+ place-items: center;
+ flex: none;
+ color: white;
+ border-radius: 999px;
+ background: var(--blue);
+ font-weight: 900;
+}
+
+.footer {
+ display: flex;
+ justify-content: space-between;
+ gap: 24px;
+ align-items: flex-start;
+ color: var(--muted);
+ border-top: 1px solid var(--line);
+}
+.footer strong { color: var(--ink); }
+.footer-links { display: flex; gap: 18px; flex-wrap: wrap; font-weight: 800; color: var(--ink); }
+
+/* Responsive */
+@media (max-width: 900px) {
+ .topbar { border-radius: 24px; align-items: flex-start; flex-direction: column; }
+ .nav-links { flex-wrap: wrap; }
+ .hero-grid, .two-col, .demo-grid, .video-copy, .feature-grid, .trust-grid, .release-grid { grid-template-columns: 1fr; }
+ .hero { padding-left: 16px; padding-right: 16px; padding-top: 20px; min-height: auto; }
+ .hero-grid { width: 100%; }
+ .hero-grid > div:first-child { padding-right: 0; }
+ .hero-phone-stack { min-height: 400px; overflow: visible; }
+ .hero-phone-stack img { height: 480px; width: min(240px, 42vw); border-radius: 36px; border-width: 10px; }
+ .hero-phone-stack img:nth-child(1) { left: -5%; top: 36px; transform: rotate(-8deg) translateZ(-20px); }
+ .hero-phone-stack img:nth-child(2) { left: 22%; top: 0; transform: rotate(4deg) translateZ(40px); }
+ .hero-phone-stack img:nth-child(3) { right: -5%; top: 100px; transform: rotate(10deg) translateZ(10px); }
+ .eyebrow { font-size: 11px; letter-spacing: 0.1em; }
+ h1 { font-size: clamp(32px, 8vw, 52px) !important; }
+ .hero-subtitle { font-size: 15px; }
+ .journey-layout { grid-template-columns: 1fr; }
+ .journey-phone-area { position: relative; top: 0; order: -1; }
+ .journey-phone-container { justify-content: center; }
+ .section-pad { padding: 48px 16px; }
+ .hash-cell { grid-column: auto; }
+ .screenshot-stack { min-height: 680px; }
+ .shot { width: min(300px, 74vw); }
+ .shot.back { right: auto; left: 4%; }
+ .shot.front { right: 4%; top: 160px; }
+ .footer { flex-direction: column; }
+ .workspace-chips { justify-content: flex-start; }
+}
+
+@media (prefers-reduced-motion: reduce) {
+ *, *::before, *::after {
+ animation-duration: 0.01ms !important;
+ animation-iteration-count: 1 !important;
+ scroll-behavior: auto !important;
+ }
+}
+
+/* Workspace card grid */
+.workspace-card-grid {
+ display: grid;
+ grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
+ gap: 14px;
+ margin-top: 8px;
+}
+
+.workspace-card {
+ border: 1px solid var(--line);
+ border-radius: 18px;
+ background: rgba(255, 255, 255, 0.72);
+ overflow: hidden;
+ cursor: pointer;
+ transition: border-color 0.18s, box-shadow 0.18s, background 0.18s;
+}
+
+.workspace-card:hover {
+ background: white;
+ border-color: rgba(22, 71, 255, 0.18);
+}
+
+.workspace-card-active {
+ border-color: var(--blue);
+ box-shadow: 0 10px 28px rgba(22, 71, 255, 0.12);
+ background: white;
+}
+
+.workspace-card-thumb {
+ width: 100%;
+ aspect-ratio: 9 / 19.7;
+ object-fit: cover;
+ object-position: top center;
+ display: block;
+ border-bottom: 1px solid var(--line);
+}
+
+.workspace-card-label {
+ padding: 10px 12px;
+}
+
+.workspace-card-label strong {
+ display: block;
+ font-size: 13px;
+ font-weight: 850;
+ letter-spacing: -0.01em;
+ margin-bottom: 2px;
+}
+
+.workspace-card-label span {
+ display: block;
+ font-size: 11px;
+ color: var(--muted);
+ line-height: 1.4;
+}
+
+@media (max-width: 900px) {
+ .workspace-card-grid {
+ grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
+ }
+}
+
+.star-hint {
+ margin-top: 20px;
+ font-size: 18px;
+ color: var(--muted);
+ text-align: center;
+ font-weight: 600;
+}
+
+.star-hint a {
+ text-decoration: underline;
+ text-underline-offset: 3px;
+}
+
+/* ── Footer pills ── */
+.pill {
+ display: inline-flex; align-items: center; gap: 7px;
+ padding: 10px 22px; border-radius: 999px;
+ font-weight: 850; font-size: 15px; letter-spacing: -0.01em;
+ text-decoration: none; transition: all 0.22s;
+}
+.pill-android {
+ background: var(--blue); color: #fff;
+ box-shadow: 0 12px 30px rgba(22,71,255,0.30);
+}
+.pill-android:hover { background: var(--blue-2); transform: translateY(-1px); }
+.pill-android .android-icon {
+ width: 15px; height: 15px; display: inline-block; background: #fff;
+ -webkit-mask: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNCAyNCI+PHBhdGggZD0iTTYgMThjMCAuNTUuNDUgMSAxIDFoMXYzLjVjMCAuODMuNjcgMS41IDEuNSAxLjVzMS41LS42NyAxLjUtMS41VjE5aDJ2My41YzAgLjgzLjY3IDEuNSAxLjUgMS41czEuNS0uNjcgMS41LTEuNVYxOWgxYy41NSAwIDEtLjQ1IDEtMVY4SDZ2MTB6TTMuNSA4QzIuNjcgOCAyIDguNjcgMiA5LjV2N2MwIC44My42NyAxLjUgMS41IDEuNVM1IDE3LjMzIDUgMTYuNXYtN0M1IDguNjcgNC4zMyA4IDMuNSA4em0xNyAwYy0uODMgMC0xLjUuNjctMS41IDEuNXY3YzAgLjgzLjY3IDEuNSAxLjUgMS41czEuNS0uNjcgMS41LTEuNXYtN2MwLS44My0uNjctMS41LTEuNS0xLjV6bS00Ljk3LTUuODRsMS4zLTEuM2MuMi0uMi4yLS41MSAwLS43MS0uMi0uMi0uNTEtLjItLjcxIDBsLTEuNDggMS40OEE1Ljg0IDUuODQgMCAwMDEyIDFjLS45NiAwLTEuODYuMjMtMi42Ni42M0w3Ljg1LjE1Yy0uMi0uMi0uNTEtLjItLjcxIDAtLjIuMi0uMi41MSAwIC43MWwxLjMxIDEuMzFBNS45ODMgNS45ODMgMCAwMDYgN2gxMmMwLTIuMTItMS4xLTMuOTgtMi40Ny00Ljg0ek0xMCA1SDlWNGgxdjF6bTUgMGgtMVY0aDF2MXoiLz48L3N2Zz4=) center/contain no-repeat;
+ mask: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNCAyNCI+PHBhdGggZD0iTTYgMThjMCAuNTUuNDUgMSAxIDFoMXYzLjVjMCAuODMuNjcgMS41IDEuNSAxLjVzMS41LS42NyAxLjUtMS41VjE5aDJ2My41YzAgLjgzLjY3IDEuNSAxLjUgMS41czEuNS0uNjcgMS41LTEuNVYxOWgxYy41NSAwIDEtLjQ1IDEtMVY4SDZ2MTB6TTMuNSA4QzIuNjcgOCAyIDguNjcgMiA5LjV2N2MwIC44My42NyAxLjUgMS41IDEuNVM1IDE3LjMzIDUgMTYuNXYtN0M1IDguNjcgNC4zMyA4IDMuNSA4em0xNyAwYy0uODMgMC0xLjUuNjctMS41IDEuNXY3YzAgLjgzLjY3IDEuNSAxLjUgMS41czEuNS0uNjcgMS41LTEuNXYtN2MwLS44My0uNjctMS41LTEuNS0xLjV6bS00Ljk3LTUuODRsMS4zLTEuM2MuMi0uMi4yLS41MSAwLS43MS0uMi0uMi0uNTEtLjItLjcxIDBsLTEuNDggMS40OEE1Ljg0IDUuODQgMCAwMDEyIDFjLS45NiAwLTEuODYuMjMtMi42Ni42M0w3Ljg1LjE1Yy0uMi0uMi0uNTEtLjItLjcxIDAtLjIuMi0uMi41MSAwIC43MWwxLjMxIDEuMzFBNS45ODMgNS45ODMgMCAwMDYgN2gxMmMwLTIuMTItMS4xLTMuOTgtMi40Ny00Ljg0ek0xMCA1SDlWNGgxdjF6bTUgMGgtMVY0aDF2MXoiLz48L3N2Zz4=) center/contain no-repeat;
+}
+
+.pill-ios {
+ position: relative; overflow: hidden;
+ background: rgba(255,255,255,0.22);
+ backdrop-filter: blur(20px) saturate(1.8);
+ -webkit-backdrop-filter: blur(20px) saturate(1.8);
+ color: #1a1a2e; font-weight: 850;
+ border: 1px solid rgba(255,255,255,0.55);
+ box-shadow: 0 4px 20px rgba(0,0,0,0.08),
+ inset 0 1px 0 rgba(255,255,255,0.9),
+ inset 0 -1px 0 rgba(0,0,0,0.04);
+}
+.pill-ios:hover {
+ background: rgba(255,255,255,0.38);
+ transform: translateY(-1px);
+ box-shadow: 0 8px 28px rgba(0,0,0,0.12),
+ inset 0 1px 0 rgba(255,255,255,1),
+ inset 0 -1px 0 rgba(0,0,0,0.04);
+}
+.pill-ios::before {
+ content: "";
+ position: absolute; top: 0; left: -40%; width: 180%; height: 50%;
+ background: linear-gradient(180deg, rgba(255,255,255,0.7) 0%, rgba(255,255,255,0) 100%);
+ border-radius: 999px; pointer-events: none;
+}
+.pill-ios::after {
+ content: "";
+ position: absolute; bottom: -2px; left: 10%; width: 80%; height: 6px;
+ background: linear-gradient(90deg, #ff6b9d, #c44dff, #6b9dff, #45d4a8);
+ filter: blur(5px); opacity: 0.4; border-radius: 999px;
+ pointer-events: none; z-index: -1;
+}
+.pill-ios .apple-icon {
+ width: 14px; height: 14px; display: inline-block; background: #1a1a2e;
+ -webkit-mask: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNCAyNCI+PHBhdGggZD0iTTE4LjcxIDE5LjVjLS44MyAxLjI0LTEuNzEgMi40NS0zLjA1IDIuNDctMS4zNC4wMy0xLjc3LS43OS0zLjI5LS43OS0xLjUzIDAtMiAuNzctMy4yNy44Mi0xLjMxLjA1LTIuMy0xLjMyLTMuMTQtMi41M0M0LjI1IDE3IDIuOTQgMTIuNDUgNC43IDkuMzljLjg3LTEuNTIgMi40My0yLjQ4IDQuMTItMi41MSAxLjI4LS4wMiAyLjUuODcgMy4yOS44Ny43OCAwIDIuMjYtMS4wNyAzLjgxLS45MS42NS4wMyAyLjQ3LjI2IDMuNjQgMS45OC0uMDkuMDYtMi4xNyAxLjI4LTIuMTUgMy44MS4wMyAzLjAyIDIuNjUgNC4wMyAyLjY4IDQuMDQtLjAzLjA3LS40MiAxLjQ0LTEuMzggMi44M00xMyAzLjVjLjczLS44MyAxLjk0LTEuNDYgMi45NC0xLjUuMTMgMS4xNy0uMzQgMi4zNS0xLjA0IDMuMTktLjY5Ljg1LTEuODMgMS41MS0yLjk1IDEuNDItLjE1LTEuMTUuNDEtMi4zNSAxLjA1LTMuMTF6Ii8+PC9zdmc+) center/contain no-repeat;
+ mask: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNCAyNCI+PHBhdGggZD0iTTE4LjcxIDE5LjVjLS44MyAxLjI0LTEuNzEgMi40NS0zLjA1IDIuNDctMS4zNC4wMy0xLjc3LS43OS0zLjI5LS43OS0xLjUzIDAtMiAuNzctMy4yNy44Mi0xLjMxLjA1LTIuMy0xLjMyLTMuMTQtMi41M0M0LjI1IDE3IDIuOTQgMTIuNDUgNC43IDkuMzljLjg3LTEuNTIgMi40My0yLjQ4IDQuMTItMi41MSAxLjI4LS4wMiAyLjUuODcgMy4yOS44Ny43OCAwIDIuMjYtMS4wNyAzLjgxLS45MS42NS4wMyAyLjQ3LjI2IDMuNjQgMS45OC0uMDkuMDYtMi4xNyAxLjI4LTIuMTUgMy44MS4wMyAzLjAyIDIuNjUgNC4wMyAyLjY4IDQuMDQtLjAzLjA3LS40MiAxLjQ0LTEuMzggMi44M00xMyAzLjVjLjczLS44MyAxLjk0LTEuNDYgMi45NC0xLjUuMTMgMS4xNy0uMzQgMi4zNS0xLjA0IDMuMTktLjY5Ljg1LTEuODMgMS41MS0yLjk1IDEuNDItLjE1LTEuMTUuNDEtMi4zNSAxLjA1LTMuMTF6Ii8+PC9zdmc+) center/contain no-repeat;
+}
+
+@media (max-width: 600px) {
+ .pill { padding: 8px 16px; font-size: 14px; }
+}
diff --git a/site-internal/src/vite-env.d.ts b/site-internal/src/vite-env.d.ts
new file mode 100644
index 0000000..11f02fe
--- /dev/null
+++ b/site-internal/src/vite-env.d.ts
@@ -0,0 +1 @@
+///
diff --git a/site-internal/tsconfig.json b/site-internal/tsconfig.json
new file mode 100644
index 0000000..596336d
--- /dev/null
+++ b/site-internal/tsconfig.json
@@ -0,0 +1,21 @@
+{
+ "compilerOptions": {
+ "target": "ES2022",
+ "useDefineForClassFields": true,
+ "lib": ["DOM", "DOM.Iterable", "ES2022"],
+ "allowJs": false,
+ "skipLibCheck": true,
+ "esModuleInterop": true,
+ "allowSyntheticDefaultImports": true,
+ "strict": true,
+ "forceConsistentCasingInFileNames": true,
+ "module": "ESNext",
+ "moduleResolution": "Bundler",
+ "resolveJsonModule": true,
+ "isolatedModules": true,
+ "noEmit": true,
+ "jsx": "react-jsx"
+ },
+ "include": ["src"],
+ "references": []
+}
diff --git a/site-internal/vite.config.ts b/site-internal/vite.config.ts
new file mode 100644
index 0000000..189c8a4
--- /dev/null
+++ b/site-internal/vite.config.ts
@@ -0,0 +1,13 @@
+import { defineConfig } from 'vite';
+import react from '@vitejs/plugin-react';
+
+export default defineConfig(() => ({
+ plugins: [react()],
+ base: process.env.VITE_BASE || '/',
+ build: {
+ outDir: 'dist',
+ },
+ server: {
+ host: '127.0.0.1',
+ },
+}));