diff --git a/src/frontend/package-lock.json b/src/frontend/package-lock.json
new file mode 100644
index 0000000..af428d5
--- /dev/null
+++ b/src/frontend/package-lock.json
@@ -0,0 +1,2448 @@
+{
+ "lockfileVersion": 3,
+ "name": "pygentic-ai-frontend",
+ "packages": {
+ "": {
+ "dependencies": {
+ "@creativebulma/bulma-collapsible": "^1.0.4",
+ "@vizuaalog/bulmajs": "^0.12.2",
+ "bulma": "^1.0.4",
+ "bulma-tagsinput": "^2.0.0",
+ "htmx.org": "^2.0.8",
+ "install": "^0.13.0",
+ "jquery": "^4.0.0",
+ "npm": "^11.8.0"
+ },
+ "devDependencies": {
+ "sass": "^1.83.0"
+ },
+ "name": "pygentic-ai-frontend",
+ "version": "1.0.0"
+ },
+ "node_modules/@creativebulma/bulma-collapsible": {
+ "dependencies": {
+ "bulma": "latest"
+ },
+ "integrity": "sha512-aNqSwyuJxshoIc4oD3wJ3eRqOANRweYfpzqmef/fj5tf0Yn7UVx99yh8ovY6vhB8Il31bFcc7f/eRfJvEMNUPw==",
+ "resolved": "https://registry.npmjs.org/@creativebulma/bulma-collapsible/-/bulma-collapsible-1.0.4.tgz",
+ "version": "1.0.4"
+ },
+ "node_modules/@parcel/watcher": {
+ "dependencies": {
+ "detect-libc": "^2.0.3",
+ "is-glob": "^4.0.3",
+ "node-addon-api": "^7.0.0",
+ "picomatch": "^4.0.3"
+ },
+ "dev": true,
+ "engines": {
+ "node": ">= 10.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ },
+ "hasInstallScript": true,
+ "integrity": "sha512-tmmZ3lQxAe/k/+rNnXQRawJ4NjxO2hqiOLTHvWchtGZULp4RyFeh6aU4XdOYBFe2KE1oShQTv4AblOs2iOrNnQ==",
+ "license": "MIT",
+ "optional": true,
+ "optionalDependencies": {
+ "@parcel/watcher-android-arm64": "2.5.6",
+ "@parcel/watcher-darwin-arm64": "2.5.6",
+ "@parcel/watcher-darwin-x64": "2.5.6",
+ "@parcel/watcher-freebsd-x64": "2.5.6",
+ "@parcel/watcher-linux-arm-glibc": "2.5.6",
+ "@parcel/watcher-linux-arm-musl": "2.5.6",
+ "@parcel/watcher-linux-arm64-glibc": "2.5.6",
+ "@parcel/watcher-linux-arm64-musl": "2.5.6",
+ "@parcel/watcher-linux-x64-glibc": "2.5.6",
+ "@parcel/watcher-linux-x64-musl": "2.5.6",
+ "@parcel/watcher-win32-arm64": "2.5.6",
+ "@parcel/watcher-win32-ia32": "2.5.6",
+ "@parcel/watcher-win32-x64": "2.5.6"
+ },
+ "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.5.6.tgz",
+ "version": "2.5.6"
+ },
+ "node_modules/@parcel/watcher-android-arm64": {
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "engines": {
+ "node": ">= 10.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ },
+ "integrity": "sha512-YQxSS34tPF/6ZG7r/Ih9xy+kP/WwediEUsqmtf0cuCV5TPPKw/PQHRhueUo6JdeFJaqV3pyjm0GdYjZotbRt/A==",
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.5.6.tgz",
+ "version": "2.5.6"
+ },
+ "node_modules/@parcel/watcher-darwin-arm64": {
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "engines": {
+ "node": ">= 10.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ },
+ "integrity": "sha512-Z2ZdrnwyXvvvdtRHLmM4knydIdU9adO3D4n/0cVipF3rRiwP+3/sfzpAwA/qKFL6i1ModaabkU7IbpeMBgiVEA==",
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.5.6.tgz",
+ "version": "2.5.6"
+ },
+ "node_modules/@parcel/watcher-darwin-x64": {
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "engines": {
+ "node": ">= 10.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ },
+ "integrity": "sha512-HgvOf3W9dhithcwOWX9uDZyn1lW9R+7tPZ4sug+NGrGIo4Rk1hAXLEbcH1TQSqxts0NYXXlOWqVpvS1SFS4fRg==",
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-x64/-/watcher-darwin-x64-2.5.6.tgz",
+ "version": "2.5.6"
+ },
+ "node_modules/@parcel/watcher-freebsd-x64": {
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "engines": {
+ "node": ">= 10.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ },
+ "integrity": "sha512-vJVi8yd/qzJxEKHkeemh7w3YAn6RJCtYlE4HPMoVnCpIXEzSrxErBW5SJBgKLbXU3WdIpkjBTeUNtyBVn8TRng==",
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-freebsd-x64/-/watcher-freebsd-x64-2.5.6.tgz",
+ "version": "2.5.6"
+ },
+ "node_modules/@parcel/watcher-linux-arm-glibc": {
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "engines": {
+ "node": ">= 10.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ },
+ "integrity": "sha512-9JiYfB6h6BgV50CCfasfLf/uvOcJskMSwcdH1PHH9rvS1IrNy8zad6IUVPVUfmXr+u+Km9IxcfMLzgdOudz9EQ==",
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-glibc/-/watcher-linux-arm-glibc-2.5.6.tgz",
+ "version": "2.5.6"
+ },
+ "node_modules/@parcel/watcher-linux-arm-musl": {
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "engines": {
+ "node": ">= 10.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ },
+ "integrity": "sha512-Ve3gUCG57nuUUSyjBq/MAM0CzArtuIOxsBdQ+ftz6ho8n7s1i9E1Nmk/xmP323r2YL0SONs1EuwqBp2u1k5fxg==",
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-musl/-/watcher-linux-arm-musl-2.5.6.tgz",
+ "version": "2.5.6"
+ },
+ "node_modules/@parcel/watcher-linux-arm64-glibc": {
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "engines": {
+ "node": ">= 10.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ },
+ "integrity": "sha512-f2g/DT3NhGPdBmMWYoxixqYr3v/UXcmLOYy16Bx0TM20Tchduwr4EaCbmxh1321TABqPGDpS8D/ggOTaljijOA==",
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-glibc/-/watcher-linux-arm64-glibc-2.5.6.tgz",
+ "version": "2.5.6"
+ },
+ "node_modules/@parcel/watcher-linux-arm64-musl": {
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "engines": {
+ "node": ">= 10.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ },
+ "integrity": "sha512-qb6naMDGlbCwdhLj6hgoVKJl2odL34z2sqkC7Z6kzir8b5W65WYDpLB6R06KabvZdgoHI/zxke4b3zR0wAbDTA==",
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-musl/-/watcher-linux-arm64-musl-2.5.6.tgz",
+ "version": "2.5.6"
+ },
+ "node_modules/@parcel/watcher-linux-x64-glibc": {
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "engines": {
+ "node": ">= 10.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ },
+ "integrity": "sha512-kbT5wvNQlx7NaGjzPFu8nVIW1rWqV780O7ZtkjuWaPUgpv2NMFpjYERVi0UYj1msZNyCzGlaCWEtzc+exjMGbQ==",
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-glibc/-/watcher-linux-x64-glibc-2.5.6.tgz",
+ "version": "2.5.6"
+ },
+ "node_modules/@parcel/watcher-linux-x64-musl": {
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "engines": {
+ "node": ">= 10.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ },
+ "integrity": "sha512-1JRFeC+h7RdXwldHzTsmdtYR/Ku8SylLgTU/reMuqdVD7CtLwf0VR1FqeprZ0eHQkO0vqsbvFLXUmYm/uNKJBg==",
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-musl/-/watcher-linux-x64-musl-2.5.6.tgz",
+ "version": "2.5.6"
+ },
+ "node_modules/@parcel/watcher-win32-arm64": {
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "engines": {
+ "node": ">= 10.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ },
+ "integrity": "sha512-3ukyebjc6eGlw9yRt678DxVF7rjXatWiHvTXqphZLvo7aC5NdEgFufVwjFfY51ijYEWpXbqF5jtrK275z52D4Q==",
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-arm64/-/watcher-win32-arm64-2.5.6.tgz",
+ "version": "2.5.6"
+ },
+ "node_modules/@parcel/watcher-win32-ia32": {
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "engines": {
+ "node": ">= 10.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ },
+ "integrity": "sha512-k35yLp1ZMwwee3Ez/pxBi5cf4AoBKYXj00CZ80jUz5h8prpiaQsiRPKQMxoLstNuqe2vR4RNPEAEcjEFzhEz/g==",
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-ia32/-/watcher-win32-ia32-2.5.6.tgz",
+ "version": "2.5.6"
+ },
+ "node_modules/@parcel/watcher-win32-x64": {
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "engines": {
+ "node": ">= 10.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ },
+ "integrity": "sha512-hbQlYcCq5dlAX9Qx+kFb0FHue6vbjlf0FrNzSKdYK2APUf7tGfGxQCk2ihEREmbR6ZMc0MVAD5RIX/41gpUzTw==",
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-x64/-/watcher-win32-x64-2.5.6.tgz",
+ "version": "2.5.6"
+ },
+ "node_modules/@vizuaalog/bulmajs": {
+ "integrity": "sha512-I8YIQnMB9R0D0yHet4f60RSN55Y2jkqwsbtNnDOntNdiSB4JcUAtXlcG0U9DzxJ9ugliE2q3/8oJiFkSvSBt7w==",
+ "license": "MIT",
+ "resolved": "https://registry.npmjs.org/@vizuaalog/bulmajs/-/bulmajs-0.12.2.tgz",
+ "version": "0.12.2"
+ },
+ "node_modules/bulma": {
+ "integrity": "sha512-Ffb6YGXDiZYX3cqvSbHWqQ8+LkX6tVoTcZuVB3lm93sbAVXlO0D6QlOTMnV6g18gILpAXqkG2z9hf9z4hCjz2g==",
+ "license": "MIT",
+ "resolved": "https://registry.npmjs.org/bulma/-/bulma-1.0.4.tgz",
+ "version": "1.0.4"
+ },
+ "node_modules/bulma-tagsinput": {
+ "integrity": "sha512-BFvd0oaxgeWHOEh3d4cgETy5vpSSjRRBA9w+8TWEuhjFQg38Rb+3vjDCavL+udpdjf+dRV0SK5T4kYCXTOrz5A==",
+ "license": "MIT",
+ "resolved": "https://registry.npmjs.org/bulma-tagsinput/-/bulma-tagsinput-2.0.0.tgz",
+ "version": "2.0.0"
+ },
+ "node_modules/chokidar": {
+ "dependencies": {
+ "readdirp": "^4.0.1"
+ },
+ "dev": true,
+ "engines": {
+ "node": ">= 14.16.0"
+ },
+ "funding": {
+ "url": "https://paulmillr.com/funding/"
+ },
+ "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==",
+ "license": "MIT",
+ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz",
+ "version": "4.0.3"
+ },
+ "node_modules/detect-libc": {
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ },
+ "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==",
+ "license": "Apache-2.0",
+ "optional": true,
+ "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz",
+ "version": "2.1.2"
+ },
+ "node_modules/htmx.org": {
+ "integrity": "sha512-fm297iru0iWsNJlBrjvtN7V9zjaxd+69Oqjh4F/Vq9Wwi2kFisLcrLCiv5oBX0KLfOX/zG8AUo9ROMU5XUB44Q==",
+ "license": "0BSD",
+ "resolved": "https://registry.npmjs.org/htmx.org/-/htmx.org-2.0.8.tgz",
+ "version": "2.0.8"
+ },
+ "node_modules/immutable": {
+ "dev": true,
+ "integrity": "sha512-p6u1bG3YSnINT5RQmx/yRZBpenIl30kVxkTLDyHLIMk0gict704Q9n+thfDI7lTRm9vXdDYutVzXhzcThxTnXA==",
+ "license": "MIT",
+ "resolved": "https://registry.npmjs.org/immutable/-/immutable-5.1.4.tgz",
+ "version": "5.1.4"
+ },
+ "node_modules/install": {
+ "engines": {
+ "node": ">= 0.10"
+ },
+ "integrity": "sha512-zDml/jzr2PKU9I8J/xyZBQn8rPCAY//UOYNmR01XwNwyfhEWObo2SWfSl1+0tm1u6PhxLwDnfsT/6jB7OUxqFA==",
+ "license": "MIT",
+ "resolved": "https://registry.npmjs.org/install/-/install-0.13.0.tgz",
+ "version": "0.13.0"
+ },
+ "node_modules/is-extglob": {
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ },
+ "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
+ "license": "MIT",
+ "optional": true,
+ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
+ "version": "2.1.1"
+ },
+ "node_modules/is-glob": {
+ "dependencies": {
+ "is-extglob": "^2.1.1"
+ },
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ },
+ "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
+ "license": "MIT",
+ "optional": true,
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
+ "version": "4.0.3"
+ },
+ "node_modules/jquery": {
+ "integrity": "sha512-TXCHVR3Lb6TZdtw1l3RTLf8RBWVGexdxL6AC8/e0xZKEpBflBsjh9/8LXw+dkNFuOyW9B7iB3O1sP7hS0Kiacg==",
+ "license": "MIT",
+ "resolved": "https://registry.npmjs.org/jquery/-/jquery-4.0.0.tgz",
+ "version": "4.0.0"
+ },
+ "node_modules/node-addon-api": {
+ "dev": true,
+ "integrity": "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==",
+ "license": "MIT",
+ "optional": true,
+ "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.1.1.tgz",
+ "version": "7.1.1"
+ },
+ "node_modules/npm": {
+ "bin": {
+ "npm": "bin/npm-cli.js",
+ "npx": "bin/npx-cli.js"
+ },
+ "bundleDependencies": [
+ "@isaacs/string-locale-compare",
+ "@npmcli/arborist",
+ "@npmcli/config",
+ "@npmcli/fs",
+ "@npmcli/map-workspaces",
+ "@npmcli/metavuln-calculator",
+ "@npmcli/package-json",
+ "@npmcli/promise-spawn",
+ "@npmcli/redact",
+ "@npmcli/run-script",
+ "@sigstore/tuf",
+ "abbrev",
+ "archy",
+ "cacache",
+ "chalk",
+ "ci-info",
+ "cli-columns",
+ "fastest-levenshtein",
+ "fs-minipass",
+ "glob",
+ "graceful-fs",
+ "hosted-git-info",
+ "ini",
+ "init-package-json",
+ "is-cidr",
+ "json-parse-even-better-errors",
+ "libnpmaccess",
+ "libnpmdiff",
+ "libnpmexec",
+ "libnpmfund",
+ "libnpmorg",
+ "libnpmpack",
+ "libnpmpublish",
+ "libnpmsearch",
+ "libnpmteam",
+ "libnpmversion",
+ "make-fetch-happen",
+ "minimatch",
+ "minipass",
+ "minipass-pipeline",
+ "ms",
+ "node-gyp",
+ "nopt",
+ "npm-audit-report",
+ "npm-install-checks",
+ "npm-package-arg",
+ "npm-pick-manifest",
+ "npm-profile",
+ "npm-registry-fetch",
+ "npm-user-validate",
+ "p-map",
+ "pacote",
+ "parse-conflict-json",
+ "proc-log",
+ "qrcode-terminal",
+ "read",
+ "semver",
+ "spdx-expression-parse",
+ "ssri",
+ "supports-color",
+ "tar",
+ "text-table",
+ "tiny-relative-date",
+ "treeverse",
+ "validate-npm-package-name",
+ "which"
+ ],
+ "dependencies": {
+ "@isaacs/string-locale-compare": "^1.1.0",
+ "@npmcli/arborist": "^9.1.10",
+ "@npmcli/config": "^10.5.0",
+ "@npmcli/fs": "^5.0.0",
+ "@npmcli/map-workspaces": "^5.0.3",
+ "@npmcli/metavuln-calculator": "^9.0.3",
+ "@npmcli/package-json": "^7.0.4",
+ "@npmcli/promise-spawn": "^9.0.1",
+ "@npmcli/redact": "^4.0.0",
+ "@npmcli/run-script": "^10.0.3",
+ "@sigstore/tuf": "^4.0.1",
+ "abbrev": "^4.0.0",
+ "archy": "~1.0.0",
+ "cacache": "^20.0.3",
+ "chalk": "^5.6.2",
+ "ci-info": "^4.3.1",
+ "cli-columns": "^4.0.0",
+ "fastest-levenshtein": "^1.0.16",
+ "fs-minipass": "^3.0.3",
+ "glob": "^13.0.0",
+ "graceful-fs": "^4.2.11",
+ "hosted-git-info": "^9.0.2",
+ "ini": "^6.0.0",
+ "init-package-json": "^8.2.4",
+ "is-cidr": "^6.0.1",
+ "json-parse-even-better-errors": "^5.0.0",
+ "libnpmaccess": "^10.0.3",
+ "libnpmdiff": "^8.0.13",
+ "libnpmexec": "^10.1.12",
+ "libnpmfund": "^7.0.13",
+ "libnpmorg": "^8.0.1",
+ "libnpmpack": "^9.0.13",
+ "libnpmpublish": "^11.1.3",
+ "libnpmsearch": "^9.0.1",
+ "libnpmteam": "^8.0.2",
+ "libnpmversion": "^8.0.3",
+ "make-fetch-happen": "^15.0.3",
+ "minimatch": "^10.1.1",
+ "minipass": "^7.1.1",
+ "minipass-pipeline": "^1.2.4",
+ "ms": "^2.1.2",
+ "node-gyp": "^12.1.0",
+ "nopt": "^9.0.0",
+ "npm-audit-report": "^7.0.0",
+ "npm-install-checks": "^8.0.0",
+ "npm-package-arg": "^13.0.2",
+ "npm-pick-manifest": "^11.0.3",
+ "npm-profile": "^12.0.1",
+ "npm-registry-fetch": "^19.1.1",
+ "npm-user-validate": "^4.0.0",
+ "p-map": "^7.0.4",
+ "pacote": "^21.0.4",
+ "parse-conflict-json": "^5.0.1",
+ "proc-log": "^6.1.0",
+ "qrcode-terminal": "^0.12.0",
+ "read": "^5.0.1",
+ "semver": "^7.7.3",
+ "spdx-expression-parse": "^4.0.0",
+ "ssri": "^13.0.0",
+ "supports-color": "^10.2.2",
+ "tar": "^7.5.4",
+ "text-table": "~0.2.0",
+ "tiny-relative-date": "^2.0.2",
+ "treeverse": "^3.0.0",
+ "validate-npm-package-name": "^7.0.2",
+ "which": "^6.0.0"
+ },
+ "engines": {
+ "node": "^20.17.0 || >=22.9.0"
+ },
+ "integrity": "sha512-n19sJeW+RGKdkHo8SCc5xhSwkKhQUFfZaFzSc+EsYXLjSqIV0tl72aDYQVuzVvfrbysGwdaQsNLNy58J10EBSQ==",
+ "license": "Artistic-2.0",
+ "resolved": "https://registry.npmjs.org/npm/-/npm-11.8.0.tgz",
+ "version": "11.8.0",
+ "workspaces": [
+ "docs",
+ "smoke-tests",
+ "mock-globals",
+ "mock-registry",
+ "workspaces/*"
+ ]
+ },
+ "node_modules/npm/node_modules/@isaacs/balanced-match": {
+ "engines": {
+ "node": "20 || >=22"
+ },
+ "inBundle": true,
+ "license": "MIT",
+ "version": "4.0.1"
+ },
+ "node_modules/npm/node_modules/@isaacs/brace-expansion": {
+ "dependencies": {
+ "@isaacs/balanced-match": "^4.0.1"
+ },
+ "engines": {
+ "node": "20 || >=22"
+ },
+ "inBundle": true,
+ "license": "MIT",
+ "version": "5.0.0"
+ },
+ "node_modules/npm/node_modules/@isaacs/fs-minipass": {
+ "dependencies": {
+ "minipass": "^7.0.4"
+ },
+ "engines": {
+ "node": ">=18.0.0"
+ },
+ "inBundle": true,
+ "license": "ISC",
+ "version": "4.0.1"
+ },
+ "node_modules/npm/node_modules/@isaacs/string-locale-compare": {
+ "inBundle": true,
+ "license": "ISC",
+ "version": "1.1.0"
+ },
+ "node_modules/npm/node_modules/@npmcli/agent": {
+ "dependencies": {
+ "agent-base": "^7.1.0",
+ "http-proxy-agent": "^7.0.0",
+ "https-proxy-agent": "^7.0.1",
+ "lru-cache": "^11.2.1",
+ "socks-proxy-agent": "^8.0.3"
+ },
+ "engines": {
+ "node": "^20.17.0 || >=22.9.0"
+ },
+ "inBundle": true,
+ "license": "ISC",
+ "version": "4.0.0"
+ },
+ "node_modules/npm/node_modules/@npmcli/arborist": {
+ "bin": {
+ "arborist": "bin/index.js"
+ },
+ "dependencies": {
+ "@isaacs/string-locale-compare": "^1.1.0",
+ "@npmcli/fs": "^5.0.0",
+ "@npmcli/installed-package-contents": "^4.0.0",
+ "@npmcli/map-workspaces": "^5.0.0",
+ "@npmcli/metavuln-calculator": "^9.0.2",
+ "@npmcli/name-from-folder": "^4.0.0",
+ "@npmcli/node-gyp": "^5.0.0",
+ "@npmcli/package-json": "^7.0.0",
+ "@npmcli/query": "^5.0.0",
+ "@npmcli/redact": "^4.0.0",
+ "@npmcli/run-script": "^10.0.0",
+ "bin-links": "^6.0.0",
+ "cacache": "^20.0.1",
+ "common-ancestor-path": "^2.0.0",
+ "hosted-git-info": "^9.0.0",
+ "json-stringify-nice": "^1.1.4",
+ "lru-cache": "^11.2.1",
+ "minimatch": "^10.0.3",
+ "nopt": "^9.0.0",
+ "npm-install-checks": "^8.0.0",
+ "npm-package-arg": "^13.0.0",
+ "npm-pick-manifest": "^11.0.1",
+ "npm-registry-fetch": "^19.0.0",
+ "pacote": "^21.0.2",
+ "parse-conflict-json": "^5.0.1",
+ "proc-log": "^6.0.0",
+ "proggy": "^4.0.0",
+ "promise-all-reject-late": "^1.0.0",
+ "promise-call-limit": "^3.0.1",
+ "semver": "^7.3.7",
+ "ssri": "^13.0.0",
+ "treeverse": "^3.0.0",
+ "walk-up-path": "^4.0.0"
+ },
+ "engines": {
+ "node": "^20.17.0 || >=22.9.0"
+ },
+ "inBundle": true,
+ "license": "ISC",
+ "version": "9.1.10"
+ },
+ "node_modules/npm/node_modules/@npmcli/config": {
+ "dependencies": {
+ "@npmcli/map-workspaces": "^5.0.0",
+ "@npmcli/package-json": "^7.0.0",
+ "ci-info": "^4.0.0",
+ "ini": "^6.0.0",
+ "nopt": "^9.0.0",
+ "proc-log": "^6.0.0",
+ "semver": "^7.3.5",
+ "walk-up-path": "^4.0.0"
+ },
+ "engines": {
+ "node": "^20.17.0 || >=22.9.0"
+ },
+ "inBundle": true,
+ "license": "ISC",
+ "version": "10.5.0"
+ },
+ "node_modules/npm/node_modules/@npmcli/fs": {
+ "dependencies": {
+ "semver": "^7.3.5"
+ },
+ "engines": {
+ "node": "^20.17.0 || >=22.9.0"
+ },
+ "inBundle": true,
+ "license": "ISC",
+ "version": "5.0.0"
+ },
+ "node_modules/npm/node_modules/@npmcli/git": {
+ "dependencies": {
+ "@npmcli/promise-spawn": "^9.0.0",
+ "ini": "^6.0.0",
+ "lru-cache": "^11.2.1",
+ "npm-pick-manifest": "^11.0.1",
+ "proc-log": "^6.0.0",
+ "promise-retry": "^2.0.1",
+ "semver": "^7.3.5",
+ "which": "^6.0.0"
+ },
+ "engines": {
+ "node": "^20.17.0 || >=22.9.0"
+ },
+ "inBundle": true,
+ "license": "ISC",
+ "version": "7.0.1"
+ },
+ "node_modules/npm/node_modules/@npmcli/installed-package-contents": {
+ "bin": {
+ "installed-package-contents": "bin/index.js"
+ },
+ "dependencies": {
+ "npm-bundled": "^5.0.0",
+ "npm-normalize-package-bin": "^5.0.0"
+ },
+ "engines": {
+ "node": "^20.17.0 || >=22.9.0"
+ },
+ "inBundle": true,
+ "license": "ISC",
+ "version": "4.0.0"
+ },
+ "node_modules/npm/node_modules/@npmcli/map-workspaces": {
+ "dependencies": {
+ "@npmcli/name-from-folder": "^4.0.0",
+ "@npmcli/package-json": "^7.0.0",
+ "glob": "^13.0.0",
+ "minimatch": "^10.0.3"
+ },
+ "engines": {
+ "node": "^20.17.0 || >=22.9.0"
+ },
+ "inBundle": true,
+ "license": "ISC",
+ "version": "5.0.3"
+ },
+ "node_modules/npm/node_modules/@npmcli/metavuln-calculator": {
+ "dependencies": {
+ "cacache": "^20.0.0",
+ "json-parse-even-better-errors": "^5.0.0",
+ "pacote": "^21.0.0",
+ "proc-log": "^6.0.0",
+ "semver": "^7.3.5"
+ },
+ "engines": {
+ "node": "^20.17.0 || >=22.9.0"
+ },
+ "inBundle": true,
+ "license": "ISC",
+ "version": "9.0.3"
+ },
+ "node_modules/npm/node_modules/@npmcli/name-from-folder": {
+ "engines": {
+ "node": "^20.17.0 || >=22.9.0"
+ },
+ "inBundle": true,
+ "license": "ISC",
+ "version": "4.0.0"
+ },
+ "node_modules/npm/node_modules/@npmcli/node-gyp": {
+ "engines": {
+ "node": "^20.17.0 || >=22.9.0"
+ },
+ "inBundle": true,
+ "license": "ISC",
+ "version": "5.0.0"
+ },
+ "node_modules/npm/node_modules/@npmcli/package-json": {
+ "dependencies": {
+ "@npmcli/git": "^7.0.0",
+ "glob": "^13.0.0",
+ "hosted-git-info": "^9.0.0",
+ "json-parse-even-better-errors": "^5.0.0",
+ "proc-log": "^6.0.0",
+ "semver": "^7.5.3",
+ "validate-npm-package-license": "^3.0.4"
+ },
+ "engines": {
+ "node": "^20.17.0 || >=22.9.0"
+ },
+ "inBundle": true,
+ "license": "ISC",
+ "version": "7.0.4"
+ },
+ "node_modules/npm/node_modules/@npmcli/promise-spawn": {
+ "dependencies": {
+ "which": "^6.0.0"
+ },
+ "engines": {
+ "node": "^20.17.0 || >=22.9.0"
+ },
+ "inBundle": true,
+ "license": "ISC",
+ "version": "9.0.1"
+ },
+ "node_modules/npm/node_modules/@npmcli/query": {
+ "dependencies": {
+ "postcss-selector-parser": "^7.0.0"
+ },
+ "engines": {
+ "node": "^20.17.0 || >=22.9.0"
+ },
+ "inBundle": true,
+ "license": "ISC",
+ "version": "5.0.0"
+ },
+ "node_modules/npm/node_modules/@npmcli/redact": {
+ "engines": {
+ "node": "^20.17.0 || >=22.9.0"
+ },
+ "inBundle": true,
+ "license": "ISC",
+ "version": "4.0.0"
+ },
+ "node_modules/npm/node_modules/@npmcli/run-script": {
+ "dependencies": {
+ "@npmcli/node-gyp": "^5.0.0",
+ "@npmcli/package-json": "^7.0.0",
+ "@npmcli/promise-spawn": "^9.0.0",
+ "node-gyp": "^12.1.0",
+ "proc-log": "^6.0.0",
+ "which": "^6.0.0"
+ },
+ "engines": {
+ "node": "^20.17.0 || >=22.9.0"
+ },
+ "inBundle": true,
+ "license": "ISC",
+ "version": "10.0.3"
+ },
+ "node_modules/npm/node_modules/@sigstore/bundle": {
+ "dependencies": {
+ "@sigstore/protobuf-specs": "^0.5.0"
+ },
+ "engines": {
+ "node": "^20.17.0 || >=22.9.0"
+ },
+ "inBundle": true,
+ "license": "Apache-2.0",
+ "version": "4.0.0"
+ },
+ "node_modules/npm/node_modules/@sigstore/core": {
+ "engines": {
+ "node": "^20.17.0 || >=22.9.0"
+ },
+ "inBundle": true,
+ "license": "Apache-2.0",
+ "version": "3.1.0"
+ },
+ "node_modules/npm/node_modules/@sigstore/protobuf-specs": {
+ "engines": {
+ "node": "^18.17.0 || >=20.5.0"
+ },
+ "inBundle": true,
+ "license": "Apache-2.0",
+ "version": "0.5.0"
+ },
+ "node_modules/npm/node_modules/@sigstore/sign": {
+ "dependencies": {
+ "@sigstore/bundle": "^4.0.0",
+ "@sigstore/core": "^3.1.0",
+ "@sigstore/protobuf-specs": "^0.5.0",
+ "make-fetch-happen": "^15.0.3",
+ "proc-log": "^6.1.0",
+ "promise-retry": "^2.0.1"
+ },
+ "engines": {
+ "node": "^20.17.0 || >=22.9.0"
+ },
+ "inBundle": true,
+ "license": "Apache-2.0",
+ "version": "4.1.0"
+ },
+ "node_modules/npm/node_modules/@sigstore/tuf": {
+ "dependencies": {
+ "@sigstore/protobuf-specs": "^0.5.0",
+ "tuf-js": "^4.1.0"
+ },
+ "engines": {
+ "node": "^20.17.0 || >=22.9.0"
+ },
+ "inBundle": true,
+ "license": "Apache-2.0",
+ "version": "4.0.1"
+ },
+ "node_modules/npm/node_modules/@sigstore/verify": {
+ "dependencies": {
+ "@sigstore/bundle": "^4.0.0",
+ "@sigstore/core": "^3.1.0",
+ "@sigstore/protobuf-specs": "^0.5.0"
+ },
+ "engines": {
+ "node": "^20.17.0 || >=22.9.0"
+ },
+ "inBundle": true,
+ "license": "Apache-2.0",
+ "version": "3.1.0"
+ },
+ "node_modules/npm/node_modules/@tufjs/canonical-json": {
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ },
+ "inBundle": true,
+ "license": "MIT",
+ "version": "2.0.0"
+ },
+ "node_modules/npm/node_modules/@tufjs/models": {
+ "dependencies": {
+ "@tufjs/canonical-json": "2.0.0",
+ "minimatch": "^10.1.1"
+ },
+ "engines": {
+ "node": "^20.17.0 || >=22.9.0"
+ },
+ "inBundle": true,
+ "license": "MIT",
+ "version": "4.1.0"
+ },
+ "node_modules/npm/node_modules/abbrev": {
+ "engines": {
+ "node": "^20.17.0 || >=22.9.0"
+ },
+ "inBundle": true,
+ "license": "ISC",
+ "version": "4.0.0"
+ },
+ "node_modules/npm/node_modules/agent-base": {
+ "engines": {
+ "node": ">= 14"
+ },
+ "inBundle": true,
+ "license": "MIT",
+ "version": "7.1.4"
+ },
+ "node_modules/npm/node_modules/ansi-regex": {
+ "engines": {
+ "node": ">=8"
+ },
+ "inBundle": true,
+ "license": "MIT",
+ "version": "5.0.1"
+ },
+ "node_modules/npm/node_modules/aproba": {
+ "inBundle": true,
+ "license": "ISC",
+ "version": "2.1.0"
+ },
+ "node_modules/npm/node_modules/archy": {
+ "inBundle": true,
+ "license": "MIT",
+ "version": "1.0.0"
+ },
+ "node_modules/npm/node_modules/bin-links": {
+ "dependencies": {
+ "cmd-shim": "^8.0.0",
+ "npm-normalize-package-bin": "^5.0.0",
+ "proc-log": "^6.0.0",
+ "read-cmd-shim": "^6.0.0",
+ "write-file-atomic": "^7.0.0"
+ },
+ "engines": {
+ "node": "^20.17.0 || >=22.9.0"
+ },
+ "inBundle": true,
+ "license": "ISC",
+ "version": "6.0.0"
+ },
+ "node_modules/npm/node_modules/binary-extensions": {
+ "engines": {
+ "node": ">=18.20"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ },
+ "inBundle": true,
+ "license": "MIT",
+ "version": "3.1.0"
+ },
+ "node_modules/npm/node_modules/cacache": {
+ "dependencies": {
+ "@npmcli/fs": "^5.0.0",
+ "fs-minipass": "^3.0.0",
+ "glob": "^13.0.0",
+ "lru-cache": "^11.1.0",
+ "minipass": "^7.0.3",
+ "minipass-collect": "^2.0.1",
+ "minipass-flush": "^1.0.5",
+ "minipass-pipeline": "^1.2.4",
+ "p-map": "^7.0.2",
+ "ssri": "^13.0.0",
+ "unique-filename": "^5.0.0"
+ },
+ "engines": {
+ "node": "^20.17.0 || >=22.9.0"
+ },
+ "inBundle": true,
+ "license": "ISC",
+ "version": "20.0.3"
+ },
+ "node_modules/npm/node_modules/chalk": {
+ "engines": {
+ "node": "^12.17.0 || ^14.13 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ },
+ "inBundle": true,
+ "license": "MIT",
+ "version": "5.6.2"
+ },
+ "node_modules/npm/node_modules/chownr": {
+ "engines": {
+ "node": ">=18"
+ },
+ "inBundle": true,
+ "license": "BlueOak-1.0.0",
+ "version": "3.0.0"
+ },
+ "node_modules/npm/node_modules/ci-info": {
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/sibiraj-s"
+ }
+ ],
+ "inBundle": true,
+ "license": "MIT",
+ "version": "4.3.1"
+ },
+ "node_modules/npm/node_modules/cidr-regex": {
+ "dependencies": {
+ "ip-regex": "5.0.0"
+ },
+ "engines": {
+ "node": ">=20"
+ },
+ "inBundle": true,
+ "license": "BSD-2-Clause",
+ "version": "5.0.1"
+ },
+ "node_modules/npm/node_modules/cli-columns": {
+ "dependencies": {
+ "string-width": "^4.2.3",
+ "strip-ansi": "^6.0.1"
+ },
+ "engines": {
+ "node": ">= 10"
+ },
+ "inBundle": true,
+ "license": "MIT",
+ "version": "4.0.0"
+ },
+ "node_modules/npm/node_modules/cmd-shim": {
+ "engines": {
+ "node": "^20.17.0 || >=22.9.0"
+ },
+ "inBundle": true,
+ "license": "ISC",
+ "version": "8.0.0"
+ },
+ "node_modules/npm/node_modules/common-ancestor-path": {
+ "engines": {
+ "node": ">= 18"
+ },
+ "inBundle": true,
+ "license": "BlueOak-1.0.0",
+ "version": "2.0.0"
+ },
+ "node_modules/npm/node_modules/cssesc": {
+ "bin": {
+ "cssesc": "bin/cssesc"
+ },
+ "engines": {
+ "node": ">=4"
+ },
+ "inBundle": true,
+ "license": "MIT",
+ "version": "3.0.0"
+ },
+ "node_modules/npm/node_modules/debug": {
+ "dependencies": {
+ "ms": "^2.1.3"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "inBundle": true,
+ "license": "MIT",
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ },
+ "version": "4.4.3"
+ },
+ "node_modules/npm/node_modules/diff": {
+ "engines": {
+ "node": ">=0.3.1"
+ },
+ "inBundle": true,
+ "license": "BSD-3-Clause",
+ "version": "8.0.3"
+ },
+ "node_modules/npm/node_modules/emoji-regex": {
+ "inBundle": true,
+ "license": "MIT",
+ "version": "8.0.0"
+ },
+ "node_modules/npm/node_modules/encoding": {
+ "dependencies": {
+ "iconv-lite": "^0.6.2"
+ },
+ "inBundle": true,
+ "license": "MIT",
+ "optional": true,
+ "version": "0.1.13"
+ },
+ "node_modules/npm/node_modules/env-paths": {
+ "engines": {
+ "node": ">=6"
+ },
+ "inBundle": true,
+ "license": "MIT",
+ "version": "2.2.1"
+ },
+ "node_modules/npm/node_modules/err-code": {
+ "inBundle": true,
+ "license": "MIT",
+ "version": "2.0.3"
+ },
+ "node_modules/npm/node_modules/exponential-backoff": {
+ "inBundle": true,
+ "license": "Apache-2.0",
+ "version": "3.1.3"
+ },
+ "node_modules/npm/node_modules/fastest-levenshtein": {
+ "engines": {
+ "node": ">= 4.9.1"
+ },
+ "inBundle": true,
+ "license": "MIT",
+ "version": "1.0.16"
+ },
+ "node_modules/npm/node_modules/fs-minipass": {
+ "dependencies": {
+ "minipass": "^7.0.3"
+ },
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ },
+ "inBundle": true,
+ "license": "ISC",
+ "version": "3.0.3"
+ },
+ "node_modules/npm/node_modules/glob": {
+ "dependencies": {
+ "minimatch": "^10.1.1",
+ "minipass": "^7.1.2",
+ "path-scurry": "^2.0.0"
+ },
+ "engines": {
+ "node": "20 || >=22"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ },
+ "inBundle": true,
+ "license": "BlueOak-1.0.0",
+ "version": "13.0.0"
+ },
+ "node_modules/npm/node_modules/graceful-fs": {
+ "inBundle": true,
+ "license": "ISC",
+ "version": "4.2.11"
+ },
+ "node_modules/npm/node_modules/hosted-git-info": {
+ "dependencies": {
+ "lru-cache": "^11.1.0"
+ },
+ "engines": {
+ "node": "^20.17.0 || >=22.9.0"
+ },
+ "inBundle": true,
+ "license": "ISC",
+ "version": "9.0.2"
+ },
+ "node_modules/npm/node_modules/http-cache-semantics": {
+ "inBundle": true,
+ "license": "BSD-2-Clause",
+ "version": "4.2.0"
+ },
+ "node_modules/npm/node_modules/http-proxy-agent": {
+ "dependencies": {
+ "agent-base": "^7.1.0",
+ "debug": "^4.3.4"
+ },
+ "engines": {
+ "node": ">= 14"
+ },
+ "inBundle": true,
+ "license": "MIT",
+ "version": "7.0.2"
+ },
+ "node_modules/npm/node_modules/https-proxy-agent": {
+ "dependencies": {
+ "agent-base": "^7.1.2",
+ "debug": "4"
+ },
+ "engines": {
+ "node": ">= 14"
+ },
+ "inBundle": true,
+ "license": "MIT",
+ "version": "7.0.6"
+ },
+ "node_modules/npm/node_modules/iconv-lite": {
+ "dependencies": {
+ "safer-buffer": ">= 2.1.2 < 3.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ },
+ "inBundle": true,
+ "license": "MIT",
+ "optional": true,
+ "version": "0.6.3"
+ },
+ "node_modules/npm/node_modules/ignore-walk": {
+ "dependencies": {
+ "minimatch": "^10.0.3"
+ },
+ "engines": {
+ "node": "^20.17.0 || >=22.9.0"
+ },
+ "inBundle": true,
+ "license": "ISC",
+ "version": "8.0.0"
+ },
+ "node_modules/npm/node_modules/imurmurhash": {
+ "engines": {
+ "node": ">=0.8.19"
+ },
+ "inBundle": true,
+ "license": "MIT",
+ "version": "0.1.4"
+ },
+ "node_modules/npm/node_modules/ini": {
+ "engines": {
+ "node": "^20.17.0 || >=22.9.0"
+ },
+ "inBundle": true,
+ "license": "ISC",
+ "version": "6.0.0"
+ },
+ "node_modules/npm/node_modules/init-package-json": {
+ "dependencies": {
+ "@npmcli/package-json": "^7.0.0",
+ "npm-package-arg": "^13.0.0",
+ "promzard": "^3.0.1",
+ "read": "^5.0.1",
+ "semver": "^7.7.2",
+ "validate-npm-package-license": "^3.0.4",
+ "validate-npm-package-name": "^7.0.0"
+ },
+ "engines": {
+ "node": "^20.17.0 || >=22.9.0"
+ },
+ "inBundle": true,
+ "license": "ISC",
+ "version": "8.2.4"
+ },
+ "node_modules/npm/node_modules/ip-address": {
+ "engines": {
+ "node": ">= 12"
+ },
+ "inBundle": true,
+ "license": "MIT",
+ "version": "10.1.0"
+ },
+ "node_modules/npm/node_modules/ip-regex": {
+ "engines": {
+ "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ },
+ "inBundle": true,
+ "license": "MIT",
+ "version": "5.0.0"
+ },
+ "node_modules/npm/node_modules/is-cidr": {
+ "dependencies": {
+ "cidr-regex": "5.0.1"
+ },
+ "engines": {
+ "node": ">=20"
+ },
+ "inBundle": true,
+ "license": "BSD-2-Clause",
+ "version": "6.0.1"
+ },
+ "node_modules/npm/node_modules/is-fullwidth-code-point": {
+ "engines": {
+ "node": ">=8"
+ },
+ "inBundle": true,
+ "license": "MIT",
+ "version": "3.0.0"
+ },
+ "node_modules/npm/node_modules/isexe": {
+ "engines": {
+ "node": ">=16"
+ },
+ "inBundle": true,
+ "license": "ISC",
+ "version": "3.1.1"
+ },
+ "node_modules/npm/node_modules/json-parse-even-better-errors": {
+ "engines": {
+ "node": "^20.17.0 || >=22.9.0"
+ },
+ "inBundle": true,
+ "license": "MIT",
+ "version": "5.0.0"
+ },
+ "node_modules/npm/node_modules/json-stringify-nice": {
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ },
+ "inBundle": true,
+ "license": "ISC",
+ "version": "1.1.4"
+ },
+ "node_modules/npm/node_modules/jsonparse": {
+ "engines": [
+ "node >= 0.2.0"
+ ],
+ "inBundle": true,
+ "license": "MIT",
+ "version": "1.3.1"
+ },
+ "node_modules/npm/node_modules/just-diff": {
+ "inBundle": true,
+ "license": "MIT",
+ "version": "6.0.2"
+ },
+ "node_modules/npm/node_modules/just-diff-apply": {
+ "inBundle": true,
+ "license": "MIT",
+ "version": "5.5.0"
+ },
+ "node_modules/npm/node_modules/libnpmaccess": {
+ "dependencies": {
+ "npm-package-arg": "^13.0.0",
+ "npm-registry-fetch": "^19.0.0"
+ },
+ "engines": {
+ "node": "^20.17.0 || >=22.9.0"
+ },
+ "inBundle": true,
+ "license": "ISC",
+ "version": "10.0.3"
+ },
+ "node_modules/npm/node_modules/libnpmdiff": {
+ "dependencies": {
+ "@npmcli/arborist": "^9.1.10",
+ "@npmcli/installed-package-contents": "^4.0.0",
+ "binary-extensions": "^3.0.0",
+ "diff": "^8.0.2",
+ "minimatch": "^10.0.3",
+ "npm-package-arg": "^13.0.0",
+ "pacote": "^21.0.2",
+ "tar": "^7.5.1"
+ },
+ "engines": {
+ "node": "^20.17.0 || >=22.9.0"
+ },
+ "inBundle": true,
+ "license": "ISC",
+ "version": "8.0.13"
+ },
+ "node_modules/npm/node_modules/libnpmexec": {
+ "dependencies": {
+ "@npmcli/arborist": "^9.1.10",
+ "@npmcli/package-json": "^7.0.0",
+ "@npmcli/run-script": "^10.0.0",
+ "ci-info": "^4.0.0",
+ "npm-package-arg": "^13.0.0",
+ "pacote": "^21.0.2",
+ "proc-log": "^6.0.0",
+ "promise-retry": "^2.0.1",
+ "read": "^5.0.1",
+ "semver": "^7.3.7",
+ "signal-exit": "^4.1.0",
+ "walk-up-path": "^4.0.0"
+ },
+ "engines": {
+ "node": "^20.17.0 || >=22.9.0"
+ },
+ "inBundle": true,
+ "license": "ISC",
+ "version": "10.1.12"
+ },
+ "node_modules/npm/node_modules/libnpmfund": {
+ "dependencies": {
+ "@npmcli/arborist": "^9.1.10"
+ },
+ "engines": {
+ "node": "^20.17.0 || >=22.9.0"
+ },
+ "inBundle": true,
+ "license": "ISC",
+ "version": "7.0.13"
+ },
+ "node_modules/npm/node_modules/libnpmorg": {
+ "dependencies": {
+ "aproba": "^2.0.0",
+ "npm-registry-fetch": "^19.0.0"
+ },
+ "engines": {
+ "node": "^20.17.0 || >=22.9.0"
+ },
+ "inBundle": true,
+ "license": "ISC",
+ "version": "8.0.1"
+ },
+ "node_modules/npm/node_modules/libnpmpack": {
+ "dependencies": {
+ "@npmcli/arborist": "^9.1.10",
+ "@npmcli/run-script": "^10.0.0",
+ "npm-package-arg": "^13.0.0",
+ "pacote": "^21.0.2"
+ },
+ "engines": {
+ "node": "^20.17.0 || >=22.9.0"
+ },
+ "inBundle": true,
+ "license": "ISC",
+ "version": "9.0.13"
+ },
+ "node_modules/npm/node_modules/libnpmpublish": {
+ "dependencies": {
+ "@npmcli/package-json": "^7.0.0",
+ "ci-info": "^4.0.0",
+ "npm-package-arg": "^13.0.0",
+ "npm-registry-fetch": "^19.0.0",
+ "proc-log": "^6.0.0",
+ "semver": "^7.3.7",
+ "sigstore": "^4.0.0",
+ "ssri": "^13.0.0"
+ },
+ "engines": {
+ "node": "^20.17.0 || >=22.9.0"
+ },
+ "inBundle": true,
+ "license": "ISC",
+ "version": "11.1.3"
+ },
+ "node_modules/npm/node_modules/libnpmsearch": {
+ "dependencies": {
+ "npm-registry-fetch": "^19.0.0"
+ },
+ "engines": {
+ "node": "^20.17.0 || >=22.9.0"
+ },
+ "inBundle": true,
+ "license": "ISC",
+ "version": "9.0.1"
+ },
+ "node_modules/npm/node_modules/libnpmteam": {
+ "dependencies": {
+ "aproba": "^2.0.0",
+ "npm-registry-fetch": "^19.0.0"
+ },
+ "engines": {
+ "node": "^20.17.0 || >=22.9.0"
+ },
+ "inBundle": true,
+ "license": "ISC",
+ "version": "8.0.2"
+ },
+ "node_modules/npm/node_modules/libnpmversion": {
+ "dependencies": {
+ "@npmcli/git": "^7.0.0",
+ "@npmcli/run-script": "^10.0.0",
+ "json-parse-even-better-errors": "^5.0.0",
+ "proc-log": "^6.0.0",
+ "semver": "^7.3.7"
+ },
+ "engines": {
+ "node": "^20.17.0 || >=22.9.0"
+ },
+ "inBundle": true,
+ "license": "ISC",
+ "version": "8.0.3"
+ },
+ "node_modules/npm/node_modules/lru-cache": {
+ "engines": {
+ "node": "20 || >=22"
+ },
+ "inBundle": true,
+ "license": "BlueOak-1.0.0",
+ "version": "11.2.4"
+ },
+ "node_modules/npm/node_modules/make-fetch-happen": {
+ "dependencies": {
+ "@npmcli/agent": "^4.0.0",
+ "cacache": "^20.0.1",
+ "http-cache-semantics": "^4.1.1",
+ "minipass": "^7.0.2",
+ "minipass-fetch": "^5.0.0",
+ "minipass-flush": "^1.0.5",
+ "minipass-pipeline": "^1.2.4",
+ "negotiator": "^1.0.0",
+ "proc-log": "^6.0.0",
+ "promise-retry": "^2.0.1",
+ "ssri": "^13.0.0"
+ },
+ "engines": {
+ "node": "^20.17.0 || >=22.9.0"
+ },
+ "inBundle": true,
+ "license": "ISC",
+ "version": "15.0.3"
+ },
+ "node_modules/npm/node_modules/minimatch": {
+ "dependencies": {
+ "@isaacs/brace-expansion": "^5.0.0"
+ },
+ "engines": {
+ "node": "20 || >=22"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ },
+ "inBundle": true,
+ "license": "BlueOak-1.0.0",
+ "version": "10.1.1"
+ },
+ "node_modules/npm/node_modules/minipass": {
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ },
+ "inBundle": true,
+ "license": "ISC",
+ "version": "7.1.2"
+ },
+ "node_modules/npm/node_modules/minipass-collect": {
+ "dependencies": {
+ "minipass": "^7.0.3"
+ },
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ },
+ "inBundle": true,
+ "license": "ISC",
+ "version": "2.0.1"
+ },
+ "node_modules/npm/node_modules/minipass-fetch": {
+ "dependencies": {
+ "minipass": "^7.0.3",
+ "minipass-sized": "^1.0.3",
+ "minizlib": "^3.0.1"
+ },
+ "engines": {
+ "node": "^20.17.0 || >=22.9.0"
+ },
+ "inBundle": true,
+ "license": "MIT",
+ "optionalDependencies": {
+ "encoding": "^0.1.13"
+ },
+ "version": "5.0.0"
+ },
+ "node_modules/npm/node_modules/minipass-flush": {
+ "dependencies": {
+ "minipass": "^3.0.0"
+ },
+ "engines": {
+ "node": ">= 8"
+ },
+ "inBundle": true,
+ "license": "ISC",
+ "version": "1.0.5"
+ },
+ "node_modules/npm/node_modules/minipass-flush/node_modules/minipass": {
+ "dependencies": {
+ "yallist": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "inBundle": true,
+ "license": "ISC",
+ "version": "3.3.6"
+ },
+ "node_modules/npm/node_modules/minipass-pipeline": {
+ "dependencies": {
+ "minipass": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "inBundle": true,
+ "license": "ISC",
+ "version": "1.2.4"
+ },
+ "node_modules/npm/node_modules/minipass-pipeline/node_modules/minipass": {
+ "dependencies": {
+ "yallist": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "inBundle": true,
+ "license": "ISC",
+ "version": "3.3.6"
+ },
+ "node_modules/npm/node_modules/minipass-sized": {
+ "dependencies": {
+ "minipass": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "inBundle": true,
+ "license": "ISC",
+ "version": "1.0.3"
+ },
+ "node_modules/npm/node_modules/minipass-sized/node_modules/minipass": {
+ "dependencies": {
+ "yallist": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "inBundle": true,
+ "license": "ISC",
+ "version": "3.3.6"
+ },
+ "node_modules/npm/node_modules/minizlib": {
+ "dependencies": {
+ "minipass": "^7.1.2"
+ },
+ "engines": {
+ "node": ">= 18"
+ },
+ "inBundle": true,
+ "license": "MIT",
+ "version": "3.1.0"
+ },
+ "node_modules/npm/node_modules/ms": {
+ "inBundle": true,
+ "license": "MIT",
+ "version": "2.1.3"
+ },
+ "node_modules/npm/node_modules/mute-stream": {
+ "engines": {
+ "node": "^20.17.0 || >=22.9.0"
+ },
+ "inBundle": true,
+ "license": "ISC",
+ "version": "3.0.0"
+ },
+ "node_modules/npm/node_modules/negotiator": {
+ "engines": {
+ "node": ">= 0.6"
+ },
+ "inBundle": true,
+ "license": "MIT",
+ "version": "1.0.0"
+ },
+ "node_modules/npm/node_modules/node-gyp": {
+ "bin": {
+ "node-gyp": "bin/node-gyp.js"
+ },
+ "dependencies": {
+ "env-paths": "^2.2.0",
+ "exponential-backoff": "^3.1.1",
+ "graceful-fs": "^4.2.6",
+ "make-fetch-happen": "^15.0.0",
+ "nopt": "^9.0.0",
+ "proc-log": "^6.0.0",
+ "semver": "^7.3.5",
+ "tar": "^7.5.2",
+ "tinyglobby": "^0.2.12",
+ "which": "^6.0.0"
+ },
+ "engines": {
+ "node": "^20.17.0 || >=22.9.0"
+ },
+ "inBundle": true,
+ "license": "MIT",
+ "version": "12.1.0"
+ },
+ "node_modules/npm/node_modules/nopt": {
+ "bin": {
+ "nopt": "bin/nopt.js"
+ },
+ "dependencies": {
+ "abbrev": "^4.0.0"
+ },
+ "engines": {
+ "node": "^20.17.0 || >=22.9.0"
+ },
+ "inBundle": true,
+ "license": "ISC",
+ "version": "9.0.0"
+ },
+ "node_modules/npm/node_modules/npm-audit-report": {
+ "engines": {
+ "node": "^20.17.0 || >=22.9.0"
+ },
+ "inBundle": true,
+ "license": "ISC",
+ "version": "7.0.0"
+ },
+ "node_modules/npm/node_modules/npm-bundled": {
+ "dependencies": {
+ "npm-normalize-package-bin": "^5.0.0"
+ },
+ "engines": {
+ "node": "^20.17.0 || >=22.9.0"
+ },
+ "inBundle": true,
+ "license": "ISC",
+ "version": "5.0.0"
+ },
+ "node_modules/npm/node_modules/npm-install-checks": {
+ "dependencies": {
+ "semver": "^7.1.1"
+ },
+ "engines": {
+ "node": "^20.17.0 || >=22.9.0"
+ },
+ "inBundle": true,
+ "license": "BSD-2-Clause",
+ "version": "8.0.0"
+ },
+ "node_modules/npm/node_modules/npm-normalize-package-bin": {
+ "engines": {
+ "node": "^20.17.0 || >=22.9.0"
+ },
+ "inBundle": true,
+ "license": "ISC",
+ "version": "5.0.0"
+ },
+ "node_modules/npm/node_modules/npm-package-arg": {
+ "dependencies": {
+ "hosted-git-info": "^9.0.0",
+ "proc-log": "^6.0.0",
+ "semver": "^7.3.5",
+ "validate-npm-package-name": "^7.0.0"
+ },
+ "engines": {
+ "node": "^20.17.0 || >=22.9.0"
+ },
+ "inBundle": true,
+ "license": "ISC",
+ "version": "13.0.2"
+ },
+ "node_modules/npm/node_modules/npm-packlist": {
+ "dependencies": {
+ "ignore-walk": "^8.0.0",
+ "proc-log": "^6.0.0"
+ },
+ "engines": {
+ "node": "^20.17.0 || >=22.9.0"
+ },
+ "inBundle": true,
+ "license": "ISC",
+ "version": "10.0.3"
+ },
+ "node_modules/npm/node_modules/npm-pick-manifest": {
+ "dependencies": {
+ "npm-install-checks": "^8.0.0",
+ "npm-normalize-package-bin": "^5.0.0",
+ "npm-package-arg": "^13.0.0",
+ "semver": "^7.3.5"
+ },
+ "engines": {
+ "node": "^20.17.0 || >=22.9.0"
+ },
+ "inBundle": true,
+ "license": "ISC",
+ "version": "11.0.3"
+ },
+ "node_modules/npm/node_modules/npm-profile": {
+ "dependencies": {
+ "npm-registry-fetch": "^19.0.0",
+ "proc-log": "^6.0.0"
+ },
+ "engines": {
+ "node": "^20.17.0 || >=22.9.0"
+ },
+ "inBundle": true,
+ "license": "ISC",
+ "version": "12.0.1"
+ },
+ "node_modules/npm/node_modules/npm-registry-fetch": {
+ "dependencies": {
+ "@npmcli/redact": "^4.0.0",
+ "jsonparse": "^1.3.1",
+ "make-fetch-happen": "^15.0.0",
+ "minipass": "^7.0.2",
+ "minipass-fetch": "^5.0.0",
+ "minizlib": "^3.0.1",
+ "npm-package-arg": "^13.0.0",
+ "proc-log": "^6.0.0"
+ },
+ "engines": {
+ "node": "^20.17.0 || >=22.9.0"
+ },
+ "inBundle": true,
+ "license": "ISC",
+ "version": "19.1.1"
+ },
+ "node_modules/npm/node_modules/npm-user-validate": {
+ "engines": {
+ "node": "^20.17.0 || >=22.9.0"
+ },
+ "inBundle": true,
+ "license": "BSD-2-Clause",
+ "version": "4.0.0"
+ },
+ "node_modules/npm/node_modules/p-map": {
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ },
+ "inBundle": true,
+ "license": "MIT",
+ "version": "7.0.4"
+ },
+ "node_modules/npm/node_modules/pacote": {
+ "bin": {
+ "pacote": "bin/index.js"
+ },
+ "dependencies": {
+ "@npmcli/git": "^7.0.0",
+ "@npmcli/installed-package-contents": "^4.0.0",
+ "@npmcli/package-json": "^7.0.0",
+ "@npmcli/promise-spawn": "^9.0.0",
+ "@npmcli/run-script": "^10.0.0",
+ "cacache": "^20.0.0",
+ "fs-minipass": "^3.0.0",
+ "minipass": "^7.0.2",
+ "npm-package-arg": "^13.0.0",
+ "npm-packlist": "^10.0.1",
+ "npm-pick-manifest": "^11.0.1",
+ "npm-registry-fetch": "^19.0.0",
+ "proc-log": "^6.0.0",
+ "promise-retry": "^2.0.1",
+ "sigstore": "^4.0.0",
+ "ssri": "^13.0.0",
+ "tar": "^7.4.3"
+ },
+ "engines": {
+ "node": "^20.17.0 || >=22.9.0"
+ },
+ "inBundle": true,
+ "license": "ISC",
+ "version": "21.0.4"
+ },
+ "node_modules/npm/node_modules/parse-conflict-json": {
+ "dependencies": {
+ "json-parse-even-better-errors": "^5.0.0",
+ "just-diff": "^6.0.0",
+ "just-diff-apply": "^5.2.0"
+ },
+ "engines": {
+ "node": "^20.17.0 || >=22.9.0"
+ },
+ "inBundle": true,
+ "license": "ISC",
+ "version": "5.0.1"
+ },
+ "node_modules/npm/node_modules/path-scurry": {
+ "dependencies": {
+ "lru-cache": "^11.0.0",
+ "minipass": "^7.1.2"
+ },
+ "engines": {
+ "node": "20 || >=22"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ },
+ "inBundle": true,
+ "license": "BlueOak-1.0.0",
+ "version": "2.0.1"
+ },
+ "node_modules/npm/node_modules/postcss-selector-parser": {
+ "dependencies": {
+ "cssesc": "^3.0.0",
+ "util-deprecate": "^1.0.2"
+ },
+ "engines": {
+ "node": ">=4"
+ },
+ "inBundle": true,
+ "license": "MIT",
+ "version": "7.1.1"
+ },
+ "node_modules/npm/node_modules/proc-log": {
+ "engines": {
+ "node": "^20.17.0 || >=22.9.0"
+ },
+ "inBundle": true,
+ "license": "ISC",
+ "version": "6.1.0"
+ },
+ "node_modules/npm/node_modules/proggy": {
+ "engines": {
+ "node": "^20.17.0 || >=22.9.0"
+ },
+ "inBundle": true,
+ "license": "ISC",
+ "version": "4.0.0"
+ },
+ "node_modules/npm/node_modules/promise-all-reject-late": {
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ },
+ "inBundle": true,
+ "license": "ISC",
+ "version": "1.0.1"
+ },
+ "node_modules/npm/node_modules/promise-call-limit": {
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ },
+ "inBundle": true,
+ "license": "ISC",
+ "version": "3.0.2"
+ },
+ "node_modules/npm/node_modules/promise-retry": {
+ "dependencies": {
+ "err-code": "^2.0.2",
+ "retry": "^0.12.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "inBundle": true,
+ "license": "MIT",
+ "version": "2.0.1"
+ },
+ "node_modules/npm/node_modules/promzard": {
+ "dependencies": {
+ "read": "^5.0.0"
+ },
+ "engines": {
+ "node": "^20.17.0 || >=22.9.0"
+ },
+ "inBundle": true,
+ "license": "ISC",
+ "version": "3.0.1"
+ },
+ "node_modules/npm/node_modules/qrcode-terminal": {
+ "bin": {
+ "qrcode-terminal": "bin/qrcode-terminal.js"
+ },
+ "inBundle": true,
+ "version": "0.12.0"
+ },
+ "node_modules/npm/node_modules/read": {
+ "dependencies": {
+ "mute-stream": "^3.0.0"
+ },
+ "engines": {
+ "node": "^20.17.0 || >=22.9.0"
+ },
+ "inBundle": true,
+ "license": "ISC",
+ "version": "5.0.1"
+ },
+ "node_modules/npm/node_modules/read-cmd-shim": {
+ "engines": {
+ "node": "^20.17.0 || >=22.9.0"
+ },
+ "inBundle": true,
+ "license": "ISC",
+ "version": "6.0.0"
+ },
+ "node_modules/npm/node_modules/retry": {
+ "engines": {
+ "node": ">= 4"
+ },
+ "inBundle": true,
+ "license": "MIT",
+ "version": "0.12.0"
+ },
+ "node_modules/npm/node_modules/safer-buffer": {
+ "inBundle": true,
+ "license": "MIT",
+ "optional": true,
+ "version": "2.1.2"
+ },
+ "node_modules/npm/node_modules/semver": {
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "inBundle": true,
+ "license": "ISC",
+ "version": "7.7.3"
+ },
+ "node_modules/npm/node_modules/signal-exit": {
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ },
+ "inBundle": true,
+ "license": "ISC",
+ "version": "4.1.0"
+ },
+ "node_modules/npm/node_modules/sigstore": {
+ "dependencies": {
+ "@sigstore/bundle": "^4.0.0",
+ "@sigstore/core": "^3.1.0",
+ "@sigstore/protobuf-specs": "^0.5.0",
+ "@sigstore/sign": "^4.1.0",
+ "@sigstore/tuf": "^4.0.1",
+ "@sigstore/verify": "^3.1.0"
+ },
+ "engines": {
+ "node": "^20.17.0 || >=22.9.0"
+ },
+ "inBundle": true,
+ "license": "Apache-2.0",
+ "version": "4.1.0"
+ },
+ "node_modules/npm/node_modules/smart-buffer": {
+ "engines": {
+ "node": ">= 6.0.0",
+ "npm": ">= 3.0.0"
+ },
+ "inBundle": true,
+ "license": "MIT",
+ "version": "4.2.0"
+ },
+ "node_modules/npm/node_modules/socks": {
+ "dependencies": {
+ "ip-address": "^10.0.1",
+ "smart-buffer": "^4.2.0"
+ },
+ "engines": {
+ "node": ">= 10.0.0",
+ "npm": ">= 3.0.0"
+ },
+ "inBundle": true,
+ "license": "MIT",
+ "version": "2.8.7"
+ },
+ "node_modules/npm/node_modules/socks-proxy-agent": {
+ "dependencies": {
+ "agent-base": "^7.1.2",
+ "debug": "^4.3.4",
+ "socks": "^2.8.3"
+ },
+ "engines": {
+ "node": ">= 14"
+ },
+ "inBundle": true,
+ "license": "MIT",
+ "version": "8.0.5"
+ },
+ "node_modules/npm/node_modules/spdx-correct": {
+ "dependencies": {
+ "spdx-expression-parse": "^3.0.0",
+ "spdx-license-ids": "^3.0.0"
+ },
+ "inBundle": true,
+ "license": "Apache-2.0",
+ "version": "3.2.0"
+ },
+ "node_modules/npm/node_modules/spdx-correct/node_modules/spdx-expression-parse": {
+ "dependencies": {
+ "spdx-exceptions": "^2.1.0",
+ "spdx-license-ids": "^3.0.0"
+ },
+ "inBundle": true,
+ "license": "MIT",
+ "version": "3.0.1"
+ },
+ "node_modules/npm/node_modules/spdx-exceptions": {
+ "inBundle": true,
+ "license": "CC-BY-3.0",
+ "version": "2.5.0"
+ },
+ "node_modules/npm/node_modules/spdx-expression-parse": {
+ "dependencies": {
+ "spdx-exceptions": "^2.1.0",
+ "spdx-license-ids": "^3.0.0"
+ },
+ "inBundle": true,
+ "license": "MIT",
+ "version": "4.0.0"
+ },
+ "node_modules/npm/node_modules/spdx-license-ids": {
+ "inBundle": true,
+ "license": "CC0-1.0",
+ "version": "3.0.22"
+ },
+ "node_modules/npm/node_modules/ssri": {
+ "dependencies": {
+ "minipass": "^7.0.3"
+ },
+ "engines": {
+ "node": "^20.17.0 || >=22.9.0"
+ },
+ "inBundle": true,
+ "license": "ISC",
+ "version": "13.0.0"
+ },
+ "node_modules/npm/node_modules/string-width": {
+ "dependencies": {
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "inBundle": true,
+ "license": "MIT",
+ "version": "4.2.3"
+ },
+ "node_modules/npm/node_modules/strip-ansi": {
+ "dependencies": {
+ "ansi-regex": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "inBundle": true,
+ "license": "MIT",
+ "version": "6.0.1"
+ },
+ "node_modules/npm/node_modules/supports-color": {
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/supports-color?sponsor=1"
+ },
+ "inBundle": true,
+ "license": "MIT",
+ "version": "10.2.2"
+ },
+ "node_modules/npm/node_modules/tar": {
+ "dependencies": {
+ "@isaacs/fs-minipass": "^4.0.0",
+ "chownr": "^3.0.0",
+ "minipass": "^7.1.2",
+ "minizlib": "^3.1.0",
+ "yallist": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "inBundle": true,
+ "license": "BlueOak-1.0.0",
+ "version": "7.5.4"
+ },
+ "node_modules/npm/node_modules/tar/node_modules/yallist": {
+ "engines": {
+ "node": ">=18"
+ },
+ "inBundle": true,
+ "license": "BlueOak-1.0.0",
+ "version": "5.0.0"
+ },
+ "node_modules/npm/node_modules/text-table": {
+ "inBundle": true,
+ "license": "MIT",
+ "version": "0.2.0"
+ },
+ "node_modules/npm/node_modules/tiny-relative-date": {
+ "inBundle": true,
+ "license": "MIT",
+ "version": "2.0.2"
+ },
+ "node_modules/npm/node_modules/tinyglobby": {
+ "dependencies": {
+ "fdir": "^6.5.0",
+ "picomatch": "^4.0.3"
+ },
+ "engines": {
+ "node": ">=12.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/SuperchupuDev"
+ },
+ "inBundle": true,
+ "license": "MIT",
+ "version": "0.2.15"
+ },
+ "node_modules/npm/node_modules/tinyglobby/node_modules/fdir": {
+ "engines": {
+ "node": ">=12.0.0"
+ },
+ "inBundle": true,
+ "license": "MIT",
+ "peerDependencies": {
+ "picomatch": "^3 || ^4"
+ },
+ "peerDependenciesMeta": {
+ "picomatch": {
+ "optional": true
+ }
+ },
+ "version": "6.5.0"
+ },
+ "node_modules/npm/node_modules/tinyglobby/node_modules/picomatch": {
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ },
+ "inBundle": true,
+ "license": "MIT",
+ "version": "4.0.3"
+ },
+ "node_modules/npm/node_modules/treeverse": {
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ },
+ "inBundle": true,
+ "license": "ISC",
+ "version": "3.0.0"
+ },
+ "node_modules/npm/node_modules/tuf-js": {
+ "dependencies": {
+ "@tufjs/models": "4.1.0",
+ "debug": "^4.4.3",
+ "make-fetch-happen": "^15.0.1"
+ },
+ "engines": {
+ "node": "^20.17.0 || >=22.9.0"
+ },
+ "inBundle": true,
+ "license": "MIT",
+ "version": "4.1.0"
+ },
+ "node_modules/npm/node_modules/unique-filename": {
+ "dependencies": {
+ "unique-slug": "^6.0.0"
+ },
+ "engines": {
+ "node": "^20.17.0 || >=22.9.0"
+ },
+ "inBundle": true,
+ "license": "ISC",
+ "version": "5.0.0"
+ },
+ "node_modules/npm/node_modules/unique-slug": {
+ "dependencies": {
+ "imurmurhash": "^0.1.4"
+ },
+ "engines": {
+ "node": "^20.17.0 || >=22.9.0"
+ },
+ "inBundle": true,
+ "license": "ISC",
+ "version": "6.0.0"
+ },
+ "node_modules/npm/node_modules/util-deprecate": {
+ "inBundle": true,
+ "license": "MIT",
+ "version": "1.0.2"
+ },
+ "node_modules/npm/node_modules/validate-npm-package-license": {
+ "dependencies": {
+ "spdx-correct": "^3.0.0",
+ "spdx-expression-parse": "^3.0.0"
+ },
+ "inBundle": true,
+ "license": "Apache-2.0",
+ "version": "3.0.4"
+ },
+ "node_modules/npm/node_modules/validate-npm-package-license/node_modules/spdx-expression-parse": {
+ "dependencies": {
+ "spdx-exceptions": "^2.1.0",
+ "spdx-license-ids": "^3.0.0"
+ },
+ "inBundle": true,
+ "license": "MIT",
+ "version": "3.0.1"
+ },
+ "node_modules/npm/node_modules/validate-npm-package-name": {
+ "engines": {
+ "node": "^20.17.0 || >=22.9.0"
+ },
+ "inBundle": true,
+ "license": "ISC",
+ "version": "7.0.2"
+ },
+ "node_modules/npm/node_modules/walk-up-path": {
+ "engines": {
+ "node": "20 || >=22"
+ },
+ "inBundle": true,
+ "license": "ISC",
+ "version": "4.0.0"
+ },
+ "node_modules/npm/node_modules/which": {
+ "bin": {
+ "node-which": "bin/which.js"
+ },
+ "dependencies": {
+ "isexe": "^3.1.1"
+ },
+ "engines": {
+ "node": "^20.17.0 || >=22.9.0"
+ },
+ "inBundle": true,
+ "license": "ISC",
+ "version": "6.0.0"
+ },
+ "node_modules/npm/node_modules/write-file-atomic": {
+ "dependencies": {
+ "imurmurhash": "^0.1.4",
+ "signal-exit": "^4.0.1"
+ },
+ "engines": {
+ "node": "^20.17.0 || >=22.9.0"
+ },
+ "inBundle": true,
+ "license": "ISC",
+ "version": "7.0.0"
+ },
+ "node_modules/npm/node_modules/yallist": {
+ "inBundle": true,
+ "license": "ISC",
+ "version": "4.0.0"
+ },
+ "node_modules/picomatch": {
+ "dev": true,
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ },
+ "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
+ "license": "MIT",
+ "optional": true,
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz",
+ "version": "4.0.3"
+ },
+ "node_modules/readdirp": {
+ "dev": true,
+ "engines": {
+ "node": ">= 14.18.0"
+ },
+ "funding": {
+ "type": "individual",
+ "url": "https://paulmillr.com/funding/"
+ },
+ "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==",
+ "license": "MIT",
+ "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz",
+ "version": "4.1.2"
+ },
+ "node_modules/sass": {
+ "bin": {
+ "sass": "sass.js"
+ },
+ "dependencies": {
+ "chokidar": "^4.0.0",
+ "immutable": "^5.0.2",
+ "source-map-js": ">=0.6.2 <2.0.0"
+ },
+ "dev": true,
+ "engines": {
+ "node": ">=14.0.0"
+ },
+ "integrity": "sha512-fDz1zJpd5GycprAbu4Q2PV/RprsRtKC/0z82z0JLgdytmcq0+ujJbJ/09bPGDxCLkKY3Np5cRAOcWiVkLXJURg==",
+ "license": "MIT",
+ "optionalDependencies": {
+ "@parcel/watcher": "^2.4.1"
+ },
+ "resolved": "https://registry.npmjs.org/sass/-/sass-1.97.3.tgz",
+ "version": "1.97.3"
+ },
+ "node_modules/source-map-js": {
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ },
+ "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
+ "license": "BSD-3-Clause",
+ "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
+ "version": "1.2.1"
+ }
+ },
+ "requires": true,
+ "version": "1.0.0"
+}
diff --git a/src/frontend/package.json b/src/frontend/package.json
new file mode 100644
index 0000000..6446fcf
--- /dev/null
+++ b/src/frontend/package.json
@@ -0,0 +1,23 @@
+{
+ "dependencies": {
+ "@creativebulma/bulma-collapsible": "^1.0.4",
+ "@vizuaalog/bulmajs": "^0.12.2",
+ "bulma": "^1.0.4",
+ "bulma-tagsinput": "^2.0.0",
+ "htmx.org": "^2.0.8",
+ "install": "^0.13.0",
+ "jquery": "^4.0.0",
+ "npm": "^11.8.0"
+ },
+ "description": "Pygentic AI Frontend - SWOT Analysis Interface",
+ "devDependencies": {
+ "sass": "^1.83.0"
+ },
+ "name": "pygentic-ai-frontend",
+ "scripts": {
+ "build:css": "sass scss/styles.scss static/css/pygentic_ai.css --style compressed",
+ "dev": "npm run watch:css",
+ "watch:css": "sass scss/styles.scss static/css/pygentic_ai.css --watch"
+ },
+ "version": "1.0.0"
+}
diff --git a/src/frontend/scss/_animations.scss b/src/frontend/scss/_animations.scss
new file mode 100644
index 0000000..1cd5adb
--- /dev/null
+++ b/src/frontend/scss/_animations.scss
@@ -0,0 +1,96 @@
+// ============================================
+// ANIMATIONS & KEYFRAMES
+// ============================================
+
+@keyframes spin {
+ from {
+ transform: rotate(0deg);
+ }
+ to {
+ transform: rotate(360deg);
+ }
+}
+
+@keyframes float {
+ 0%, 100% {
+ transform: translateY(0px);
+ }
+ 50% {
+ transform: translateY(-10px);
+ }
+}
+
+@keyframes pulse {
+ 0%, 100% {
+ box-shadow: 0 0 0 0 rgba($brand-primary, 0.7);
+ }
+ 50% {
+ box-shadow: 0 0 0 10px rgba($brand-primary, 0);
+ }
+}
+
+@keyframes slideUp {
+ from {
+ opacity: 0;
+ transform: translateY(20px);
+ }
+ to {
+ opacity: 1;
+ transform: translateY(0);
+ }
+}
+
+@keyframes fadeIn {
+ from {
+ opacity: 0;
+ }
+ to {
+ opacity: 1;
+ }
+}
+
+@keyframes shake {
+ 0%, 100% { transform: translateX(0); }
+ 25% { transform: translateX(-10px); }
+ 75% { transform: translateX(10px); }
+}
+
+@keyframes iconPulse {
+ 0%, 100% {
+ transform: scale(1);
+ }
+ 50% {
+ transform: scale(1.1);
+ }
+}
+
+@keyframes containerFadeIn {
+ from {
+ opacity: 0;
+ transform: translateY(30px);
+ }
+ to {
+ opacity: 1;
+ transform: translateY(0);
+ }
+}
+
+@keyframes statusFadeIn {
+ from {
+ opacity: 0;
+ transform: translateX(-10px);
+ }
+ to {
+ opacity: 1;
+ transform: translateX(0);
+ }
+}
+
+@keyframes statusPulse {
+ 0%, 100% {
+ box-shadow: $shadow-md;
+ }
+ 50% {
+ box-shadow: 0 4px 20px rgba($swot-weakness, 0.3);
+ }
+}
diff --git a/src/frontend/scss/_components.scss b/src/frontend/scss/_components.scss
new file mode 100644
index 0000000..b53044a
--- /dev/null
+++ b/src/frontend/scss/_components.scss
@@ -0,0 +1,176 @@
+// ============================================
+// COMPONENTS
+// Reusable UI components
+// ============================================
+
+// Loading Spinner
+// ===================================
+.spinner-wrapper {
+ position: fixed;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ background-color: rgba(255, 255, 255, 0.95);
+ backdrop-filter: blur(8px);
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ z-index: 9999;
+}
+
+.loading-content {
+ text-align: center;
+}
+
+.loader {
+ border: 4px solid rgba($brand-primary, 0.1);
+ border-top: 4px solid $brand-primary;
+ border-radius: 50%;
+ width: 60px;
+ height: 60px;
+ animation: spin 0.8s linear infinite;
+ margin: 0 auto;
+}
+
+.loading-text {
+ margin-top: 1.5rem;
+
+ h3 {
+ font-size: 1.25rem;
+ font-weight: 600;
+ color: $neutral-900;
+ margin-bottom: 0.5rem;
+ }
+
+ p {
+ font-size: 0.875rem;
+ color: $neutral-600;
+ }
+}
+
+// Search Form
+// ===================================
+.search-container {
+ max-width: 800px;
+ margin: 0 auto;
+ padding: 2rem 1rem;
+}
+
+.search-form {
+ width: 100%;
+}
+
+.search-input-group {
+ display: flex;
+ align-items: center;
+ background: white;
+ border-radius: $radius-full;
+ padding: 0.5rem;
+ box-shadow: $shadow-xl;
+ transition: all $transition-base;
+
+ &:focus-within {
+ box-shadow: 0 20px 40px rgba($brand-primary, 0.2);
+ transform: translateY(-2px);
+ }
+}
+
+.search-icon {
+ padding: 0 1rem;
+ color: $neutral-400;
+ font-size: 1.25rem;
+}
+
+.search-input {
+ flex: 1;
+ border: none;
+ outline: none;
+ padding: 0.875rem 1rem;
+ font-size: 1rem;
+ background: transparent;
+ color: $neutral-900;
+
+ &::placeholder {
+ color: $neutral-400;
+ }
+}
+
+.search-button {
+ background: $brand-primary;
+ color: white;
+ border: none;
+ border-radius: $radius-full;
+ padding: 0.875rem 2rem;
+ font-weight: 600;
+ font-size: 1rem;
+ cursor: pointer;
+ display: flex;
+ align-items: center;
+ gap: 0.5rem;
+ transition: all $transition-base;
+ white-space: nowrap;
+
+ &:hover {
+ background: $brand-primary-dark;
+ transform: translateX(2px);
+ box-shadow: $shadow-lg;
+ }
+
+ &:active {
+ transform: scale(0.95);
+ }
+
+ &:focus {
+ outline: 2px solid $brand-primary-light;
+ outline-offset: 2px;
+ }
+
+ &.is-loading {
+ position: relative;
+ color: transparent;
+ pointer-events: none;
+
+ &::after {
+ content: '';
+ position: absolute;
+ width: 16px;
+ height: 16px;
+ top: 50%;
+ left: 50%;
+ margin-left: -8px;
+ margin-top: -8px;
+ border: 2px solid transparent;
+ border-top-color: white;
+ border-radius: 50%;
+ animation: spin 0.6s linear infinite;
+ }
+ }
+}
+
+.search-help {
+ margin-top: 1rem;
+ text-align: center;
+ color: $neutral-600;
+ font-size: 0.875rem;
+
+ i {
+ margin-right: 0.25rem;
+ color: $brand-primary;
+ }
+}
+
+// Smooth transitions for all interactive elements
+button,
+a,
+input,
+.swot-card,
+.swot-card__icon {
+ transition: all $transition-base;
+}
+
+// Focus visible styles for accessibility
+:focus-visible {
+ outline: 2px solid $brand-primary;
+ outline-offset: 2px;
+}
diff --git a/src/frontend/scss/_layout.scss b/src/frontend/scss/_layout.scss
new file mode 100644
index 0000000..2361bc2
--- /dev/null
+++ b/src/frontend/scss/_layout.scss
@@ -0,0 +1,269 @@
+// ============================================
+// LAYOUT
+// Page structure and major sections
+// ============================================
+
+// Hero Section
+// ===================================
+.gradient-hero {
+ background: $gradient-hero !important;
+ position: relative;
+ overflow: hidden;
+}
+
+.hero-icon {
+ img {
+ filter: brightness(0) invert(1);
+ animation: float 3s ease-in-out infinite;
+
+ &:hover {
+ animation: float 1s ease-in-out infinite;
+ filter: brightness(0) invert(1) drop-shadow(0 0 20px rgba(255, 255, 255, 0.5));
+ }
+ }
+}
+
+.hero-cta .button {
+ animation: pulse 2s infinite;
+}
+
+// SWOT Cards
+// ===================================
+.swot-grid {
+ display: grid;
+ grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
+ gap: $spacing-lg;
+ margin-top: $spacing-xl;
+}
+
+.swot-card {
+ background: white;
+ border-radius: $radius-lg;
+ padding: $spacing-lg;
+ box-shadow: $shadow-lg;
+ transition: all $transition-base;
+ border-top: 4px solid var(--card-color);
+ animation: slideUp 0.5s ease-out backwards;
+
+ &:hover {
+ transform: translateY(-4px);
+ box-shadow: $shadow-2xl;
+
+ .swot-card__icon {
+ animation: iconPulse 0.5s ease-out;
+ }
+ }
+
+ // Card variants
+ &--strength {
+ --card-color: #{$swot-strength};
+ }
+
+ &--weakness {
+ --card-color: #{$swot-weakness};
+ }
+
+ &--opportunity {
+ --card-color: #{$swot-opportunity};
+ }
+
+ &--threat {
+ --card-color: #{$swot-threat};
+ }
+}
+
+.swot-card__header {
+ display: flex;
+ align-items: center;
+ gap: 0.75rem;
+ margin-bottom: 1rem;
+ padding-bottom: 1rem;
+ border-bottom: 1px solid $neutral-200;
+}
+
+.swot-card__icon {
+ width: 48px;
+ height: 48px;
+ border-radius: $radius-md;
+ background: var(--card-color);
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ color: white;
+ font-size: 1.5rem;
+ flex-shrink: 0;
+}
+
+.swot-card__title {
+ font-weight: 600;
+ font-size: 1.375rem;
+ color: $neutral-900;
+ flex-grow: 1;
+ margin: 0;
+}
+
+.swot-card__count {
+ background: $neutral-100;
+ padding: 0.25rem 0.75rem;
+ border-radius: $radius-xl;
+ font-size: 0.875rem;
+ font-weight: 600;
+ color: $neutral-700;
+ flex-shrink: 0;
+}
+
+.swot-card__body {
+ overflow: hidden;
+}
+
+.swot-list {
+ list-style: none;
+ padding: 0;
+ margin: 0;
+}
+
+.swot-list__item {
+ display: flex;
+ align-items: flex-start;
+ gap: 0.75rem;
+ padding: 0.75rem 0;
+ border-bottom: 1px solid $neutral-100;
+ animation: fadeIn 0.3s ease-out backwards;
+
+ &:last-child {
+ border-bottom: none;
+ }
+
+ // Stagger animation for list items
+ @for $i from 1 through 10 {
+ &:nth-child(#{$i}) {
+ animation-delay: #{$i * 0.1}s;
+ }
+ }
+}
+
+.swot-list__bullet {
+ width: 6px;
+ height: 6px;
+ border-radius: 50%;
+ background: var(--card-color);
+ margin-top: 0.5rem;
+ flex-shrink: 0;
+}
+
+.swot-list__text {
+ flex: 1;
+ color: $neutral-700;
+ line-height: 1.6;
+}
+
+// Stagger card animations
+@for $i from 1 through 4 {
+ .swot-card:nth-child(#{$i}) {
+ animation-delay: #{$i * 0.1}s;
+ }
+}
+
+// Result container entrance
+#result-container.animate-in {
+ animation: containerFadeIn 0.6s ease-out;
+}
+
+// Status Timeline
+// ===================================
+.status-timeline {
+ position: relative;
+ padding-left: 2rem;
+
+ &::before {
+ content: '';
+ position: absolute;
+ left: 14px;
+ top: 24px;
+ bottom: 24px;
+ width: 2px;
+ background: $neutral-200;
+ }
+}
+
+.status-item {
+ position: relative;
+ padding: 1rem 0 1rem 2rem;
+ animation: statusFadeIn 0.3s ease-out;
+
+ // Status variants
+ &--info {
+ .status-item__indicator,
+ .status-item__header {
+ color: $swot-opportunity;
+ }
+ }
+
+ &--loading {
+ .status-item__indicator,
+ .status-item__header {
+ color: $swot-weakness;
+ }
+
+ .status-item__content {
+ animation: statusPulse 2s ease-in-out infinite;
+ }
+ }
+
+ &--success {
+ .status-item__indicator,
+ .status-item__header {
+ color: $swot-strength;
+ }
+ }
+
+ &--error {
+ .status-item__indicator,
+ .status-item__header {
+ color: $swot-threat;
+ }
+ }
+}
+
+.status-item__indicator {
+ position: absolute;
+ left: 0;
+ top: 1.25rem;
+ width: 30px;
+ height: 30px;
+ border-radius: 50%;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ font-size: 1rem;
+ background: white;
+ box-shadow: 0 0 0 4px white;
+ z-index: 1;
+}
+
+.status-item__content {
+ background: white;
+ border-radius: $radius-md;
+ padding: 1rem 1.25rem;
+ box-shadow: $shadow-md;
+ transition: all $transition-base;
+}
+
+.status-item:hover .status-item__content {
+ box-shadow: $shadow-lg;
+ transform: translateX(4px);
+}
+
+.status-item__header {
+ font-weight: 600;
+ font-size: 0.875rem;
+ text-transform: uppercase;
+ letter-spacing: 0.05em;
+ margin-bottom: 0.5rem;
+}
+
+.status-item__message {
+ color: $neutral-700;
+ line-height: 1.6;
+ font-size: 0.9375rem;
+}
diff --git a/src/frontend/scss/_responsive.scss b/src/frontend/scss/_responsive.scss
new file mode 100644
index 0000000..fdefeaf
--- /dev/null
+++ b/src/frontend/scss/_responsive.scss
@@ -0,0 +1,74 @@
+// ============================================
+// RESPONSIVE DESIGN
+// Mobile-first breakpoints
+// ============================================
+
+// Tablet and below (768px)
+@media (max-width: $breakpoint-tablet) {
+ .cell.is-col-span-2 {
+ grid-column: span 1;
+ }
+
+ .swot-grid {
+ grid-template-columns: 1fr;
+ }
+
+ .hero-title {
+ font-size: 2rem;
+ }
+
+ .search-input-group {
+ flex-direction: column;
+ gap: 0.5rem;
+ border-radius: $radius-xl;
+ padding: 1rem;
+ }
+
+ .search-input {
+ width: 100%;
+ text-align: center;
+ }
+
+ .search-button {
+ width: 100%;
+ justify-content: center;
+ }
+
+ .swot-card__header {
+ flex-wrap: wrap;
+ }
+
+ .swot-card__count {
+ order: -1;
+ margin-left: auto;
+ }
+}
+
+// Mobile (480px)
+@media (max-width: $breakpoint-mobile) {
+ .swot-card {
+ padding: 1rem;
+ }
+
+ .swot-card__icon {
+ width: 40px;
+ height: 40px;
+ font-size: 1.25rem;
+ }
+
+ .swot-card__title {
+ font-size: 1.125rem;
+ }
+
+ .hero-title {
+ font-size: 1.75rem;
+ }
+
+ .status-timeline {
+ padding-left: 1.5rem;
+ }
+
+ .status-item {
+ padding-left: 1.5rem;
+ }
+}
diff --git a/src/frontend/scss/_states.scss b/src/frontend/scss/_states.scss
new file mode 100644
index 0000000..effb4cf
--- /dev/null
+++ b/src/frontend/scss/_states.scss
@@ -0,0 +1,169 @@
+// ============================================
+// STATES
+// Empty and error states
+// ============================================
+
+// Empty State
+// ===================================
+.empty-state {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ min-height: 400px;
+ padding: 3rem 1.5rem;
+}
+
+.empty-state__content {
+ text-align: center;
+ max-width: 500px;
+}
+
+.empty-state__icon {
+ width: 120px;
+ height: 120px;
+ margin: 0 auto 2rem;
+ border-radius: 50%;
+ background: linear-gradient(135deg, $neutral-100 0%, $neutral-200 100%);
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ font-size: 3rem;
+ color: $neutral-400;
+ animation: float 3s ease-in-out infinite;
+}
+
+.empty-state__title {
+ font-size: 1.75rem;
+ font-weight: 600;
+ color: $neutral-800;
+ margin-bottom: 0.75rem;
+}
+
+.empty-state__description {
+ font-size: 1.125rem;
+ color: $neutral-600;
+ line-height: 1.6;
+ margin-bottom: 1.5rem;
+}
+
+.empty-state__cta {
+ display: inline-flex;
+ align-items: center;
+ gap: 0.5rem;
+ padding: 0.875rem 2rem;
+ background: $brand-primary;
+ color: white;
+ border-radius: $radius-full;
+ text-decoration: none;
+ font-weight: 600;
+ transition: all $transition-base;
+ box-shadow: $shadow-md;
+
+ &:hover {
+ background: $brand-primary-dark;
+ transform: translateY(-2px);
+ box-shadow: $shadow-lg;
+ color: white;
+ }
+}
+
+// Error State
+// ===================================
+.error-state {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ min-height: 400px;
+ padding: 3rem 1.5rem;
+}
+
+.error-state__content {
+ text-align: center;
+ max-width: 500px;
+}
+
+.error-state__icon {
+ width: 120px;
+ height: 120px;
+ margin: 0 auto 2rem;
+ border-radius: 50%;
+ background: linear-gradient(135deg, #FEE2E2 0%, #FEF2F2 100%);
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ font-size: 3rem;
+ color: $swot-threat;
+ animation: shake 0.5s ease-in-out;
+}
+
+.error-state__title {
+ font-size: 1.75rem;
+ font-weight: 600;
+ color: $neutral-800;
+ margin-bottom: 0.75rem;
+}
+
+.error-state__description {
+ font-size: 1.125rem;
+ color: $neutral-600;
+ line-height: 1.6;
+ margin-bottom: 1.5rem;
+}
+
+.error-state__details {
+ background: $neutral-100;
+ border-radius: $radius-md;
+ padding: 1rem;
+ margin: 1.5rem 0;
+ font-family: 'Courier New', monospace;
+ font-size: 0.875rem;
+ color: $neutral-700;
+ text-align: left;
+ overflow-x: auto;
+}
+
+.error-state__actions {
+ display: flex;
+ gap: 1rem;
+ justify-content: center;
+ flex-wrap: wrap;
+}
+
+.error-state__button {
+ display: inline-flex;
+ align-items: center;
+ gap: 0.5rem;
+ padding: 0.875rem 2rem;
+ border-radius: $radius-full;
+ font-weight: 600;
+ transition: all $transition-base;
+ box-shadow: $shadow-md;
+ cursor: pointer;
+ border: none;
+ text-decoration: none;
+
+ &--primary {
+ background: $brand-primary;
+ color: white;
+
+ &:hover {
+ background: $brand-primary-dark;
+ transform: translateY(-2px);
+ box-shadow: $shadow-lg;
+ color: white;
+ }
+ }
+
+ &--secondary {
+ background: white;
+ color: $neutral-700;
+ border: 2px solid $neutral-300;
+
+ &:hover {
+ background: $neutral-100;
+ border-color: $neutral-400;
+ transform: translateY(-2px);
+ color: $neutral-800;
+ }
+ }
+}
diff --git a/src/frontend/scss/_typography.scss b/src/frontend/scss/_typography.scss
new file mode 100644
index 0000000..4e1f671
--- /dev/null
+++ b/src/frontend/scss/_typography.scss
@@ -0,0 +1,30 @@
+// ============================================
+// TYPOGRAPHY
+// ============================================
+
+body {
+ font-family: $font-body;
+ font-feature-settings: 'cv02', 'cv03', 'cv04', 'cv11';
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
+
+.title,
+.subtitle,
+h1, h2, h3, h4, h5, h6 {
+ font-family: $font-heading;
+ letter-spacing: -0.02em;
+ font-weight: 600;
+}
+
+// Hero Title with Gradient
+.hero-title {
+ font-size: clamp(2.5rem, 5vw, 4rem);
+ font-weight: 700;
+ background: $gradient-hero-alt;
+ -webkit-background-clip: text;
+ -webkit-text-fill-color: transparent;
+ background-clip: text;
+ margin-bottom: 1rem;
+ line-height: 1.1;
+}
diff --git a/src/frontend/scss/_variables.scss b/src/frontend/scss/_variables.scss
new file mode 100644
index 0000000..2c61f67
--- /dev/null
+++ b/src/frontend/scss/_variables.scss
@@ -0,0 +1,77 @@
+// ============================================
+// PYGENTIC AI - SCSS VARIABLES
+// Design tokens and configuration
+// ============================================
+
+// Font Imports
+@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=Space+Grotesk:wght@500;600;700&display=swap');
+
+// Font Families
+$font-body: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
+$font-heading: 'Space Grotesk', 'Inter', sans-serif;
+
+// Brand Colors (from purple.svg logo)
+$brand-primary: #8B5CF6;
+$brand-primary-light: #A78BFA;
+$brand-primary-dark: #7C3AED;
+$brand-primary-darker: #6D28D9;
+
+// Semantic SWOT Colors
+$swot-strength: #10B981;
+$swot-strength-light: #34D399;
+$swot-weakness: #F59E0B;
+$swot-weakness-light: #FBBF24;
+$swot-opportunity: #3B82F6;
+$swot-opportunity-light: #60A5FA;
+$swot-threat: #EF4444;
+$swot-threat-light: #F87171;
+
+// Neutral Palette
+$neutral-50: #F9FAFB;
+$neutral-100: #F3F4F6;
+$neutral-200: #E5E7EB;
+$neutral-300: #D1D5DB;
+$neutral-400: #9CA3AF;
+$neutral-500: #6B7280;
+$neutral-600: #4B5563;
+$neutral-700: #374151;
+$neutral-800: #1F2937;
+$neutral-900: #111827;
+
+// Gradients
+$gradient-hero: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
+$gradient-hero-alt: linear-gradient(135deg, $brand-primary 0%, $brand-primary-darker 100%);
+$gradient-card: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
+
+// Shadows
+$shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
+$shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
+$shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
+$shadow-xl: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04);
+$shadow-2xl: 0 25px 50px -12px rgba(0, 0, 0, 0.25);
+
+// Transitions
+$transition-fast: 150ms cubic-bezier(0.4, 0, 0.2, 1);
+$transition-base: 300ms cubic-bezier(0.4, 0, 0.2, 1);
+$transition-slow: 500ms cubic-bezier(0.4, 0, 0.2, 1);
+
+// Breakpoints
+$breakpoint-mobile: 480px;
+$breakpoint-tablet: 768px;
+$breakpoint-desktop: 1024px;
+$breakpoint-widescreen: 1216px;
+
+// Spacing
+$spacing-xs: 0.25rem;
+$spacing-sm: 0.5rem;
+$spacing-md: 1rem;
+$spacing-lg: 1.5rem;
+$spacing-xl: 2rem;
+$spacing-2xl: 3rem;
+
+// Border Radius
+$radius-sm: 8px;
+$radius-md: 12px;
+$radius-lg: 16px;
+$radius-xl: 20px;
+$radius-full: 9999px;
diff --git a/src/frontend/scss/styles.scss b/src/frontend/scss/styles.scss
new file mode 100644
index 0000000..c8dfb2f
--- /dev/null
+++ b/src/frontend/scss/styles.scss
@@ -0,0 +1,64 @@
+/*!
+ * Pygentic AI - Main Stylesheet
+ * Compiled from SCSS partials
+ * Version: 1.0.0
+ */
+
+// Import order matters!
+// 1. Variables first (used by all other partials)
+// 2. Typography (base styles)
+// 3. Animations (keyframes)
+// 4. Components (reusable UI elements)
+// 5. Layout (page structure)
+// 6. States (empty/error states)
+// 7. Responsive (media queries last)
+
+@import 'variables';
+@import 'typography';
+@import 'animations';
+@import 'components';
+@import 'layout';
+@import 'states';
+@import 'responsive';
+
+// ============================================
+// CSS CUSTOM PROPERTIES
+// For runtime theming support
+// ============================================
+
+:root {
+ // Brand Colors
+ --brand-primary: #{$brand-primary};
+ --brand-primary-light: #{$brand-primary-light};
+ --brand-primary-dark: #{$brand-primary-dark};
+
+ // SWOT Colors
+ --swot-strength: #{$swot-strength};
+ --swot-weakness: #{$swot-weakness};
+ --swot-opportunity: #{$swot-opportunity};
+ --swot-threat: #{$swot-threat};
+
+ // Neutrals
+ --neutral-50: #{$neutral-50};
+ --neutral-100: #{$neutral-100};
+ --neutral-200: #{$neutral-200};
+ --neutral-300: #{$neutral-300};
+ --neutral-400: #{$neutral-400};
+ --neutral-500: #{$neutral-500};
+ --neutral-600: #{$neutral-600};
+ --neutral-700: #{$neutral-700};
+ --neutral-800: #{$neutral-800};
+ --neutral-900: #{$neutral-900};
+
+ // Shadows
+ --shadow-sm: #{$shadow-sm};
+ --shadow-md: #{$shadow-md};
+ --shadow-lg: #{$shadow-lg};
+ --shadow-xl: #{$shadow-xl};
+ --shadow-2xl: #{$shadow-2xl};
+
+ // Transitions
+ --transition-fast: #{$transition-fast};
+ --transition-base: #{$transition-base};
+ --transition-slow: #{$transition-slow};
+}
diff --git a/src/frontend/static/css/pygentic_ai.css b/src/frontend/static/css/pygentic_ai.css
index 8e70c5e..1998969 100644
--- a/src/frontend/static/css/pygentic_ai.css
+++ b/src/frontend/static/css/pygentic_ai.css
@@ -1,471 +1,5 @@
-/* ============================================
- PYGENTIC AI CUSTOM STYLES
- Brand Colors & Typography System
- ============================================ */
-
-/* Import Modern Font Stack */
-@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=Space+Grotesk:wght@500;600;700&display=swap');
-
-/* ============================================
- CSS CUSTOM PROPERTIES (CSS Variables)
- ============================================ */
-
-:root {
- /* Primary Brand Colors (from purple.svg logo) */
- --brand-primary: #8B5CF6;
- --brand-primary-light: #A78BFA;
- --brand-primary-dark: #7C3AED;
- --brand-primary-darker: #6D28D9;
-
- /* Semantic SWOT Colors */
- --swot-strength: #10B981;
- --swot-strength-light: #34D399;
- --swot-weakness: #F59E0B;
- --swot-weakness-light: #FBBF24;
- --swot-opportunity: #3B82F6;
- --swot-opportunity-light: #60A5FA;
- --swot-threat: #EF4444;
- --swot-threat-light: #F87171;
-
- /* Neutral Palette */
- --neutral-50: #F9FAFB;
- --neutral-100: #F3F4F6;
- --neutral-200: #E5E7EB;
- --neutral-300: #D1D5DB;
- --neutral-400: #9CA3AF;
- --neutral-500: #6B7280;
- --neutral-600: #4B5563;
- --neutral-700: #374151;
- --neutral-800: #1F2937;
- --neutral-900: #111827;
-
- /* Gradients */
- --gradient-hero: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
- --gradient-hero-alt: linear-gradient(135deg, #8B5CF6 0%, #6D28D9 100%);
- --gradient-card: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
-
- /* Shadows */
- --shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
- --shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
- --shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
- --shadow-xl: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04);
- --shadow-2xl: 0 25px 50px -12px rgba(0, 0, 0, 0.25);
-
- /* Transitions */
- --transition-fast: 150ms cubic-bezier(0.4, 0, 0.2, 1);
- --transition-base: 300ms cubic-bezier(0.4, 0, 0.2, 1);
- --transition-slow: 500ms cubic-bezier(0.4, 0, 0.2, 1);
-}
-
-/* ============================================
- TYPOGRAPHY
- ============================================ */
-
-body {
- font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
- font-feature-settings: 'cv02', 'cv03', 'cv04', 'cv11';
- -webkit-font-smoothing: antialiased;
- -moz-osx-font-smoothing: grayscale;
-}
-
-.title,
-.subtitle,
-h1, h2, h3, h4, h5, h6 {
- font-family: 'Space Grotesk', 'Inter', sans-serif;
- letter-spacing: -0.02em;
- font-weight: 600;
-}
-
-/* Hero Title with Gradient */
-.hero-title {
- font-size: clamp(2.5rem, 5vw, 4rem);
- font-weight: 700;
- background: var(--gradient-hero-alt);
- -webkit-background-clip: text;
- -webkit-text-fill-color: transparent;
- background-clip: text;
- margin-bottom: 1rem;
- line-height: 1.1;
-}
-
-/* ============================================
- SPINNER / LOADING STATES
- ============================================ */
-
-/* Spinner Wrapper with Overlay Effect */
-.spinner-wrapper {
- position: fixed;
- top: 0;
- left: 0;
- width: 100%;
- height: 100%;
- background-color: rgba(255, 255, 255, 0.95);
- backdrop-filter: blur(8px);
- display: flex;
- justify-content: center;
- align-items: center;
- z-index: 9999;
-}
-
-.loading-content {
- text-align: center;
-}
-
-.loader {
- border: 4px solid rgba(139, 92, 246, 0.1);
- border-top: 4px solid var(--brand-primary);
- border-radius: 50%;
- width: 60px;
- height: 60px;
- animation: spin 0.8s linear infinite;
- margin: 0 auto;
-}
-
-@keyframes spin {
- from {
- transform: rotate(0deg);
- }
- to {
- transform: rotate(360deg);
- }
-}
-
-.loading-text {
- margin-top: 1.5rem;
-}
-
-.loading-text h3 {
- font-size: 1.25rem;
- font-weight: 600;
- color: var(--neutral-900);
- margin-bottom: 0.5rem;
-}
-
-.loading-text p {
- font-size: 0.875rem;
- color: var(--neutral-600);
-}
-
-/* ============================================
- HERO SECTION ENHANCEMENTS
- ============================================ */
-
-.gradient-hero {
- background: var(--gradient-hero) !important;
- position: relative;
- overflow: hidden;
-}
-
-.hero-icon img {
- filter: brightness(0) invert(1);
- animation: float 3s ease-in-out infinite;
-}
-
-@keyframes float {
- 0%, 100% {
- transform: translateY(0px);
- }
- 50% {
- transform: translateY(-10px);
- }
-}
-
-/* ============================================
- SWOT RESULT CARDS
- ============================================ */
-
-.swot-grid {
- display: grid;
- grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
- gap: 1.5rem;
- margin-top: 2rem;
-}
-
-.swot-card {
- background: white;
- border-radius: 16px;
- padding: 1.5rem;
- box-shadow: var(--shadow-lg);
- transition: all var(--transition-base);
- border-top: 4px solid var(--card-color);
- animation: slideUp 0.5s ease-out backwards;
-}
-
-.swot-card:hover {
- transform: translateY(-4px);
- box-shadow: var(--shadow-2xl);
-}
-
-.swot-card--strength {
- --card-color: var(--swot-strength);
-}
-
-.swot-card--weakness {
- --card-color: var(--swot-weakness);
-}
-
-.swot-card--opportunity {
- --card-color: var(--swot-opportunity);
-}
-
-.swot-card--threat {
- --card-color: var(--swot-threat);
-}
-
-.swot-card__header {
- display: flex;
- align-items: center;
- gap: 0.75rem;
- margin-bottom: 1rem;
- padding-bottom: 1rem;
- border-bottom: 1px solid var(--neutral-200);
-}
-
-.swot-card__icon {
- width: 48px;
- height: 48px;
- border-radius: 12px;
- background: var(--card-color);
- display: flex;
- align-items: center;
- justify-content: center;
- color: white;
- font-size: 1.5rem;
- flex-shrink: 0;
-}
-
-.swot-card__title {
- font-weight: 600;
- font-size: 1.375rem;
- color: var(--neutral-900);
- flex-grow: 1;
- margin: 0;
-}
-
-.swot-card__count {
- background: var(--neutral-100);
- padding: 0.25rem 0.75rem;
- border-radius: 20px;
- font-size: 0.875rem;
- font-weight: 600;
- color: var(--neutral-700);
- flex-shrink: 0;
-}
-
-.swot-card__body {
- overflow: hidden;
-}
-
-.swot-list {
- list-style: none;
- padding: 0;
- margin: 0;
-}
-
-.swot-list__item {
- display: flex;
- align-items: flex-start;
- gap: 0.75rem;
- padding: 0.75rem 0;
- border-bottom: 1px solid var(--neutral-100);
- animation: fadeIn 0.3s ease-out backwards;
-}
-
-.swot-list__item:last-child {
- border-bottom: none;
-}
-
-.swot-list__bullet {
- width: 6px;
- height: 6px;
- border-radius: 50%;
- background: var(--card-color);
- margin-top: 0.5rem;
- flex-shrink: 0;
-}
-
-.swot-list__text {
- flex: 1;
- color: var(--neutral-700);
- line-height: 1.6;
-}
-
-/* Stagger animation for list items */
-.swot-list__item:nth-child(1) { animation-delay: 0.1s; }
-.swot-list__item:nth-child(2) { animation-delay: 0.2s; }
-.swot-list__item:nth-child(3) { animation-delay: 0.3s; }
-.swot-list__item:nth-child(4) { animation-delay: 0.4s; }
-.swot-list__item:nth-child(5) { animation-delay: 0.5s; }
-
-@keyframes slideUp {
- from {
- opacity: 0;
- transform: translateY(20px);
- }
- to {
- opacity: 1;
- transform: translateY(0);
- }
-}
-
-@keyframes fadeIn {
- from {
- opacity: 0;
- }
- to {
- opacity: 1;
- }
-}
-
-/* Stagger card animations */
-.swot-card:nth-child(1) { animation-delay: 0.1s; }
-.swot-card:nth-child(2) { animation-delay: 0.2s; }
-.swot-card:nth-child(3) { animation-delay: 0.3s; }
-.swot-card:nth-child(4) { animation-delay: 0.4s; }
-
-/* ============================================
- SEARCH FORM ENHANCEMENTS
- ============================================ */
-
-.search-container {
- max-width: 800px;
- margin: 0 auto;
- padding: 2rem 1rem;
-}
-
-.search-form {
- width: 100%;
-}
-
-.search-input-group {
- display: flex;
- align-items: center;
- background: white;
- border-radius: 50px;
- padding: 0.5rem;
- box-shadow: var(--shadow-xl);
- transition: all var(--transition-base);
-}
-
-.search-input-group:focus-within {
- box-shadow: 0 20px 40px rgba(139, 92, 246, 0.2);
- transform: translateY(-2px);
-}
-
-.search-icon {
- padding: 0 1rem;
- color: var(--neutral-400);
- font-size: 1.25rem;
-}
-
-.search-input {
- flex: 1;
- border: none;
- outline: none;
- padding: 0.875rem 1rem;
- font-size: 1rem;
- background: transparent;
- color: var(--neutral-900);
-}
-
-.search-input::placeholder {
- color: var(--neutral-400);
-}
-
-.search-button {
- background: var(--brand-primary);
- color: white;
- border: none;
- border-radius: 40px;
- padding: 0.875rem 2rem;
- font-weight: 600;
- font-size: 1rem;
- cursor: pointer;
- display: flex;
- align-items: center;
- gap: 0.5rem;
- transition: all var(--transition-base);
- white-space: nowrap;
-}
-
-.search-button:hover {
- background: var(--brand-primary-dark);
- transform: translateX(2px);
- box-shadow: var(--shadow-lg);
-}
-
-.search-button:active {
- transform: scale(0.98);
-}
-
-.search-help {
- margin-top: 1rem;
- text-align: center;
- color: var(--neutral-600);
- font-size: 0.875rem;
-}
-
-.search-help i {
- margin-right: 0.25rem;
- color: var(--brand-primary);
-}
-
-/* ============================================
- RESPONSIVE DESIGN
- ============================================ */
-
-@media (max-width: 768px) {
- .cell.is-col-span-2 {
- grid-column: span 1;
- }
-
- .swot-grid {
- grid-template-columns: 1fr;
- }
-
- .hero-title {
- font-size: 2rem;
- }
-
- .search-input-group {
- flex-direction: column;
- gap: 0.5rem;
- border-radius: 20px;
- padding: 1rem;
- }
-
- .search-input {
- width: 100%;
- text-align: center;
- }
-
- .search-button {
- width: 100%;
- justify-content: center;
- }
-
- .swot-card__header {
- flex-wrap: wrap;
- }
-
- .swot-card__count {
- order: -1;
- margin-left: auto;
- }
-}
-
-@media (max-width: 480px) {
- .swot-card {
- padding: 1rem;
- }
-
- .swot-card__icon {
- width: 40px;
- height: 40px;
- font-size: 1.25rem;
- }
-
- .swot-card__title {
- font-size: 1.125rem;
- }
-}
+/*!
+ * Pygentic AI - Main Stylesheet
+ * Compiled from SCSS partials
+ * Version: 1.0.0
+ */@import"https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=Space+Grotesk:wght@500;600;700&display=swap";body{font-family:"Inter",-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen,Ubuntu,Cantarell,sans-serif;font-feature-settings:"cv02","cv03","cv04","cv11";-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.title,.subtitle,h1,h2,h3,h4,h5,h6{font-family:"Space Grotesk","Inter",sans-serif;letter-spacing:-0.02em;font-weight:600}.hero-title{font-size:clamp(2.5rem,5vw,4rem);font-weight:700;background:linear-gradient(135deg, #8B5CF6 0%, #6D28D9 100%);-webkit-background-clip:text;-webkit-text-fill-color:rgba(0,0,0,0);background-clip:text;margin-bottom:1rem;line-height:1.1}@keyframes spin{from{transform:rotate(0deg)}to{transform:rotate(360deg)}}@keyframes float{0%,100%{transform:translateY(0px)}50%{transform:translateY(-10px)}}@keyframes pulse{0%,100%{box-shadow:0 0 0 0 rgba(139,92,246,.7)}50%{box-shadow:0 0 0 10px rgba(139,92,246,0)}}@keyframes slideUp{from{opacity:0;transform:translateY(20px)}to{opacity:1;transform:translateY(0)}}@keyframes fadeIn{from{opacity:0}to{opacity:1}}@keyframes shake{0%,100%{transform:translateX(0)}25%{transform:translateX(-10px)}75%{transform:translateX(10px)}}@keyframes iconPulse{0%,100%{transform:scale(1)}50%{transform:scale(1.1)}}@keyframes containerFadeIn{from{opacity:0;transform:translateY(30px)}to{opacity:1;transform:translateY(0)}}@keyframes statusFadeIn{from{opacity:0;transform:translateX(-10px)}to{opacity:1;transform:translateX(0)}}@keyframes statusPulse{0%,100%{box-shadow:0 4px 6px -1px rgba(0,0,0,.1),0 2px 4px -1px rgba(0,0,0,.06)}50%{box-shadow:0 4px 20px rgba(245,158,11,.3)}}.spinner-wrapper{position:fixed;top:0;left:0;width:100%;height:100%;background-color:hsla(0,0%,100%,.95);backdrop-filter:blur(8px);display:flex;justify-content:center;align-items:center;z-index:9999}.loading-content{text-align:center}.loader{border:4px solid rgba(139,92,246,.1);border-top:4px solid #8b5cf6;border-radius:50%;width:60px;height:60px;animation:spin .8s linear infinite;margin:0 auto}.loading-text{margin-top:1.5rem}.loading-text h3{font-size:1.25rem;font-weight:600;color:#111827;margin-bottom:.5rem}.loading-text p{font-size:.875rem;color:#4b5563}.search-container{max-width:800px;margin:0 auto;padding:2rem 1rem}.search-form{width:100%}.search-input-group{display:flex;align-items:center;background:#fff;border-radius:9999px;padding:.5rem;box-shadow:0 20px 25px -5px rgba(0,0,0,.1),0 10px 10px -5px rgba(0,0,0,.04);transition:all 300ms cubic-bezier(0.4, 0, 0.2, 1)}.search-input-group:focus-within{box-shadow:0 20px 40px rgba(139,92,246,.2);transform:translateY(-2px)}.search-icon{padding:0 1rem;color:#9ca3af;font-size:1.25rem}.search-input{flex:1;border:none;outline:none;padding:.875rem 1rem;font-size:1rem;background:rgba(0,0,0,0);color:#111827}.search-input::placeholder{color:#9ca3af}.search-button{background:#8b5cf6;color:#fff;border:none;border-radius:9999px;padding:.875rem 2rem;font-weight:600;font-size:1rem;cursor:pointer;display:flex;align-items:center;gap:.5rem;transition:all 300ms cubic-bezier(0.4, 0, 0.2, 1);white-space:nowrap}.search-button:hover{background:#7c3aed;transform:translateX(2px);box-shadow:0 10px 15px -3px rgba(0,0,0,.1),0 4px 6px -2px rgba(0,0,0,.05)}.search-button:active{transform:scale(0.95)}.search-button:focus{outline:2px solid #a78bfa;outline-offset:2px}.search-button.is-loading{position:relative;color:rgba(0,0,0,0);pointer-events:none}.search-button.is-loading::after{content:"";position:absolute;width:16px;height:16px;top:50%;left:50%;margin-left:-8px;margin-top:-8px;border:2px solid rgba(0,0,0,0);border-top-color:#fff;border-radius:50%;animation:spin .6s linear infinite}.search-help{margin-top:1rem;text-align:center;color:#4b5563;font-size:.875rem}.search-help i{margin-right:.25rem;color:#8b5cf6}button,a,input,.swot-card,.swot-card__icon{transition:all 300ms cubic-bezier(0.4, 0, 0.2, 1)}:focus-visible{outline:2px solid #8b5cf6;outline-offset:2px}.gradient-hero{background:linear-gradient(135deg, #667eea 0%, #764ba2 100%) !important;position:relative;overflow:hidden}.hero-icon img{filter:brightness(0) invert(1);animation:float 3s ease-in-out infinite}.hero-icon img:hover{animation:float 1s ease-in-out infinite;filter:brightness(0) invert(1) drop-shadow(0 0 20px rgba(255, 255, 255, 0.5))}.hero-cta .button{animation:pulse 2s infinite}.swot-grid{display:grid;grid-template-columns:repeat(auto-fit, minmax(300px, 1fr));gap:1.5rem;margin-top:2rem}.swot-card{background:#fff;border-radius:16px;padding:1.5rem;box-shadow:0 10px 15px -3px rgba(0,0,0,.1),0 4px 6px -2px rgba(0,0,0,.05);transition:all 300ms cubic-bezier(0.4, 0, 0.2, 1);border-top:4px solid var(--card-color);animation:slideUp .5s ease-out backwards}.swot-card:hover{transform:translateY(-4px);box-shadow:0 25px 50px -12px rgba(0,0,0,.25)}.swot-card:hover .swot-card__icon{animation:iconPulse .5s ease-out}.swot-card--strength{--card-color: #10B981}.swot-card--weakness{--card-color: #F59E0B}.swot-card--opportunity{--card-color: #3B82F6}.swot-card--threat{--card-color: #EF4444}.swot-card__header{display:flex;align-items:center;gap:.75rem;margin-bottom:1rem;padding-bottom:1rem;border-bottom:1px solid #e5e7eb}.swot-card__icon{width:48px;height:48px;border-radius:12px;background:var(--card-color);display:flex;align-items:center;justify-content:center;color:#fff;font-size:1.5rem;flex-shrink:0}.swot-card__title{font-weight:600;font-size:1.375rem;color:#111827;flex-grow:1;margin:0}.swot-card__count{background:#f3f4f6;padding:.25rem .75rem;border-radius:20px;font-size:.875rem;font-weight:600;color:#374151;flex-shrink:0}.swot-card__body{overflow:hidden}.swot-list{list-style:none;padding:0;margin:0}.swot-list__item{display:flex;align-items:flex-start;gap:.75rem;padding:.75rem 0;border-bottom:1px solid #f3f4f6;animation:fadeIn .3s ease-out backwards}.swot-list__item:last-child{border-bottom:none}.swot-list__item:nth-child(1){animation-delay:0.1s}.swot-list__item:nth-child(2){animation-delay:0.2s}.swot-list__item:nth-child(3){animation-delay:0.3s}.swot-list__item:nth-child(4){animation-delay:0.4s}.swot-list__item:nth-child(5){animation-delay:0.5s}.swot-list__item:nth-child(6){animation-delay:0.6s}.swot-list__item:nth-child(7){animation-delay:0.7s}.swot-list__item:nth-child(8){animation-delay:0.8s}.swot-list__item:nth-child(9){animation-delay:0.9s}.swot-list__item:nth-child(10){animation-delay:1s}.swot-list__bullet{width:6px;height:6px;border-radius:50%;background:var(--card-color);margin-top:.5rem;flex-shrink:0}.swot-list__text{flex:1;color:#374151;line-height:1.6}.swot-card:nth-child(1){animation-delay:0.1s}.swot-card:nth-child(2){animation-delay:0.2s}.swot-card:nth-child(3){animation-delay:0.3s}.swot-card:nth-child(4){animation-delay:0.4s}#result-container.animate-in{animation:containerFadeIn .6s ease-out}.status-timeline{position:relative;padding-left:2rem}.status-timeline::before{content:"";position:absolute;left:14px;top:24px;bottom:24px;width:2px;background:#e5e7eb}.status-item{position:relative;padding:1rem 0 1rem 2rem;animation:statusFadeIn .3s ease-out}.status-item--info .status-item__indicator,.status-item--info .status-item__header{color:#3b82f6}.status-item--loading .status-item__indicator,.status-item--loading .status-item__header{color:#f59e0b}.status-item--loading .status-item__content{animation:statusPulse 2s ease-in-out infinite}.status-item--success .status-item__indicator,.status-item--success .status-item__header{color:#10b981}.status-item--error .status-item__indicator,.status-item--error .status-item__header{color:#ef4444}.status-item__indicator{position:absolute;left:0;top:1.25rem;width:30px;height:30px;border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:1rem;background:#fff;box-shadow:0 0 0 4px #fff;z-index:1}.status-item__content{background:#fff;border-radius:12px;padding:1rem 1.25rem;box-shadow:0 4px 6px -1px rgba(0,0,0,.1),0 2px 4px -1px rgba(0,0,0,.06);transition:all 300ms cubic-bezier(0.4, 0, 0.2, 1)}.status-item:hover .status-item__content{box-shadow:0 10px 15px -3px rgba(0,0,0,.1),0 4px 6px -2px rgba(0,0,0,.05);transform:translateX(4px)}.status-item__header{font-weight:600;font-size:.875rem;text-transform:uppercase;letter-spacing:.05em;margin-bottom:.5rem}.status-item__message{color:#374151;line-height:1.6;font-size:.9375rem}.empty-state{display:flex;align-items:center;justify-content:center;min-height:400px;padding:3rem 1.5rem}.empty-state__content{text-align:center;max-width:500px}.empty-state__icon{width:120px;height:120px;margin:0 auto 2rem;border-radius:50%;background:linear-gradient(135deg, #F3F4F6 0%, #E5E7EB 100%);display:flex;align-items:center;justify-content:center;font-size:3rem;color:#9ca3af;animation:float 3s ease-in-out infinite}.empty-state__title{font-size:1.75rem;font-weight:600;color:#1f2937;margin-bottom:.75rem}.empty-state__description{font-size:1.125rem;color:#4b5563;line-height:1.6;margin-bottom:1.5rem}.empty-state__cta{display:inline-flex;align-items:center;gap:.5rem;padding:.875rem 2rem;background:#8b5cf6;color:#fff;border-radius:9999px;text-decoration:none;font-weight:600;transition:all 300ms cubic-bezier(0.4, 0, 0.2, 1);box-shadow:0 4px 6px -1px rgba(0,0,0,.1),0 2px 4px -1px rgba(0,0,0,.06)}.empty-state__cta:hover{background:#7c3aed;transform:translateY(-2px);box-shadow:0 10px 15px -3px rgba(0,0,0,.1),0 4px 6px -2px rgba(0,0,0,.05);color:#fff}.error-state{display:flex;align-items:center;justify-content:center;min-height:400px;padding:3rem 1.5rem}.error-state__content{text-align:center;max-width:500px}.error-state__icon{width:120px;height:120px;margin:0 auto 2rem;border-radius:50%;background:linear-gradient(135deg, #FEE2E2 0%, #FEF2F2 100%);display:flex;align-items:center;justify-content:center;font-size:3rem;color:#ef4444;animation:shake .5s ease-in-out}.error-state__title{font-size:1.75rem;font-weight:600;color:#1f2937;margin-bottom:.75rem}.error-state__description{font-size:1.125rem;color:#4b5563;line-height:1.6;margin-bottom:1.5rem}.error-state__details{background:#f3f4f6;border-radius:12px;padding:1rem;margin:1.5rem 0;font-family:"Courier New",monospace;font-size:.875rem;color:#374151;text-align:left;overflow-x:auto}.error-state__actions{display:flex;gap:1rem;justify-content:center;flex-wrap:wrap}.error-state__button{display:inline-flex;align-items:center;gap:.5rem;padding:.875rem 2rem;border-radius:9999px;font-weight:600;transition:all 300ms cubic-bezier(0.4, 0, 0.2, 1);box-shadow:0 4px 6px -1px rgba(0,0,0,.1),0 2px 4px -1px rgba(0,0,0,.06);cursor:pointer;border:none;text-decoration:none}.error-state__button--primary{background:#8b5cf6;color:#fff}.error-state__button--primary:hover{background:#7c3aed;transform:translateY(-2px);box-shadow:0 10px 15px -3px rgba(0,0,0,.1),0 4px 6px -2px rgba(0,0,0,.05);color:#fff}.error-state__button--secondary{background:#fff;color:#374151;border:2px solid #d1d5db}.error-state__button--secondary:hover{background:#f3f4f6;border-color:#9ca3af;transform:translateY(-2px);color:#1f2937}@media(max-width: 768px){.cell.is-col-span-2{grid-column:span 1}.swot-grid{grid-template-columns:1fr}.hero-title{font-size:2rem}.search-input-group{flex-direction:column;gap:.5rem;border-radius:20px;padding:1rem}.search-input{width:100%;text-align:center}.search-button{width:100%;justify-content:center}.swot-card__header{flex-wrap:wrap}.swot-card__count{order:-1;margin-left:auto}}@media(max-width: 480px){.swot-card{padding:1rem}.swot-card__icon{width:40px;height:40px;font-size:1.25rem}.swot-card__title{font-size:1.125rem}.hero-title{font-size:1.75rem}.status-timeline{padding-left:1.5rem}.status-item{padding-left:1.5rem}}:root{--brand-primary: #8B5CF6;--brand-primary-light: #A78BFA;--brand-primary-dark: #7C3AED;--swot-strength: #10B981;--swot-weakness: #F59E0B;--swot-opportunity: #3B82F6;--swot-threat: #EF4444;--neutral-50: #F9FAFB;--neutral-100: #F3F4F6;--neutral-200: #E5E7EB;--neutral-300: #D1D5DB;--neutral-400: #9CA3AF;--neutral-500: #6B7280;--neutral-600: #4B5563;--neutral-700: #374151;--neutral-800: #1F2937;--neutral-900: #111827;--shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, 0.05);--shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);--shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);--shadow-xl: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04);--shadow-2xl: 0 25px 50px -12px rgba(0, 0, 0, 0.25);--transition-fast: 150ms cubic-bezier(0.4, 0, 0.2, 1);--transition-base: 300ms cubic-bezier(0.4, 0, 0.2, 1);--transition-slow: 500ms cubic-bezier(0.4, 0, 0.2, 1)}/*# sourceMappingURL=pygentic_ai.css.map */
diff --git a/src/frontend/static/css/pygentic_ai.css.map b/src/frontend/static/css/pygentic_ai.css.map
new file mode 100644
index 0000000..0aa385c
--- /dev/null
+++ b/src/frontend/static/css/pygentic_ai.css.map
@@ -0,0 +1 @@
+{"version":3,"sourceRoot":"","sources":["../../scss/styles.scss","../../scss/_variables.scss","../../scss/_typography.scss","../../scss/_animations.scss","../../scss/_components.scss","../../scss/_layout.scss","../../scss/_states.scss","../../scss/_responsive.scss"],"names":[],"mappings":"AAAA;AAAA;AAAA;AAAA;AAAA,GCMQ,gICFR,KACE,YDIU,8FCHV,kDACA,mCACA,kCAGF,mCAGE,YDJa,mCCKb,uBACA,gBAIF,YACE,iCACA,gBACA,WDmBkB,kDClBlB,6BACA,sCACA,qBACA,mBACA,gBCxBF,gBACE,KACE,uBAEF,GACE,0BAIJ,iBACE,QACE,0BAEF,IACE,6BAIJ,iBACE,QACE,uCAEF,IACE,0CAIJ,mBACE,KACE,UACA,2BAEF,GACE,UACA,yBAIJ,kBACE,KACE,UAEF,GACE,WAIJ,iBACE,gCACA,gCACA,gCAGF,qBACE,QACE,mBAEF,IACE,sBAIJ,2BACE,KACE,UACA,2BAEF,GACE,UACA,yBAIJ,wBACE,KACE,UACA,4BAEF,GACE,UACA,yBAIJ,uBACE,QACE,WF3CQ,6DE6CV,IACE,2CCtFJ,iBACE,eACA,MACA,OACA,WACA,YACA,qCACA,0BACA,aACA,uBACA,mBACA,aAGF,iBACE,kBAGF,QACE,qCACA,6BACA,kBACA,WACA,YACA,mCACA,cAGF,cACE,kBAEA,iBACE,kBACA,gBACA,MHHU,QGIV,oBAGF,gBACE,kBACA,MHZU,QGkBd,kBACE,gBACA,cACA,kBAGF,aACE,WAGF,oBACE,aACA,mBACA,gBACA,cHSY,OGRZ,cACA,WHpBU,iEGqBV,kDAEA,iCACE,2CACA,2BAIJ,aACE,eACA,MH/CY,QGgDZ,kBAGF,cACE,OACA,YACA,aACA,qBACA,eACA,yBACA,MHrDY,QGuDZ,2BACE,MH7DU,QGiEd,eACE,WHtFc,QGuFd,WACA,YACA,cH1BY,OG2BZ,qBACA,gBACA,eACA,eACA,aACA,mBACA,UACA,kDACA,mBAEA,qBACE,WHnGiB,QGoGjB,0BACA,WHpEQ,+DGuEV,sBACE,sBAGF,qBACE,0BACA,mBAGF,0BACE,kBACA,oBACA,oBAEA,iCACE,WACA,kBACA,WACA,YACA,QACA,SACA,iBACA,gBACA,+BACA,sBACA,kBACA,mCAKN,aACE,gBACA,kBACA,MHtHY,QGuHZ,kBAEA,eACE,oBACA,MHjJY,QGsJhB,2CAKE,kDAIF,eACE,0BACA,mBCvKF,eACE,wEACA,kBACA,gBAIA,eACE,+BACA,wCAEA,qBACE,wCACA,8EAKN,kBACE,4BAKF,WACE,aACA,2DACA,IJiCW,OIhCX,WJiCW,KI9Bb,WACE,gBACA,cJkCU,KIjCV,QJ0BW,OIzBX,WJMU,+DILV,kDACA,uCACA,yCAEA,iBACE,2BACA,WJCS,kCICT,kCACE,iCAKJ,qBACE,sBAGF,qBACE,sBAGF,wBACE,sBAGF,mBACE,sBAIJ,mBACE,aACA,mBACA,WACA,mBACA,oBACA,gCAGF,iBACE,WACA,YACA,cJbU,KIcV,6BACA,aACA,mBACA,uBACA,WACA,iBACA,cAGF,kBACE,gBACA,mBACA,MJ7DY,QI8DZ,YACA,SAGF,kBACE,WJ3EY,QI4EZ,sBACA,cJhCU,KIiCV,kBACA,gBACA,MJ1EY,QI2EZ,cAGF,iBACE,gBAGF,WACE,gBACA,UACA,SAGF,iBACE,aACA,uBACA,WACA,iBACA,gCACA,wCAEA,4BACE,mBAKA,8BACE,qBADF,8BACE,qBADF,8BACE,qBADF,8BACE,qBADF,8BACE,qBADF,8BACE,qBADF,8BACE,qBADF,8BACE,qBADF,8BACE,qBADF,+BACE,mBAKN,mBACE,UACA,WACA,kBACA,6BACA,iBACA,cAGF,iBACE,OACA,MJvHY,QIwHZ,gBAKA,wBACE,qBADF,wBACE,qBADF,wBACE,qBADF,wBACE,qBAKJ,6BACE,uCAKF,iBACE,kBACA,kBAEA,yBACE,WACA,kBACA,UACA,SACA,YACA,UACA,WJzJU,QI6Jd,aACE,kBACA,yBACA,oCAIE,mFAEE,MJ9Ka,QImLf,yFAEE,MJvLU,QI0LZ,4CACE,8CAKF,yFAEE,MJpMU,QIyMZ,qFAEE,MJrMQ,QI0Md,wBACE,kBACA,OACA,YACA,WACA,YACA,kBACA,aACA,mBACA,uBACA,eACA,gBACA,0BACA,UAGF,sBACE,gBACA,cJ5KU,KI6KV,qBACA,WJxMU,6DIyMV,kDAGF,yCACE,WJ5MU,+DI6MV,0BAGF,qBACE,gBACA,kBACA,yBACA,qBACA,oBAGF,sBACE,MJrOY,QIsOZ,gBACA,mBCpQF,aACE,aACA,mBACA,uBACA,iBACA,oBAGF,sBACE,kBACA,gBAGF,mBACE,YACA,aACA,mBACA,kBACA,6DACA,aACA,mBACA,uBACA,eACA,MLGY,QKFZ,wCAGF,oBACE,kBACA,gBACA,cACA,qBAGF,0BACE,mBACA,MLRY,QKSZ,gBACA,qBAGF,kBACE,oBACA,mBACA,UACA,qBACA,WLxCc,QKyCd,WACA,cLqBY,OKpBZ,qBACA,gBACA,kDACA,WLZU,6DKcV,wBACE,WL/CiB,QKgDjB,2BACA,WLhBQ,+DKiBR,WAMJ,aACE,aACA,mBACA,uBACA,iBACA,oBAGF,sBACE,kBACA,gBAGF,mBACE,YACA,aACA,mBACA,kBACA,6DACA,aACA,mBACA,uBACA,eACA,MLrEY,QKsEZ,gCAGF,oBACE,kBACA,gBACA,MLhEY,QKiEZ,qBAGF,0BACE,mBACA,MLxEY,QKyEZ,gBACA,qBAGF,sBACE,WLnFY,QKoFZ,cLzCU,KK0CV,aACA,gBACA,oCACA,kBACA,MLnFY,QKoFZ,gBACA,gBAGF,sBACE,aACA,SACA,uBACA,eAGF,qBACE,oBACA,mBACA,UACA,qBACA,cL5DY,OK6DZ,gBACA,kDACA,WL5FU,6DK6FV,eACA,YACA,qBAEA,8BACE,WLpIY,QKqIZ,WAEA,oCACE,WLtIe,QKuIf,2BACA,WLvGM,+DKwGN,WAIJ,gCACE,gBACA,ML1HU,QK2HV,yBAEA,sCACE,WLpIQ,QKqIR,aLlIQ,QKmIR,2BACA,MLhIQ,QM/Bd,yBACE,oBACE,mBAGF,WACE,0BAGF,YACE,eAGF,oBACE,sBACA,UACA,cNqDQ,KMpDR,aAGF,cACE,WACA,kBAGF,eACE,WACA,uBAGF,mBACE,eAGF,kBACE,SACA,kBAKJ,yBACE,WACE,aAGF,iBACE,WACA,YACA,kBAGF,kBACE,mBAGF,YACE,kBAGF,iBACE,oBAGF,aACE,qBP3CJ,MAEE,yBACA,+BACA,8BAGA,yBACA,yBACA,4BACA,uBAGA,sBACA,uBACA,uBACA,uBACA,uBACA,uBACA,uBACA,uBACA,uBACA,uBAGA,6CACA,mFACA,qFACA,uFACA,oDAGA,sDACA,sDACA","file":"pygentic_ai.css"}
\ No newline at end of file
diff --git a/src/frontend/static/js/app.js b/src/frontend/static/js/app.js
new file mode 100644
index 0000000..85fcffe
--- /dev/null
+++ b/src/frontend/static/js/app.js
@@ -0,0 +1,224 @@
+/**
+ * Pygentic AI - Frontend Application
+ * Progressive loading and enhanced UX interactions
+ */
+
+(function() {
+ 'use strict';
+
+ // Progressive loading messages
+ const LOADING_MESSAGES = [
+ 'Fetching URL content...',
+ 'Analyzing page structure...',
+ 'Extracting key information...',
+ 'Identifying patterns...',
+ 'Generating SWOT analysis...',
+ 'Finalizing insights...',
+ 'Almost there...'
+ ];
+
+ let loadingMessageIndex = 0;
+ let loadingInterval = null;
+ let pollCount = 0;
+ let pollInterval = 1000; // Start at 1s
+ const MAX_POLL_INTERVAL = 5000; // Max 5s
+
+ /**
+ * Update loading message progressively
+ */
+ function updateLoadingMessage() {
+ const statusElement = document.getElementById('loading-status');
+ if (!statusElement) return;
+
+ if (loadingMessageIndex < LOADING_MESSAGES.length - 1) {
+ loadingMessageIndex++;
+ }
+
+ statusElement.textContent = LOADING_MESSAGES[loadingMessageIndex];
+ statusElement.style.animation = 'fadeIn 0.3s ease-in';
+ }
+
+ /**
+ * Start progressive loading messages
+ */
+ function startLoadingMessages() {
+ loadingMessageIndex = 0;
+ pollCount = 0;
+ pollInterval = 1000;
+
+ const statusElement = document.getElementById('loading-status');
+ if (statusElement) {
+ statusElement.textContent = LOADING_MESSAGES[0];
+ }
+
+ // Update message every 3 seconds
+ if (loadingInterval) {
+ clearInterval(loadingInterval);
+ }
+
+ loadingInterval = setInterval(updateLoadingMessage, 3000);
+ }
+
+ /**
+ * Stop loading messages
+ */
+ function stopLoadingMessages() {
+ if (loadingInterval) {
+ clearInterval(loadingInterval);
+ loadingInterval = null;
+ }
+ loadingMessageIndex = 0;
+ }
+
+ /**
+ * Smooth scroll to results
+ */
+ function scrollToResults() {
+ const resultsSection = document.getElementById('result-container');
+ if (resultsSection) {
+ resultsSection.scrollIntoView({
+ behavior: 'smooth',
+ block: 'start'
+ });
+ }
+ }
+
+ /**
+ * Exponential backoff for polling
+ */
+ function calculateNextPollInterval() {
+ pollCount++;
+
+ if (pollCount > 3) {
+ pollInterval = Math.min(pollInterval * 1.5, MAX_POLL_INTERVAL);
+ }
+
+ return pollInterval;
+ }
+
+ /**
+ * Initialize form submission handler
+ */
+ function initializeForm() {
+ const form = document.getElementById('swotSearch');
+ if (!form) return;
+
+ form.addEventListener('submit', function(e) {
+ // Start loading messages when form is submitted
+ startLoadingMessages();
+
+ // Show spinner
+ const spinner = document.getElementById('spinner');
+ if (spinner) {
+ spinner.classList.remove('is-hidden');
+ }
+ });
+ }
+
+ /**
+ * Monitor for analysis completion
+ */
+ function monitorAnalysisCompletion() {
+ const resultBox = document.getElementById('result');
+ if (!resultBox) return;
+
+ // Use MutationObserver to watch for content changes
+ const observer = new MutationObserver(function(mutations) {
+ mutations.forEach(function(mutation) {
+ if (mutation.type === 'childList' && resultBox.innerHTML.trim().length > 0) {
+ // Analysis complete
+ stopLoadingMessages();
+
+ // Hide spinner
+ const spinner = document.getElementById('spinner');
+ if (spinner) {
+ spinner.classList.add('is-hidden');
+ }
+
+ // Scroll to results after a brief delay
+ setTimeout(scrollToResults, 500);
+
+ // Add success class for animation
+ const resultContainer = document.getElementById('result-container');
+ if (resultContainer) {
+ resultContainer.classList.add('animate-in');
+ }
+ }
+ });
+ });
+
+ observer.observe(resultBox, {
+ childList: true,
+ subtree: true
+ });
+ }
+
+ /**
+ * Add button press effects
+ */
+ function initializeButtonEffects() {
+ const buttons = document.querySelectorAll('.search-button, .error-state__button');
+
+ buttons.forEach(button => {
+ button.addEventListener('mousedown', function() {
+ this.style.transform = 'scale(0.95)';
+ });
+
+ button.addEventListener('mouseup', function() {
+ this.style.transform = '';
+ });
+
+ button.addEventListener('mouseleave', function() {
+ this.style.transform = '';
+ });
+ });
+ }
+
+ /**
+ * Initialize smooth anchor scrolling
+ */
+ function initializeSmoothScrolling() {
+ document.querySelectorAll('a[href^="#"]').forEach(anchor => {
+ anchor.addEventListener('click', function(e) {
+ const href = this.getAttribute('href');
+ if (href === '#' || !href) return;
+
+ e.preventDefault();
+ const target = document.querySelector(href);
+
+ if (target) {
+ target.scrollIntoView({
+ behavior: 'smooth',
+ block: 'start'
+ });
+ }
+ });
+ });
+ }
+
+ /**
+ * Initialize all features on DOM ready
+ */
+ function initialize() {
+ initializeForm();
+ monitorAnalysisCompletion();
+ initializeButtonEffects();
+ initializeSmoothScrolling();
+
+ console.log('✨ Pygentic AI initialized');
+ }
+
+ // Initialize when DOM is ready
+ if (document.readyState === 'loading') {
+ document.addEventListener('DOMContentLoaded', initialize);
+ } else {
+ initialize();
+ }
+
+ // Export functions for external use if needed
+ window.PygenticAI = {
+ startLoadingMessages,
+ stopLoadingMessages,
+ scrollToResults
+ };
+})();
diff --git a/src/frontend/templates/components/main/Scripts.jinja b/src/frontend/templates/components/main/Scripts.jinja
index 7aecb53..2fdf4a7 100644
--- a/src/frontend/templates/components/main/Scripts.jinja
+++ b/src/frontend/templates/components/main/Scripts.jinja
@@ -1,3 +1,4 @@
{{ description }}
+ {{ content }} +{{ description }}
+ + {% if error_details %} +