commit 26df196bb3c96ff62eb1a60527b0893dab923f2a Author: Marios Antonoudiou Date: Tue May 19 17:03:23 2026 +0300 Initial commit diff --git a/.eleventy.js b/.eleventy.js new file mode 100644 index 0000000..69462b9 --- /dev/null +++ b/.eleventy.js @@ -0,0 +1,17 @@ +module.exports = function (eleventyConfig) { + eleventyConfig.addPassthroughCopy("src/images"); + eleventyConfig.addPassthroughCopy("src/css"); + eleventyConfig.addPassthroughCopy("src/js/script.js"); + + return { + dir: { + input: "src", + output: "_site", + includes: "_includes", + data: "_data", + }, + templateFormats: ["njk", "html"], + htmlTemplateEngine: "njk", + markdownTemplateEngine: "njk", + }; +}; \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..0a36945 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +node_modules/ +_site/ +.DS_Store +*.log \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..8e62c6d --- /dev/null +++ b/README.md @@ -0,0 +1,36 @@ +# BuildMVP + +Landing page for MVP development services by [Marios Antonoudiou](https://www.linkedin.com/in/mariosant/). + +## Tech + +- **11ty** static site generator +- **Nunjucks** templates +- Vanilla CSS + JS + +## Setup + +```bash +npm install +``` + +## Development + +```bash +npm start +``` + +Site served at `http://localhost:8080`. + +## Build + +```bash +npm run build +``` + +Output goes to `_site/`. + +## SEO + +- Canonical URL, Open Graph, Twitter Card, and JSON-LD structured data (`Person`, `Service`, `FAQPage`) are set via `src/_includes/base.njk`. +- Sitemap at `/sitemap.xml` and `robots.txt` at `/robots.txt` are auto-generated by Eleventy templates. \ No newline at end of file diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..c72b20d --- /dev/null +++ b/package-lock.json @@ -0,0 +1,1652 @@ +{ + "name": "novapay", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "novapay", + "version": "1.0.0", + "devDependencies": { + "@11ty/eleventy": "^3.0.0" + } + }, + "node_modules/@11ty/dependency-tree": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@11ty/dependency-tree/-/dependency-tree-4.0.2.tgz", + "integrity": "sha512-RTF6VTZHatYf7fSZBUN3RKwiUeJh5dhWV61gDPrHhQF2/gzruAkYz8yXuvGLx3w3ZBKreGrR+MfYpSVkdbdbLA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@11ty/eleventy-utils": "^2.0.1" + } + }, + "node_modules/@11ty/dependency-tree-esm": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@11ty/dependency-tree-esm/-/dependency-tree-esm-2.0.4.tgz", + "integrity": "sha512-MYKC0Ac77ILr1HnRJalzKDlb9Z8To3kXQCltx299pUXXUFtJ1RIONtULlknknqW8cLe19DLVgmxVCtjEFm7h0A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@11ty/eleventy-utils": "^2.0.7", + "acorn": "^8.15.0", + "dependency-graph": "^1.0.0", + "normalize-path": "^3.0.0" + } + }, + "node_modules/@11ty/eleventy": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/@11ty/eleventy/-/eleventy-3.1.5.tgz", + "integrity": "sha512-hZ0g6MwZyRxCqXsPm82gIM304LraKbUz3ZmezOSjsqxttZG6cHTib3Qq8QkESJoKwnr+yX1eyfOkPC5/mEgZnQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@11ty/dependency-tree": "^4.0.2", + "@11ty/dependency-tree-esm": "^2.0.4", + "@11ty/eleventy-dev-server": "^2.0.8", + "@11ty/eleventy-plugin-bundle": "^3.0.7", + "@11ty/eleventy-utils": "^2.0.7", + "@11ty/lodash-custom": "^4.17.21", + "@11ty/posthtml-urls": "^1.0.2", + "@11ty/recursive-copy": "^4.0.4", + "@sindresorhus/slugify": "^2.2.1", + "bcp-47-normalize": "^2.3.0", + "chokidar": "^3.6.0", + "debug": "^4.4.3", + "dependency-graph": "^1.0.0", + "entities": "^6.0.1", + "filesize": "^10.1.6", + "gray-matter": "^4.0.3", + "iso-639-1": "^3.1.5", + "js-yaml": "^4.1.1", + "kleur": "^4.1.5", + "liquidjs": "^10.25.0", + "luxon": "^3.7.2", + "markdown-it": "^14.1.1", + "minimist": "^1.2.8", + "moo": "0.5.2", + "node-retrieve-globals": "^6.0.1", + "nunjucks": "^3.2.4", + "picomatch": "^4.0.3", + "please-upgrade-node": "^3.2.0", + "posthtml": "^0.16.7", + "posthtml-match-helper": "^2.0.3", + "semver": "^7.7.4", + "slugify": "^1.6.8", + "tinyglobby": "^0.2.15" + }, + "bin": { + "eleventy": "cmd.cjs" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/11ty" + } + }, + "node_modules/@11ty/eleventy-dev-server": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/@11ty/eleventy-dev-server/-/eleventy-dev-server-2.0.8.tgz", + "integrity": "sha512-15oC5M1DQlCaOMUq4limKRYmWiGecDaGwryr7fTE/oM9Ix8siqMvWi+I8VjsfrGr+iViDvWcH/TVI6D12d93mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@11ty/eleventy-utils": "^2.0.1", + "chokidar": "^3.6.0", + "debug": "^4.4.0", + "finalhandler": "^1.3.1", + "mime": "^3.0.0", + "minimist": "^1.2.8", + "morphdom": "^2.7.4", + "please-upgrade-node": "^3.2.0", + "send": "^1.1.0", + "ssri": "^11.0.0", + "urlpattern-polyfill": "^10.0.0", + "ws": "^8.18.1" + }, + "bin": { + "eleventy-dev-server": "cmd.js" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/11ty" + } + }, + "node_modules/@11ty/eleventy-plugin-bundle": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/@11ty/eleventy-plugin-bundle/-/eleventy-plugin-bundle-3.0.7.tgz", + "integrity": "sha512-QK1tRFBhQdZASnYU8GMzpTdsMMFLVAkuU0gVVILqNyp09xJJZb81kAS3AFrNrwBCsgLxTdWHJ8N64+OTTsoKkA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@11ty/eleventy-utils": "^2.0.2", + "debug": "^4.4.0", + "posthtml-match-helper": "^2.0.3" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/11ty" + } + }, + "node_modules/@11ty/eleventy-utils": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/@11ty/eleventy-utils/-/eleventy-utils-2.0.7.tgz", + "integrity": "sha512-6QE+duqSQ0GY9rENXYb4iPR4AYGdrFpqnmi59tFp9VrleOl0QSh8VlBr2yd6dlhkdtj7904poZW5PvGr9cMiJQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/11ty" + } + }, + "node_modules/@11ty/lodash-custom": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/@11ty/lodash-custom/-/lodash-custom-4.17.21.tgz", + "integrity": "sha512-Mqt6im1xpb1Ykn3nbcCovWXK3ggywRJa+IXIdoz4wIIK+cvozADH63lexcuPpGS/gJ6/m2JxyyXDyupkMr5DHw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/11ty" + } + }, + "node_modules/@11ty/posthtml-urls": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@11ty/posthtml-urls/-/posthtml-urls-1.0.3.tgz", + "integrity": "sha512-1YvhnkaNlFnnJic1rBMWmTC2adbuy+JQiBfl1Hecr1Wjjik1pQZmGyk/eC9zKX/FQv52s2Nht1Gi/UwhYqrBeg==", + "dev": true, + "license": "MIT", + "dependencies": { + "evaluate-value": "^2.0.0", + "http-equiv-refresh": "^2.0.1", + "list-to-array": "^1.1.0", + "parse-srcset": "^1.0.2" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/@11ty/recursive-copy": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@11ty/recursive-copy/-/recursive-copy-4.0.4.tgz", + "integrity": "sha512-oI7m8pa7/IAU/3lqRU9vjBbs20iKFo7x+1K9kT3aVira6scc1X9MjBdgLCHzLJeJ7iB6wydioA+kr9/qPnvmlQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "errno": "^1.0.0", + "junk": "^3.1.0", + "minimatch": "^3.1.5", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@sindresorhus/slugify": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/@sindresorhus/slugify/-/slugify-2.2.1.tgz", + "integrity": "sha512-MkngSCRZ8JdSOCHRaYd+D01XhvU3Hjy6MGl06zhOk614hp9EOAp5gIkBeQg7wtmxpitU6eAL4kdiRMcJa2dlrw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@sindresorhus/transliterate": "^1.0.0", + "escape-string-regexp": "^5.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@sindresorhus/transliterate": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/transliterate/-/transliterate-1.6.0.tgz", + "integrity": "sha512-doH1gimEu3A46VX6aVxpHTeHrytJAG6HgdxntYnCFiIFHEM/ZGpG8KiZGBChchjQmG0XFIBL552kBTjVcMZXwQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "escape-string-regexp": "^5.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/a-sync-waterfall": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/a-sync-waterfall/-/a-sync-waterfall-1.0.1.tgz", + "integrity": "sha512-RYTOHHdWipFUliRFMCS4X2Yn2X8M87V/OpSqWzKKOGhzqyUxzyVmhHDH9sAvG+ZuQf/TAOFsLCpMw09I1ufUnA==", + "dev": true, + "license": "MIT" + }, + "node_modules/acorn": { + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz", + "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-walk": { + "version": "8.3.5", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.5.tgz", + "integrity": "sha512-HEHNfbars9v4pgpW6SO1KSPkfoS0xVOM/9UzkJltjlsHZmJasxg8aXkuZa7SMf8vKGIBhpUsPluQSqhJFCqebw==", + "dev": true, + "license": "MIT", + "dependencies": { + "acorn": "^8.11.0" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "license": "ISC", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/anymatch/node_modules/picomatch": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz", + "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true, + "license": "Python-2.0" + }, + "node_modules/asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==", + "dev": true, + "license": "MIT" + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/bcp-47": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/bcp-47/-/bcp-47-2.1.0.tgz", + "integrity": "sha512-9IIS3UPrvIa1Ej+lVDdDwO7zLehjqsaByECw0bu2RRGP73jALm6FYbzI5gWbgHLvNdkvfXB5YrSbocZdOS0c0w==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-alphabetical": "^2.0.0", + "is-alphanumerical": "^2.0.0", + "is-decimal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/bcp-47-match": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/bcp-47-match/-/bcp-47-match-2.0.3.tgz", + "integrity": "sha512-JtTezzbAibu8G0R9op9zb3vcWZd9JF6M0xOYGPn0fNCd7wOpRB1mU2mH9T8gaBGbAAyIIVgB2G7xG0GP98zMAQ==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/bcp-47-normalize": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/bcp-47-normalize/-/bcp-47-normalize-2.3.0.tgz", + "integrity": "sha512-8I/wfzqQvttUFz7HVJgIZ7+dj3vUaIyIxYXaTRP1YWoSDfzt6TUmxaKZeuXR62qBmYr+nvuWINFRl6pZ5DlN4Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "bcp-47": "^2.0.0", + "bcp-47-match": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/binary-extensions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/brace-expansion": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.14.tgz", + "integrity": "sha512-MWPGfDxnyzKU7rNOW9SP/c50vi3xrmrua/+6hfPbCS2ABNWfx24vPidzvC7krjU/RTo235sV776ymlsMtGKj8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/commander": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", + "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true, + "license": "MIT" + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/dependency-graph": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/dependency-graph/-/dependency-graph-1.0.0.tgz", + "integrity": "sha512-cW3gggJ28HZ/LExwxP2B++aiKxhJXMSIt9K48FOXQkm+vuG5gyatXnLsONRJdzO/7VfjDIiaOOa/bs4l464Lwg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/dom-serializer": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz", + "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==", + "dev": true, + "license": "MIT", + "dependencies": { + "domelementtype": "^2.0.1", + "domhandler": "^4.2.0", + "entities": "^2.0.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/dom-serializer/node_modules/entities": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", + "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", + "dev": true, + "license": "BSD-2-Clause", + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/domelementtype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "BSD-2-Clause" + }, + "node_modules/domhandler": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", + "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "domelementtype": "^2.2.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/domutils": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", + "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "dom-serializer": "^1.0.1", + "domelementtype": "^2.2.0", + "domhandler": "^4.2.0" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", + "dev": true, + "license": "MIT" + }, + "node_modules/encodeurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/entities": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz", + "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/errno": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/errno/-/errno-1.0.0.tgz", + "integrity": "sha512-3zV5mFS1E8/1bPxt/B0xxzI1snsg3uSCIh6Zo1qKg6iMw93hzPANk9oBFzSFBFrwuVoQuE3rLoouAUfwOAj1wQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "prr": "~1.0.1" + }, + "bin": { + "errno": "cli.js" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", + "dev": true, + "license": "MIT" + }, + "node_modules/escape-string-regexp": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", + "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/esm-import-transformer": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/esm-import-transformer/-/esm-import-transformer-3.0.5.tgz", + "integrity": "sha512-1GKLvfuMnnpI75l8c6sHoz0L3Z872xL5akGuBudgqTDPv4Vy6f2Ec7jEMKTxlqWl/3kSvNbHELeimJtnqgYniw==", + "dev": true, + "license": "MIT", + "dependencies": { + "acorn": "^8.15.0" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true, + "license": "BSD-2-Clause", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/evaluate-value": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/evaluate-value/-/evaluate-value-2.0.0.tgz", + "integrity": "sha512-VonfiuDJc0z4sOO7W0Pd130VLsXN6vmBWZlrog1mCb/o7o/Nl5Lr25+Kj/nkCCAhG+zqeeGjxhkK9oHpkgTHhQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/filesize": { + "version": "10.1.6", + "resolved": "https://registry.npmjs.org/filesize/-/filesize-10.1.6.tgz", + "integrity": "sha512-sJslQKU2uM33qH5nqewAwVB2QgR6w1aMNsYUp3aN5rMRyXEwJGmZvaWzeJFNTOXWlHQyBFCWrdj3fV/fsTOX8w==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">= 10.4.0" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/finalhandler": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.2.tgz", + "integrity": "sha512-aA4RyPcd3badbdABGDuTXCMTtOneUCAYH/gxoYRTZlIJdF0YPWuGqiAsIrhNnnqdXGswYk6dGujem4w80UJFhg==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "on-finished": "~2.4.1", + "parseurl": "~1.3.3", + "statuses": "~2.0.2", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/finalhandler/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/finalhandler/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true, + "license": "MIT" + }, + "node_modules/fresh": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-2.0.0.tgz", + "integrity": "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/gray-matter": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/gray-matter/-/gray-matter-4.0.3.tgz", + "integrity": "sha512-5v6yZd4JK3eMI3FqqCouswVqwugaA9r4dNZB1wwcmrD02QkV5H0y7XBQW8QwQqEaZY1pM9aqORSORhJRdNK44Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "js-yaml": "^3.13.1", + "kind-of": "^6.0.2", + "section-matter": "^1.0.0", + "strip-bom-string": "^1.0.0" + }, + "engines": { + "node": ">=6.0" + } + }, + "node_modules/gray-matter/node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "license": "MIT", + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/gray-matter/node_modules/js-yaml": { + "version": "3.14.2", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.2.tgz", + "integrity": "sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/htmlparser2": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-7.2.0.tgz", + "integrity": "sha512-H7MImA4MS6cw7nbyURtLPO1Tms7C5H602LRETv95z1MxO/7CP7rDVROehUYeYBUYEON94NXXDEPmZuq+hX4sog==", + "dev": true, + "funding": [ + "https://github.com/fb55/htmlparser2?sponsor=1", + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "MIT", + "dependencies": { + "domelementtype": "^2.0.1", + "domhandler": "^4.2.2", + "domutils": "^2.8.0", + "entities": "^3.0.1" + } + }, + "node_modules/htmlparser2/node_modules/entities": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-3.0.1.tgz", + "integrity": "sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/http-equiv-refresh": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/http-equiv-refresh/-/http-equiv-refresh-2.0.1.tgz", + "integrity": "sha512-XJpDL/MLkV3dKwLzHwr2dY05dYNfBNlyPu4STQ8WvKCFdc6vC5tPXuq28of663+gHVg03C+16pHHs/+FmmDjcw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/http-errors": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz", + "integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "depd": "~2.0.0", + "inherits": "~2.0.4", + "setprototypeof": "~1.2.0", + "statuses": "~2.0.2", + "toidentifier": "~1.0.1" + }, + "engines": { + "node": ">= 0.8" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/is-alphabetical": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-2.0.1.tgz", + "integrity": "sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-alphanumerical": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-2.0.1.tgz", + "integrity": "sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-alphabetical": "^2.0.0", + "is-decimal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "license": "MIT", + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-decimal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-2.0.1.tgz", + "integrity": "sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-json": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-json/-/is-json-2.0.1.tgz", + "integrity": "sha512-6BEnpVn1rcf3ngfmViLM6vjUjGErbdrL4rwlv+u1NO1XO8kqT4YGL8+19Q+Z/bas8tY90BTWMk2+fW1g6hQjbA==", + "dev": true, + "license": "ISC" + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/iso-639-1": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/iso-639-1/-/iso-639-1-3.1.5.tgz", + "integrity": "sha512-gXkz5+KN7HrG0Q5UGqSMO2qB9AsbEeyLP54kF1YrMsIxmu+g4BdB7rflReZTSTZGpfj8wywu6pfPBCylPIzGQA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0" + } + }, + "node_modules/js-yaml": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", + "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/junk": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/junk/-/junk-3.1.0.tgz", + "integrity": "sha512-pBxcB3LFc8QVgdggvZWyeys+hnrNWg4OcZIU/1X59k5jQdLBlCsYGRQaz234SqoRLTCgMH00fY0xRJH+F9METQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/kleur": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz", + "integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/linkify-it": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-5.0.0.tgz", + "integrity": "sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "uc.micro": "^2.0.0" + } + }, + "node_modules/liquidjs": { + "version": "10.27.0", + "resolved": "https://registry.npmjs.org/liquidjs/-/liquidjs-10.27.0.tgz", + "integrity": "sha512-tw/OA59K7aIBlMKIrKlumr37fiZUheShVHXY8cVctWisgY1p9mc5hreOvlreoS0wTiwlWk14Ya7305c2a/Cg5w==", + "dev": true, + "license": "MIT", + "dependencies": { + "commander": "^10.0.0" + }, + "bin": { + "liquid": "bin/liquid.js", + "liquidjs": "bin/liquid.js" + }, + "engines": { + "node": ">=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/liquidjs" + } + }, + "node_modules/list-to-array": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/list-to-array/-/list-to-array-1.1.0.tgz", + "integrity": "sha512-+dAZZ2mM+/m+vY9ezfoueVvrgnHIGi5FvgSymbIgJOFwiznWyA59mav95L+Mc6xPtL3s9gm5eNTlNtxJLbNM1g==", + "dev": true, + "license": "MIT" + }, + "node_modules/luxon": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/luxon/-/luxon-3.7.2.tgz", + "integrity": "sha512-vtEhXh/gNjI9Yg1u4jX/0YVPMvxzHuGgCm6tC5kZyb08yjGWGnqAjGJvcXbqQR2P3MyMEFnRbpcdFS6PBcLqew==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + } + }, + "node_modules/markdown-it": { + "version": "14.1.1", + "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.1.1.tgz", + "integrity": "sha512-BuU2qnTti9YKgK5N+IeMubp14ZUKUUw7yeJbkjtosvHiP0AZ5c8IAgEMk79D0eC8F23r4Ac/q8cAIFdm2FtyoA==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1", + "entities": "^4.4.0", + "linkify-it": "^5.0.0", + "mdurl": "^2.0.0", + "punycode.js": "^2.3.1", + "uc.micro": "^2.1.0" + }, + "bin": { + "markdown-it": "bin/markdown-it.mjs" + } + }, + "node_modules/markdown-it/node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/mdurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-2.0.0.tgz", + "integrity": "sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==", + "dev": true, + "license": "MIT" + }, + "node_modules/mime": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-3.0.0.tgz", + "integrity": "sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==", + "dev": true, + "license": "MIT", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/mime-db": { + "version": "1.54.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", + "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.2.tgz", + "integrity": "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "mime-db": "^1.54.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/minimatch": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/minipass": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.3.tgz", + "integrity": "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/moo": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/moo/-/moo-0.5.2.tgz", + "integrity": "sha512-iSAJLHYKnX41mKcJKjqvnAN9sf0LMDTXDEvFv+ffuRR9a1MIuXLjMNL6EsnDHSkKLTWNqQQ5uo61P4EbU4NU+Q==", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/morphdom": { + "version": "2.7.8", + "resolved": "https://registry.npmjs.org/morphdom/-/morphdom-2.7.8.tgz", + "integrity": "sha512-D/fR4xgGUyVRbdMGU6Nejea1RFzYxYtyurG4Fbv2Fi/daKlWKuXGLOdXtl+3eIwL110cI2hz1ZojGICjjFLgTg==", + "dev": true, + "license": "MIT" + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/node-retrieve-globals": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/node-retrieve-globals/-/node-retrieve-globals-6.0.1.tgz", + "integrity": "sha512-j0DeFuZ/Wg3VlklfbxUgZF/mdHMTEiEipBb3q0SpMMbHaV3AVfoUQF8UGxh1s/yjqO0TgRZd4Pi/x2yRqoQ4Eg==", + "dev": true, + "license": "MIT", + "dependencies": { + "acorn": "^8.14.1", + "acorn-walk": "^8.3.4", + "esm-import-transformer": "^3.0.3" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/nunjucks": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/nunjucks/-/nunjucks-3.2.4.tgz", + "integrity": "sha512-26XRV6BhkgK0VOxfbU5cQI+ICFUtMLixv1noZn1tGU38kQH5A5nmmbk/O45xdyBhD1esk47nKrY0mvQpZIhRjQ==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "a-sync-waterfall": "^1.0.0", + "asap": "^2.0.3", + "commander": "^5.1.0" + }, + "bin": { + "nunjucks-precompile": "bin/precompile" + }, + "engines": { + "node": ">= 6.9.0" + }, + "peerDependencies": { + "chokidar": "^3.3.0" + }, + "peerDependenciesMeta": { + "chokidar": { + "optional": true + } + } + }, + "node_modules/nunjucks/node_modules/commander": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz", + "integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "dev": true, + "license": "MIT", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/parse-srcset": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/parse-srcset/-/parse-srcset-1.0.2.tgz", + "integrity": "sha512-/2qh0lav6CmI15FzA3i/2Bzk2zCgQhGMkvhOhKNcBVQ1ldgpbfiNTVslmooUmWJcADi1f1kIeynbDRVzNlfR6Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/picomatch": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", + "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/please-upgrade-node": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/please-upgrade-node/-/please-upgrade-node-3.2.0.tgz", + "integrity": "sha512-gQR3WpIgNIKwBMVLkpMUeR3e1/E1y42bqDQZfql+kDeXd8COYfM8PQA4X6y7a8u9Ua9FHmsrrmirW2vHs45hWg==", + "dev": true, + "license": "MIT", + "dependencies": { + "semver-compare": "^1.0.0" + } + }, + "node_modules/posthtml": { + "version": "0.16.7", + "resolved": "https://registry.npmjs.org/posthtml/-/posthtml-0.16.7.tgz", + "integrity": "sha512-7Hc+IvlQ7hlaIfQFZnxlRl0jnpWq2qwibORBhQYIb0QbNtuicc5ZxvKkVT71HJ4Py1wSZ/3VR1r8LfkCtoCzhw==", + "dev": true, + "license": "MIT", + "dependencies": { + "posthtml-parser": "^0.11.0", + "posthtml-render": "^3.0.0" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/posthtml-match-helper": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/posthtml-match-helper/-/posthtml-match-helper-2.0.3.tgz", + "integrity": "sha512-p9oJgTdMF2dyd7WE54QI1LvpBIkNkbSiiECKezNnDVYhGhD1AaOnAkw0Uh0y5TW+OHO8iBdSqnd8Wkpb6iUqmw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "posthtml": "^0.16.6" + } + }, + "node_modules/posthtml-parser": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/posthtml-parser/-/posthtml-parser-0.11.0.tgz", + "integrity": "sha512-QecJtfLekJbWVo/dMAA+OSwY79wpRmbqS5TeXvXSX+f0c6pW4/SE6inzZ2qkU7oAMCPqIDkZDvd/bQsSFUnKyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "htmlparser2": "^7.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/posthtml-render": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/posthtml-render/-/posthtml-render-3.0.0.tgz", + "integrity": "sha512-z+16RoxK3fUPgwaIgH9NGnK1HKY9XIDpydky5eQGgAFVXTCSezalv9U2jQuNV+Z9qV1fDWNzldcw4eK0SSbqKA==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-json": "^2.0.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/prr": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", + "integrity": "sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==", + "dev": true, + "license": "MIT" + }, + "node_modules/punycode.js": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode.js/-/punycode.js-2.3.1.tgz", + "integrity": "sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/readdirp/node_modules/picomatch": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz", + "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/section-matter": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/section-matter/-/section-matter-1.0.0.tgz", + "integrity": "sha512-vfD3pmTzGpufjScBh50YHKzEu2lxBWhVEHsNGoEXmCmn2hKGfeNLYMzCJpe8cD7gqX7TJluOVpBkAequ6dgMmA==", + "dev": true, + "license": "MIT", + "dependencies": { + "extend-shallow": "^2.0.1", + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/semver": { + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.0.tgz", + "integrity": "sha512-AcM7dV/5ul4EekoQ29Agm5vri8JNqRyj39o0qpX6vDF2GZrtutZl5RwgD1XnZjiTAfncsJhMI48QQH3sN87YNA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/semver-compare": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz", + "integrity": "sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow==", + "dev": true, + "license": "MIT" + }, + "node_modules/send": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/send/-/send-1.2.1.tgz", + "integrity": "sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^4.4.3", + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "etag": "^1.8.1", + "fresh": "^2.0.0", + "http-errors": "^2.0.1", + "mime-types": "^3.0.2", + "ms": "^2.1.3", + "on-finished": "^2.4.1", + "range-parser": "^1.2.1", + "statuses": "^2.0.2" + }, + "engines": { + "node": ">= 18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", + "dev": true, + "license": "ISC" + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/slugify": { + "version": "1.6.9", + "resolved": "https://registry.npmjs.org/slugify/-/slugify-1.6.9.tgz", + "integrity": "sha512-vZ7rfeehZui7wQs438JXBckYLkIIdfHOXsaVEUMyS5fHo1483l1bMdo0EDSWYclY0yZKFOipDy4KHuKs6ssvdg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/ssri": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-11.0.0.tgz", + "integrity": "sha512-aZpUoMN/Jj2MqA4vMCeiKGnc/8SuSyHbGSBdgFbZxP8OJGF/lFkIuElzPxsN0q8TQQ+prw3P4EDfB3TBHHgfXw==", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^7.0.3" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/statuses": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz", + "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/strip-bom-string": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-bom-string/-/strip-bom-string-1.0.0.tgz", + "integrity": "sha512-uCC2VHvQRYu+lMh4My/sFNmF2klFymLX1wHJeXnbEJERpV/ZsVuonzerjfrGpIGF7LBVa1O7i9kjiWvJiFck8g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/tinyglobby": { + "version": "0.2.16", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.16.tgz", + "integrity": "sha512-pn99VhoACYR8nFHhxqix+uvsbXineAasWm5ojXoN8xEwK5Kd3/TrhNn1wByuD52UxWRLy8pu+kRMniEi6Eq9Zg==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.4" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/uc.micro": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-2.1.0.tgz", + "integrity": "sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==", + "dev": true, + "license": "MIT" + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/urlpattern-polyfill": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/urlpattern-polyfill/-/urlpattern-polyfill-10.1.0.tgz", + "integrity": "sha512-IGjKp/o0NL3Bso1PymYURCJxMPNAf/ILOpendP9f5B6e1rTJgdgiOvgfoT8VxCAdY+Wisb9uhGaJJf3yZ2V9nw==", + "dev": true, + "license": "MIT" + }, + "node_modules/ws": { + "version": "8.20.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.20.1.tgz", + "integrity": "sha512-It4dO0K5v//JtTXuPkfEOaI3uUN87iYPnqo/ZzqCoG3g8uhA66QUMs/SrM0YK7/NAu+r4LMh/9dq2A7k+rHs+w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..3440993 --- /dev/null +++ b/package.json @@ -0,0 +1,12 @@ +{ + "name": "novapay", + "version": "1.0.0", + "description": "NovaPay - Modern Financial Platform (11ty)", + "scripts": { + "start": "eleventy --serve --input=src --output=_site", + "build": "eleventy --input=src --output=_site" + }, + "devDependencies": { + "@11ty/eleventy": "^3.0.0" + } +} \ No newline at end of file diff --git a/src/_data/app.json b/src/_data/app.json new file mode 100644 index 0000000..e51222f --- /dev/null +++ b/src/_data/app.json @@ -0,0 +1,7 @@ +{ + "headerTag": "About me", + "title": "I am Marios Antonoudiou.", + "subtitle": "Product engineer with 10+ years of experience. Building AI-powered products that feel simple, useful, and ready for real users.", + "ctaText": "Arrange a call", + "ctaSubtext": "Athens, Greece · No obligations, just an honest conversation." +} diff --git a/src/_data/dashboard.json b/src/_data/dashboard.json new file mode 100644 index 0000000..a85f53e --- /dev/null +++ b/src/_data/dashboard.json @@ -0,0 +1,39 @@ +{ + "headerTag": "How it works", + "title": "From idea to launch", + "subtitle": "A proven process refined over 10+ years of building products. Clear milestones, weekly updates, no black boxes.", + "chartValue": "8 weeks", + "periods": { + "7d": "Week 1-2: Discovery & Architecture", + "1m": "Week 3-5: Core Development", + "3m": "Week 6-7: Feature Polish", + "1y": "Week 8: Launch & Handoff" + }, + "chartDays": ["W1", "W2", "W3", "W4", "W5", "W6", "W7", "W8"], + "chartHeights": ["20%", "35%", "50%", "65%", "75%", "85%", "92%", "100%"], + "chartHeightsToday": [20, 35, 50, 65, 75, 85, 92, 100], + "sideCards": { + "cashflow": { + "label": "Discovery & Design", + "value": "Week 1-2", + "change": "Requirements, UX wireframes, tech decisions", + "positive": true, + "allocations": [ + { "label": "Requirements", "pct": 40, "color": "var(--sky)" }, + { "label": "UX Design", "pct": 35, "color": "var(--sky2)" }, + { "label": "Architecture", "pct": 25, "color": "#8888F8" } + ] + }, + "transactions": { + "label": "Build & Ship", + "value": "Week 3-8", + "change": "Sprint-based development, weekly demos", + "positive": true, + "allocations": [ + { "label": "Development", "pct": 60, "color": "var(--sky)" }, + { "label": "Testing", "pct": 25, "color": "var(--green)" }, + { "label": "Deploy & Docs", "pct": 15, "color": "#8888F8" } + ] + } + } +} \ No newline at end of file diff --git a/src/_data/faq.json b/src/_data/faq.json new file mode 100644 index 0000000..b4f2d1f --- /dev/null +++ b/src/_data/faq.json @@ -0,0 +1,44 @@ +{ + "headerTag": "Got questions?", + "title": "Frequently asked", + "expandAll": "Expand all", + "collapseAll": "Collapse all", + "items": [ + { + "question": "What is a Discovery Sprint?", + "answer": "A 3-day paid intensive workshop (€500) where we deeply understand your product, define detailed requirements, and produce UX wireframes for your core flows. This is credited 100% toward the MVP Package if you decide to move forward — effectively making it free if we build together." + }, + { + "question": "What exactly do I get after 8 weeks?", + "answer": "A fully functional MVP ready to ship. This includes: the complete source code (yours, not licensed), deployed application, full documentation (setup guides, architecture, API reference), and 2 weeks of post-launch support to squash any bugs." + }, + { + "question": "What tech stack do you use?", + "answer": "I primarily use React/Next.js for web apps, Flutter/React Native for mobile, Appwrite as a backend (or custom Node.js when needed), TypeScript throughout, and deploy to Vercel, Netlify, or AWS depending on the project. If you have specific requirements, we discuss them during discovery." + }, + { + "question": "Do I really own the code?", + "answer": "100%. No licensing, no lock-in. You get full Git repository access with clean, commit-by-commit history. The code is yours to modify, host, and commercialize however you like — now and in the future." + }, + { + "question": "What if my project needs more than 8 weeks?", + "answer": "We scope honestly during discovery. Some MVPs genuinely need 10-12 weeks depending on complexity, integrations, or multi-platform requirements. If that's the case, I'll tell you upfront and we'll adjust the scope or timeline accordingly." + }, + { + "question": "Can you build both web and mobile?", + "answer": "Yes. I can build a web app, a mobile app, or both as part of a single MVP package. Multi-platform projects typically take 10-12 weeks and are priced accordingly." + }, + { + "question": "How does the process work?", + "answer": "It starts with a free discovery call where we discuss your idea. If we're a good fit, I send a detailed proposal. Then: Week 1-2 is discovery and architecture (requirements, UX wireframes, tech stack). Week 3-7 is sprint-based development with weekly demos. Week 8 is final polish, deployment, documentation handoff, and launch support." + }, + { + "question": "What about after launch?", + "answer": "2 weeks of bug-fix support are included. After that, I offer ongoing maintenance at an hourly rate — or you can bring in any developer since you own the code. Many clients start with me and add internal team members once the product is live." + }, + { + "question": "How do we communicate during the project?", + "answer": "Direct access to me — no project managers, no gatekeepers. You'll get a dedicated Slack channel, weekly video demos, and async updates. You can reach out anytime. I'm the only person working on your project, so there's no handoff friction." + } + ] +} \ No newline at end of file diff --git a/src/_data/features.json b/src/_data/features.json new file mode 100644 index 0000000..592298c --- /dev/null +++ b/src/_data/features.json @@ -0,0 +1,125 @@ +{ + "headerTag": "What you get", + "title": "Everything your MVP needs", + "subtitle": "From concept to launch in 8 weeks. Clean code, modern tech, full ownership.", + "features": [ + { + "icon": "", + "title": "Rapid MVP Delivery", + "description": "Ship in 8 weeks, not 8 months. Clear timeline, fixed scope, no surprises. Weekly progress updates so you're never in the dark.", + "pills": ["8 weeks", "Fixed scope", "Weekly updates"], + "panelLabel": "Timeline", + "panel": { + "stats": [ + { "label": "Discovery", "value": "2 weeks", "change": "Week 1-2", "positive": false }, + { "label": "Development", "value": "5 weeks", "change": "Week 3-7", "positive": false } + ], + "transactions": [ + { + "icon": "W1", + "iconBg": "#0A2030", + "iconColor": "#4A9EE8", + "name": "Discovery & Architecture", + "sub": "Requirements, UX, tech stack", + "amount": "Done", + "positive": true + }, + { + "icon": "W3", + "iconBg": "#0A1428", + "iconColor": "#7EC8F0", + "name": "Core Features MVP", + "sub": "User auth, dashboard, core flow", + "amount": "In progress", + "positive": false + }, + { + "icon": "W8", + "iconBg": "#101828", + "iconColor": "#8888F8", + "name": "Launch & Handoff", + "sub": "Deploy, docs, support", + "amount": "Pending", + "positive": false + } + ] + } + }, + { + "icon": "", + "title": "Modern Tech Stack", + "description": "React, Next.js, Flutter, TypeScript, Appwrite. The same tools used by top startups — scalable, maintainable, future-proof.", + "pills": ["React", "Next.js", "Flutter", "TypeScript"], + "panelLabel": "Tech", + "panel": { + "stats": [ + { "label": "Frontend", "value": "React/Next.js", "change": "Web apps", "positive": false }, + { "label": "Backend", "value": "Appwrite", "change": "Open source BaaS", "positive": true } + ], + "chartData": [60, 75, 50, 90, 65, 85, 70, 95], + "revenue": [ + { "label": "Web apps", "value": "65%", "pct": 65, "color": "var(--sky)" }, + { "label": "Mobile apps", "value": "25%", "pct": 25, "color": "var(--sky2)" }, + { "label": "Full-stack", "value": "10%", "pct": 10, "color": "#8888F8" } + ] + } + }, + { + "icon": "", + "title": "Full Code Ownership", + "description": "You own 100% of the code. No lock-in, no licensing fees. Clean, documented, production-ready — delivered to you after launch.", + "pills": ["Your code", "No lock-in", "Fully documented"], + "panelLabel": "Deliverables", + "panel": { + "stats": [ + { "label": "Source code", "value": "100%", "change": "Git repo access", "positive": true }, + { "label": "Documentation", "value": "Full", "change": "Setup guides included", "positive": true } + ], + "transactions": [ + { + "icon": "GC", + "iconBg": "#0A1830", + "iconColor": "#4A9EE8", + "name": "Git Repository", + "sub": "Full history, clean commits", + "amount": "Included", + "positive": true + }, + { + "icon": "DC", + "iconBg": "#0A1428", + "iconColor": "#7EC8F0", + "name": "Documentation", + "sub": "Setup, API, architecture", + "amount": "Included", + "positive": true + }, + { + "icon": "DB", + "iconBg": "#101828", + "iconColor": "#8888F8", + "name": "Deploy Ready", + "sub": "Vercel, Netlify, AWS", + "amount": "Included", + "positive": true + } + ] + } + }, + { + "icon": "", + "title": "Product Engineering", + "description": "Not just coding. I help validate your idea, design the UX, and ship a product your users actually want to use. Senior-level execution, end-to-end.", + "pills": ["UX Design", "Idea validation", "End-to-end"], + "panelLabel": "Approach", + "panel": { + "badges": [ + { "icon": "", "name": "UX Research", "status": "Included" }, + { "icon": "", "name": "Rapid Prototyping", "status": "Included" }, + { "icon": "", "name": "Quality Code", "status": "Included" }, + { "icon": "", "name": "Direct Accountability", "status": "Direct contact" } + ] + } + } + ] +} \ No newline at end of file diff --git a/src/_data/hero.json b/src/_data/hero.json new file mode 100644 index 0000000..6ddc40d --- /dev/null +++ b/src/_data/hero.json @@ -0,0 +1,70 @@ +{ + "badge": "Currently accepting projects", + "headline": "Validate your idea in 8 weeks", + "headlineHighlight": "8 weeks", + "subtitle": "Product engineer with 10+ years of experience. Full code ownership. Modern tech. Ship your MVP fast.", + "primaryBtn": "Book a call", + "primaryBtnIcon": "", + "secondaryBtn": "See the process", + "trustAvatars": ["MS", "KL", "RP", "+"], + "trustCount": "10+", + "trustLabel": "MVPs delivered", + "floatBadges": [ + { + "icon": "", + "iconBg": "rgba(61,204,142,.12)", + "value": "8 weeks", + "label": "delivery time" + }, + { + "icon": "", + "iconBg": "rgba(74,158,232,.12)", + "value": "€6,000", + "label": "starting price" + } + ], + "dashboard": { + "dashTitle": "MVP SAAS", + "projectName": "AI Analytics Dashboard", + "projectStatus": "In Progress", + "milestone": "Week 5 of 8", + "progress": "62%", + "sent": "3", + "sentLabel": "milestones shipped", + "received": "€4,340", + "receivedChange": "+€740 this sprint", + "chartTitle": "Revenue — 30 days", + "chartBadge": "+12.4%", + "chartDays": ["W1", "W2", "W3", "W4", "W5", "W6", "W7", "W8"], + "chartHeights": ["15%", "30%", "45%", "55%", "62%", "75%", "88%", "100%"], + "transactions": [ + { + "icon": "DS", + "iconBg": "#0E2230", + "iconColor": "#4A9EE8", + "name": "User Auth & Onboarding", + "date": "Week 1-2", + "amount": "Complete", + "positive": true + }, + { + "icon": "BL", + "iconBg": "#1A1020", + "iconColor": "#A87EE8", + "name": "AI Insights Engine", + "date": "Week 3-5", + "amount": "In progress", + "positive": false + }, + { + "icon": "PD", + "iconBg": "#0A2030", + "iconColor": "#3DCC8E", + "name": "Stripe Billing", + "date": "Week 5-6", + "amount": "Next", + "positive": true + } + ] + } +} diff --git a/src/_data/logos.json b/src/_data/logos.json new file mode 100644 index 0000000..f743f65 --- /dev/null +++ b/src/_data/logos.json @@ -0,0 +1,4 @@ +{ + "label": "Technologies I build with", + "logos": ["React", "Next.js", "TypeScript", "Node.js", "Flutter", "React Native", "Appwrite", "AWS", "Docker", "Tailwind CSS", "Python", "Firebase"] +} \ No newline at end of file diff --git a/src/_data/navigation.json b/src/_data/navigation.json new file mode 100644 index 0000000..d1d2dd9 --- /dev/null +++ b/src/_data/navigation.json @@ -0,0 +1,16 @@ +{ + "logo": { + "mark": "" + }, + "links": [ + { "label": "Features", "href": "#features" }, + { "label": "Process", "href": "#dashboard" }, + { "label": "Pricing", "href": "#pricing" }, + { "label": "FAQ", "href": "#faq" } + ], + "cta": { + "signIn": "Contact", + "getStarted": "Start your MVP" + }, + "mobileCta": "Start your MVP" +} \ No newline at end of file diff --git a/src/_data/pricing.json b/src/_data/pricing.json new file mode 100644 index 0000000..b2d6d10 --- /dev/null +++ b/src/_data/pricing.json @@ -0,0 +1,52 @@ +{ + "headerTag": "Simple pricing", + "title": "Transparent, fixed price", + "subtitle": "No surprises. No hidden fees. One clear price for your entire MVP.", + "tiers": [ + { + "plan": "Discovery Sprint", + "price": "€500", + "featured": false, + "features": [ + "3-day intensive workshop", + "Understand your product end-to-end", + "Detailed scope & requirements", + "UX wireframes for core flows", + "Tech stack recommendations", + "Credited 100% toward MVP Package" + ], + "cta": "Book a sprint", + "note": "Applied as a credit if you move forward" + }, + { + "plan": "MVP Package", + "price": "€6,000", + "featured": true, + "badge": "Most popular", + "features": [ + "Delivered in 8 weeks", + "Web or mobile app", + "Full source code ownership", + "Appwrite backend (or custom)", + "Clean, documented code", + "2 weeks post-launch support", + "Deploy to production" + ], + "cta": "Start your MVP" + }, + { + "plan": "Custom Project", + "price": "Custom", + "featured": false, + "subLabel": "for larger scope", + "features": [ + "Everything in MVP Package", + "Web + mobile (both platforms)", + "Advanced features", + "Longer timeline", + "Ongoing maintenance available" + ], + "cta": "Get in touch" + } + ] +} \ No newline at end of file diff --git a/src/_data/security.json b/src/_data/security.json new file mode 100644 index 0000000..a0f1e92 --- /dev/null +++ b/src/_data/security.json @@ -0,0 +1,32 @@ +{ + "headerTag": "Quality guarantee", + "title": "Code you'll actually want to keep", + "subtitle": "Every project is built to production standards. Clean architecture, thorough testing, complete documentation — code that scales.", + "ctaText": "Book a discovery call", + "badges": [ + { + "icon": "", + "name": "Clean Architecture", + "desc": "Well-structured, maintainable code that's easy to onboard other developers to", + "status": "Every project" + }, + { + "icon": "", + "name": "Test Coverage", + "desc": "Unit and integration tests as standard. Your code works — and keeps working.", + "status": "Standard" + }, + { + "icon": "", + "name": "Full Documentation", + "desc": "Setup guides, architecture decisions, API reference. You can run this without me.", + "status": "Always included" + }, + { + "icon": "", + "name": "Post-Launch Support", + "desc": "2 weeks of bug fixes included after delivery. Ongoing maintenance available.", + "status": "2 weeks free" + } + ] +} \ No newline at end of file diff --git a/src/_data/site.json b/src/_data/site.json new file mode 100644 index 0000000..bf870ae --- /dev/null +++ b/src/_data/site.json @@ -0,0 +1,8 @@ +{ + "title": "BuildMVP — Ship your product in 8 weeks", + "name": "BuildMVP", + "description": "Product engineer with 10+ years of experience. Full code ownership. Modern tech. Ship your MVP fast.", + "url": "https://buildmvp.mariosant.dev", + "author": "Marios Antonoudiou", + "currentYear": 2026 +} \ No newline at end of file diff --git a/src/_data/stats.json b/src/_data/stats.json new file mode 100644 index 0000000..b5e676a --- /dev/null +++ b/src/_data/stats.json @@ -0,0 +1,50 @@ +[ + { + "icon": "", + "target": 50, + "suffix": "+", + "label": "MVPs delivered", + "barWidth": "85%", + "trend": { + "text": "+12 this year", + "icon": "", + "positive": true + } + }, + { + "icon": "", + "target": 10, + "suffix": "+", + "label": "Years experience", + "barWidth": "90%", + "trend": { + "text": "Senior-level expertise", + "icon": "", + "positive": true + } + }, + { + "icon": "", + "target": 8, + "suffix": " weeks", + "label": "Average delivery", + "barWidth": "75%", + "trend": { + "text": "Fixed timeline, no surprises", + "icon": "", + "positive": true + } + }, + { + "icon": "", + "target": 100, + "suffix": "%", + "label": "Code ownership", + "barWidth": "100%", + "trend": { + "text": "You own everything", + "icon": "", + "positive": true + } + } +] \ No newline at end of file diff --git a/src/_data/testimonials.json b/src/_data/testimonials.json new file mode 100644 index 0000000..e6cb067 --- /dev/null +++ b/src/_data/testimonials.json @@ -0,0 +1,42 @@ +{ + "headerTag": "What founders say", + "title": "Trusted by builders", + "testimonials": [ + { + "quote": "Mario delivered our MVP in exactly 8 weeks. The code was clean, well-documented, and our engineers could jump in immediately after handoff.", + "name": "Sarah Chen", + "role": "Founder at Relay", + "initials": "SC" + }, + { + "quote": "Finally found a developer who understands product, not just code. He challenged our assumptions in discovery and shipped something better than we imagined.", + "name": "James Okonkwo", + "role": "CEO at Kora", + "initials": "JO" + }, + { + "quote": "We interviewed 10 developers. Mario was the only one who asked about our users first, tech second. That alone told me he was the right choice.", + "name": "Elena Rodriguez", + "role": "Co-founder at Loop", + "initials": "ER" + }, + { + "quote": "The full code ownership was a game-changer. When we raised our seed, investors wanted to see our tech stack — and the code quality impressed them.", + "name": "David Park", + "role": "CTO at Meridian", + "initials": "DP" + }, + { + "quote": "Other agencies gave us timelines of 4-6 months. Mario shipped our MVP in 8 weeks at a fraction of the cost. No brainer.", + "name": "Aisha Patel", + "role": "Founder at Stash", + "initials": "AP" + }, + { + "quote": "I've worked with agencies and in-house teams. This was the smoothest project I've ever run. Weekly updates, clear milestones, delivered exactly on time.", + "name": "Michael Santos", + "role": "Product Lead at Vertex", + "initials": "MS" + } + ] +} \ No newline at end of file diff --git a/src/_includes/base.njk b/src/_includes/base.njk new file mode 100644 index 0000000..5d00e67 --- /dev/null +++ b/src/_includes/base.njk @@ -0,0 +1,78 @@ + + + + + + + +{{ site.title }} + + + + + + + + + + + + + + + + + + + + + + + + +{{ content | safe }} + + + + \ No newline at end of file diff --git a/src/_includes/sections/app.njk b/src/_includes/sections/app.njk new file mode 100644 index 0000000..a97ce91 --- /dev/null +++ b/src/_includes/sections/app.njk @@ -0,0 +1,24 @@ + +
+
+
+ +

{{ app.title }}

+

{{ app.subtitle }}

+
+ + {{ app.ctaText }} + + + {{ app.ctaSubtext }} +
+
+
+ Marios Antonoudiou +
+
10+ years building products
+
AI Product Engineer
+
+
+
+
\ No newline at end of file diff --git a/src/_includes/sections/dashboard.njk b/src/_includes/sections/dashboard.njk new file mode 100644 index 0000000..8f26db6 --- /dev/null +++ b/src/_includes/sections/dashboard.njk @@ -0,0 +1,83 @@ + +
+
+
+ +

{{ dashboard.title }}

+

{{ dashboard.subtitle }}

+
+
+
+
Portfolio overview
+
+
Live data
+
+ + + + +
+
+
+
+
+
+
+
{{ dashboard.chartValue }}
+
{{ dashboard.periods['7d'] }}
+
+
+
+
+
+
+
+
+
+
+
+
+ Mon + Tue + Wed + Thu + Fri + Sat + Today +
+
+
+
+
{{ dashboard.sideCards.cashflow.label }}
+
{{ dashboard.sideCards.cashflow.value }}
+
{{ dashboard.sideCards.cashflow.change }}
+
+ {% for alloc in dashboard.sideCards.cashflow.allocations %} +
+
+
{{ alloc.label }}
+
+
{{ alloc.pct }}%
+
+ {% endfor %} +
+
+
+
{{ dashboard.sideCards.transactions.label }}
+
{{ dashboard.sideCards.transactions.value }}
+
{{ dashboard.sideCards.transactions.change }}
+
+ {% for alloc in dashboard.sideCards.transactions.allocations %} +
+
+
{{ alloc.label }}
+
{{ alloc.pct }}%
+
+ {% endfor %} +
+
+
+
+
+
+
\ No newline at end of file diff --git a/src/_includes/sections/faq.njk b/src/_includes/sections/faq.njk new file mode 100644 index 0000000..ffa742d --- /dev/null +++ b/src/_includes/sections/faq.njk @@ -0,0 +1,22 @@ +
+
+
+
+ +

{{ faq.title }}

+
+ +
+
+ {% for item in faq.items %} +
+
{{ item.question }}
+
{{ item.answer }}
+
+ {% endfor %} +
+
+
\ No newline at end of file diff --git a/src/_includes/sections/features.njk b/src/_includes/sections/features.njk new file mode 100644 index 0000000..6a93ceb --- /dev/null +++ b/src/_includes/sections/features.njk @@ -0,0 +1,141 @@ + +
+
+ +

{{ features.title }}

+

{{ features.subtitle }}

+
+
+
+ + {% for feature in features.features %} + {% if loop.first %} +
+ {% else %} +
+ {% endif %} +
+ {{ feature.icon | safe }} +
+

{{ feature.title }}

+

{{ feature.description }}

+
+ {% for pill in feature.pills %} + {{ pill }} + {% endfor %} +
+
+ {% endfor %} + +
+ +
+
+
+
+ + + +
+ {{ features.features[0].panelLabel }} +
+
+ + {% for feature in features.features %} + {% if loop.first %} +
+ {% else %} +
+ {% endif %} + + {% if feature.panel.stats %} +
+ {% for stat in feature.panel.stats %} +
+
{{ stat.label }}
+
{{ stat.value }}
+ {% if stat.positive %} +
{{ stat.change }}
+ {% else %} +
{{ stat.change }}
+ {% endif %} +
+ {% endfor %} +
+ {% endif %} + + {% if feature.panel.transactions %} +
+ {% for tx in feature.panel.transactions %} +
+
{{ tx.icon }}
+
+
{{ tx.name }}
+
{{ tx.sub }}
+
+ {% if tx.positive %} +
{{ tx.amount }}
+ {% else %} +
{{ tx.amount }}
+ {% endif %} +
+ {% endfor %} +
+ {% endif %} + + {% if feature.panel.chartData %} +
+
Volume trend — 8 weeks
+
+
+ {% endif %} + + {% if feature.panel.revenue %} +
+ {% for rev in feature.panel.revenue %} +
+
+ {{ rev.label }} + {{ rev.value }} +
+
+
+ {% endfor %} +
+ {% endif %} + + {% if feature.panel.currencies %} +
+ {% for cur in feature.panel.currencies %} +
+
{{ cur.flag }}
+
+
{{ cur.name }}
+
{{ cur.sub }}
+
+
{{ cur.amount }}
+
+ {% endfor %} +
+ {% endif %} + + {% if feature.panel.badges %} +
+ {% for badge in feature.panel.badges %} +
+ {{ badge.icon | safe }} +
{{ badge.name }}
+
{{ badge.status }}
+
+ {% endfor %} +
+ {% endif %} + +
+ {% endfor %} + +
+
+
+
+
\ No newline at end of file diff --git a/src/_includes/sections/footer.njk b/src/_includes/sections/footer.njk new file mode 100644 index 0000000..061be32 --- /dev/null +++ b/src/_includes/sections/footer.njk @@ -0,0 +1,11 @@ + + \ No newline at end of file diff --git a/src/_includes/sections/hero.njk b/src/_includes/sections/hero.njk new file mode 100644 index 0000000..efeb639 --- /dev/null +++ b/src/_includes/sections/hero.njk @@ -0,0 +1,116 @@ + +
+
+
+ + {{ hero.badge }} +
+

{{ hero.headline }}

+

{{ hero.subtitle }}

+ +
+
+ {% for avatar in hero.trustAvatars %} + {{ avatar }} + {% endfor %} +
+

{{ hero.trustCount }} {{ hero.trustLabel }}

+
+
+
+
+
+ {{ hero.floatBadges[0].icon | safe }} +
+
+
{{ hero.floatBadges[0].value }}
+
{{ hero.floatBadges[0].label }}
+
+
+
+
+ {{ hero.floatBadges[1].icon | safe }} +
+
+
{{ hero.floatBadges[1].value }}
+
{{ hero.floatBadges[1].label }}
+
+
+
+
+
+ + + +
+ {{ hero.dashboard.dashTitle }} + ● Live +
+
+
+
+
Balance
+
{{ hero.dashboard.balance }}
+
{{ hero.dashboard.balanceChange }}
+
+
+
Sent
+
{{ hero.dashboard.sent }}
+
{{ hero.dashboard.sentLabel }}
+
+
+
Received
+
{{ hero.dashboard.received }}
+
{{ hero.dashboard.receivedChange }}
+
+
+
+
+ {{ hero.dashboard.chartTitle }} + {{ hero.dashboard.chartBadge }} +
+
+
+
+
+
+
+
+
+
+
+ Mon + Tue + Wed + Thu + Fri + Sat + Today +
+
+
+ {% for tx in hero.dashboard.transactions %} +
+
{{ tx.icon }}
+
+
{{ tx.name }}
+
{{ tx.date }}
+
+ {% if tx.positive %} +
{{ tx.amount }}
+ {% else %} +
{{ tx.amount }}
+ {% endif %} +
+ {% endfor %} +
+
+
+
+
diff --git a/src/_includes/sections/logos.njk b/src/_includes/sections/logos.njk new file mode 100644 index 0000000..3673fb8 --- /dev/null +++ b/src/_includes/sections/logos.njk @@ -0,0 +1,7 @@ + +
+
{{ logos.label }}
+
+
+
+
\ No newline at end of file diff --git a/src/_includes/sections/mobile-menu.njk b/src/_includes/sections/mobile-menu.njk new file mode 100644 index 0000000..e0e0bf5 --- /dev/null +++ b/src/_includes/sections/mobile-menu.njk @@ -0,0 +1,10 @@ + +
+ {% for link in navigation.links %} + {{ link.label }} + {% endfor %} + +
\ No newline at end of file diff --git a/src/_includes/sections/nav.njk b/src/_includes/sections/nav.njk new file mode 100644 index 0000000..17125c4 --- /dev/null +++ b/src/_includes/sections/nav.njk @@ -0,0 +1,21 @@ + + \ No newline at end of file diff --git a/src/_includes/sections/pricing.njk b/src/_includes/sections/pricing.njk new file mode 100644 index 0000000..917f70f --- /dev/null +++ b/src/_includes/sections/pricing.njk @@ -0,0 +1,40 @@ + +
+
+ +

{{ pricing.title }}

+

{{ pricing.subtitle }}

+
+
+ {% for tier in pricing.tiers %} + {% if tier.featured %} + +
diff --git a/src/_includes/sections/security.njk b/src/_includes/sections/security.njk new file mode 100644 index 0000000..0029e64 --- /dev/null +++ b/src/_includes/sections/security.njk @@ -0,0 +1,21 @@ + +
+
+
+ +

{{ security.title }}

+

{{ security.subtitle }}

+ {{ security.ctaText }} +
+
+ {% for badge in security.badges %} +
+
{{ badge.icon | safe }}
+
{{ badge.name }}
+
{{ badge.desc }}
+
{{ badge.status }}
+
+ {% endfor %} +
+
+
\ No newline at end of file diff --git a/src/_includes/sections/stats.njk b/src/_includes/sections/stats.njk new file mode 100644 index 0000000..3ec423f --- /dev/null +++ b/src/_includes/sections/stats.njk @@ -0,0 +1,17 @@ + +
+ {% for stat in stats %} +
+
+ {{ stat.icon | safe }} +
+
{{ stat.prefix | default('') }}0{{ stat.suffix | default('') }}
+
{{ stat.label }}
+
+
+ {{ stat.trend.icon | safe }} + {{ stat.trend.text }} +
+
+ {% endfor %} +
\ No newline at end of file diff --git a/src/_includes/sections/testimonials.njk b/src/_includes/sections/testimonials.njk new file mode 100644 index 0000000..306a652 --- /dev/null +++ b/src/_includes/sections/testimonials.njk @@ -0,0 +1,33 @@ +
+
+ +

{{ testimonials.title }}

+
+
+
+ {% for t in testimonials.testimonials %} +
+
+ {% for i in range(5) %} + + {% endfor %} +
+

"{{ t.quote }}"

+
+
{{ t.initials }}
+
+
{{ t.name }}
+
{{ t.role }}
+
+
+
+ {% endfor %} +
+
+
+ +
+
\ No newline at end of file diff --git a/src/_includes/sections/ticker.njk b/src/_includes/sections/ticker.njk new file mode 100644 index 0000000..ee2ffda --- /dev/null +++ b/src/_includes/sections/ticker.njk @@ -0,0 +1,4 @@ + +
+
+
\ No newline at end of file diff --git a/src/css/style.css b/src/css/style.css new file mode 100644 index 0000000..99b27fb --- /dev/null +++ b/src/css/style.css @@ -0,0 +1,1173 @@ +/* +================================================================================ + BuildMVP Stylesheet + Designed by Marios Antonoudiou +================================================================================ +*/ + +*,*::before,*::after{box-sizing:border-box;margin:0;padding:0} +:root{ + --bg:#0F1319; + --bg2:#141920; + --bg3:#1A2130; + --bg4:#1E2838; + --sky:#4A9EE8; + --sky2:#7EC8F0; + --sky3:#2A6AAA; + --sky4:#0D2A44; + --text:#E4EEF8; + --text2:#8AAEC8; + --text3:#506070; + --border:#1E3050; + --border2:#2A4060; + --green:#3DCC8E; + --red:#E85A5A; + --nav-h:68px; + --silk:cubic-bezier(0.16,1,0.3,1); + --silk-fast:cubic-bezier(0.25,1,0.4,1); + --max-w:1280px; +} +html{scroll-behavior:smooth} +body{ + background:var(--bg); + color:var(--text); + font-family:'DM Sans',sans-serif; + font-size:16px; + line-height:1.6; + overflow-x:hidden; +} + +/* TICKER */ +.ticker{ + background:var(--bg2); + border-bottom:1px solid var(--border); + height:36px; + overflow:hidden; + display:flex; + align-items:center; + width:100%; + max-width:100%; +} +.ticker:hover .ticker-track{animation-play-state:paused} +.ticker-track{ + display:flex; + gap:0; + animation:ticker-scroll 30s linear infinite; + white-space:nowrap; + will-change:transform; + flex-shrink:0; +} +.ticker-item{ + display:inline-flex; + align-items:center; + gap:8px; + padding:0 28px; + font-size:12px; + font-weight:500; + letter-spacing:.04em; + border-right:1px solid var(--border); +} +.ticker-sym{color:var(--text2)} +.ticker-price{color:var(--text)} +.ticker-up{color:var(--green)} +.ticker-dn{color:var(--red)} +@keyframes ticker-scroll{from{transform:translateX(0)}to{transform:translateX(-50%)}} +/* NAV */ +nav{ + position:fixed; + top:0; + left:0; + right:0; + z-index:100; + height:var(--nav-h); + display:flex; + align-items:center; + padding:0 max(48px, calc((100vw - var(--max-w)) / 2)); + border-bottom:1px solid transparent; + transform:translateY(36px); + transition:background .6s var(--silk),border-color .6s var(--silk),transform .5s var(--silk); +} +nav > *{position:relative} +nav.scrolled{background:rgba(15,19,25,.95);backdrop-filter:blur(20px);border-color:var(--border);transform:translateY(0)} +.nav-logo{ + font-family:'Outfit',sans-serif; + font-size:22px; + font-weight:800; + color:var(--text); + letter-spacing:-.02em; + text-decoration:none; + display:flex; + align-items:center; + gap:8px; +} +.nav-logo-mark{ + width:30px;height:30px; + background:var(--sky); + border-radius:8px; + display:flex;align-items:center;justify-content:center; +} +.nav-logo-mark svg{width:16px;height:16px;fill:none;stroke:#fff;stroke-width:2.5;stroke-linecap:round} +.nav-links{ + display:flex; + align-items:center; + gap:2px; + margin-left:auto; +} +.nav-links a{ + color:var(--text2); + text-decoration:none; + font-size:14px; + font-weight:400; + padding:6px 14px; + border-radius:6px; + transition:color .4s var(--silk),background .4s var(--silk); + letter-spacing:.01em; +} +.nav-links a:hover{color:var(--text);background:rgba(255,255,255,.05)} +.nav-cta{ + margin-left:12px; + display:flex; + align-items:center; + gap:8px; +} +.btn-ghost{ + background:transparent; + border:1px solid var(--border2); + color:var(--text2); + font-family:'DM Sans',sans-serif; + font-size:14px; + font-weight:500; + padding:8px 18px; + border-radius:8px; + cursor:pointer; + transition:border-color .5s var(--silk),color .5s var(--silk); + text-decoration:none; +} +.btn-ghost:hover{border-color:var(--sky);color:var(--sky)} +.btn-primary{ + background:var(--sky); + border:1px solid var(--sky); + color:#0A1A2C; + font-family:'DM Sans',sans-serif; + font-size:14px; + font-weight:600; + padding:8px 20px; + border-radius:8px; + cursor:pointer; + transition:background .5s var(--silk),transform .4s var(--silk); + text-decoration:none; +} +.btn-primary:hover{background:var(--sky2);transform:translateY(-1px)} + +/* HAMBURGER */ +.hamburger{ + display:none; + flex-direction:column; + gap:5px; + cursor:pointer; + margin-left:auto; + padding:4px; + background:none; + border:none; +} +.hamburger span{ + display:block;width:22px;height:2px; + background:var(--text2); + border-radius:2px; + transition:all .3s; +} +.hamburger.open span:nth-child(1){transform:translateY(7px) rotate(45deg)} +.hamburger.open span:nth-child(2){opacity:0} +.hamburger.open span:nth-child(3){transform:translateY(-7px) rotate(-45deg)} + +/* MOBILE MENU */ +.mobile-menu{ + display:none; + position:fixed; + top:0;left:0;right:0;bottom:0; + background:var(--bg); + z-index:99; + flex-direction:column; + align-items:center; + justify-content:flex-start; + gap:4px; + padding:100px 24px 60px; + overflow-y:auto; + -webkit-overflow-scrolling:touch; + opacity:0; + pointer-events:none; + transition:opacity .3s; +} +.mobile-menu.open{opacity:1;pointer-events:all} +.mobile-menu a{ + font-family:'Outfit',sans-serif; + font-size:20px; + font-weight:600; + color:var(--text2); + text-decoration:none; + padding:8px 0; + transition:color .2s; + flex-shrink:0; +} +.mobile-menu a:hover{color:var(--sky)} +.mobile-menu .m-btns{ + display:flex;flex-direction:column;gap:10px;width:100%;max-width:260px;margin-top:20px; + flex-shrink:0; +} +.mobile-menu .btn-primary,.mobile-menu .btn-ghost{ + width:100%;text-align:center;padding:12px;font-size:14px; +} + +/* HERO */ +.hero{ + min-height:100vh; + padding-top:calc(36px + var(--nav-h) + 60px); + padding-bottom:80px; + padding-left:max(48px, calc((100vw - var(--max-w)) / 2)); + padding-right:max(48px, calc((100vw - var(--max-w)) / 2)); + display:grid; + grid-template-columns:1fr 1fr; + gap:60px; + align-items:center; + position:relative; + overflow:hidden; +} +.hero::before{ + content:''; + position:absolute; + top:0;left:0; + width:100%;height:100%; + background-image: + repeating-linear-gradient(45deg,transparent 0,transparent 119px,rgba(74,158,232,.35) 119px,rgba(74,158,232,.35) 120px), + repeating-linear-gradient(-45deg,transparent 0,transparent 119px,rgba(74,158,232,.35) 119px,rgba(74,158,232,.35) 120px); + -webkit-mask-image:radial-gradient(ellipse 100% 100% at 0% 0%,#000 0%,transparent 70%); + mask-image:radial-gradient(ellipse 100% 100% at 0% 0%,#000 0%,transparent 70%); + pointer-events:none; + z-index:0; +} +.hero::after{ + content:''; + position:absolute; + top:-200px;right:-200px; + width:600px;height:600px; + background:radial-gradient(circle,rgba(74,158,232,.08) 0%,transparent 70%); + pointer-events:none; + z-index:0; +} +.hero > *{position:relative;z-index:1} +.hero-badge{ + display:inline-flex; + align-items:center; + gap:8px; + background:rgba(74,158,232,.1); + border:1px solid rgba(74,158,232,.25); + color:var(--sky); + font-size:12px; + font-weight:500; + letter-spacing:.06em; + text-transform:uppercase; + padding:6px 14px; + border-radius:20px; + margin-bottom:24px; +} +.badge-dot{width:6px;height:6px;background:var(--sky);border-radius:50%;animation:pulse 2s infinite} +@keyframes pulse{0%,100%{opacity:1}50%{opacity:.4}} +.hero h1{ + font-family:'Outfit',sans-serif; + font-size:clamp(40px,5vw,68px); + font-weight:800; + line-height:1.05; + letter-spacing:-.03em; + color:var(--text); + margin-bottom:24px; +} +.hero h1 span{color:var(--sky)} +.hero-sub{ + font-size:17px; + color:var(--text2); + line-height:1.7; + max-width:460px; + margin-bottom:36px; + font-weight:300; +} +.hero-btns{ + display:flex; + align-items:center; + gap:12px; + flex-wrap:wrap; + margin-bottom:48px; +} +.btn-hero{ + background:var(--sky); + border:none; + color:#0A1A2C; + font-family:'DM Sans',sans-serif; + font-size:15px; + font-weight:600; + padding:14px 28px; + border-radius:10px; + cursor:pointer; + transition:background .6s var(--silk),transform .6s var(--silk),box-shadow .6s var(--silk); + text-decoration:none; + display:inline-flex; + align-items:center; + gap:8px; +} +.btn-hero:hover{background:var(--sky2);transform:translateY(-2px);box-shadow:0 12px 32px rgba(74,158,232,.25)} +.btn-hero svg{width:16px;height:16px;fill:none;stroke:currentColor;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;transition:transform .5s var(--silk)} +.btn-hero:hover svg{transform:translateX(3px)} +.btn-outline{ + background:transparent; + border:1px solid var(--border2); + color:var(--text); + font-family:'DM Sans',sans-serif; + font-size:15px; + font-weight:400; + padding:14px 28px; + border-radius:10px; + cursor:pointer; + transition:border-color .5s var(--silk),color .5s var(--silk); + text-decoration:none; +} +.btn-outline:hover{border-color:var(--sky);color:var(--sky)} +.hero-trust{ + display:flex; + align-items:center; + gap:12px; +} +.hero-avatars{display:flex} +.hero-avatars span{ + width:32px;height:32px; + border-radius:50%; + border:2px solid var(--bg); + background:var(--bg3); + display:flex;align-items:center;justify-content:center; + font-size:11px;font-weight:600; + color:var(--sky); + margin-right:-10px; +} +.hero-trust-text{ + font-size:13px; + color:var(--text2); + margin-left:18px; +} +.hero-trust-text strong{color:var(--text);font-weight:500} + +/* HERO DASHBOARD MOCKUP */ +.hero-visual{ + position:relative; +} +.dash-card{ + background:var(--bg2); + border:1px solid var(--border); + border-radius:16px; + overflow:hidden; + position:relative; +} +.dash-topbar{ + background:var(--bg3); + padding:14px 20px; + display:flex; + align-items:center; + justify-content:space-between; + border-bottom:1px solid var(--border); +} +.dash-dots{display:flex;gap:6px} +.dash-dots span{width:10px;height:10px;border-radius:50%} +.dash-title-bar{font-size:12px;color:var(--text3);font-weight:500;letter-spacing:.04em} +.dash-body{padding:20px} +.dash-stats{display:grid;grid-template-columns:repeat(3,1fr);gap:10px;margin-bottom:16px} +.dash-stat{ + background:var(--bg3); + border:1px solid var(--border); + border-radius:10px; + padding:12px 14px; +} +.dash-stat-label{font-size:10px;color:var(--text3);letter-spacing:.05em;text-transform:uppercase;margin-bottom:6px} +.dash-stat-val{font-family:'Outfit',sans-serif;font-size:18px;font-weight:700;color:var(--text)} +.dash-stat-change{font-size:10px;margin-top:2px} +.chart-wrap{ + background:var(--bg3); + border:1px solid var(--border); + border-radius:10px; + padding:14px; + margin-bottom:12px; +} +.chart-head{display:flex;justify-content:space-between;align-items:center;margin-bottom:12px} +.chart-head-title{font-size:12px;font-weight:500;color:var(--text2)} +.chart-badge{font-size:10px;background:rgba(61,204,142,.12);color:var(--green);border:1px solid rgba(61,204,142,.2);padding:2px 8px;border-radius:10px} +.tx-list{display:flex;flex-direction:column;gap:6px} +.tx-item{ + display:flex;align-items:center;gap:10px; + background:var(--bg3);border:1px solid var(--border); + border-radius:8px;padding:8px 12px; +} +.tx-icon{ + width:28px;height:28px;border-radius:7px; + display:flex;align-items:center;justify-content:center; + font-size:11px;font-weight:700; + flex-shrink:0; +} +.tx-info{flex:1} +.tx-name{font-size:12px;font-weight:500;color:var(--text)} +.tx-date{font-size:10px;color:var(--text3)} +.tx-amount{font-size:13px;font-weight:600} + +/* FLOAT BADGES */ +.float-badge{ + position:absolute; + background:var(--bg2); + border:1px solid var(--border2); + border-radius:12px; + padding:10px 16px; + display:flex;align-items:center;gap:10px; + animation:float 3s ease-in-out infinite; + z-index:2; +} +.float-badge:nth-child(2){animation-delay:1.5s} +.float-badge-icon{width:32px;height:32px;border-radius:8px;display:flex;align-items:center;justify-content:center;font-size:14px} +.float-badge-info .val{font-family:'Outfit',sans-serif;font-size:14px;font-weight:700;color:var(--text)} +.float-badge-info .lbl{font-size:10px;color:var(--text3)} +.fb-left{left:-60px;top:30%} +.fb-right{right:-50px;bottom:25%} +@keyframes float{0%,100%{transform:translateY(0)}50%{transform:translateY(-8px)}} + +/* LOGOS */ +.logos-section{ + padding:40px max(48px, calc((100vw - var(--max-w)) / 2)); + border-top:1px solid var(--border); + border-bottom:1px solid var(--border); + overflow:hidden; + max-width:100%; +} +.logos-label{ + text-align:center; + font-size:12px; + letter-spacing:.1em; + text-transform:uppercase; + color:var(--text3); + margin-bottom:24px; +} +.logos-track-wrap{overflow:hidden;position:relative;max-width:100%;width:100%} +.logos-track-wrap::before,.logos-track-wrap::after{ + content:''; + position:absolute;top:0;bottom:0;width:120px;z-index:2; + pointer-events:none; +} +.logos-track-wrap::before{left:0;background:linear-gradient(to right,var(--bg),transparent)} +.logos-track-wrap::after{right:0;background:linear-gradient(to left,var(--bg),transparent)} +.logos-track{ + display:flex;gap:0; + animation:ticker-scroll 22s linear infinite; + width:max-content; + will-change:transform; + flex-shrink:0; +} +.logo-item{ + padding:0 40px; + font-family:'Outfit',sans-serif; + font-size:15px; + font-weight:700; + color:var(--text3); + letter-spacing:.05em; + white-space:nowrap; + border-right:1px solid var(--border); + transition:color .2s; +} + +/* STATS */ +.stats-section{ + padding:60px max(48px, calc((100vw - var(--max-w)) / 2)); + display:grid; + grid-template-columns:repeat(4,1fr); + gap:16px; + background:var(--bg); +} +.stat-block{ + background:var(--bg2); + border:1px solid var(--border); + border-radius:16px; + padding:28px 24px; + position:relative; + overflow:hidden; + transition:border-color .6s var(--silk),transform .6s var(--silk),background .6s var(--silk); +} +.stat-block:hover{border-color:var(--border2);transform:translateY(-3px);background:var(--bg3)} +.stat-icon{ + width:38px;height:38px; + background:rgba(74,158,232,.1); + border:1px solid rgba(74,158,232,.15); + border-radius:10px; + display:flex;align-items:center;justify-content:center; + margin-bottom:16px; + position:relative; + transition:transform .6s var(--silk); +} +.stat-block:hover .stat-icon{transform:scale(1.08) rotate(-4deg)} +.stat-icon::before,.stat-icon::after{ + content:''; + position:absolute; + inset:-1px; + border-radius:10px; + border:1px solid var(--sky); + opacity:0; + pointer-events:none; +} +.stat-block:hover .stat-icon::before{ + animation:ring-pulse 1.4s var(--silk) infinite; +} +.stat-block:hover .stat-icon::after{ + animation:ring-pulse 1.4s var(--silk) infinite; + animation-delay:.7s; +} +@keyframes ring-pulse{ + 0%{opacity:.7;transform:scale(1)} + 100%{opacity:0;transform:scale(1.7)} +} +.stat-icon svg{width:18px;height:18px;fill:none;stroke:var(--sky);stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round} +.stat-num{ + font-family:'Outfit',sans-serif; + font-size:clamp(28px,3vw,42px); + font-weight:800; + color:var(--text); + letter-spacing:-.03em; + line-height:1; + margin-bottom:6px; +} +.stat-label{font-size:13px;color:var(--text3);font-weight:400;margin-bottom:14px} +.stat-bar-wrap{background:var(--bg3);border-radius:4px;height:4px;margin-bottom:8px} +.stat-bar{height:100%;border-radius:4px;background:var(--sky);transition:width 1.2s ease} +.stat-trend{ + display:flex;align-items:center;gap:5px; + font-size:11px;font-weight:600; +} +.stat-trend svg{width:12px;height:12px;fill:none;stroke:currentColor;stroke-width:2.5;stroke-linecap:round;stroke-linejoin:round} + +/* FEATURES STICKY STACK */ +.features-section{ + padding:100px max(48px, calc((100vw - var(--max-w)) / 2)); +} +.features-header{ + text-align:center; + max-width:600px; + margin:0 auto 80px; +} +.section-tag{ + display:inline-block; + font-size:11px; + font-weight:600; + letter-spacing:.12em; + text-transform:uppercase; + color:var(--sky); + margin-bottom:16px; +} +.section-title{ + font-family:'Outfit',sans-serif; + font-size:clamp(32px,4vw,48px); + font-weight:800; + letter-spacing:-.03em; + line-height:1.1; + margin-bottom:16px; +} +.section-sub{font-size:16px;color:var(--text2);font-weight:300;line-height:1.7} + +.sticky-layout{ + display:grid; + grid-template-columns:1fr 1fr; + gap:80px; + align-items:start; +} +.sticky-cards{ + display:flex; + flex-direction:column; + gap:16px; +} +.sticky-card{ + background:var(--bg2); + border:1px solid var(--border); + border-radius:16px; + padding:28px; + cursor:pointer; + transition:border-color .6s var(--silk),background .6s var(--silk),transform .6s var(--silk); + position:relative; + overflow:hidden; +} +.sticky-card::before{ + content:''; + position:absolute; + left:0;top:0;bottom:0; + width:3px; + background:var(--sky); + opacity:0; + transition:opacity .5s var(--silk); +} +.sticky-card:hover{transform:translateX(4px)} +.sticky-card.active{border-color:var(--border2);background:var(--bg3)} +.sticky-card.active::before{opacity:1} +.sticky-card-icon{ + width:44px;height:44px; + background:rgba(74,158,232,.1); + border:1px solid rgba(74,158,232,.2); + border-radius:10px; + display:flex;align-items:center;justify-content:center; + margin-bottom:16px; + transition:background .3s; +} +.sticky-card.active .sticky-card-icon{background:rgba(74,158,232,.18)} +.sticky-card-icon svg{width:20px;height:20px;fill:none;stroke:var(--sky);stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round} +.sticky-card h3{ + font-family:'Outfit',sans-serif; + font-size:18px; + font-weight:700; + margin-bottom:8px; + color:var(--text); +} +.sticky-card p{font-size:14px;color:var(--text2);line-height:1.65;font-weight:300} +.sticky-card-pills{display:flex;gap:6px;margin-top:14px;flex-wrap:wrap} +.sc-pill{ + font-size:11px;font-weight:500; + padding:3px 10px;border-radius:20px; + background:rgba(74,158,232,.08); + border:1px solid rgba(74,158,232,.15); + color:var(--sky2); +} + +/* STICKY PANEL */ +.sticky-panel-wrap{ + position:sticky; + top:calc(36px + var(--nav-h) + 32px); +} +.sticky-panel{ + background:var(--bg2); + border:1px solid var(--border); + border-radius:20px; + overflow:hidden; + min-height:400px; +} +.panel-topbar{ + background:var(--bg3); + padding:14px 18px; + display:flex; + align-items:center; + gap:8px; + border-bottom:1px solid var(--border); +} +.panel-dots{display:flex;gap:5px} +.panel-dots span{width:9px;height:9px;border-radius:50%} +.panel-content{ + padding:24px; + min-height:360px; + display:flex; + flex-direction:column; + gap:14px; +} +.panel-view{display:none} +.panel-view.active{display:flex;flex-direction:column;gap:12px;animation:fadein .35s ease} +@keyframes fadein{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:translateY(0)}} + +/* panel mockups */ +.pm-row{display:flex;gap:10px} +.pm-card{ + flex:1; + background:var(--bg3); + border:1px solid var(--border); + border-radius:10px; + padding:14px; +} +.pm-label{font-size:10px;color:var(--text3);text-transform:uppercase;letter-spacing:.06em;margin-bottom:6px} +.pm-val{font-family:'Outfit',sans-serif;font-size:20px;font-weight:700;color:var(--text)} +.pm-change{font-size:11px;margin-top:3px} +.pm-bar-wrap{background:var(--bg);border-radius:6px;height:6px;margin-top:8px;overflow:hidden} +.pm-bar{height:100%;border-radius:6px;background:var(--sky)} +.pm-list{display:flex;flex-direction:column;gap:8px} +.pm-list-item{ + display:flex;align-items:center;gap:10px; + background:var(--bg3);border:1px solid var(--border); + border-radius:8px;padding:10px 12px; +} +.pm-list-icon{ + width:30px;height:30px;border-radius:7px; + display:flex;align-items:center;justify-content:center; + font-size:12px;font-weight:700;flex-shrink:0; +} +.pm-list-info{flex:1} +.pm-list-name{font-size:12px;font-weight:500} +.pm-list-sub{font-size:10px;color:var(--text3)} +.pm-list-amt{font-size:13px;font-weight:600} +.pm-chart-mini{ + background:var(--bg3);border:1px solid var(--border); + border-radius:10px;padding:14px; +} +.pm-sparkline{ + display:flex;align-items:flex-end;gap:4px;height:50px;margin-top:8px; +} +.pm-spark-bar{ + flex:1;background:rgba(74,158,232,.25);border-radius:3px 3px 0 0; + border-top:2px solid var(--sky); + transition:height .4s ease; +} +.pm-security-grid{display:grid;grid-template-columns:1fr 1fr;gap:8px} +.pm-sec-item{ + background:var(--bg3);border:1px solid var(--border); + border-radius:10px;padding:14px 12px; + display:flex;flex-direction:column;gap:6px; +} +.pm-sec-icon{font-size:20px} +.pm-sec-name{font-size:11px;font-weight:600;color:var(--text)} +.pm-sec-status{font-size:10px;color:var(--green)} + +/* DASHBOARD PREVIEW */ +.dashboard-section{ + padding:100px max(48px, calc((100vw - var(--max-w)) / 2)); + background:var(--bg2); + border-top:1px solid var(--border); + border-bottom:1px solid var(--border); +} +.dashboard-inner{max-width:900px;margin:0 auto} +.dashboard-preview{ + background:var(--bg); + border:1px solid var(--border); + border-radius:20px; + overflow:hidden; + margin-top:48px; +} +.dp-topbar{ + background:var(--bg2); + padding:16px 24px; + display:flex;align-items:center;justify-content:space-between; + border-bottom:1px solid var(--border); +} +.dp-title{font-family:'Outfit',sans-serif;font-size:14px;font-weight:700;color:var(--text)} +.dp-live{ + display:flex;align-items:center;gap:6px; + font-size:11px;color:var(--green);font-weight:500; +} +.dp-live-dot{width:6px;height:6px;background:var(--green);border-radius:50%;animation:pulse 1.5s infinite} +.dp-body{padding:24px;display:grid;grid-template-columns:2fr 1fr;gap:20px} +.dp-chart-area{ + background:var(--bg2);border:1px solid var(--border); + border-radius:12px;padding:20px; +} +.dp-chart-head{display:flex;justify-content:space-between;align-items:flex-start;margin-bottom:16px} +.dp-chart-val{font-family:'Outfit',sans-serif;font-size:28px;font-weight:800;color:var(--text)} +.dp-chart-change{font-size:12px;color:var(--green);margin-top:4px} +.dp-chart-period{display:flex;gap:4px} +.dp-period-btn{ + font-size:11px;padding:4px 10px;border-radius:5px; + background:transparent;border:1px solid var(--border); + color:var(--text3);cursor:pointer;font-family:'DM Sans',sans-serif; + transition:all .2s; +} +.dp-period-btn.active{background:var(--sky4);border-color:var(--sky3);color:var(--sky)} +.dp-side{display:flex;flex-direction:column;gap:12px} +.dp-side-card{ + background:var(--bg2);border:1px solid var(--border); + border-radius:12px;padding:16px; +} +.dp-side-label{font-size:10px;color:var(--text3);text-transform:uppercase;letter-spacing:.06em;margin-bottom:8px} +.dp-side-val{font-family:'Outfit',sans-serif;font-size:22px;font-weight:700;color:var(--text)} +.dp-side-change{font-size:11px;margin-top:4px} +.dp-allocations{margin-top:12px;display:flex;flex-direction:column;gap:8px} +.dp-alloc-row{display:flex;align-items:center;gap:10px} +.dp-alloc-dot{width:8px;height:8px;border-radius:50%;flex-shrink:0} +.dp-alloc-name{font-size:12px;color:var(--text2);flex:1} +.dp-alloc-pct{font-size:12px;font-weight:500;color:var(--text)} +.dp-alloc-bar-wrap{flex:1;background:var(--bg3);border-radius:3px;height:4px} +.dp-alloc-bar{height:100%;border-radius:3px} + +/* PRICING */ +.pricing-section{padding:100px max(48px, calc((100vw - var(--max-w)) / 2))} +.pricing-toggle-wrap{ + display:flex;align-items:center;justify-content:center; + gap:12px;margin-bottom:48px;margin-top:32px; +} +.toggle-label{font-size:14px;color:var(--text2)} +.toggle-switch{ + width:44px;height:24px;background:var(--bg3); + border:1px solid var(--border2);border-radius:12px; + cursor:pointer;position:relative;transition:background .2s; +} +.toggle-switch.on{background:var(--sky3)} +.toggle-knob{ + position:absolute;top:3px;left:3px; + width:16px;height:16px;background:var(--text2); + border-radius:50%;transition:transform .2s,background .2s; +} +.toggle-switch.on .toggle-knob{transform:translateX(20px);background:#fff} +.toggle-save{ + font-size:11px;font-weight:600; + background:rgba(61,204,142,.12); + color:var(--green); + border:1px solid rgba(61,204,142,.2); + padding:3px 10px;border-radius:20px; +} +.pricing-grid{ + display:grid; + grid-template-columns:repeat(3,1fr); + gap:16px; + max-width:960px; + margin:0 auto; +} +.price-card{ + background:var(--bg2); + border:1px solid var(--border); + border-radius:20px; + padding:32px 28px; + position:relative; + transition:border-color .6s var(--silk),transform .6s var(--silk),box-shadow .6s var(--silk); +} +.price-card:hover{border-color:var(--border2);transform:translateY(-4px);box-shadow:0 20px 48px rgba(0,0,0,.3)} +.price-card.featured{border-color:var(--sky3);background:var(--bg3)} +.featured-badge{ + position:absolute;top:-12px;left:50%;transform:translateX(-50%); + background:var(--sky); + color:#0A1A2C; + font-size:11px;font-weight:700; + padding:4px 16px;border-radius:20px; + white-space:nowrap;letter-spacing:.04em; +} +.price-plan{font-size:12px;font-weight:600;letter-spacing:.1em;text-transform:uppercase;color:var(--text2);margin-bottom:16px} +.price-amount{ + font-family:'Outfit',sans-serif; + font-size:42px;font-weight:800; + color:var(--text); + letter-spacing:-.03em; + line-height:1; + margin-bottom:4px; +} +.price-amount sup{font-size:20px;vertical-align:top;margin-top:8px;display:inline-block} +.price-period{font-size:13px;color:var(--text3);margin-bottom:24px} +.price-features{list-style:none;display:flex;flex-direction:column;gap:10px;margin-bottom:28px} +.price-features li{ + display:flex;align-items:center;gap:10px; + font-size:14px;color:var(--text2); +} +.price-features li svg{width:16px;height:16px;fill:none;stroke:var(--green);stroke-width:2.5;stroke-linecap:round;stroke-linejoin:round;flex-shrink:0} +.price-btn{ + width:100%; + padding:12px;border-radius:10px; + font-family:'DM Sans',sans-serif; + font-size:14px;font-weight:600; + cursor:pointer;transition:all .2s;border:none; + text-decoration:none; +} +.price-btn-ghost{ + background:transparent; + border:1px solid var(--border2); + color:var(--text); +} +.price-btn-ghost:hover{border-color:var(--sky);color:var(--sky)} +.price-btn-primary{background:var(--sky);color:#0A1A2C} +.price-btn-primary:hover{background:var(--sky2)} + +/* SECURITY */ +.security-section{ + padding:100px max(48px, calc((100vw - var(--max-w)) / 2)); + background:var(--bg2); + border-top:1px solid var(--border); +} +.security-inner{ + display:grid; + grid-template-columns:1fr 1fr; + gap:80px; + align-items:center; + max-width:1100px; + margin:0 auto; +} +.security-badges{display:grid;grid-template-columns:1fr 1fr;gap:12px} +.sec-badge{ + background:var(--bg); + border:1px solid var(--border); + border-radius:14px; + padding:20px; + display:flex;flex-direction:column;gap:8px; + transition:border-color .6s var(--silk),transform .6s var(--silk); +} +.sec-badge:hover{border-color:var(--border2);transform:translateY(-2px)} +.sec-badge-icon{ + width:40px;height:40px; + background:rgba(74,158,232,.1); + border:1px solid rgba(74,158,232,.2); + border-radius:10px; + display:flex;align-items:center;justify-content:center; +} +.sec-badge-icon svg{width:20px;height:20px;fill:none;stroke:var(--sky);stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round} +.sec-badge-name{font-size:14px;font-weight:600;color:var(--text)} +.sec-badge-desc{font-size:12px;color:var(--text3);line-height:1.5} +.sec-badge-status{ + display:inline-flex;align-items:center;gap:5px; + font-size:11px;color:var(--green);font-weight:500;margin-top:4px; +} +.sec-badge-status::before{content:'';width:5px;height:5px;background:var(--green);border-radius:50%} + +/* TESTIMONIALS */ +.testimonials-section{padding:100px max(48px, calc((100vw - var(--max-w)) / 2))} +.testi-track-wrap{overflow:hidden;margin-top:48px;position:relative;max-width:100%;width:100%} +.testi-track-wrap::before,.testi-track-wrap::after{ + content:'';position:absolute;top:0;bottom:0;width:80px;z-index:2;pointer-events:none; +} +.testi-track-wrap::before{left:0;background:linear-gradient(to right,var(--bg),transparent)} +.testi-track-wrap::after{right:0;background:linear-gradient(to left,var(--bg),transparent)} +.testi-track{ + display:flex;gap:16px; + animation:ticker-scroll 28s linear infinite; + width:max-content; + will-change:transform; + flex-shrink:0; +} +.testi-card{ + background:var(--bg2); + border:1px solid var(--border); + border-radius:16px; + padding:24px; + width:320px; + flex-shrink:0; +} +.testi-stars{display:flex;gap:3px;margin-bottom:14px} +.testi-stars svg{width:14px;height:14px;fill:var(--sky);stroke:none} +.testi-quote{font-size:14px;color:var(--text2);line-height:1.65;margin-bottom:16px;font-style:italic} +.testi-author{display:flex;align-items:center;gap:10px} +.testi-avatar{ + width:36px;height:36px;border-radius:50%; + background:var(--bg3);border:1px solid var(--border2); + display:flex;align-items:center;justify-content:center; + font-size:12px;font-weight:700;color:var(--sky); +} +.testi-name{font-size:13px;font-weight:600;color:var(--text)} +.testi-role{font-size:11px;color:var(--text3)} + +/* APP DOWNLOAD */ +.app-section{ + padding:100px max(48px, calc((100vw - var(--max-w)) / 2)); + background:var(--bg2); + border-top:1px solid var(--border); + border-bottom:1px solid var(--border); + position:relative; + overflow:hidden; +} +.app-section::before{ + content:''; + position:absolute; + bottom:0;right:0; + width:100%;height:100%; + background-image: + repeating-linear-gradient(45deg,transparent 0,transparent 119px,rgba(74,158,232,.35) 119px,rgba(74,158,232,.35) 120px), + repeating-linear-gradient(-45deg,transparent 0,transparent 119px,rgba(74,158,232,.35) 119px,rgba(74,158,232,.35) 120px); + -webkit-mask-image:radial-gradient(ellipse 100% 100% at 100% 100%,#000 0%,transparent 70%); + mask-image:radial-gradient(ellipse 100% 100% at 100% 100%,#000 0%,transparent 70%); + pointer-events:none; + z-index:0; +} +.app-section > *{position:relative;z-index:1} +.app-inner{ + display:grid;grid-template-columns:3fr 2fr; + gap:80px;align-items:center;max-width:1000px;margin:0 auto; +} +.app-btns{display:flex;gap:12px;flex-wrap:wrap;margin-top:28px} +.app-store-btn{ + display:flex;align-items:center;gap:12px; + background:var(--bg3);border:1px solid var(--border2); + border-radius:14px;padding:14px 26px; + text-decoration:none;transition:border-color .5s var(--silk),background .5s var(--silk); + min-width:200px; +} +.app-store-btn:hover{border-color:var(--sky);background:var(--bg4)} +.app-store-btn svg{fill:var(--text);flex-shrink:0} +.app-store-btn-info{display:flex;flex-direction:column} +.app-store-btn-sub{font-size:10px;color:var(--text3);letter-spacing:.02em} +.app-store-btn-name{font-size:16px;font-weight:700;color:var(--text);font-family:'Outfit',sans-serif;letter-spacing:-.01em} +.phone-mockup{ + width:220px; + margin:0 auto; + background:var(--bg3); + border:2px solid var(--border2); + border-radius:36px; + padding:20px 14px; + position:relative; +} +.phone-notch{ + width:70px;height:20px;background:var(--bg); + border-radius:0 0 12px 12px;margin:0 auto 16px; +} +.phone-screen{ + background:var(--bg); + border-radius:16px; + padding:16px; + min-height:320px; + display:flex;flex-direction:column;gap:10px; +} +.phone-header{ + display:flex;align-items:center;justify-content:space-between;margin-bottom:4px; +} +.phone-greeting{font-size:12px;color:var(--text3)} +.phone-name{font-size:14px;font-weight:700;color:var(--text);font-family:'Outfit',sans-serif} +.phone-balance{ + background:var(--bg3);border:1px solid var(--border); + border-radius:12px;padding:14px; +} +.phone-bal-label{font-size:9px;color:var(--text3);text-transform:uppercase;letter-spacing:.06em} +.phone-bal-val{font-family:'Outfit',sans-serif;font-size:22px;font-weight:800;color:var(--text);margin-top:4px} +.phone-bal-change{font-size:10px;color:var(--green);margin-top:2px} +.phone-quick{display:grid;grid-template-columns:repeat(3,1fr);gap:6px} +.phone-quick-btn{ + background:var(--bg3);border:1px solid var(--border); + border-radius:8px;padding:8px 4px;text-align:center; + font-size:9px;color:var(--text2); +} +.phone-quick-icon{font-size:16px;margin-bottom:3px} +.phone-chart-mini{ + background:var(--bg3);border:1px solid var(--border); + border-radius:8px;padding:10px; +} +.phone-spark{display:flex;align-items:flex-end;gap:3px;height:30px} +.phone-spark-bar{flex:1;background:rgba(74,158,232,.2);border-radius:2px 2px 0 0;border-top:1.5px solid var(--sky)} +.phone-qr{ + width:60px;height:60px; + background:var(--bg3);border:1px solid var(--border); + border-radius:8px;margin-top:12px; + display:flex;align-items:center;justify-content:center; + font-size:10px;color:var(--text3); +} + +/* FAQ */ +.faq-section{ + padding:100px max(48px, calc((100vw - var(--max-w)) / 2)); + position:relative; + overflow:hidden; +} +.faq-section::before{ + content:''; + position:absolute; + bottom:0;left:0; + width:140%;height:140%; + background-image: + repeating-linear-gradient(45deg,transparent 0,transparent 119px,rgba(74,158,232,.35) 119px,rgba(74,158,232,.35) 120px), + repeating-linear-gradient(-45deg,transparent 0,transparent 119px,rgba(74,158,232,.35) 119px,rgba(74,158,232,.35) 120px); + -webkit-mask-image:radial-gradient(ellipse 100% 100% at 0% 100%,#000 0%,transparent 70%); + mask-image:radial-gradient(ellipse 100% 100% at 0% 100%,#000 0%,transparent 70%); + pointer-events:none; + z-index:0; +} +.faq-section > *{position:relative;z-index:1} +.faq-inner{max-width:720px;margin:0 auto} +.faq-list{margin-top:48px;display:flex;flex-direction:column;gap:4px} +.faq-item{ + background:rgba(20,25,32,.4); + border:1px solid var(--border); + border-radius:12px; + overflow:hidden; + transition:border-color .5s var(--silk),background .5s var(--silk); +} +.faq-item.open{border-color:var(--border2);background:rgba(20,25,32,.65)} +.faq-q{ + display:flex;align-items:center;justify-content:space-between; + padding:20px 24px; + cursor:pointer; + gap:16px; +} +.faq-q-text{font-size:15px;font-weight:500;color:var(--text);transition:color .4s var(--silk)} +.faq-q:hover .faq-q-text{color:var(--sky)} +.faq-chevron{ + width:20px;height:20px;flex-shrink:0; + fill:none;stroke:var(--text3);stroke-width:2; + stroke-linecap:round;stroke-linejoin:round; + transition:transform .6s var(--silk),stroke .4s var(--silk); +} +.faq-item.open .faq-chevron{transform:rotate(180deg);stroke:var(--sky)} +.faq-a{ + max-height:0;overflow:hidden; + transition:max-height .6s var(--silk),padding .5s var(--silk); + font-size:14px;color:var(--text2);line-height:1.7; + padding:0 24px;font-weight:300; +} +.faq-item.open .faq-a{max-height:200px;padding-bottom:20px} + +/* FOOTER */ +footer{ + padding:40px max(48px, calc((100vw - var(--max-w)) / 2)) 28px; + border-top:1px solid var(--border); +} +.footer-grid{ + display:grid; + grid-template-columns:1fr 1fr; + gap:48px; + margin-bottom:28px; + align-items:start; +} +.footer-brand{max-width:300px} +.footer-logo{ + font-family:'Outfit',sans-serif; + font-size:20px;font-weight:800; + color:var(--text);margin-bottom:10px; + display:flex;align-items:center;gap:8px; +} +.footer-desc{font-size:13px;color:var(--text3);line-height:1.6;margin-bottom:14px} +.footer-newsletter{display:flex;gap:8px} +.footer-input{ + flex:1;background:var(--bg2); + border:1px solid var(--border); + border-radius:8px;padding:10px 14px; + color:var(--text);font-family:'DM Sans',sans-serif; + font-size:13px;outline:none; +} +.footer-input::placeholder{color:var(--text3)} +.footer-input:focus{border-color:var(--sky)} +.footer-sub-btn{ + background:var(--sky);border:none; + color:#0A1A2C;font-family:'DM Sans',sans-serif; + font-size:13px;font-weight:600; + padding:10px 16px;border-radius:8px;cursor:pointer; + white-space:nowrap;transition:background .2s; +} +.footer-sub-btn:hover{background:var(--sky2)} +.footer-col-title{font-size:12px;font-weight:600;letter-spacing:.08em;text-transform:uppercase;color:var(--text2);margin-bottom:16px} +.footer-links{list-style:none;display:flex;flex-direction:column;gap:10px} +.footer-links a{font-size:14px;color:var(--text3);text-decoration:none;transition:color .2s} +.footer-links a:hover{color:var(--sky)} +.footer-bottom{ + border-top:1px solid var(--border); + padding-top:20px; + display:flex;align-items:center;justify-content:space-between; +} +.footer-copy{font-size:13px;color:var(--text3)} +.footer-link{ + font-size:13px;color:var(--text3);text-decoration:none; + transition:color .4s var(--silk); +} +.footer-link:hover{color:var(--sky)} +.footer-socials{display:flex;gap:8px} +.social-btn{ + width:34px;height:34px;border-radius:8px; + background:var(--bg2);border:1px solid var(--border); + display:flex;align-items:center;justify-content:center; + text-decoration:none;transition:border-color .2s; +} +.social-btn:hover{border-color:var(--sky)} +.social-btn svg{width:16px;height:16px;fill:none;stroke:var(--text3);stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round} + +/* RESPONSIVE */ +@media(max-width:900px){ + nav{padding:0 24px} + .nav-links,.nav-cta{display:none} + .hamburger{display:flex} + .mobile-menu{display:flex} + .hero{grid-template-columns:1fr;padding:calc(36px + var(--nav-h) + 40px) 24px 60px;gap:40px} + .fb-left,.fb-right{display:none} + .stats-section{grid-template-columns:1fr 1fr} + .features-section,.pricing-section,.faq-section,.testimonials-section,.dashboard-section,.logos-section,.security-section,.app-section,.stats-section{padding:60px 24px} + footer{padding-left:24px !important;padding-right:24px !important} + .sticky-layout{grid-template-columns:1fr} + .sticky-panel-wrap{position:static} + .pricing-grid{grid-template-columns:1fr} + .security-inner{grid-template-columns:1fr;gap:40px} + .app-inner{grid-template-columns:1fr;gap:40px} + .footer-grid{grid-template-columns:1fr;gap:32px} + .footer-bottom{flex-direction:column;gap:16px;text-align:center} + .dp-body{grid-template-columns:1fr} +} +@media(max-width:600px){ + .stats-section{grid-template-columns:1fr} + .footer-grid{grid-template-columns:1fr} + .hero h1{font-size:36px} + .pricing-grid{gap:12px} +} diff --git a/src/images/favicon.svg b/src/images/favicon.svg new file mode 100644 index 0000000..65f0bdd --- /dev/null +++ b/src/images/favicon.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/src/index.njk b/src/index.njk new file mode 100644 index 0000000..cab9148 --- /dev/null +++ b/src/index.njk @@ -0,0 +1,16 @@ +--- +layout: base.njk +--- +{% include "sections/nav.njk" %} +{% include "sections/mobile-menu.njk" %} +{% include "sections/hero.njk" %} +{% include "sections/logos.njk" %} +{% include "sections/stats.njk" %} +{% include "sections/features.njk" %} +{% include "sections/dashboard.njk" %} +{% include "sections/pricing.njk" %} +{% include "sections/security.njk" %} +{% include "sections/testimonials.njk" %} +{% include "sections/app.njk" %} +{% include "sections/faq.njk" %} +{% include "sections/footer.njk" %} \ No newline at end of file diff --git a/src/js/script.js b/src/js/script.js new file mode 100644 index 0000000..5676400 --- /dev/null +++ b/src/js/script.js @@ -0,0 +1,135 @@ +const nav=document.getElementById('mainNav'); +window.addEventListener('scroll',()=>{ + nav.classList.toggle('scrolled',window.scrollY>10); +}); + +const hamburger=document.getElementById('hamburger'); +const mobileMenu=document.getElementById('mobileMenu'); +if(hamburger&&mobileMenu){ + let scrollY=0; + hamburger.addEventListener('click',()=>{ + const open=mobileMenu.classList.contains('open'); + if(open){ + mobileMenu.classList.remove('open'); + hamburger.classList.remove('open'); + hamburger.setAttribute('aria-expanded','false'); + document.body.style.position=''; + document.body.style.top=''; + window.scrollTo({top:scrollY,behavior:'instant'}); + } else { + scrollY=window.scrollY; + document.body.style.position='fixed'; + document.body.style.top=`-${scrollY}px`; + mobileMenu.classList.add('open'); + hamburger.classList.add('open'); + hamburger.setAttribute('aria-expanded','true'); + } + }); + mobileMenu.querySelectorAll('a').forEach(a=>{ + a.addEventListener('click',()=>{ + mobileMenu.classList.remove('open'); + hamburger.classList.remove('open'); + hamburger.setAttribute('aria-expanded','false'); + document.body.style.position=''; + document.body.style.top=''; + window.scrollTo({top:scrollY,behavior:'instant'}); + }); + }); +} + +const stickyCards=document.querySelectorAll('.sticky-card'); +const panelViews=document.querySelectorAll('.panel-view'); +const panelLabel=document.getElementById('panelLabel'); +const panelLabels=['Timeline','Tech','Deliverables','Approach']; +if(stickyCards.length&&panelViews.length){ + stickyCards.forEach((card,i)=>{ + card.addEventListener('click',()=>{ + stickyCards.forEach(c=>c.classList.remove('active')); + panelViews.forEach(p=>p.classList.remove('active')); + card.classList.add('active'); + document.getElementById('panel-'+i).classList.add('active'); + if(panelLabel)panelLabel.textContent=panelLabels[i]||''; + }); + }); + const observer=new IntersectionObserver((entries)=>{ + entries.forEach(e=>{ + if(e.isIntersecting){ + stickyCards.forEach((card,i)=>{ + const rect=card.getBoundingClientRect(); + const viewH=window.innerHeight; + if(rect.topviewH*0.3){ + stickyCards.forEach(c=>c.classList.remove('active')); + panelViews.forEach(p=>p.classList.remove('active')); + card.classList.add('active'); + document.getElementById('panel-'+i).classList.add('active'); + if(panelLabel)panelLabel.textContent=panelLabels[i]||''; + } + }); + } + }); + },{threshold:0.3}); + stickyCards.forEach(c=>observer.observe(c)); +} + +const statNums=document.querySelectorAll('.stat-num[data-target]'); +const statsObs=new IntersectionObserver((entries)=>{ + entries.forEach(e=>{ + if(e.isIntersecting){ + const el=e.target; + const target=parseFloat(el.dataset.target); + const suffix=el.dataset.suffix||''; + const decimal=parseInt(el.dataset.decimal)||0; + const prefix=el.dataset.prefix||''; + let start=0,duration=1800,startTime=null; + function animate(ts){ + if(!startTime)startTime=ts; + const progress=Math.min((ts-startTime)/duration,1); + const ease=1-Math.pow(1-progress,3); + const val=start+(target-start)*ease; + el.textContent=prefix+(decimal?val.toFixed(decimal):Math.round(val))+suffix; + if(progress<1)requestAnimationFrame(animate); + } + requestAnimationFrame(animate); + const bar=el.closest('.stat-block').querySelector('.stat-bar'); + if(bar){setTimeout(()=>{bar.style.width=bar.dataset.width;},200);} + statsObs.unobserve(el); + } + }); +},{threshold:0.5}); +statNums.forEach(el=>statsObs.observe(el)); + +document.querySelectorAll('.faq-item .faq-q').forEach(el => { + el.addEventListener('click', () => { + el.closest('.faq-item').classList.toggle('open'); + }); +}); + +window.toggleAllFaq = function() { + const faqList = document.querySelectorAll('.faq-item'); + let allExpanded = faqList[0] && faqList[0].classList.contains('open'); + faqList.forEach(el => { + allExpanded ? el.classList.remove('open') : el.classList.add('open'); + }); + document.getElementById('faqToggleLabel').textContent = allExpanded ? 'Expand all' : 'Collapse all'; + const icon = document.getElementById('faqToggleIcon'); + icon.innerHTML = allExpanded + ? '' + : ''; +}; + +const tt=document.getElementById('testiTrack'); +if(tt){ + window.toggleTestimonials=function(){ + tt.style.animationPlayState=tt.style.animationPlayState==='paused'?'running':'paused'; + }; +} + +document.querySelectorAll('a[href^="#"]').forEach(a=>{ + a.addEventListener('click',e=>{ + const href=a.getAttribute('href'); + if(href==='#')return; + e.preventDefault(); + const target=document.querySelector(href); + if(target)target.scrollIntoView({behavior:'smooth'}); + }); +}); \ No newline at end of file diff --git a/src/robots.njk b/src/robots.njk new file mode 100644 index 0000000..77d5dd7 --- /dev/null +++ b/src/robots.njk @@ -0,0 +1,7 @@ +--- +permalink: /robots.txt +--- +User-agent: * +Allow: / + +Sitemap: {{ site.url }}/sitemap.xml \ No newline at end of file diff --git a/src/sitemap.njk b/src/sitemap.njk new file mode 100644 index 0000000..ee936bc --- /dev/null +++ b/src/sitemap.njk @@ -0,0 +1,11 @@ +--- +permalink: /sitemap.xml +--- + + + + {{ site.url }}/ + weekly + 1.0 + + \ No newline at end of file