From 67fce2656b3a08d8a2ba0c7d7b5bbc9c11105aec Mon Sep 17 00:00:00 2001 From: Francis Secada Date: Mon, 2 Feb 2026 16:17:10 -0500 Subject: [PATCH] feat: migrate frontend styling to SCSS with modular architecture - Implement SCSS with 7 modular partials for better maintainability: - _variables.scss: Complete design token system - _typography.scss: Font hierarchy and styles - _animations.scss: Reusable keyframe animations - _components.scss: UI components (spinner, search, buttons) - _layout.scss: Page structure (hero, SWOT cards, status timeline) - _states.scss: Empty and error state components - _responsive.scss: Mobile-first breakpoints - Add build scripts for SCSS compilation and watch mode - Add EmptyState and ErrorState components for better UX - Enhance templates with progressive loading and accessibility - Configure npm with local registry override (.npmrc) - Add app.js for progressive loading and smooth interactions Benefits: - Better code organization with partial separation - CSS custom properties for runtime theming - BEM naming convention for maintainability - Compressed output for production (13KB) - Easy development with watch mode Co-Authored-By: Claude Sonnet 4.5 --- src/frontend/package-lock.json | 2448 +++++++++++++++++ src/frontend/package.json | 23 + src/frontend/scss/_animations.scss | 96 + src/frontend/scss/_components.scss | 176 ++ src/frontend/scss/_layout.scss | 269 ++ src/frontend/scss/_responsive.scss | 74 + src/frontend/scss/_states.scss | 169 ++ src/frontend/scss/_typography.scss | 30 + src/frontend/scss/_variables.scss | 77 + src/frontend/scss/styles.scss | 64 + src/frontend/static/css/pygentic_ai.css | 476 +--- src/frontend/static/css/pygentic_ai.css.map | 1 + src/frontend/static/js/app.js | 224 ++ .../templates/components/main/Scripts.jinja | 3 +- .../components/snippets/EmptyState.jinja | 16 + .../components/snippets/ErrorState.jinja | 39 + src/frontend/templates/home.html | 12 +- src/frontend/templates/status.html | 75 +- 18 files changed, 3763 insertions(+), 509 deletions(-) create mode 100644 src/frontend/package-lock.json create mode 100644 src/frontend/package.json create mode 100644 src/frontend/scss/_animations.scss create mode 100644 src/frontend/scss/_components.scss create mode 100644 src/frontend/scss/_layout.scss create mode 100644 src/frontend/scss/_responsive.scss create mode 100644 src/frontend/scss/_states.scss create mode 100644 src/frontend/scss/_typography.scss create mode 100644 src/frontend/scss/_variables.scss create mode 100644 src/frontend/scss/styles.scss create mode 100644 src/frontend/static/css/pygentic_ai.css.map create mode 100644 src/frontend/static/js/app.js create mode 100644 src/frontend/templates/components/snippets/EmptyState.jinja create mode 100644 src/frontend/templates/components/snippets/ErrorState.jinja 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 @@ type="modules" - \ No newline at end of file + + \ No newline at end of file diff --git a/src/frontend/templates/components/snippets/EmptyState.jinja b/src/frontend/templates/components/snippets/EmptyState.jinja new file mode 100644 index 0000000..01d3f01 --- /dev/null +++ b/src/frontend/templates/components/snippets/EmptyState.jinja @@ -0,0 +1,16 @@ +{# def + title: str = "No Analysis Yet", + description: str = "Enter a URL above to get started with your first SWOT analysis", + icon: str = "fa-chart-simple" +#} + +
+
+
+ +
+

{{ title }}

+

{{ description }}

+ {{ content }} +
+
\ No newline at end of file diff --git a/src/frontend/templates/components/snippets/ErrorState.jinja b/src/frontend/templates/components/snippets/ErrorState.jinja new file mode 100644 index 0000000..baec9a4 --- /dev/null +++ b/src/frontend/templates/components/snippets/ErrorState.jinja @@ -0,0 +1,39 @@ +{# def + title: str = "Analysis Failed", + description: str = "We couldn't analyze this URL. Please check the URL and try again.", + error_details: str = None, + show_retry: bool = True +#} + +
+
+
+ +
+

{{ title }}

+

{{ description }}

+ + {% if error_details %} +
+ {{ error_details }} +
+ {% endif %} + +
+ {% if show_retry %} + + {% endif %} + + + Go Home + +
+ + {{ content }} +
+
\ No newline at end of file diff --git a/src/frontend/templates/home.html b/src/frontend/templates/home.html index 1b57980..cbb18e6 100644 --- a/src/frontend/templates/home.html +++ b/src/frontend/templates/home.html @@ -29,8 +29,10 @@ action={{ url_for('analyze_url') }} target="status" method="post"> -
- +