From 222b2168d876c6dcdd7dcdd5be815803f1bec839 Mon Sep 17 00:00:00 2001 From: Melendez Date: Mon, 3 Aug 2026 12:47:55 +0800 Subject: [PATCH 1/3] Add AGENTS.md and update Web styles Add AGENTS.md documenting repository structure, workflows and conventions. Refactor Web CSS --- AGENTS.md | 54 +++ Web/css/index.css | 136 +++--- Web/index.html | 2 +- Web/package-lock.json | 950 +++++++++++++++++++++--------------------- Web/package.json | 2 +- 5 files changed, 588 insertions(+), 556 deletions(-) create mode 100644 AGENTS.md diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..d033ad9 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,54 @@ +# AGENTS.md + +Monorepo for **Known** (知学情), an exam-score analysis app for students. Three independent platform apps that share no +code: + +- `Web/` — marketing/landing site (Vite, plain HTML/CSS/JS, no framework). Most active work. +- `Android/` — Kotlin + Jetpack Compose (Material 3), Gradle Kotlin DSL, `mobile` + `wear` modules. +- `HarmonyOS/` — ArkTS app for DevEco Studio (hvigor build). + +## Git workflow + +- Default branch is `main`. Feature work happens on per-platform branches: `dev_web`, `dev_android`, `dev_harmony`, + `dev_wear`. Currently checked out: `dev_web`. +- All Git commits require explicit human confirmation before running. +- Pushes to `main` touching `Web/**` trigger `.github/workflows/static.yml`, which deploys the **raw `Web/` directory** + to GitHub Pages — there is no build step, so `src/`/`css/` edits go live as-is after the push. `vite build` output + (`dist/`) is not deployed. + +## Web (`Web/`) + +Commands (run in `Web/`): + +- `npm run dev` — Vite dev server. Vite is only a dev server/build tool here; the site itself is static HTML. +- `npm run build` / `npm run preview` +- No tests, no lint, no typecheck. Only Prettier for formatting (`.prettierrc`: single quotes, printWidth 80, tabWidth + 2). + +Gotchas: + +- `src/script.js` is the real UI logic (theme, language, particles, changelog timeline). +- `src/main.js` is leftover WebStorm counter boilerplate. Its top-level + `setupCounter(document.getElementById('counter-value'))` throws at load because no `#counter-value` element exists, + which also prevents its `DOMContentLoaded` handler from registering. Don't build on it. +- All UI strings are in `assets/values/translations.json` (locales `zh`, `zh-tw`, `en`, `en-GB`), applied via + `data-i18n` attributes. Theme/lang dropdown state persists in `localStorage`. +- The changelog section is fetched live from the GitHub API (`Melendez1209/Known`: releases, then commits fallback) — it + is not stored in the repo. +- `404.html` also loads `src/i18n.js` and shares the same translations file. + +## Android (`Android/`) + +- Jetpack Compose + Material 3, Gradle Kotlin DSL, modules `mobile` and `wear`. Build with `gradlew.bat`/`./gradlew`; + developed in Android Studio. + +## HarmonyOS (`HarmonyOS/`) + +- DevEco Studio project (ArkTS, hvigor). Requires the DevEco toolchain. + +## Project conventions (from `CONTRIBUTING.md`) + +- Audience is minors — never add porn/violence/gambling/drugs content anywhere in the repo. +- Use **CRLF** line endings and leave a blank line at the end of every file. +- Code comments in standard English; a space before and after `//`, no trailing full stop. +- Android: run Android Studio's code cleanup on changed files before committing. diff --git a/Web/css/index.css b/Web/css/index.css index d713263..1796994 100644 --- a/Web/css/index.css +++ b/Web/css/index.css @@ -134,7 +134,30 @@ nav a.active { .theme-dropdown, .lang-dropdown { + position: absolute; top: calc(100% + 0.5rem); + right: 0; + z-index: 1000; + min-width: 180px; + padding: 0.5rem; + gap: 0.2rem; + display: flex; + flex-direction: column; + border-radius: 12px; + background: rgba(255, 255, 255, 0.85); + backdrop-filter: blur(20px); + -webkit-backdrop-filter: blur(20px); + border: 1px solid rgba(165, 75, 207, 0.1); + box-shadow: 0 8px 30px var(--shadow-color); + opacity: 0; + visibility: hidden; + transform: translateY(-10px) scale(0.95); + transition: all 0.25s cubic-bezier(0.16, 1, 0.3, 1); +} + +[data-theme="dark"] .theme-dropdown, +[data-theme="dark"] .lang-dropdown { + background: rgba(22, 33, 62, 0.85); } .theme-selector, @@ -874,32 +897,14 @@ footer { position: relative; } -.theme-dropdown { - position: absolute; - top: 100%; - right: 0; - background: var(--card-background); - border-radius: 12px; - box-shadow: 0 8px 30px var(--shadow-color); - padding: 0.5rem; - z-index: 1000; - min-width: 180px; - gap: 0.2rem; - display: flex; - flex-direction: column; - opacity: 0; - visibility: hidden; - transform: translateY(-10px) scale(0.95); - transition: all 0.25s cubic-bezier(0.16, 1, 0.3, 1); -} - .theme-selector:hover .theme-dropdown { opacity: 1; visibility: visible; transform: translateY(0) scale(1); } -.theme-dropdown button { +.theme-dropdown button, +.lang-dropdown button { display: flex; align-items: center; gap: 0.8rem; @@ -912,26 +917,50 @@ footer { transition: all 0.2s ease; border-radius: 8px; font-size: 0.9rem; + line-height: 1.4; + text-align: left; white-space: nowrap; } -.theme-dropdown button:hover { +.theme-dropdown button:hover, +.lang-dropdown button:hover { background: var(--shadow-color); } .theme-dropdown button i { + display: inline-flex; + align-items: center; + justify-content: center; + width: 1.2rem; + height: 1.2rem; + font-size: 0.9rem; + line-height: 1; + flex-shrink: 0; +} + +.lang-dropdown button::before { + content: ''; width: 1.2rem; text-align: center; + line-height: 1; flex-shrink: 0; } -.theme-dropdown button[data-selected="true"] { +.theme-dropdown button[data-selected="true"], +.lang-dropdown button[data-selected="true"] { color: var(--primary-color); background: var(--shadow-color); font-weight: 600; } -.theme-selector button { +.lang-dropdown button[data-selected="true"]::before { + content: '\f00c'; + font-family: 'Font Awesome 6 Free', serif; + font-weight: 900; + color: var(--primary-color); +} + +.theme-toggle { background: none; border: none; color: var(--text-color); @@ -941,7 +970,7 @@ footer { transition: color 0.3s ease; } -.theme-selector button:hover { +.theme-toggle:hover { color: var(--primary-color); } @@ -971,71 +1000,12 @@ footer { position: relative; } -.lang-dropdown { - position: absolute; - top: 100%; - right: 0; - background: var(--card-background); - border-radius: 12px; - box-shadow: 0 8px 30px var(--shadow-color); - padding: 0.5rem; - z-index: 1000; - min-width: 180px; - gap: 0.2rem; - display: flex; - flex-direction: column; - opacity: 0; - visibility: hidden; - transform: translateY(-10px) scale(0.95); - transition: all 0.25s cubic-bezier(0.16, 1, 0.3, 1); -} - .lang-selector:hover .lang-dropdown { opacity: 1; visibility: visible; transform: translateY(0) scale(1); } -.lang-dropdown button { - display: flex; - align-items: center; - gap: 0.8rem; - width: 100%; - padding: 0.7rem 1rem; - border: none; - background: none; - color: var(--text-color); - cursor: pointer; - transition: all 0.2s ease; - border-radius: 8px; - font-size: 0.9rem; - white-space: nowrap; -} - -.lang-dropdown button:hover { - background: var(--shadow-color); -} - -.lang-dropdown button::before { - content: ''; - width: 1.2rem; - text-align: center; - flex-shrink: 0; -} - -.lang-dropdown button[data-selected="true"]::before { - content: '\f00c'; - font-family: 'Font Awesome 6 Free', serif; - font-weight: 900; - color: var(--primary-color); -} - -.lang-dropdown button[data-selected="true"] { - color: var(--primary-color); - background: var(--shadow-color); - font-weight: 600; -} - .lang-toggle { background: none; border: none; diff --git a/Web/index.html b/Web/index.html index 5e86bbc..94ff22d 100644 --- a/Web/index.html +++ b/Web/index.html @@ -42,7 +42,7 @@ Light Mode - diff --git a/Web/package-lock.json b/Web/package-lock.json index f84fe38..5bae81a 100644 --- a/Web/package-lock.json +++ b/Web/package-lock.json @@ -1,89 +1,87 @@ { - "name": "Web", + "name": "Known", "version": "1.2.2", "lockfileVersion": 3, "requires": true, "packages": { "": { - "name": "Web", - "version": "0.0.0", + "name": "Known", + "version": "1.2.2", "devDependencies": { "prettier": "^3.3.1", - "vite": "^5.1.6" + "vite": "8.0.16" } }, - "node_modules/@esbuild/aix-ppc64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", - "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", - "cpu": [ - "ppc64" - ], + "node_modules/@emnapi/core": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.10.0.tgz", + "integrity": "sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==", "dev": true, "license": "MIT", "optional": true, - "os": [ - "aix" - ], - "engines": { - "node": ">=12" + "dependencies": { + "@emnapi/wasi-threads": "1.2.1", + "tslib": "^2.4.0" } }, - "node_modules/@esbuild/android-arm": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", - "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", - "cpu": [ - "arm" - ], + "node_modules/@emnapi/runtime": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.10.0.tgz", + "integrity": "sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==", "dev": true, "license": "MIT", "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" + "dependencies": { + "tslib": "^2.4.0" } }, - "node_modules/@esbuild/android-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", - "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", - "cpu": [ - "arm64" - ], + "node_modules/@emnapi/wasi-threads": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.1.tgz", + "integrity": "sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==", "dev": true, "license": "MIT", "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" + "dependencies": { + "tslib": "^2.4.0" } }, - "node_modules/@esbuild/android-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", - "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", - "cpu": [ - "x64" - ], + "node_modules/@napi-rs/wasm-runtime": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.2.2.tgz", + "integrity": "sha512-JfB4kuJQjaoHuCTseIINHtHWeJnvgEcxjwA5t/Y00ZgaOO1Crz3fjT/p8kT28zA/Caz7oiUMn3d6H2yOVCVwuw==", "dev": true, "license": "MIT", "optional": true, - "os": [ - "android" - ], + "dependencies": { + "@tybys/wasm-util": "^0.10.3" + }, "engines": { - "node": ">=12" + "node": "^20.19.0 || ^22.13.0 || >=23.5.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Brooooooklyn" + }, + "peerDependencies": { + "@emnapi/core": "^1.7.1 || ^2.0.0-alpha.3", + "@emnapi/runtime": "^1.7.1 || ^2.0.0-alpha.3" } }, - "node_modules/@esbuild/darwin-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", - "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", + "node_modules/@oxc-project/types": { + "version": "0.133.0", + "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.133.0.tgz", + "integrity": "sha512-KzkdCd6Uxqnf6l3HOw1xfatAlUURA0g14cvBYFyJ5SaNOQbOUvBr9PKArcPcrNIeRsBdgcUzOGrhKveVpvOIGA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/Boshen" + } + }, + "node_modules/@rolldown/binding-android-arm64": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.0.3.tgz", + "integrity": "sha512-454rs7jHngixp/NMxd5srYD57OnzSlZ/eFTETjORQHLwJG1lRtmNOJcBerZlfu4GjKqeq8aCCIQrMdHyhI51Hw==", "cpu": [ "arm64" ], @@ -91,18 +89,18 @@ "license": "MIT", "optional": true, "os": [ - "darwin" + "android" ], "engines": { - "node": ">=12" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@esbuild/darwin-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", - "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", + "node_modules/@rolldown/binding-darwin-arm64": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.0.3.tgz", + "integrity": "sha512-PcAhP+ynjURNyy8SKGl5DQP94aGuB/7JrXJb/t7P+hanXvQVMWzUvRRhBAcg/lNRadBhoUPqSoP4xw5tR/KBEA==", "cpu": [ - "x64" + "arm64" ], "dev": true, "license": "MIT", @@ -111,30 +109,30 @@ "darwin" ], "engines": { - "node": ">=12" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@esbuild/freebsd-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", - "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", + "node_modules/@rolldown/binding-darwin-x64": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.0.3.tgz", + "integrity": "sha512-9YpfeUvSE2RS7wysJ81uOZkXJz7f7Q55H2Gvp3VEw/EsahqDtrphrZ0EwDLK5vvKOzaCrBsjF8JmnMLcUt78Gg==", "cpu": [ - "arm64" + "x64" ], "dev": true, "license": "MIT", "optional": true, "os": [ - "freebsd" + "darwin" ], "engines": { - "node": ">=12" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@esbuild/freebsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", - "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", + "node_modules/@rolldown/binding-freebsd-x64": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.0.3.tgz", + "integrity": "sha512-yB1IlAsSNHncV6SCTL27/MVGR5htvQsoGxIv5KMGXALp+Ll1wYsn+x98M9MW7qa+NdSbvrrY7ANI4wLJ0n1e6g==", "cpu": [ "x64" ], @@ -145,13 +143,13 @@ "freebsd" ], "engines": { - "node": ">=12" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@esbuild/linux-arm": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", - "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", + "node_modules/@rolldown/binding-linux-arm-gnueabihf": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.0.3.tgz", + "integrity": "sha512-Yi30IVAAfLUCy2MseFjbB1jAMDl1VMCAas5StnYp8da9+CKvMd2H2cbEjWcw5NPaPqzvYkVIaF1nNUG+b7u/sw==", "cpu": [ "arm" ], @@ -162,166 +160,186 @@ "linux" ], "engines": { - "node": ">=12" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@esbuild/linux-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", - "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", + "node_modules/@rolldown/binding-linux-arm64-gnu": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.0.3.tgz", + "integrity": "sha512-jsO7R8To+AdlYgUmN5sHSCZbfhtMBkO0WUx8iORQnPcMMdgr7qM2DQmMwgabs3GhNztdmoKkMKQFHD6DTMCIQw==", "cpu": [ "arm64" ], "dev": true, + "libc": [ + "glibc" + ], "license": "MIT", "optional": true, "os": [ "linux" ], "engines": { - "node": ">=12" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@esbuild/linux-ia32": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", - "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", + "node_modules/@rolldown/binding-linux-arm64-musl": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.0.3.tgz", + "integrity": "sha512-VWkUHwWriDciit80wleYwKILoR/KMvxh/IdwS/paX+ZgpuRpCrKLUdadJbc0NpBEiyhpYawsJ73j9aCvOH+f7Q==", "cpu": [ - "ia32" + "arm64" ], "dev": true, + "libc": [ + "musl" + ], "license": "MIT", "optional": true, "os": [ "linux" ], "engines": { - "node": ">=12" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@esbuild/linux-loong64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", - "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", + "node_modules/@rolldown/binding-linux-ppc64-gnu": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.0.3.tgz", + "integrity": "sha512-5f1laC0SlIR0yDbFCd8acUhvJIag6N3zC5P7oUPN6wX0aOma+uKJ0wBDH5aq7I1PVI2ttTlhJwzwRIBnLiSGEg==", "cpu": [ - "loong64" + "ppc64" ], "dev": true, + "libc": [ + "glibc" + ], "license": "MIT", "optional": true, "os": [ "linux" ], "engines": { - "node": ">=12" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@esbuild/linux-mips64el": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", - "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", + "node_modules/@rolldown/binding-linux-s390x-gnu": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.0.3.tgz", + "integrity": "sha512-Iq4ko0r4XsgbrF/LunNgHtAGLRRVE2kXonAXQ/MV0mC6jQpMOhW1SvtZja2EhC/kd05++bP78dsqBeIQyYJ6Yg==", "cpu": [ - "mips64el" + "s390x" ], "dev": true, + "libc": [ + "glibc" + ], "license": "MIT", "optional": true, "os": [ "linux" ], "engines": { - "node": ">=12" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@esbuild/linux-ppc64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", - "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", + "node_modules/@rolldown/binding-linux-x64-gnu": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.0.3.tgz", + "integrity": "sha512-B8m6tD5+/N5FeNQFbKlLA/2yVq9ycQP1SeedyEYYKWBNR3ZQbkvIUcNnDNM03lO1l5F2roiiFJGgvoLLyZXtSg==", "cpu": [ - "ppc64" + "x64" ], "dev": true, + "libc": [ + "glibc" + ], "license": "MIT", "optional": true, "os": [ "linux" ], "engines": { - "node": ">=12" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@esbuild/linux-riscv64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", - "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", + "node_modules/@rolldown/binding-linux-x64-musl": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.0.3.tgz", + "integrity": "sha512-pSdpdUJHkuCxun9LE7jvgUB9qsRgaiyNNCX7m/AvHTcq67AiT/Yhoxvw5zPfhrM8k/BfP8ce/hMOpthKDpEUow==", "cpu": [ - "riscv64" + "x64" ], "dev": true, + "libc": [ + "musl" + ], "license": "MIT", "optional": true, "os": [ "linux" ], "engines": { - "node": ">=12" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@esbuild/linux-s390x": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", - "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", + "node_modules/@rolldown/binding-openharmony-arm64": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.0.3.tgz", + "integrity": "sha512-OXXS3RKJgX2uLwM+gYyuH5omcH8fL1LJs96pZGgtetVCahON57+d4SJHzTgZiOjxgGkSnpXpOsWuPDGAKAigEg==", "cpu": [ - "s390x" + "arm64" ], "dev": true, "license": "MIT", "optional": true, "os": [ - "linux" + "openharmony" ], "engines": { - "node": ">=12" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@esbuild/linux-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", - "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", + "node_modules/@rolldown/binding-wasm32-wasi": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.0.3.tgz", + "integrity": "sha512-JTtb8BWFynicNSoPrehsCzBtOKjZ6jhMiPFEmOiuXg1Fl8dn2KHQob+GuPSGR0dryQa1PQJbzjF3dqO/whhjLg==", "cpu": [ - "x64" + "wasm32" ], "dev": true, "license": "MIT", "optional": true, - "os": [ - "linux" - ], + "dependencies": { + "@emnapi/core": "1.10.0", + "@emnapi/runtime": "1.10.0", + "@napi-rs/wasm-runtime": "^1.1.4" + }, "engines": { - "node": ">=12" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@esbuild/netbsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", - "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", + "node_modules/@rolldown/binding-win32-arm64-msvc": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.0.3.tgz", + "integrity": "sha512-gEdFFEN70A/jxb2svrWsN3aDL7OUtmvlOy+6fa2jxG8K0wQ1ZbdeLGnidov6Yu5/733dI5ySfzFlQ/cb0bSz1g==", "cpu": [ - "x64" + "arm64" ], "dev": true, "license": "MIT", "optional": true, "os": [ - "netbsd" + "win32" ], "engines": { - "node": ">=12" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@esbuild/openbsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", - "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", + "node_modules/@rolldown/binding-win32-x64-msvc": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.0.3.tgz", + "integrity": "sha512-eXB7CHuaQdqmJcc3koCNtNPmT/bj2gc999kUFgBxG8Ac0NdgXc4rkCHhqrgrhN3zddvvvrgzj1e90SuSfmyIXA==", "cpu": [ "x64" ], @@ -329,411 +347,350 @@ "license": "MIT", "optional": true, "os": [ - "openbsd" + "win32" ], "engines": { - "node": ">=12" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@esbuild/sunos-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", - "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", - "cpu": [ - "x64" - ], + "node_modules/@rolldown/pluginutils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.1.tgz", + "integrity": "sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw==", + "dev": true, + "license": "MIT" + }, + "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==", "dev": true, "license": "MIT", "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=12" + "dependencies": { + "tslib": "^2.4.0" } }, - "node_modules/@esbuild/win32-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", - "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", - "cpu": [ - "arm64" - ], + "node_modules/detect-libc": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", + "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], + "license": "Apache-2.0", "engines": { - "node": ">=12" + "node": ">=8" } }, - "node_modules/@esbuild/win32-ia32": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", - "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", - "cpu": [ - "ia32" - ], + "node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "win32" - ], "engines": { - "node": ">=12" + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } } }, - "node_modules/@esbuild/win32-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", - "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", - "cpu": [ - "x64" - ], + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", "dev": true, + "hasInstallScript": true, "license": "MIT", "optional": true, "os": [ - "win32" + "darwin" ], "engines": { - "node": ">=12" + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, - "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.34.6", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.34.6.tgz", - "integrity": "sha512-+GcCXtOQoWuC7hhX1P00LqjjIiS/iOouHXhMdiDSnq/1DGTox4SpUvO52Xm+div6+106r+TcvOeo/cxvyEyTgg==", - "cpu": [ - "arm" - ], + "node_modules/lightningcss": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.33.0.tgz", + "integrity": "sha512-WkUDrojuJs0xkgGf2udWxa3yGBRxPtxUkB79i6aCZLRgc7PM8fZe9TosfPDcvEpQZbuFASnHYmRLBLUbmLOIIA==", "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@rollup/rollup-android-arm64": { - "version": "4.34.6", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.34.6.tgz", - "integrity": "sha512-E8+2qCIjciYUnCa1AiVF1BkRgqIGW9KzJeesQqVfyRITGQN+dFuoivO0hnro1DjT74wXLRZ7QF8MIbz+luGaJA==", + "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.33.0", + "lightningcss-darwin-arm64": "1.33.0", + "lightningcss-darwin-x64": "1.33.0", + "lightningcss-freebsd-x64": "1.33.0", + "lightningcss-linux-arm-gnueabihf": "1.33.0", + "lightningcss-linux-arm64-gnu": "1.33.0", + "lightningcss-linux-arm64-musl": "1.33.0", + "lightningcss-linux-x64-gnu": "1.33.0", + "lightningcss-linux-x64-musl": "1.33.0", + "lightningcss-win32-arm64-msvc": "1.33.0", + "lightningcss-win32-x64-msvc": "1.33.0" + } + }, + "node_modules/lightningcss-android-arm64": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.33.0.tgz", + "integrity": "sha512-gEpRTalKdosp4Bb8qWtc2iOgE5SeIHlpS1up9bFq2wAyYhl1UdTObYiHe98zEM9SQvSoqQZ1IQD0JNpg3Ml5pg==", "cpu": [ "arm64" ], "dev": true, - "license": "MIT", + "license": "MPL-2.0", "optional": true, "os": [ "android" - ] + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } }, - "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.34.6", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.34.6.tgz", - "integrity": "sha512-z9Ib+OzqN3DZEjX7PDQMHEhtF+t6Mi2z/ueChQPLS/qUMKY7Ybn5A2ggFoKRNRh1q1T03YTQfBTQCJZiepESAg==", + "node_modules/lightningcss-darwin-arm64": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.33.0.tgz", + "integrity": "sha512-Sciaz8eenNTKn9b3t7+xr0ipTp9YxKQY4npwQ3mrRuL0BAVHBLyZxofhaKBAVtzmtRZ/zTyo0/to4B1uWG/Djg==", "cpu": [ "arm64" ], "dev": true, - "license": "MIT", + "license": "MPL-2.0", "optional": true, "os": [ "darwin" - ] + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } }, - "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.34.6", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.34.6.tgz", - "integrity": "sha512-PShKVY4u0FDAR7jskyFIYVyHEPCPnIQY8s5OcXkdU8mz3Y7eXDJPdyM/ZWjkYdR2m0izD9HHWA8sGcXn+Qrsyg==", + "node_modules/lightningcss-darwin-x64": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.33.0.tgz", + "integrity": "sha512-Z5UPAxzrjlWNNyGy6i65cJzzvgJ5D3T6wMvs+gWpY9d7qRhANrxqAp6LhxIgZhWEw18RfJTGcRxjuLIBr+m8XQ==", "cpu": [ "x64" ], "dev": true, - "license": "MIT", + "license": "MPL-2.0", "optional": true, "os": [ "darwin" - ] - }, - "node_modules/@rollup/rollup-freebsd-arm64": { - "version": "4.34.6", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.34.6.tgz", - "integrity": "sha512-YSwyOqlDAdKqs0iKuqvRHLN4SrD2TiswfoLfvYXseKbL47ht1grQpq46MSiQAx6rQEN8o8URtpXARCpqabqxGQ==", - "cpu": [ - "arm64" ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ] + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } }, - "node_modules/@rollup/rollup-freebsd-x64": { - "version": "4.34.6", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.34.6.tgz", - "integrity": "sha512-HEP4CgPAY1RxXwwL5sPFv6BBM3tVeLnshF03HMhJYCNc6kvSqBgTMmsEjb72RkZBAWIqiPUyF1JpEBv5XT9wKQ==", + "node_modules/lightningcss-freebsd-x64": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.33.0.tgz", + "integrity": "sha512-QQM/Ti/hQajJwCY+RiWuCZ9sdtI/XQk7nDK5vC8kkdwixezOlDgvDx7+RT+QjK6FcFT4MpsuoBnHIo/O3StRRg==", "cpu": [ "x64" ], "dev": true, - "license": "MIT", + "license": "MPL-2.0", "optional": true, "os": [ "freebsd" - ] - }, - "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.34.6", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.34.6.tgz", - "integrity": "sha512-88fSzjC5xeH9S2Vg3rPgXJULkHcLYMkh8faix8DX4h4TIAL65ekwuQMA/g2CXq8W+NJC43V6fUpYZNjaX3+IIg==", - "cpu": [ - "arm" ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } }, - "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.34.6", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.34.6.tgz", - "integrity": "sha512-wM4ztnutBqYFyvNeR7Av+reWI/enK9tDOTKNF+6Kk2Q96k9bwhDDOlnCUNRPvromlVXo04riSliMBs/Z7RteEg==", + "node_modules/lightningcss-linux-arm-gnueabihf": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.33.0.tgz", + "integrity": "sha512-N7FVBe6iS24MlM6R/4RBTxGhQheZGs7tiQ9U32UtF75NzP5Q7xWPRqLBCKxlRQRk3rY1jCIPLzx7WzOhuUIRLQ==", "cpu": [ "arm" ], "dev": true, - "license": "MIT", + "license": "MPL-2.0", "optional": true, "os": [ "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.34.6", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.34.6.tgz", - "integrity": "sha512-9RyprECbRa9zEjXLtvvshhw4CMrRa3K+0wcp3KME0zmBe1ILmvcVHnypZ/aIDXpRyfhSYSuN4EPdCCj5Du8FIA==", - "cpu": [ - "arm64" ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } }, - "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.34.6", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.34.6.tgz", - "integrity": "sha512-qTmklhCTyaJSB05S+iSovfo++EwnIEZxHkzv5dep4qoszUMX5Ca4WM4zAVUMbfdviLgCSQOu5oU8YoGk1s6M9Q==", + "node_modules/lightningcss-linux-arm64-gnu": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.33.0.tgz", + "integrity": "sha512-j2v/itmy4HlNxlc6voKXYgBqNi0Ng2LShg4z7GufpEgs05P+2suBVyi9I6YHq5uoVFx9ETin3eCEhLVyXGQnKg==", "cpu": [ "arm64" ], "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-loongarch64-gnu": { - "version": "4.34.6", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.34.6.tgz", - "integrity": "sha512-4Qmkaps9yqmpjY5pvpkfOerYgKNUGzQpFxV6rnS7c/JfYbDSU0y6WpbbredB5cCpLFGJEqYX40WUmxMkwhWCjw==", - "cpu": [ - "loong64" + "libc": [ + "glibc" ], - "dev": true, - "license": "MIT", + "license": "MPL-2.0", "optional": true, "os": [ "linux" - ] - }, - "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { - "version": "4.34.6", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.34.6.tgz", - "integrity": "sha512-Zsrtux3PuaxuBTX/zHdLaFmcofWGzaWW1scwLU3ZbW/X+hSsFbz9wDIp6XvnT7pzYRl9MezWqEqKy7ssmDEnuQ==", - "cpu": [ - "ppc64" ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } }, - "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.34.6", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.34.6.tgz", - "integrity": "sha512-aK+Zp+CRM55iPrlyKiU3/zyhgzWBxLVrw2mwiQSYJRobCURb781+XstzvA8Gkjg/hbdQFuDw44aUOxVQFycrAg==", + "node_modules/lightningcss-linux-arm64-musl": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.33.0.tgz", + "integrity": "sha512-yiO5ROMuYQgXbC60yjZU5CYSFZGKXL0HFATXt9mHJn1+zW55oCtMI9NfcVhYLMFDL7gV7oBPon/EmMMGg2OvtQ==", "cpu": [ - "riscv64" + "arm64" ], "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.34.6", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.34.6.tgz", - "integrity": "sha512-WoKLVrY9ogmaYPXwTH326+ErlCIgMmsoRSx6bO+l68YgJnlOXhygDYSZe/qbUJCSiCiZAQ+tKm88NcWuUXqOzw==", - "cpu": [ - "s390x" + "libc": [ + "musl" ], - "dev": true, - "license": "MIT", + "license": "MPL-2.0", "optional": true, "os": [ "linux" - ] + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } }, - "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.34.6", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.34.6.tgz", - "integrity": "sha512-Sht4aFvmA4ToHd2vFzwMFaQCiYm2lDFho5rPcvPBT5pCdC+GwHG6CMch4GQfmWTQ1SwRKS0dhDYb54khSrjDWw==", + "node_modules/lightningcss-linux-x64-gnu": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.33.0.tgz", + "integrity": "sha512-ar+Ju7LmcN0Jo4FpL4hpFybwNG9/3A/Br5KW2n2jyODg3MEZXaDYADdemoNS+BDNfMgKvylJLj4S5tyRActuAg==", "cpu": [ "x64" ], "dev": true, - "license": "MIT", + "libc": [ + "glibc" + ], + "license": "MPL-2.0", "optional": true, "os": [ "linux" - ] + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } }, - "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.34.6", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.34.6.tgz", - "integrity": "sha512-zmmpOQh8vXc2QITsnCiODCDGXFC8LMi64+/oPpPx5qz3pqv0s6x46ps4xoycfUiVZps5PFn1gksZzo4RGTKT+A==", + "node_modules/lightningcss-linux-x64-musl": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.33.0.tgz", + "integrity": "sha512-RYiYbkokw0trfKqqzfF55lginwEPrD3OJDfTuJzFs1MK6iFnDenaz1fqLLtX4ITG3OktJQXOeTaw1awrBAlZPw==", "cpu": [ "x64" ], "dev": true, - "license": "MIT", + "libc": [ + "musl" + ], + "license": "MPL-2.0", "optional": true, "os": [ "linux" - ] + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } }, - "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.34.6", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.34.6.tgz", - "integrity": "sha512-3/q1qUsO/tLqGBaD4uXsB6coVGB3usxw3qyeVb59aArCgedSF66MPdgRStUd7vbZOsko/CgVaY5fo2vkvPLWiA==", + "node_modules/lightningcss-win32-arm64-msvc": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.33.0.tgz", + "integrity": "sha512-1K+MPfLSFVpphzpdbfkhlWk6wBrTObBzS2T6db10PNOZgR9GoVsAWzwNyuhUYYbTp23j+4RrncfujZ4uAzXvwA==", "cpu": [ "arm64" ], "dev": true, - "license": "MIT", + "license": "MPL-2.0", "optional": true, "os": [ "win32" - ] - }, - "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.34.6", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.34.6.tgz", - "integrity": "sha512-oLHxuyywc6efdKVTxvc0135zPrRdtYVjtVD5GUm55I3ODxhU/PwkQFD97z16Xzxa1Fz0AEe4W/2hzRtd+IfpOA==", - "cpu": [ - "ia32" ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } }, - "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.34.6", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.34.6.tgz", - "integrity": "sha512-0PVwmgzZ8+TZ9oGBmdZoQVXflbvuwzN/HRclujpl4N/q3i+y0lqLw8n1bXA8ru3sApDjlmONaNAuYr38y1Kr9w==", + "node_modules/lightningcss-win32-x64-msvc": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.33.0.tgz", + "integrity": "sha512-OlEICDx/Xl0FqSp4bry8zFnCvGpig3Gl4gCquvYwHuqJKEC1+n9NgDniFvqHGmMv1ZkqDJrDqKKSykTDX+ehuA==", "cpu": [ "x64" ], "dev": true, - "license": "MIT", + "license": "MPL-2.0", "optional": true, "os": [ "win32" - ] - }, - "node_modules/@types/estree": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", - "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", - "dev": true, - "license": "MIT" - }, - "node_modules/esbuild": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", - "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=12" - }, - "optionalDependencies": { - "@esbuild/aix-ppc64": "0.21.5", - "@esbuild/android-arm": "0.21.5", - "@esbuild/android-arm64": "0.21.5", - "@esbuild/android-x64": "0.21.5", - "@esbuild/darwin-arm64": "0.21.5", - "@esbuild/darwin-x64": "0.21.5", - "@esbuild/freebsd-arm64": "0.21.5", - "@esbuild/freebsd-x64": "0.21.5", - "@esbuild/linux-arm": "0.21.5", - "@esbuild/linux-arm64": "0.21.5", - "@esbuild/linux-ia32": "0.21.5", - "@esbuild/linux-loong64": "0.21.5", - "@esbuild/linux-mips64el": "0.21.5", - "@esbuild/linux-ppc64": "0.21.5", - "@esbuild/linux-riscv64": "0.21.5", - "@esbuild/linux-s390x": "0.21.5", - "@esbuild/linux-x64": "0.21.5", - "@esbuild/netbsd-x64": "0.21.5", - "@esbuild/openbsd-x64": "0.21.5", - "@esbuild/sunos-x64": "0.21.5", - "@esbuild/win32-arm64": "0.21.5", - "@esbuild/win32-ia32": "0.21.5", - "@esbuild/win32-x64": "0.21.5" - } - }, - "node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" ], "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" } }, "node_modules/nanoid": { - "version": "3.3.8", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.8.tgz", - "integrity": "sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==", + "version": "3.3.16", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.16.tgz", + "integrity": "sha512-bzlKTyNJ7+LdGIIwy8ijFpIqEQIvafahV7eYykJ8Cvh42EdJeODoJ6gUJXpQJvej1BddH8OqTXZNE/KfbWAu8Q==", "dev": true, "funding": [ { @@ -756,10 +713,23 @@ "dev": true, "license": "ISC" }, + "node_modules/picomatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.5.tgz", + "integrity": "sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, "node_modules/postcss": { - "version": "8.5.1", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.1.tgz", - "integrity": "sha512-6oz2beyjc5VMn/KV1pPw8fliQkhBXrVn1Z3TVyqZxU8kZpzEKhBdmCFqI6ZbmGtamQvQGuU1sgPTk8ZrXDD7jQ==", + "version": "8.5.25", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.25.tgz", + "integrity": "sha512-DTPx3RWSSnWyzLxQnlH0rJP+EW5ekl16ZU4/psbIhA0e53kJfdgaN5vKM+xP7yJtXVu+nfdVFmlgFDEKAe4Pyw==", "dev": true, "funding": [ { @@ -777,7 +747,7 @@ ], "license": "MIT", "dependencies": { - "nanoid": "^3.3.8", + "nanoid": "^3.3.16", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" }, @@ -801,43 +771,38 @@ "url": "https://github.com/prettier/prettier?sponsor=1" } }, - "node_modules/rollup": { - "version": "4.34.6", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.34.6.tgz", - "integrity": "sha512-wc2cBWqJgkU3Iz5oztRkQbfVkbxoz5EhnCGOrnJvnLnQ7O0WhQUYyv18qQI79O8L7DdHrrlJNeCHd4VGpnaXKQ==", + "node_modules/rolldown": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.0.3.tgz", + "integrity": "sha512-i00lAJ2ks1BYr7rjNjKC7BcqAS7nVfiT3QX1SI5aY+AFHblCmaUf9OE9dbdzDvW6dJxbi2ZCZiy9v3CcwOiX3g==", "dev": true, "license": "MIT", "dependencies": { - "@types/estree": "1.0.6" + "@oxc-project/types": "=0.133.0", + "@rolldown/pluginutils": "^1.0.0" }, "bin": { - "rollup": "dist/bin/rollup" + "rolldown": "bin/cli.mjs" }, "engines": { - "node": ">=18.0.0", - "npm": ">=8.0.0" + "node": "^20.19.0 || >=22.12.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.34.6", - "@rollup/rollup-android-arm64": "4.34.6", - "@rollup/rollup-darwin-arm64": "4.34.6", - "@rollup/rollup-darwin-x64": "4.34.6", - "@rollup/rollup-freebsd-arm64": "4.34.6", - "@rollup/rollup-freebsd-x64": "4.34.6", - "@rollup/rollup-linux-arm-gnueabihf": "4.34.6", - "@rollup/rollup-linux-arm-musleabihf": "4.34.6", - "@rollup/rollup-linux-arm64-gnu": "4.34.6", - "@rollup/rollup-linux-arm64-musl": "4.34.6", - "@rollup/rollup-linux-loongarch64-gnu": "4.34.6", - "@rollup/rollup-linux-powerpc64le-gnu": "4.34.6", - "@rollup/rollup-linux-riscv64-gnu": "4.34.6", - "@rollup/rollup-linux-s390x-gnu": "4.34.6", - "@rollup/rollup-linux-x64-gnu": "4.34.6", - "@rollup/rollup-linux-x64-musl": "4.34.6", - "@rollup/rollup-win32-arm64-msvc": "4.34.6", - "@rollup/rollup-win32-ia32-msvc": "4.34.6", - "@rollup/rollup-win32-x64-msvc": "4.34.6", - "fsevents": "~2.3.2" + "@rolldown/binding-android-arm64": "1.0.3", + "@rolldown/binding-darwin-arm64": "1.0.3", + "@rolldown/binding-darwin-x64": "1.0.3", + "@rolldown/binding-freebsd-x64": "1.0.3", + "@rolldown/binding-linux-arm-gnueabihf": "1.0.3", + "@rolldown/binding-linux-arm64-gnu": "1.0.3", + "@rolldown/binding-linux-arm64-musl": "1.0.3", + "@rolldown/binding-linux-ppc64-gnu": "1.0.3", + "@rolldown/binding-linux-s390x-gnu": "1.0.3", + "@rolldown/binding-linux-x64-gnu": "1.0.3", + "@rolldown/binding-linux-x64-musl": "1.0.3", + "@rolldown/binding-openharmony-arm64": "1.0.3", + "@rolldown/binding-wasm32-wasi": "1.0.3", + "@rolldown/binding-win32-arm64-msvc": "1.0.3", + "@rolldown/binding-win32-x64-msvc": "1.0.3" } }, "node_modules/source-map-js": { @@ -850,22 +815,49 @@ "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.4" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "dev": true, + "license": "0BSD", + "optional": true + }, "node_modules/vite": { - "version": "5.4.14", - "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.14.tgz", - "integrity": "sha512-EK5cY7Q1D8JNhSaPKVK4pwBFvaTmZxEnoKXLG/U9gmdDcihQGNzFlgIvaxezFR4glP1LsuiedwMBqCXH3wZccA==", + "version": "8.0.16", + "resolved": "https://registry.npmjs.org/vite/-/vite-8.0.16.tgz", + "integrity": "sha512-h9bXPmJichP5fLmVQo3PyaGSDE2n3aPuomeAlVRm0JLmt4rY6zmPKd59HYI4LNW8oTK7tlTsuC7l/m7awx9Jcw==", "dev": true, "license": "MIT", "dependencies": { - "esbuild": "^0.21.3", - "postcss": "^8.4.43", - "rollup": "^4.20.0" + "lightningcss": "^1.32.0", + "picomatch": "^4.0.4", + "postcss": "^8.5.15", + "rolldown": "1.0.3", + "tinyglobby": "^0.2.17" }, "bin": { "vite": "bin/vite.js" }, "engines": { - "node": "^18.0.0 || >=20.0.0" + "node": "^20.19.0 || >=22.12.0" }, "funding": { "url": "https://github.com/vitejs/vite?sponsor=1" @@ -874,23 +866,33 @@ "fsevents": "~2.3.3" }, "peerDependencies": { - "@types/node": "^18.0.0 || >=20.0.0", - "less": "*", - "lightningcss": "^1.21.0", - "sass": "*", - "sass-embedded": "*", - "stylus": "*", - "sugarss": "*", - "terser": "^5.4.0" + "@types/node": "^20.19.0 || >=22.12.0", + "@vitejs/devtools": "^0.1.18", + "esbuild": "^0.27.0 || ^0.28.0", + "jiti": ">=1.21.0", + "less": "^4.0.0", + "sass": "^1.70.0", + "sass-embedded": "^1.70.0", + "stylus": ">=0.54.8", + "sugarss": "^5.0.0", + "terser": "^5.16.0", + "tsx": "^4.8.1", + "yaml": "^2.4.2" }, "peerDependenciesMeta": { "@types/node": { "optional": true }, - "less": { + "@vitejs/devtools": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "jiti": { "optional": true }, - "lightningcss": { + "less": { "optional": true }, "sass": { @@ -907,6 +909,12 @@ }, "terser": { "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true } } } diff --git a/Web/package.json b/Web/package.json index 7db1aca..5d2a017 100644 --- a/Web/package.json +++ b/Web/package.json @@ -10,6 +10,6 @@ }, "devDependencies": { "prettier": "^3.3.1", - "vite": "^5.1.6" + "vite": "8.0.16" } } From 95168d51ab2bca59a2d19f4ac9de60dcdbac1f30 Mon Sep 17 00:00:00 2001 From: Melendez Date: Mon, 3 Aug 2026 13:31:12 +0800 Subject: [PATCH 2/3] Add SVG illustrations and download/OSS sections Adds two SVG illustrations and integrates them inline so theme variables apply. --- Web/assets/svg/download.svg | 87 ++++++++++++++++++++++ Web/assets/svg/opensource.svg | 81 +++++++++++++++++++++ Web/css/index.css | 131 ++++++++++++++++++++++++++++++---- Web/index.html | 68 ++++++++++-------- Web/src/script.js | 21 ++++-- 5 files changed, 341 insertions(+), 47 deletions(-) create mode 100644 Web/assets/svg/download.svg create mode 100644 Web/assets/svg/opensource.svg diff --git a/Web/assets/svg/download.svg b/Web/assets/svg/download.svg new file mode 100644 index 0000000..a49faf6 --- /dev/null +++ b/Web/assets/svg/download.svg @@ -0,0 +1,87 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Web/assets/svg/opensource.svg b/Web/assets/svg/opensource.svg new file mode 100644 index 0000000..4dbb6f5 --- /dev/null +++ b/Web/assets/svg/opensource.svg @@ -0,0 +1,81 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + </> opensource.js + // free for everyone + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Web/css/index.css b/Web/css/index.css index 1796994..9772731 100644 --- a/Web/css/index.css +++ b/Web/css/index.css @@ -33,6 +33,7 @@ html { scroll-behavior: smooth; + scroll-snap-type: y mandatory; } body { @@ -169,13 +170,15 @@ nav a.active { } /* ===== Main Content ===== */ -main { - margin-top: 60px; -} - -section { +main section { + min-height: 100vh; + display: flex; + flex-direction: column; + justify-content: center; padding: 5rem 10%; position: relative; + scroll-snap-align: start; + scroll-snap-stop: always; } /* ===== Hero Section ===== */ @@ -517,12 +520,41 @@ section { background-clip: text; } +.download-container { + display: flex; + align-items: center; + justify-content: center; + gap: clamp(2rem, 5vw, 4rem); + width: 100%; + max-width: 1000px; + margin: 0 auto; + flex-wrap: wrap; +} + +.download-content { + flex: 1 1 320px; + max-width: 440px; + text-align: left; +} + +.download-art { + flex: 1 1 320px; + max-width: 460px; + min-width: 280px; +} + +.download-art svg { + width: 100%; + height: auto; + display: block; +} + .download-options { display: flex; gap: 2rem; - justify-content: center; + justify-content: flex-start; flex-wrap: wrap; - margin: 3rem 0; + margin: 2rem 0 0; } .download-button { @@ -590,18 +622,20 @@ section { .download-button .version-text { position: absolute; - left: 50%; - transform: translateX(-50%); - top: calc(50% - 0.5em - 0.5em); - font-size: 0.9rem; + inset: 0; + display: flex; + align-items: center; + justify-content: center; + font-size: 1.1rem; opacity: 0; + transform: translateY(10px); transition: all 0.3s ease; color: white; } .download-button:hover .version-text { - top: calc(50% - 0.5em); opacity: 1; + transform: translateY(0); } .download-button:hover span:not(.version-text) { @@ -609,10 +643,48 @@ section { } /* ===== Open Source Section ===== */ +.open-source-container { + display: flex; + align-items: center; + justify-content: center; + gap: clamp(2rem, 5vw, 4rem); + width: 100%; + max-width: 1000px; + margin: 0 auto; + flex-wrap: wrap; +} + +.open-source-content { + flex: 1 1 320px; + max-width: 440px; + text-align: left; +} + +.open-source-content h2 { + font-size: 2.8rem; + margin-bottom: 1.5rem; + background: linear-gradient(135deg, var(--primary-color), var(--gradient-secondary)); + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + background-clip: text; +} + +.open-source-art { + flex: 1 1 320px; + max-width: 460px; + min-width: 280px; +} + +.open-source-art svg { + width: 100%; + height: auto; + display: block; +} + .open-source-link { display: flex; gap: 1.5rem; - justify-content: center; + justify-content: flex-start; margin-top: 2rem; } @@ -1045,6 +1117,20 @@ footer { gap: 1rem; } + .download-container { + flex-direction: column; + gap: 2rem; + } + + .download-content { + max-width: none; + text-align: center; + } + + .download-art { + max-width: 340px; + } + .download-button { width: 100%; max-width: 300px; @@ -1063,6 +1149,24 @@ footer { padding: 1rem; } + .open-source-container { + flex-direction: column; + gap: 2rem; + } + + .open-source-content { + max-width: none; + text-align: center; + } + + .open-source-link { + justify-content: center; + } + + .open-source-art { + max-width: 380px; + } + section { padding: 3rem 5%; } @@ -1070,6 +1174,7 @@ footer { #features h2, #download h2, #changelog h2, + .open-source-content h2, #about h2 { font-size: 2rem; } diff --git a/Web/index.html b/Web/index.html index 94ff22d..def36f9 100644 --- a/Web/index.html +++ b/Web/index.html @@ -130,35 +130,26 @@

Intelligent Planning

-

Download App

- -
- -
-

Open Source

-
@@ -173,6 +164,25 @@

Changelog

+
+
+
+

Open Source

+ +
+
+
+
+

About Known

Known is an app developed by a junior high diff --git a/Web/src/script.js b/Web/src/script.js index 6b57e0e..8a8c795 100644 --- a/Web/src/script.js +++ b/Web/src/script.js @@ -105,6 +105,19 @@ document.addEventListener('DOMContentLoaded', () => { } createParticles(); + // ===== SVG Illustrations (loaded inline to inherit theme variables) ===== + document.querySelectorAll('[data-svg]').forEach((container) => { + fetch(container.dataset.svg) + .then((res) => { + if (!res.ok) throw new Error(`Failed to load ${container.dataset.svg}`); + return res.text(); + }) + .then((svgText) => { + container.innerHTML = svgText; + }) + .catch((err) => console.error('Failed to load SVG:', err)); + }); + // ===== Scroll Reveal (Intersection Observer) ===== const revealElements = document.querySelectorAll('.scroll-reveal'); @@ -186,9 +199,8 @@ document.addEventListener('DOMContentLoaded', () => { const targetId = link.getAttribute('href'); const targetSection = document.querySelector(targetId); if (targetSection) { - const offsetTop = targetSection.offsetTop - 60; window.scrollTo({ - top: offsetTop, + top: targetSection.offsetTop, behavior: 'smooth', }); } @@ -202,9 +214,8 @@ document.addEventListener('DOMContentLoaded', () => { const targetId = btn.getAttribute('href'); const targetSection = document.querySelector(targetId); if (targetSection) { - const offsetTop = targetSection.offsetTop - 60; window.scrollTo({ - top: offsetTop, + top: targetSection.offsetTop, behavior: 'smooth', }); } @@ -364,7 +375,7 @@ document.addEventListener('DOMContentLoaded', () => { } }); }, - { threshold: 0.15 } + { threshold: 0.15 }, ); sectionObserver.observe(changelogSection); } From e88ef0476c801b2e7f05b92e6d7633553f6bcb4b Mon Sep 17 00:00:00 2001 From: Melendez Date: Mon, 3 Aug 2026 14:26:55 +0800 Subject: [PATCH 3/3] Add Open Source nav, About floating logo Introduce an "Open Source" nav item (templates + translations) and restructure the header (nav-controls, theme/lang placement). --- Web/assets/svg/download.svg | 155 +++++++++++----------- Web/assets/svg/opensource.svg | 143 ++++++++++---------- Web/assets/values/translations.json | 6 +- Web/css/index.css | 199 +++++++++++++++++++++++----- Web/index.html | 188 ++++++++++++++++++-------- Web/src/script.js | 129 ++++++++++++++++++ 6 files changed, 583 insertions(+), 237 deletions(-) diff --git a/Web/assets/svg/download.svg b/Web/assets/svg/download.svg index a49faf6..659e516 100644 --- a/Web/assets/svg/download.svg +++ b/Web/assets/svg/download.svg @@ -1,87 +1,88 @@ - - - - - - - - - - - + + + + + + + + + + + - - - + + + - - - - - + + + + + - - + + - - - - - - - + + + + + + + - - - - - - - - + + + + + + + + - - - - - + + + + + - - - - - - - - - - + + + + + + + + + + - - - - - - - + + + + + + + - - - - - - - - + + + + + + + + diff --git a/Web/assets/svg/opensource.svg b/Web/assets/svg/opensource.svg index 4dbb6f5..8fb2247 100644 --- a/Web/assets/svg/opensource.svg +++ b/Web/assets/svg/opensource.svg @@ -1,81 +1,84 @@ - - - - - - - - - - - + + + + + + + + + + + - - - + + + - - - - - + + + + + - - - - - - + + + + + + - - - - - - - </> opensource.js - // free for everyone - - - - - - - + + + + + + + </> opensource.js + + // free for everyone + + + + + + + + - - - - + + + + + - - - - - + + + + + - - - - - + + + + + - diff --git a/Web/assets/values/translations.json b/Web/assets/values/translations.json index bdf0421..e6b20a6 100644 --- a/Web/assets/values/translations.json +++ b/Web/assets/values/translations.json @@ -9,6 +9,7 @@ "nav.download": "下载", "nav.changelog": "更新日志", "nav.about": "关于", + "nav.openSource": "开源地址", "theme.light": "浅色模式", "theme.dark": "深色模式", "theme.system": "跟随系统", @@ -58,6 +59,7 @@ "nav.download": "下載", "nav.changelog": "更新日誌", "nav.about": "關於", + "nav.openSource": "開源地址", "theme.light": "淺色模式", "theme.dark": "深色模式", "theme.system": "跟隨系統", @@ -107,6 +109,7 @@ "nav.download": "Download", "nav.changelog": "Changelog", "nav.about": "About", + "nav.openSource": "Open Source", "theme.light": "Light Mode", "theme.dark": "Dark Mode", "theme.system": "Follow System", @@ -156,6 +159,7 @@ "nav.download": "Download", "nav.changelog": "Changelog", "nav.about": "About", + "nav.openSource": "Open Source", "theme.light": "Light Mode", "theme.dark": "Dark Mode", "theme.system": "Follow System", @@ -195,4 +199,4 @@ "about.description": "Known is an app developed by a middle school student (now a freshman in high school) in Beijing to help students better analyse their test scores and stay motivated. We hope Known can be your right-hand man on your way to learning.", "footer.copyright": "Open-sourced under MIT License." } -} \ No newline at end of file +} diff --git a/Web/css/index.css b/Web/css/index.css index 9772731..14d8282 100644 --- a/Web/css/index.css +++ b/Web/css/index.css @@ -1,9 +1,9 @@ :root { - --primary-color: #A54BCF; - --secondary-color: #006E2B; + --primary-color: #a54bcf; + --secondary-color: #006e2b; --background-color: #f8f5fb; --text-color: #2c3e50; - --gradient-secondary: #C78AE6; + --gradient-secondary: #c78ae6; --card-background: white; --nav-background: white; --shadow-color: rgba(165, 75, 207, 0.1); @@ -13,7 +13,7 @@ --border-color: #ddd; } -[data-theme="dark"] { +[data-theme='dark'] { --background-color: #1a1a2e; --text-color: #e0e0e0; --card-background: #16213e; @@ -37,7 +37,7 @@ html { } body { - font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; + font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; line-height: 1.6; color: var(--text-color); background-color: var(--background-color); @@ -47,28 +47,53 @@ body { /* ===== Navigation ===== */ nav { position: fixed; - top: 0; + top: 1rem; left: 0; right: 0; + margin: 0 auto; z-index: 1000; + width: calc(100% - 2rem); + max-width: 1100px; background: rgba(255, 255, 255, 0.85); backdrop-filter: blur(20px); -webkit-backdrop-filter: blur(20px); - border-bottom: 1px solid rgba(165, 75, 207, 0.1); - padding: 0.5rem 2rem; + border: 1px solid rgba(165, 75, 207, 0.1); + border-radius: 999px; + padding: 0.5rem 1.5rem; display: flex; justify-content: space-between; align-items: center; height: 60px; + box-shadow: 0 8px 30px var(--shadow-color); transition: all 0.3s ease; } -[data-theme="dark"] nav { +[data-theme='dark'] nav { background: rgba(22, 33, 62, 0.85); } nav.scrolled { - box-shadow: 0 2px 20px rgba(165, 75, 207, 0.15); + box-shadow: 0 10px 40px var(--shadow-color-hover); +} + +nav.about-active { + max-width: 780px; +} + +nav.about-active ul { + position: static; + transform: none; +} + +.logo.logo-fixed { + position: fixed; + z-index: 1001; + margin: 0; + transition: transform 0.5s cubic-bezier(0.16, 1, 0.3, 1); +} + +.logo.logo-about-large { + transform: scale(3); } .logo img { @@ -76,7 +101,18 @@ nav.scrolled { vertical-align: middle; } +.nav-controls { + display: flex; + align-items: center; + gap: 0.5rem; + height: 100%; +} + nav ul { + position: absolute; + left: 50%; + top: 50%; + transform: translate(-50%, -50%); display: flex; list-style: none; gap: 2rem; @@ -156,8 +192,8 @@ nav a.active { transition: all 0.25s cubic-bezier(0.16, 1, 0.3, 1); } -[data-theme="dark"] .theme-dropdown, -[data-theme="dark"] .lang-dropdown { +[data-theme='dark'] .theme-dropdown, +[data-theme='dark'] .lang-dropdown { background: rgba(22, 33, 62, 0.85); } @@ -186,7 +222,11 @@ main section { text-align: center; padding-top: 6rem; padding-bottom: 10rem; - background: linear-gradient(135deg, var(--primary-color), var(--gradient-secondary)); + background: linear-gradient( + 135deg, + var(--primary-color), + var(--gradient-secondary) + ); color: white; min-height: 100vh; display: flex; @@ -411,7 +451,11 @@ main section { text-align: center; font-size: 2.8rem; margin-bottom: 1rem; - background: linear-gradient(135deg, var(--primary-color), var(--gradient-secondary)); + background: linear-gradient( + 135deg, + var(--primary-color), + var(--gradient-secondary) + ); -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text; @@ -425,7 +469,11 @@ main section { transform: translateX(-50%); width: 80px; height: 4px; - background: linear-gradient(135deg, var(--primary-color), var(--gradient-secondary)); + background: linear-gradient( + 135deg, + var(--primary-color), + var(--gradient-secondary) + ); border-radius: 2px; } @@ -456,7 +504,11 @@ main section { left: 0; width: 100%; height: 3px; - background: linear-gradient(90deg, var(--primary-color), var(--gradient-secondary)); + background: linear-gradient( + 90deg, + var(--primary-color), + var(--gradient-secondary) + ); transform: scaleX(0); transform-origin: left; transition: transform 0.4s ease; @@ -475,7 +527,11 @@ main section { width: 70px; height: 70px; margin: 0 auto 1.5rem; - background: linear-gradient(135deg, var(--primary-color), var(--gradient-secondary)); + background: linear-gradient( + 135deg, + var(--primary-color), + var(--gradient-secondary) + ); border-radius: 20px; display: flex; align-items: center; @@ -507,14 +563,22 @@ main section { /* ===== Download Section ===== */ #download { text-align: center; - background: linear-gradient(180deg, var(--background-color), rgba(165, 75, 207, 0.05)); + background: linear-gradient( + 180deg, + var(--background-color), + rgba(165, 75, 207, 0.05) + ); position: relative; } #download h2 { font-size: 2.8rem; margin-bottom: 1rem; - background: linear-gradient(135deg, var(--primary-color), var(--gradient-secondary)); + background: linear-gradient( + 135deg, + var(--primary-color), + var(--gradient-secondary) + ); -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text; @@ -581,7 +645,11 @@ main section { left: 0; width: 100%; height: 100%; - background: linear-gradient(135deg, var(--primary-color), var(--gradient-secondary)); + background: linear-gradient( + 135deg, + var(--primary-color), + var(--gradient-secondary) + ); opacity: 0; transition: opacity 0.4s ease; z-index: 0; @@ -663,7 +731,11 @@ main section { .open-source-content h2 { font-size: 2.8rem; margin-bottom: 1.5rem; - background: linear-gradient(135deg, var(--primary-color), var(--gradient-secondary)); + background: linear-gradient( + 135deg, + var(--primary-color), + var(--gradient-secondary) + ); -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text; @@ -722,7 +794,11 @@ main section { text-align: center; font-size: 2.8rem; margin-bottom: 2rem; - background: linear-gradient(135deg, var(--primary-color), var(--gradient-secondary)); + background: linear-gradient( + 135deg, + var(--primary-color), + var(--gradient-secondary) + ); -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text; @@ -749,7 +825,11 @@ main section { position: absolute; top: 16px; height: 2px; - background: linear-gradient(90deg, var(--primary-color), var(--gradient-secondary)); + background: linear-gradient( + 90deg, + var(--primary-color), + var(--gradient-secondary) + ); border-radius: 1px; opacity: 0.3; z-index: 0; @@ -832,7 +912,11 @@ main section { .timeline-version { display: inline-block; padding: 0.25rem 0.75rem; - background: linear-gradient(135deg, var(--primary-color), var(--gradient-secondary)); + background: linear-gradient( + 135deg, + var(--primary-color), + var(--gradient-secondary) + ); color: white; border-radius: 20px; font-size: 0.85rem; @@ -931,15 +1015,45 @@ main section { /* ===== About Section ===== */ #about { - text-align: center; position: relative; overflow: hidden; + padding-bottom: 12rem; +} + +.about-container { + display: flex; + align-items: stretch; + justify-content: center; + gap: clamp(2rem, 5vw, 4rem); + width: 100%; + max-width: 1000px; + margin: 0 auto; + flex-wrap: wrap; +} + +.about-logo-column { + flex: 1 1 320px; + max-width: 460px; + min-width: 280px; + display: flex; + align-items: center; + justify-content: center; +} + +.about-content { + flex: 1 1 320px; + max-width: 440px; + text-align: left; } #about h2 { font-size: 2.8rem; margin-bottom: 1.5rem; - background: linear-gradient(135deg, var(--primary-color), var(--gradient-secondary)); + background: linear-gradient( + 135deg, + var(--primary-color), + var(--gradient-secondary) + ); -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text; @@ -949,7 +1063,7 @@ main section { font-size: 1.15rem; line-height: 1.9; max-width: 700px; - margin: 0 auto 2rem; + margin: 0; color: var(--text-color); opacity: 0.85; } @@ -962,6 +1076,7 @@ footer { color: var(--text-color); opacity: 0.7; font-size: 0.9rem; + scroll-snap-align: end; } /* ===== Theme Selector ===== */ @@ -1018,14 +1133,14 @@ footer { flex-shrink: 0; } -.theme-dropdown button[data-selected="true"], -.lang-dropdown button[data-selected="true"] { +.theme-dropdown button[data-selected='true'], +.lang-dropdown button[data-selected='true'] { color: var(--primary-color); background: var(--shadow-color); font-weight: 600; } -.lang-dropdown button[data-selected="true"]::before { +.lang-dropdown button[data-selected='true']::before { content: '\f00c'; font-family: 'Font Awesome 6 Free', serif; font-weight: 900; @@ -1050,20 +1165,20 @@ footer { display: none; } -[data-theme="system"] .system-icon { +[data-theme='system'] .system-icon { display: inline-block; } -[data-theme="system"] .light-icon, -[data-theme="system"] .dark-icon { +[data-theme='system'] .light-icon, +[data-theme='system'] .dark-icon { display: none; } -[data-theme="dark"] .dark-icon { +[data-theme='dark'] .dark-icon { display: none; } -[data-theme="light"] .light-icon { +[data-theme='light'] .light-icon { display: none; } @@ -1094,6 +1209,10 @@ footer { /* ===== Responsive ===== */ @media (max-width: 768px) { + nav { + width: calc(100% - 1rem); + } + nav ul { display: none; } @@ -1154,6 +1273,16 @@ footer { gap: 2rem; } + .about-container { + flex-direction: column; + gap: 2rem; + } + + .about-content { + max-width: none; + text-align: center; + } + .open-source-content { max-width: none; text-align: center; diff --git a/Web/index.html b/Web/index.html index def36f9..c07fc10 100644 --- a/Web/index.html +++ b/Web/index.html @@ -1,19 +1,25 @@ - + - - + + Known - - - + + + @@ -23,15 +29,30 @@

@@ -80,10 +101,16 @@

Known

-

Your Intelligent Learning Assistant

+

+ Your Intelligent Learning Assistant +

@@ -102,49 +129,88 @@

Key Features

Grade Analysis

-

Intelligent analysis of test scores and tracking of learning progress.

+

+ Intelligent analysis of test scores and tracking of learning + progress. +

Learning Motivation

-

Personalized incentive system for more motivated learning.

+

+ Personalized incentive system for more motivated learning. +

Data Statistics

-

Intuitive learning visualization for clear demonstration of learning - outcomes.

+

+ Intuitive learning visualization for clear demonstration of + learning outcomes. +

Intelligent Planning

-

AI-based study plan development to rationalize scheduling.

+

+ AI-based study plan development to rationalize scheduling. +

+
+ +
+ +
+

Changelog

+
+
+
+ + Loading changelog...
-
+
-

Download App

+

+ Download App +

-
-

Changelog

-
-
-
- - Loading changelog... -
-
-
- -
+
-

Open Source

+

+ Open Source +

-
+
-

About Known

-

Known is an app developed by a junior high - school student (now a senior in high - school) in Beijing to help students better analyze their test scores and stay motivated. We hope Known can - be your right hand on your study journey.

+
+
+
+

About Known

+

+ Known is an app developed by a junior high school student (now a + senior in high school) in Beijing to help students better analyze + their test scores and stay motivated. We hope Known can be your + right hand on your study journey. +

+
+
-

© 2024 Known. Open-sourced under MIT License.

+

+ © 2024 Known. + Open-sourced under MIT License. +

diff --git a/Web/src/script.js b/Web/src/script.js index 8a8c795..d94355f 100644 --- a/Web/src/script.js +++ b/Web/src/script.js @@ -175,6 +175,123 @@ document.addEventListener('DOMContentLoaded', () => { } } + // ===== Floating Logo: Fly to About description ===== + const aboutSection = document.getElementById('about'); + const aboutLogoColumn = + aboutSection && aboutSection.querySelector('.about-logo-column'); + const aboutContent = + aboutSection && aboutSection.querySelector('.about-content'); + const logo = document.querySelector('.logo'); + const LOGO_FLY_DURATION = 600; + let logoFlying = false; + let logoTrackReady = false; + + function isAboutActive() { + if (!aboutSection) return false; + const scrollY = window.scrollY + 100; + const top = aboutSection.offsetTop; + return scrollY >= top && scrollY < top + aboutSection.offsetHeight; + } + + function aboutTargetViewport() { + const colRect = aboutLogoColumn.getBoundingClientRect(); + const contentRect = aboutContent.getBoundingClientRect(); + return { + left: colRect.left + colRect.width / 2 - logo.offsetWidth / 2, + top: contentRect.top + contentRect.height / 2 - logo.offsetHeight / 2, + }; + } + + function logoSlotViewport() { + const navRect = nav.getBoundingClientRect(); + const padLeft = parseFloat(getComputedStyle(nav).paddingLeft) || 0; + return { + left: navRect.left + padLeft, + top: navRect.top + (navRect.height - logo.offsetHeight) / 2, + }; + } + + function cancelLogoAnimations() { + logo.getAnimations().forEach((anim) => anim.cancel()); + } + + function flyLogoToAbout() { + if (!logo || logoFlying) return; + cancelLogoAnimations(); + logoFlying = true; + logoTrackReady = false; + nav.classList.add('about-active'); + document.body.appendChild(logo); + logo.classList.add('logo-fixed'); + logo.classList.add('logo-about-large'); + const slot = logoSlotViewport(); + const target = aboutTargetViewport(); + logo.style.left = slot.left + 'px'; + logo.style.top = slot.top + 'px'; + const anim = logo.animate( + [ + { left: slot.left + 'px', top: slot.top + 'px' }, + { left: target.left + 'px', top: target.top + 'px' }, + ], + { + duration: LOGO_FLY_DURATION, + easing: 'cubic-bezier(0.16, 1, 0.3, 1)', + fill: 'both', + }, + ); + anim.onfinish = () => { + anim.cancel(); + logoTrackReady = true; + logo.style.left = target.left + 'px'; + logo.style.top = target.top + 'px'; + }; + } + + function flyLogoBack() { + if (!logo || !logoFlying) return; + cancelLogoAnimations(); + logoFlying = false; + logoTrackReady = false; + logo.classList.remove('logo-about-large'); + const currentLeft = parseFloat(logo.style.left) || 0; + const currentTop = parseFloat(logo.style.top) || 0; + const slot = logoSlotViewport(); + const anim = logo.animate( + [ + { left: currentLeft + 'px', top: currentTop + 'px' }, + { left: slot.left + 'px', top: slot.top + 'px' }, + ], + { + duration: LOGO_FLY_DURATION, + easing: 'cubic-bezier(0.16, 1, 0.3, 1)', + fill: 'both', + }, + ); + anim.onfinish = () => { + anim.cancel(); + nav.prepend(logo); + nav.classList.remove('about-active'); + logo.classList.remove('logo-fixed'); + logo.style.left = ''; + logo.style.top = ''; + }; + } + + function updateAboutLogo() { + if (!aboutSection || !aboutLogoColumn || !aboutContent || !logo) return; + if (isAboutActive()) { + if (!logoFlying) { + flyLogoToAbout(); + } else if (logoTrackReady) { + const target = aboutTargetViewport(); + logo.style.left = target.left + 'px'; + logo.style.top = target.top + 'px'; + } + } else if (logoFlying) { + flyLogoBack(); + } + } + // ===== Parallax Effect for Hero ===== const hero = document.querySelector('.hero'); @@ -231,6 +348,7 @@ document.addEventListener('DOMContentLoaded', () => { updateActiveNav(); updateNavStyle(); updateParallax(); + updateAboutLogo(); ticking = false; }); ticking = true; @@ -240,6 +358,17 @@ document.addEventListener('DOMContentLoaded', () => { // Initial calls updateActiveNav(); updateNavStyle(); + updateAboutLogo(); + + window.addEventListener('resize', () => { + if (logoFlying) { + cancelLogoAnimations(); + logoTrackReady = true; + const target = aboutTargetViewport(); + logo.style.left = target.left + 'px'; + logo.style.top = target.top + 'px'; + } + }); // ===== Changelog: Fetch from GitHub ===== const GITHUB_REPO = 'Melendez1209/Known';