[
  {
    "path": ".editorconfig",
    "content": "# editorconfig.org\n\nroot = true\n\n[*]\ncharset = utf-8\nend_of_line = lf\ninsert_final_newline = true\nindent_size = 2\nindent_style = space\ntrim_trailing_whitespace = true\n\n[*.md]\ntrim_trailing_whitespace = false\n\n[*.{js,json,d.ts,ts}]\nindent_size = 4\n\n[Makefile]\nindent_style = tab\n"
  },
  {
    "path": ".eslintrc.json",
    "content": "{\n    \"root\": true,\n    \"parserOptions\": {\n        \"sourceType\": \"module\"\n    },\n    \"env\": {\n        \"browser\": true,\n        \"es2020\": true,\n        \"node\": true\n    },\n    \"extends\": [\n        \"eslint:recommended\"\n    ],\n    \"overrides\": [\n        {\n            \"files\": [\n                \"*.ts\"\n            ],\n            \"parser\": \"@typescript-eslint/parser\",\n            \"plugins\": [\n                \"@typescript-eslint\"\n            ],\n            \"extends\": [\n                \"eslint:recommended\",\n                \"plugin:@typescript-eslint/recommended\"\n            ]\n        }\n    ]\n}\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/bug_report.md",
    "content": "---\nname: Bug report\nabout: Create a report to help us improve\ntitle: ''\nlabels: ''\nassignees: ''\n\n---\n\nHello 👋\n\n**Describe the bug**\nA clear and concise description of what the bug is.\n\n**To Reproduce**\nSteps to reproduce the behavior:\n1. Go to '...'\n2. Click on '....'\n3. Scroll down to '....'\n4. See error\n\n**Expected behavior**\nA clear and concise description of what you expected to happen.\n\n**Screenshots**\nIf applicable, add screenshots to help explain your problem.\n\n**Desktop (please complete the following information):**\n - OS: [e.g. iOS]\n - Browser [e.g. chrome, safari]\n - Version [e.g. 22]\n\n**Smartphone (please complete the following information):**\n - Device: [e.g. iPhone6]\n - OS: [e.g. iOS8.1]\n - Browser [e.g. stock browser, safari]\n - Version [e.g. 22]\n\nThank you 👊\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/feature_request.md",
    "content": "---\nname: Feature request\nabout: Suggest an idea for this project\ntitle: ''\nlabels: ''\nassignees: ''\n\n---\n\n**Is your feature request related to a problem? Please describe.**\nA clear and concise description of what the problem is. Ex. I'm always frustrated when [...]\n\n**Describe the solution you'd like**\nA clear and concise description of what you want to happen.\n\n**Describe alternatives you've considered**\nA clear and concise description of any alternative solutions or features you've considered.\n\n**Additional context**\nAdd any other context or screenshots about the feature request here.\n"
  },
  {
    "path": ".gitignore",
    "content": "node_modules\n.DS_Store\nThumbs.db\n\n# Turborepo\n.turbo\n\n# Ignore nested folders: https://stackoverflow.com/questions/3203228/git-ignore-exception/72380673#72380673\n/tmp/*\n!/tmp/cjs\n/tmp/cjs/*\n!/tmp/dts\n/tmp/dts/*\n!/tmp/esm\n/tmp/esm/*\n!tmp/**/package.json\n!tmp/**/tsconfig.json\n\n# generated types\n.astro\n.docusaurus\n\n# logs\nnpm-debug.log*\nyarn-debug.log*\nyarn-error.log*\npnpm-debug.log*\n\n# environment variables\n.env\n.env.production\n\n# macOS-specific files\n.DS_Store\n\n# jetbrains setting folder\n.idea\n\n# packages build output\n!/www/demo\n/www/demo/*\n!/www/docs\n/www/docs/*\n"
  },
  {
    "path": ".nvmrc",
    "content": "v20.14\n"
  },
  {
    "path": ".prettierrc.json",
    "content": "{\n    \"printWidth\": 80,\n    \"tabWidth\": 4,\n    \"trailingComma\": \"es5\",\n    \"semi\": true,\n    \"singleQuote\": true\n}\n"
  },
  {
    "path": "LICENSE",
    "content": "MIT License\n\nCopyright (c) 2026 Locomotive Inc.\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "README.md",
    "content": "# Locomotive Scroll\n\n[![npm version](https://img.shields.io/npm/v/locomotive-scroll.svg)](https://www.npmjs.com/package/locomotive-scroll)\n[![npm downloads](https://img.shields.io/npm/dm/locomotive-scroll.svg)](https://www.npmjs.com/package/locomotive-scroll)\n[![bundle size](https://img.shields.io/bundlephobia/minzip/locomotive-scroll)](https://bundlephobia.com/package/locomotive-scroll)\n\nA **lightweight** & **modern** scroll library for detection, animation, and smooth scrolling. Built on top of [Lenis](https://github.com/darkroomengineering/lenis).\n\n## Documentation\n\nFull documentation available at [scroll.locomotive.ca/docs](https://scroll.locomotive.ca/docs).\n\n## Quick Start\n\n```bash\nnpm install locomotive-scroll\n```\n\n```js\nimport LocomotiveScroll from 'locomotive-scroll';\n\nconst scroll = new LocomotiveScroll();\n```\n\n```css\n@import 'locomotive-scroll/dist/locomotive-scroll.css';\n```\n\n```html\n<div data-scroll data-scroll-speed=\"0.5\">I move at half speed</div>\n```\n\n## Features\n\n-   **Lightweight** — Only 9.4kB gzipped\n-   **TypeScript First** — Fully typed\n-   **Built on Lenis** — Latest stable release with improved performance\n-   **Dual Intersection Observers** — Optimized detection for triggers vs. animations\n-   **Smart Touch Detection** — Parallax auto-disabled on mobile\n-   **Accessible** — Native scrollbar, keyboard navigation, proper ARIA support\n\n## Demo\n\nCheck out the [examples and playground](https://scroll.locomotive.ca/docs/examples)\n\n## Support\n\n[GitHub Issues](https://github.com/locomotivemtl/locomotive-scroll/issues)\n"
  },
  {
    "path": "context7.json",
    "content": "{\n  \"url\": \"https://context7.com/locomotivemtl/locomotive-scroll\",\n  \"public_key\": \"pk_fFYCHZCsmlAjABaNmHyFM\",\n  \"foldersInclude\": [\"packages/lib\"],\n  \"foldersExclude\": [\"packages/docs\", \"packages/demo\", \"packages/landing\", \"node_modules\"],\n  \"customRules\": [\n    \"locomotive-scroll v5 wraps Lenis for smooth scrolling - use lenisOptions for scroll physics (lerp, duration, easing)\",\n    \"Elements with data-scroll-speed, data-scroll-css-progress, or data-scroll-offset trigger RAF updates every frame - minimize these for performance\",\n    \"data-scroll-speed is relative to container size, not absolute pixels - speed: 0.5 means 50% of container height displacement\",\n    \"Parallax is auto-disabled on touch devices - add data-scroll-enable-touch-speed to force it on mobile\",\n    \"scrollPosition defines WHERE in viewport to trigger (start/middle/end), scrollOffset defines WHEN with a px/% offset - they are different\",\n    \"Elements visible at page load (in fold) have different progress mapping (0→1 vs -1→1) - use data-scroll-ignore-fold to disable\",\n    \"Dynamically added elements need locomotiveScroll.addScrollElements($container) - just adding HTML to DOM won't register them\",\n    \"Custom scroll containers need fixed height + overflow hidden/auto on wrapper, with content as direct child\",\n    \"Use data-scroll-repeat for elements that should re-trigger on each scroll in/out - default is fire once\",\n    \"Access Lenis instance via locomotiveScroll.lenisInstance for programmatic scrollTo, stop(), start()\"\n  ]\n}"
  },
  {
    "path": "package.json",
    "content": "{\n    \"private\": true,\n    \"name\": \"locomotive-scroll\",\n    \"description\": \"Monorepo for Locomotive Scroll\",\n    \"license\": \"MIT\",\n    \"homepage\": \"https://github.com/locomotivemtl/locomotive-scroll\",\n    \"repository\": {\n        \"type\": \"git\",\n        \"url\": \"https://github.com/locomotivemtl/locomotive-scroll.git\"\n    },\n    \"author\": {\n        \"name\": \"Locomotive\",\n        \"email\": \"info@locomotive.ca\",\n        \"homepage\": \"https://locomotive.ca\"\n    },\n    \"devDependencies\": {\n        \"turbo\": \"^2.7.4\",\n        \"typescript\": \"^4.8.3\"\n    },\n    \"scripts\": {\n        \"build\": \"turbo run build\",\n        \"build:vercel\": \"turbo run build --filter=./packages/lib --filter=./packages/demo --filter=./packages/docs\",\n        \"build:landing\": \"npm run build --workspace=packages/landing\",\n        \"dev\": \"npm run dev --workspace=packages/demo --if-present\",\n        \"publish\": \"npm run publish --workspace=packages/lib --if-present\",\n        \"publish:next\": \"npm run publish:next --workspace=packages/lib --if-present\"\n    },\n    \"workspaces\": [\n        \"packages/lib\",\n        \"packages/demo\",\n        \"packages/landing\",\n        \"packages/docs\"\n    ],\n    \"version\": \"5.0.0-rc.1\",\n    \"packageManager\": \"npm@10.9.4\"\n}\n"
  },
  {
    "path": "packages/demo/.editorconfig",
    "content": "# editorconfig.org\nroot = true\n\n[*]\ncharset = utf-8\nend_of_line = lf\nindent_size = 4\nindent_style = space\ninsert_final_newline = true\ntrim_trailing_whitespace = true\n\n[*.{md,markdown}]\ntrim_trailing_whitespace = false\n"
  },
  {
    "path": "packages/demo/.gitignore",
    "content": "# build output\ndist/\n\n# SVG sprite\npublic/assets/images/sprite.svg\n"
  },
  {
    "path": "packages/demo/.nvmrc",
    "content": "v20.14"
  },
  {
    "path": "packages/demo/.prettierignore",
    "content": "node_modules/**"
  },
  {
    "path": "packages/demo/.prettierrc",
    "content": "{\n    \"useTabs\": false,\n    \"tabWidth\": 4,\n    \"singleQuote\": true,\n    \"trailingComma\": \"none\",\n    \"semi\": true,\n    \"printWidth\": 100,\n    \"plugins\": [\"prettier-plugin-astro\", \"prettier-plugin-tailwindcss\"]\n}\n"
  },
  {
    "path": "packages/demo/.vscode/extensions.json",
    "content": "{\n  \"recommendations\": [\"astro-build.astro-vscode\"],\n  \"unwantedRecommendations\": []\n}\n"
  },
  {
    "path": "packages/demo/.vscode/launch.json",
    "content": "{\n  \"version\": \"0.2.0\",\n  \"configurations\": [\n    {\n      \"command\": \"./node_modules/.bin/astro dev\",\n      \"name\": \"Development server\",\n      \"request\": \"launch\",\n      \"type\": \"node-terminal\"\n    }\n  ]\n}\n"
  },
  {
    "path": "packages/demo/.vscode/settings.json",
    "content": "{\n    \"css.customData\": [\".vscode/tailwind.json\"],\n    \"scss.lint.unknownAtRules\": \"ignore\",\n}"
  },
  {
    "path": "packages/demo/.vscode/tailwind.json",
    "content": "{\n    \"version\": 1.1,\n    \"atDirectives\": [\n      {\n        \"name\": \"@tailwind\",\n        \"description\": \"Use the `@tailwind` directive to insert Tailwind's `base`, `components`, `utilities` and `screens` styles into your CSS.\",\n        \"references\": [\n          {\n            \"name\": \"Tailwind Documentation\",\n            \"url\": \"https://tailwindcss.com/docs/functions-and-directives#tailwind\"\n          }\n        ]\n      },\n      {\n        \"name\": \"@apply\",\n        \"description\": \"Use the `@apply` directive to inline any existing utility classes into your own custom CSS. This is useful when you find a common utility pattern in your HTML that you’d like to extract to a new component.\",\n        \"references\": [\n          {\n            \"name\": \"Tailwind Documentation\",\n            \"url\": \"https://tailwindcss.com/docs/functions-and-directives#apply\"\n          }\n        ]\n      },\n      {\n        \"name\": \"@responsive\",\n        \"description\": \"You can generate responsive variants of your own classes by wrapping their definitions in the `@responsive` directive:\\n```css\\n@responsive {\\n  .alert {\\n    background-color: #E53E3E;\\n  }\\n}\\n```\\n\",\n        \"references\": [\n          {\n            \"name\": \"Tailwind Documentation\",\n            \"url\": \"https://tailwindcss.com/docs/functions-and-directives#responsive\"\n          }\n        ]\n      },\n      {\n        \"name\": \"@screen\",\n        \"description\": \"The `@screen` directive allows you to create media queries that reference your breakpoints by **name** instead of duplicating their values in your own CSS:\\n```css\\n@screen sm {\\n  /* ... */\\n}\\n```\\n…gets transformed into this:\\n```css\\n@media (min-width: 640px) {\\n  /* ... */\\n}\\n```\\n\",\n        \"references\": [\n          {\n            \"name\": \"Tailwind Documentation\",\n            \"url\": \"https://tailwindcss.com/docs/functions-and-directives#screen\"\n          }\n        ]\n      },\n      {\n        \"name\": \"@variants\",\n        \"description\": \"Generate `hover`, `focus`, `active` and other **variants** of your own utilities by wrapping their definitions in the `@variants` directive:\\n```css\\n@variants hover, focus {\\n   .btn-brand {\\n    background-color: #3182CE;\\n  }\\n}\\n```\\n\",\n        \"references\": [\n          {\n            \"name\": \"Tailwind Documentation\",\n            \"url\": \"https://tailwindcss.com/docs/functions-and-directives#variants\"\n          }\n        ]\n      }\n    ]\n  }"
  },
  {
    "path": "packages/demo/LICENSE",
    "content": "The MIT License (MIT)\n\nCopyright (c) Locomotive, Inc.\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of\nthis software and associated documentation files (the \"Software\"), to deal in\nthe Software without restriction, including without limitation the rights to\nuse, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of\nthe Software, and to permit persons to whom the Software is furnished to do so,\nsubject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS\nFOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\nCOPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\nIN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\nCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE."
  },
  {
    "path": "packages/demo/README.md",
    "content": "<p align=\"center\">\n    <a href=\"https://github.com/locomotivemtl/locomotive-boilerplate\">\n        <img src=\"https://user-images.githubusercontent.com/4596862/54868065-c2aea200-4d5e-11e9-9ce3-e0013c15f48c.png\" height=\"140\">\n    </a>\n</p>\n<h1 align=\"center\">Locomotive Astro Boilerplate</h1>\n<p align=\"center\">Front-end Astro boilerplate for projects by <a href=\"https://locomotive.ca/\">Locomotive</a>.</p>\n\n## Features\n\n* Uses [Astro] for all-in-one web framework.\n* Uses [Sass] for a feature rich superset of CSS.\n* Uses [Tailwind CSS] for a sane and scalable CSS architecture.\n* Uses [Locomotive Scroll] for smooth scrolling with parallax effects.\n* Uses [Swup] for versatile and extensible page transition.\n* Uses [Prettier] for a formatted and easy to maintain codebase.\n\n## Getting started\n\nMake sure you have the following installed:\n\n* [Node] — at least 20.14, the latest LTS is recommended.\n* [NPM] — at least 8.0, the latest LTS is recommended.\n\n> 💡 You can use [NVM] to install and use different versions of Node via the command-line.\n\n```sh\n# Clone the repository.\ngit clone https://github.com/locomotivemtl/astro-boilerplate.git my-new-project\n\n# Enter the newly-cloned directory.\ncd my-new-project\n```\n\n## Installation\n\n```sh\n# Switch to recommended Node version from .nvmrc\nnvm use\n\n# Install dependencies from package.json\nnpm install\n```\n\n## Development\n\n```sh\n# Start development server, watch for changes, and compile assets\nnpm start\n\n# Compile and minify assets\nnpm run build\n```\n\n## Project Structure\n\nInside of your project, you'll see the following folders and files:\n\n```text\n/\n├── public/\n│   └── favicon.svg\n├── src/\n│   ├── components/\n│   │   └── Card/\n│   │       ├── Card.astro\n│   │       └── Card.scss\n│   ├── layouts/\n│   │   └── Layout.astro\n│   ├── pages/\n│   │   └── index.astro\n│   ├── styles/\n│   │   └── main.scss\n│   └── scripts/\n│       ├── components/\n│       ├── utils/\n│       ├── app.ts\n│       └── config.ts\n└── package.json\n```\n\n## Commands\n\nAll commands are run from the root of the project, from a terminal:\n\n| Command                   | Action                                           |\n| :------------------------ | :----------------------------------------------- |\n| `npm install`             | Installs dependencies                            |\n| `npm run dev`             | Starts local dev server at `localhost:4321`      |\n| `npm run build`           | Build your production site to `./dist/`          |\n| `npm run preview`         | Preview your build locally, before deploying     |\n| `npm run astro ...`       | Run CLI commands like `astro add`, `astro check` |\n| `npm run astro -- --help` | Get help using the Astro CLI                     |\n| `npm run format`          | Format files using prettier                      |\n\n## Documentation\n\n* [Astro]\n* [Locomotive Scroll]\n* [Tailwind CSS]\n* [Swup]\n* [Prettier]\n\n[Astro]:             https://docs.astro.build/en/getting-started/\n[Tailwind CSS]:      https://tailwindcss.com/docs/installation\n[Locomotive Scroll]: https://scroll.locomotive.ca/docs\n[Sass]:              https://sass-lang.com/\n[Swup]:              https://swup.js.org/getting-started/\n[Node]:              https://nodejs.org/\n[NPM]:               https://npmjs.com/\n[NVM]:               https://github.com/nvm-sh/nvm\n[Prettier]:          https://prettier.io/\n"
  },
  {
    "path": "packages/demo/astro.config.ts",
    "content": "import { defineConfig } from 'astro/config';\nimport tailwind from '@astrojs/tailwind';\nimport tailwindConfig from './tailwind.config';\nimport postcssTailwindShortcuts from '@locomotivemtl/postcss-tailwind-shortcuts';\n\n// https://astro.build/config\nexport default defineConfig({\n    site: 'https://scroll.locomotive.ca/demo',\n    base: '/demo',\n    outDir: '../../www/demo',\n    vite: {\n        css: {\n            preprocessorOptions: {\n                scss: {\n                    additionalData: `\n                        @use \"sass:math\";\n                        @use \"sass:list\";\n                        @use \"@styles/tools/maths\" as *;\n                        @use \"@styles/tools/functions\" as *;\n                    `\n                }\n            },\n            postcss: {\n                plugins: [\n                    postcssTailwindShortcuts(tailwindConfig.theme),\n                ],\n            }\n        }\n    },\n    integrations: [\n        tailwind({\n            applyBaseStyles: false,\n        }),\n    ],\n    devToolbar: {\n        enabled: false\n    },\n    image: {\n        domains: ['locomotive.ca'],\n        remotePatterns: [{ protocol: 'https' }],\n    }\n});\n"
  },
  {
    "path": "packages/demo/package.json",
    "content": "{\n    \"private\": true,\n    \"name\": \"@locomotivemtl/astro-boilerplate\",\n    \"title\": \"Locomotive Boilerplate\",\n    \"type\": \"module\",\n    \"version\": \"0.1.0\",\n    \"engines\": {\n        \"node\": \"20.x\",\n        \"npm\": \">=8.0\"\n    },\n    \"repository\": {\n        \"type\": \"git\",\n        \"url\": \"https://github.com/locomotivemtl/astro-boilerplate.git\"\n    },\n    \"author\": {\n        \"name\": \"Locomotive\",\n        \"email\": \"info@locomotive.ca\",\n        \"homepage\": \"https://locomotive.ca\"\n    },\n    \"scripts\": {\n        \"dev\": \"astro dev --host\",\n        \"start\": \"astro dev --host\",\n        \"build\": \"astro check && astro build\",\n        \"preview\": \"astro preview\",\n        \"astro\": \"astro\",\n        \"format\": \"prettier --write \\\"src/**/*.{astro,js,ts,css,scss}\\\"\"\n    },\n    \"dependencies\": {\n        \"@astrojs/check\": \"^0.9.2\",\n        \"@astrojs/tailwind\": \"^5.1.0\",\n        \"astro\": \"^4.13.4\",\n        \"astro-seo\": \"^0.8.4\",\n        \"locomotive-scroll\": \"*\",\n        \"nanostores\": \"^0.10.3\",\n        \"sass\": \"^1.77.4\",\n        \"swup\": \"^4.7.0\",\n        \"ts-debounce\": \"^4.0.0\"\n    },\n    \"devDependencies\": {\n        \"@locomotivemtl/postcss-tailwind-shortcuts\": \"^1.0.0\",\n        \"prettier\": \"^3.3.1\",\n        \"prettier-plugin-astro\": \"^0.14.0\",\n        \"prettier-plugin-tailwindcss\": \"^0.6.1\"\n    },\n    \"optionalDependencies\": {\n        \"@rollup/rollup-linux-x64-gnu\": \"4.9.5\"\n    }\n}\n"
  },
  {
    "path": "packages/demo/public/fonts/.gitkeep",
    "content": ""
  },
  {
    "path": "packages/demo/src/components/ScrollToggler/ScrollToggler.astro",
    "content": "<button class=\"c-scroll-toggler\" type=\"button\" id=\"scrollToggler\">\n    stop scroll\n</button>\n\n<script>\n    import { isScrollStopped } from '../../stores/scroll';\n\n    const $scrollToggler = document.getElementById('scrollToggler');\n\n    $scrollToggler?.addEventListener('click', () => {\n        isScrollStopped.set(!isScrollStopped.get());\n    });\n\n    isScrollStopped.subscribe(value => {\n        if ($scrollToggler) {\n            if (value) {\n                $scrollToggler.innerHTML = 'start scroll';\n            } else {\n                $scrollToggler.innerHTML = 'stop scroll';\n            }\n        }\n    });\n</script>\n"
  },
  {
    "path": "packages/demo/src/env.d.ts",
    "content": "/// <reference types=\"astro/client\" />\n"
  },
  {
    "path": "packages/demo/src/layouts/Layout.astro",
    "content": "---\nimport '@styles/main.scss';\nimport { SEO } from 'astro-seo';\n\ninterface Props {\n    title: string;\n    seo?: Seo;\n    scrollOrientation?: 'vertical' | 'horizontal';\n}\n\nconst { title, scrollOrientation = 'vertical' } = Astro.props;\n\nconst FONTS: string[] = [\n    // 'WebfontRegular.woff2',\n    // 'WebfontBold.woff2',\n]\n---\n\n<!doctype html>\n<html lang=\"en\" data-scroll-orientation-settings={scrollOrientation}>\n    <head>\n        <meta charset=\"UTF-8\" />\n        <meta name=\"viewport\" content=\"width=device-width\" />\n        <link rel=\"icon\" type=\"image/svg+xml\" href=\"/favicon.svg\" />\n        <meta name=\"generator\" content={Astro.generator} />\n<!--\n        <SEO\n            title={seo?.title || title || defaultSeo.title}\n            description={seo?.description || defaultSeo.description}\n            openGraph={{\n                basic: {\n                    type: 'website',\n                    title: seo?.social?.facebook?.title || defaultSeo.social.facebook.title,\n                    image: seo?.social?.facebook?.image?.url || defaultSeo.social.facebook.image.url\n                }\n            }}\n            twitter={{\n                creator: seo?.social?.twitter?.creator || defaultSeo.social.twitter.creator,\n                image: seo?.social?.twitter?.image?.url || defaultSeo.social.twitter.image.url,\n                title: seo?.social?.twitter?.title || defaultSeo.social.twitter.title,\n                description:\n                    seo?.social?.twitter?.description || defaultSeo.social.twitter.description\n            }}\n            canonical={seo?.advanced?.canonical || defaultSeo.advanced.canonical}\n            noindex={seo?.advanced?.robots?.includes('noindex') ||\n                defaultSeo?.advanced?.robots?.includes('noindex')}\n            nofollow={seo?.advanced?.robots?.includes('nofollow') ||\n                defaultSeo?.advanced?.robots?.includes('noindex')}\n            extend={{\n                meta: [\n                    {\n                        name: 'robots',\n                        content:\n                            seo?.advanced?.robots?.join(',') || defaultSeo.advanced.robots.join(',')\n                    }\n                ]\n            }}\n        /> -->\n\n        <!-- Fonts -->\n        {FONTS.map(font =>\n            <link\n                rel=\"preload\"\n                href={`/fonts/${font}`}\n                as=\"font\"\n                type=\"font/woff2\"\n                crossorigin\n            />\n        )}\n\n    </head>\n    <body>\n        <main role=\"main\" id=\"swup\" class=\"transition-fade\">\n            <div id=\"content\">\n                <slot />\n            </div>\n        </main>\n        <script src=\"../scripts/app.ts\"></script>\n    </body>\n</html>\n"
  },
  {
    "path": "packages/demo/src/pages/horizontal.astro",
    "content": "---\nimport Layout from '@layouts/Layout.astro';\n---\n\n<Layout title=\"About\" scrollOrientation=\"horizontal\">\n    <div>\n        <main id=\"top\">\n            <div class=\"c-scroll_offset\" style=\"--offset-start: 10%; --offset-end: 10%;\"></div>\n\n            <div class=\"c-scroll_section -full -centered\">\n                <h1 style=\"font-size: 10vw; opacity: calc(1 - var(--progress));\" data-scroll data-scroll-css-progress data-scroll-enable-touch-speed>Locomotive Scroll</h1>\n                <div style=\"display:flex; font-size: 10vw\">\n                    <p data-scroll data-scroll-enable-touch-speed data-scroll-speed=\".25\">V</p>\n                    <p data-scroll data-scroll-enable-touch-speed data-scroll-speed=\".2\">.</p>\n                    <p data-scroll data-scroll-enable-touch-speed data-scroll-speed=\".15\">0</p>\n                    <p data-scroll data-scroll-enable-touch-speed data-scroll-speed=\".1\">X</p>\n                </div>\n            </div>\n\n            <div class=\"c-scroll_section\">\n                <div class=\"u-whitespace-nowrap\">\n                    <h2 style=\"font-size: 3vw\">data-scroll-speed</h2>\n                </div>\n            </div>\n            <div class=\"c-scroll_section -centered -row -full -parallax\" style=\"font-size: 2vw\">\n                <div class=\"c-scroll_box\" style=\"background-color: var(--color-2)\" data-scroll data-scroll-enable-touch-speed data-scroll-speed=\"-.1\">\n                    <p>-.1</p>\n                </div>\n                <div class=\"c-scroll_box\" style=\"background-color: var(--color-3); color:white;\" data-scroll data-scroll-enable-touch-speed data-scroll-speed=\"0\">\n                    <p>0</p>\n                </div>\n                <div class=\"c-scroll_box\" style=\"background-color: var(--color-4); color:white;\" data-scroll data-scroll-enable-touch-speed data-scroll-speed=\".5\">\n                    <p>.5</p>\n                </div>\n                <div class=\"c-scroll_box\" style=\"background-color: var(--color-5); color:white;\" data-scroll data-scroll-enable-touch-speed data-scroll-speed=\"-.2\">\n                    <p>-.2</p>\n                </div>\n            </div>\n\n\n            <div class=\"c-scroll_section\">\n                <div class=\"u-whitespace-nowrap\">\n                    <h2 style=\"font-size: 3vw\">data-scroll-class</h2>\n                </div>\n            </div>\n            <div class=\"c-scroll_section -centered -row -full\" style=\"font-size: 2vw\">\n                <div class=\"c-scroll_box\" style=\"background-color: var(--color-2); opacity: 0;\" data-scroll data-scroll-offset=\"10%, 10%\" data-scroll-class=\"c-scroll-opacity\">\n                    <p>c-scroll-opacity</p>\n                </div>\n                <div class=\"c-scroll_box\" style=\"background-color: var(--color-3); color:white; transform: rotate(0);\" data-scroll data-scroll-offset=\"10%, 10%\" data-scroll-class=\"c-scroll-rotate\">\n                    <p>c-scroll-rotate</p>\n                </div>\n            </div>\n\n\n            <div class=\"c-scroll_section\">\n                <div class=\"u-whitespace-nowrap\">\n                    <h2 style=\"font-size: 3vw\">data-scroll-repeat</h2>\n                </div>\n            </div>\n            <div class=\"c-scroll_section -centered -row -full\" style=\"font-size: 2vw\">\n                <div class=\"c-scroll_box\" style=\"background-color: var(--color-5); color:white; opacity: 0;\" data-scroll data-scroll-offset=\"10%, 10%\" data-scroll-repeat data-scroll-class=\"c-scroll-opacity\">\n                    <p>c-scroll-opacity</p>\n                    <p>REPEAT</p>\n                </div>\n            </div>\n\n\n            <div class=\"c-scroll_section\">\n                <div class=\"u-whitespace-nowrap\">\n                    <h2 style=\"font-size: 3vw\">data-scroll-css-progress</h2>\n                </div>\n            </div>\n            <div class=\"c-scroll_section -centered -row -full\" style=\"font-size: 2vw;\">\n                <div class=\"c-scroll_box\" style=\"background-color: var(--color-4); opacity: var(--progress); color:white;\" data-scroll data-scroll-css-progress data-scroll-offset=\"10%, 10%\">\n                    <p>css progress variable</p>\n                </div>\n            </div>\n\n\n            <!-- <div class=\"c-scroll_section\">\n                <div class=\"u-whitespace-nowrap\">\n                    <h2 style=\"font-size: 3vw\">data-scroll-module-progress</h2>\n                </div>\n            </div>\n            <div class=\"c-scroll_section -centered -row -full\" style=\"font-size: 2vw;\">\n                <div class=\"c-scroll_box\" style=\"background-color: var(--color-5); color:white;\" data-module-progress data-scroll data-scroll-module-progress data-scroll-offset=\"10%, 10%\">\n                    <p data-progress=\"progress\"></p>\n                </div>\n            </div> -->\n\n\n            <div class=\"c-scroll_section\">\n                <div class=\"u-whitespace-nowrap\">\n                    <h2 style=\"font-size: 3vw\">data-scroll-event-progress: Custom Event</h2>\n                </div>\n            </div>\n            <div class=\"c-scroll_section -centered -row -full\" style=\"font-size: 2vw;\">\n                <div class=\"c-scroll_box\" style=\"background-color: var(--color-3); color:white;\" data-scroll data-scroll-event-progress=\"progressEvent\" data-scroll-offset=\"10%, 10%\">\n                    <p data-custom-event=\"progress\"></p>\n                </div>\n            </div>\n\n\n            <div class=\"c-scroll_section\">\n                <div class=\"u-whitespace-nowrap\">\n                    <h2 style=\"font-size: 3vw\">data-scroll-position</h2>\n                </div>\n            </div>\n            <div class=\"c-scroll_section -centered -row -full\" style=\"font-size: 2vw;\">\n                <div class=\"c-scroll_box\" style=\"background-color: var(--color-2); color:white;\" data-scroll-position=\"start,end\" data-scroll data-scroll-event-progress=\"progressPositionEvent\" data-scroll-offset=\"10%, 10%\">\n                    <p>Position Enter: start</p>\n                    <p>Position Leave: end</p>\n                    <p data-position-progress></p>\n                </div>\n                <div class=\"c-scroll_box\" style=\"background-color: var(--color-3); color:white;\" data-scroll-position=\"middle,middle\" data-scroll data-scroll-event-progress=\"progressPositionEvent\" data-scroll-offset=\"10%, 10%\">\n                    <p>Position Enter: middle</p>\n                    <p>Position Leave: middle</p>\n                    <p data-position-progress></p>\n                </div>\n                <div class=\"c-scroll_box\" style=\"background-color: var(--color-5); color:white;\" data-scroll-position=\"end,start\" data-scroll data-scroll-event-progress=\"progressPositionEvent\" data-scroll-offset=\"10%, 10%\">\n                    <p>Position Enter: end</p>\n                    <p>Position Leave: start</p>\n                    <p data-position-progress></p>\n                </div>\n            </div>\n\n            <div class=\"c-scroll_section\">\n                <div class=\"u-whitespace-nowrap\">\n                    <h2 style=\"font-size: 3vw\">data-scroll-call: Custom Event</h2>\n                </div>\n            </div>\n            <div class=\"c-scroll_section -centered -row -full\" style=\"font-size: 2vw;\">\n                <div class=\"c-scroll_box\" style=\"background-color: var(--color-4); color:white;\" data-scroll-position=\"end,start\" data-scroll-repeat data-scroll data-scroll-call=\"scrollEvent\" data-scroll-offset=\"10%, 10%\">\n                    <p data-custom-event=\"event\"></p>\n                </div>\n            </div>\n\n            <div class=\"c-scroll_section\" id=\"Direction\">\n                <div class=\"u-whitespace-nowrap\">\n                    <h2 style=\"font-size: 3vw\">Lenis scroll calback: direction</h2>\n                </div>\n            </div>\n            <div class=\"c-scroll_section -centered -row -full\" style=\"font-size: 10vw;\">\n                <div class=\"c-scroll_box c-scroll-direction\">\n                    <button data-scroll-to data-scroll-to-href=\"#top\">\n                        ⬇️\n                    </button>\n                </div>\n            </div>\n        </main>\n    </div>\n</Layout>\n"
  },
  {
    "path": "packages/demo/src/pages/index.astro",
    "content": "---\nimport Layout from \"../layouts/Layout.astro\"\nimport ScrollToggler from '@components/ScrollToggler/ScrollToggler.astro';\n---\n\n<Layout title=\"test\">\n\t<div>\n        <div>\n            <ScrollToggler />\n\n            <main id=\"top\">\n                <div class=\"c-scroll_offset\" style=\"--offset-start: 10%; --offset-end: 10%;\"></div>\n\n                <div class=\"c-scroll_section -full -centered\">\n                    <h1 style=\"font-size: 10vw; opacity: calc(1 - var(--progress));\" data-scroll data-scroll-css-progress data-scroll-enable-touch-speed>Locomotive Scroll</h1>\n                    <div style=\"display:flex; font-size: 10vw\">\n                        <p data-scroll data-scroll-enable-touch-speed data-scroll-speed=\"-.1\">V</p>\n                        <p data-scroll data-scroll-enable-touch-speed data-scroll-speed=\"0\">.</p>\n                        <p data-scroll data-scroll-enable-touch-speed data-scroll-speed=\".1\">5</p>\n                    </div>\n                </div>\n\n                <div class=\"c-scroll_section\">\n                    <div class=\"o-container\">\n                        <h2 style=\"font-size: 3vw\">data-scroll-speed</h2>\n                    </div>\n                </div>\n                <div class=\"c-scroll_section -centered -row -full\" style=\"font-size: 2vw\">\n                    <div class=\"c-scroll_box\" style=\"background-color: var(--color-2)\" data-scroll data-scroll-speed=\"-.1\">\n                        <p>-.1</p>\n                    </div>\n                    <div class=\"c-scroll_box\" style=\"background-color: var(--color-3); color:white;\" data-scroll data-scroll-speed=\"0\">\n                        <p>0</p>\n                    </div>\n                    <div class=\"c-scroll_box\" style=\"background-color: var(--color-4); color:white;\" data-scroll data-scroll-speed=\".5\">\n                        <p>.5</p>\n                    </div>\n                    <div class=\"c-scroll_box\" style=\"background-color: var(--color-5); color:white;\" data-scroll data-scroll-speed=\"-.2\">\n                        <p>-.2</p>\n                    </div>\n                </div>\n\n\n                <div class=\"c-scroll_section\">\n                    <div class=\"o-container\">\n                        <h2 style=\"font-size: 3vw\">data-scroll-class</h2>\n                    </div>\n                </div>\n                <div class=\"c-scroll_section -centered -row -full\" style=\"font-size: 2vw\">\n                    <div class=\"c-scroll_box\" style=\"background-color: var(--color-2); opacity: 0;\" data-scroll data-scroll-offset=\"10%, 10%\" data-scroll-class=\"c-scroll-opacity\">\n                        <p>c-scroll-opacity</p>\n                    </div>\n                    <div class=\"c-scroll_box\" style=\"background-color: var(--color-3); color:white; transform: rotate(0);\" data-scroll data-scroll-offset=\"10%, 10%\" data-scroll-class=\"c-scroll-rotate\">\n                        <p>c-scroll-rotate</p>\n                    </div>\n                </div>\n\n\n                <div class=\"c-scroll_section\">\n                    <div class=\"o-container\">\n                        <h2 style=\"font-size: 3vw\">data-scroll-repeat</h2>\n                    </div>\n                </div>\n                <div class=\"c-scroll_section -centered -row -full\" style=\"font-size: 2vw\">\n                    <div class=\"c-scroll_box\" style=\"background-color: var(--color-5); color:white; opacity: 0;\" data-scroll data-scroll-offset=\"10%, 10%\" data-scroll-repeat data-scroll-class=\"c-scroll-opacity\">\n                        <p>c-scroll-opacity</p>\n                        <p>REPEAT</p>\n                    </div>\n                </div>\n\n\n                <div class=\"c-scroll_section\">\n                    <div class=\"o-container\">\n                        <h2 style=\"font-size: 3vw\">data-scroll-css-progress</h2>\n                    </div>\n                </div>\n                <div class=\"c-scroll_section -centered -row -full\" style=\"font-size: 2vw;\">\n                    <div class=\"c-scroll_box\" style=\"background-color: var(--color-4); opacity: var(--progress); color:white;\" data-scroll data-scroll-css-progress data-scroll-offset=\"10%, 10%\">\n                        <p>css progress variable</p>\n                    </div>\n                </div>\n\n\n                <!-- <div class=\"c-scroll_section\">\n                    <div class=\"o-container\">\n                        <h2 style=\"font-size: 3vw\">data-scroll-module-progress</h2>\n                    </div>\n                </div>\n                <div class=\"c-scroll_section -centered -row -full\" style=\"font-size: 2vw;\">\n                    <div class=\"c-scroll_box\" style=\"background-color: var(--color-5); color:white;\" data-module-progress data-scroll data-scroll-module-progress data-scroll-offset=\"10%, 10%\">\n                        <p data-progress=\"progress\"></p>\n                    </div>\n                </div> -->\n\n\n                <div class=\"c-scroll_section\">\n                    <div class=\"o-container\">\n                        <h2 style=\"font-size: 3vw\">data-scroll-event-progress: Custom Event</h2>\n                    </div>\n                </div>\n                <div class=\"c-scroll_section -centered -row -full\" style=\"font-size: 2vw;\">\n                    <div class=\"c-scroll_box\" style=\"background-color: var(--color-3); color:white;\" data-scroll data-scroll-event-progress=\"progressEvent\" data-scroll-offset=\"10%, 10%\">\n                        <p data-custom-event=\"progress\"></p>\n                    </div>\n                </div>\n\n\n                <div class=\"c-scroll_section\">\n                    <div class=\"o-container\">\n                        <h2 style=\"font-size: 3vw\">data-scroll-position</h2>\n                    </div>\n                </div>\n                <div class=\"c-scroll_section -centered -row -full\" style=\"font-size: 2vw;\">\n                    <div class=\"c-scroll_box\" style=\"background-color: var(--color-2); color:white;\" data-scroll-position=\"start,end\" data-scroll data-scroll-event-progress=\"progressPositionEvent\" data-scroll-offset=\"10%, 10%\">\n                        <p>Position Enter: start</p>\n                        <p>Position Leave: end</p>\n                        <p data-position-progress></p>\n                    </div>\n                    <div class=\"c-scroll_box\" style=\"background-color: var(--color-3); color:white;\" data-scroll-position=\"middle,middle\" data-scroll data-scroll-event-progress=\"progressPositionEvent\" data-scroll-offset=\"10%, 10%\">\n                        <p>Position Enter: middle</p>\n                        <p>Position Leave: middle</p>\n                        <p data-position-progress></p>\n                    </div>\n                    <div class=\"c-scroll_box\" style=\"background-color: var(--color-5); color:white;\" data-scroll-position=\"end,start\" data-scroll data-scroll-event-progress=\"progressPositionEvent\" data-scroll-offset=\"10%, 10%\">\n                        <p>Position Enter: end</p>\n                        <p>Position Leave: start</p>\n                        <p data-position-progress></p>\n                    </div>\n                </div>\n\n                <div class=\"c-scroll_section\">\n                    <div class=\"o-container\">\n                        <h2 style=\"font-size: 3vw\">data-scroll-call: Custom Event</h2>\n                    </div>\n                </div>\n                <div class=\"c-scroll_section -centered -row -full\" style=\"font-size: 2vw;\">\n                    <div class=\"c-scroll_box\" style=\"background-color: var(--color-4); color:white;\" data-scroll-position=\"end,start\" data-scroll-repeat data-scroll data-scroll-call=\"scrollEvent\" data-scroll-offset=\"10%, 10%\">\n                        <p data-custom-event=\"event\"></p>\n                    </div>\n                </div>\n\n                <div class=\"c-scroll_section\" id=\"Direction\">\n                    <div class=\"o-container\">\n                        <h2 style=\"font-size: 3vw\">Lenis scroll calback: direction</h2>\n                    </div>\n                </div>\n                <div class=\"c-scroll_section -centered -row -full\" style=\"font-size: 10vw;\">\n                    <div class=\"c-scroll_box c-scroll-direction\">\n                        <button data-scroll-to data-scroll-to-href=\"#top\">\n                            ⬇️\n                        </button>\n                    </div>\n                </div>\n\n            </main>\n        </div>\n    </div>\n</Layout>\n"
  },
  {
    "path": "packages/demo/src/scripts/app.ts",
    "content": "import { Scroll } from '@scripts/classes/Scroll';\nimport { $screenDebounce } from \"../stores/screen\";\nimport { setViewportSize } from './utils/setViewportSize';\n\n// Initialize the Scroll class\nScroll.init();\n\n$screenDebounce.subscribe(() => {\n    setViewportSize();\n});\n\n// Progress event\nconst $progressEventLabel = document.querySelector('[data-custom-event=\"progress\"]') as HTMLElement\nconst onProgressEventCall = (e: CustomEvent) => {\n    const { progress } = e.detail;\n    $progressEventLabel.textContent = `${Math.round(\n        (progress + Number.EPSILON) * 100\n    )}%`;\n}\nwindow.addEventListener('progressEvent', onProgressEventCall as EventListener);\n\n// Progress position\nconst $positionProgresses = Array.from(document.querySelectorAll('[data-position-progress]'))\nconst onProgressPositionCall = (e: CustomEvent) => {\n    const { target, progress } = e.detail;\n    const $positionProgress = $positionProgresses.find(($el) => $el.parentElement === target) as HTMLElement;\n    $positionProgress.textContent = `${Math.round(\n        (progress + Number.EPSILON) * 100\n    )}%`;\n}\nwindow.addEventListener('progressPositionEvent', onProgressPositionCall as EventListener);\n\n// Custom event\nconst $customEventLabel = document.querySelector('[data-custom-event=\"event\"]') as HTMLElement\nconst onCustomEventCall = (e: CustomEvent) => {\n    const { way } = e.detail;\n    $customEventLabel.textContent = `scrollEvent ${way}`;\n}\nwindow.addEventListener('scrollEvent', onCustomEventCall as EventListener);\n"
  },
  {
    "path": "packages/demo/src/scripts/classes/Scroll.ts",
    "content": "import { isScrollStopped } from '@root/src/stores/scroll';\nimport LocomotiveScroll from '../../../../lib/index';\n\nimport type {\n    ILenisScrollToOptions,\n    lenisTargetScrollTo\n} from '../../../../lib/types';\n\nexport class Scroll {\n    static locomotiveScroll: LocomotiveScroll;\n    static lastProgress: number;\n    static scrollOrientation: number;\n\n    // =============================================================================\n    // Lifecycle\n    // =============================================================================\n    static init() {\n        const scrollOrientation = document.documentElement.dataset.scrollOrientationSettings as 'vertical' | 'horizontal';\n\n        this.locomotiveScroll = new LocomotiveScroll({\n            lenisOptions: {\n                orientation: scrollOrientation,\n            },\n            scrollCallback: ({ progress }) => {\n                if (progress > this.lastProgress) {\n                    if (this.scrollOrientation != 1) {\n                        this.scrollOrientation = 1;\n                        document.documentElement.style.setProperty(\n                            '--scroll-direction',\n                            this.scrollOrientation.toString()\n                        );\n                    }\n                } else if (this.scrollOrientation != -1) {\n                    this.scrollOrientation = -1;\n                    document.documentElement.style.setProperty(\n                        '--scroll-direction',\n                        this.scrollOrientation.toString()\n                    );\n                }\n\n                this.lastProgress = progress as number;\n            }\n        });\n\n        isScrollStopped.listen((value) => {\n            if (value) {\n                this.stop();\n            } else {\n                this.start();\n            }\n        });\n    }\n\n    static destroy() {\n        this.locomotiveScroll?.destroy();\n    }\n\n    // =============================================================================\n    // Methods\n    // =============================================================================\n    static start() {\n        this.locomotiveScroll?.start();\n    }\n\n    static stop() {\n        this.locomotiveScroll?.stop();\n    }\n\n    static addScrollElements(container: HTMLElement) {\n        this.locomotiveScroll?.addScrollElements(container);\n    }\n\n    static removeScrollElements(container: HTMLElement) {\n        this.locomotiveScroll?.removeScrollElements(container);\n    }\n\n    static scrollTo(target: lenisTargetScrollTo, options?: ILenisScrollToOptions) {\n        this.locomotiveScroll?.scrollTo(target, options);\n    }\n}\n"
  },
  {
    "path": "packages/demo/src/scripts/utils/maths.ts",
    "content": "const mapRange = (min: number, max: number, nmin: number, nmax: number, value: number) => {\n    return ((value - min) / (max - min)) * (nmax - nmin) + nmin;\n};\n\nconst clamp = (min: number, max: number, value: number) => {\n    return Math.max(min, Math.min(value, max));\n};\n\nconst normalize = (min: number, max: number, value: number) => {\n    return clamp(0, 1, (value - min) / (max - min));\n};\n\nconst roundToDecimals = (value: number, decimals: number): number => {\n    const factor = Math.pow(10, decimals);\n    return Math.round((value + Number.EPSILON) * factor) / factor;\n};\n\nexport { mapRange, clamp, normalize, roundToDecimals };\n"
  },
  {
    "path": "packages/demo/src/scripts/utils/setViewportSize.ts",
    "content": "const SUPPORTS_VH: boolean =\n    'CSS' in window &&\n    'supports' in window.CSS &&\n    window.CSS.supports('height: 100svh') &&\n    window.CSS.supports('height: 100dvh') &&\n    window.CSS.supports('height: 100lvh');\n\nexport const setViewportSize = () => {\n    // Document styles\n    const documentStyles = document.documentElement.style;\n\n    // Viewport width\n    const vw: number = document.body.clientWidth * 0.01;\n    documentStyles.setProperty('--vw', `${vw}px`);\n\n    // Return if browser supports vh, svh, dvh, & lvh\n    // if (SUPPORTS_VH) {\n    //     return;\n    // }\n\n    // Viewport height\n    const svh: number = document.documentElement.clientHeight * 0.01;\n    documentStyles.setProperty('--svh', `${svh}px`);\n\n    const dvh: number = window.innerHeight * 0.01;\n    documentStyles.setProperty('--dvh', `${dvh}px`);\n\n    if (document.body) {\n        const fixed = document.createElement('div');\n        fixed.style.width = '1px';\n        fixed.style.height = '100vh';\n        fixed.style.position = 'fixed';\n        fixed.style.left = '0';\n        fixed.style.top = '0';\n        fixed.style.bottom = '0';\n        fixed.style.visibility = 'hidden';\n\n        document.body.appendChild(fixed);\n\n        const fixedHeight: number = fixed.clientHeight;\n\n        fixed.remove();\n\n        const lvh: number = fixedHeight * 0.01;\n\n        documentStyles.setProperty('--lvh', `${lvh}px`);\n    }\n};\n"
  },
  {
    "path": "packages/demo/src/scripts/utils/string.ts",
    "content": "const toDash = (str: string) =>\n    str\n        .split(/(?=[A-Z])/)\n        .join('-')\n        .toLowerCase();\n\nexport { toDash };\n"
  },
  {
    "path": "packages/demo/src/stores/screen.ts",
    "content": "import { map } from 'nanostores';\nimport { debounce } from 'ts-debounce';\n\nexport interface IScreenValues {\n    width: number;\n    height: number;\n}\n\nexport interface IScreenDebounceValues {\n    width: number;\n    height: number;\n}\n\nexport const $screen = map<IScreenValues>({\n    width: window.innerWidth,\n    height: window.innerHeight\n});\n\nexport const $screenDebounce = map<IScreenDebounceValues>({\n    width: window.innerWidth,\n    height: window.innerHeight\n});\n\nwindow.addEventListener('resize', () => {\n    $screen.setKey('width', window.innerWidth);\n    $screen.setKey('height', window.innerHeight);\n});\n\nconst debouncedFunction: any = () => {\n    $screenDebounce.setKey('width', window.innerWidth);\n    $screenDebounce.setKey('height', window.innerHeight);\n};\nwindow.addEventListener('resize', debounce(debouncedFunction, 200));\n"
  },
  {
    "path": "packages/demo/src/stores/scroll.ts",
    "content": "import { atom } from \"nanostores\";\n\nexport const isScrollStopped = atom(false);\n"
  },
  {
    "path": "packages/demo/src/styles/main.scss",
    "content": "// ==========================================================================\n// Tailwind CSS\n// ==========================================================================\n/**\n* This injects Tailwind's base styles and any base styles registered by\n* plugins.\n*/\n@tailwind base;\n\n/**\n* This injects Tailwind's component classes and any component classes\n* registered by plugins.\n*/\n@tailwind components;\n\n/**\n* This injects Tailwind's utility classes and any utility classes registered\n* by plugins.\n*/\n@tailwind utilities;\n\n// ==========================================================================\n// Fonts imports\n// ==========================================================================\n@layer base {\n    // @font-face {\n    //     font-family: 'IBM Plex Mono';\n    //     src: url('/fonts/IBMPlexMono-Regular.woff2') format('woff2');\n    //     font-weight: normal;\n    //     font-style: normal;\n    //     font-display: swap;\n    // }\n}\n\n// ==========================================================================\n// Vendors\n// ==========================================================================\n@import '../../../lib/bundled/locomotive-scroll.css';\n\n// ==========================================================================\n// Local files imports\n// ==========================================================================\n@import 'tools/maths';\n@import 'tools/functions';\n\n// ==========================================================================\n// Global styles\n// ==========================================================================\n:root {\n    --color-primary: color('black');\n    --color-secondary: color('white');\n}\n\nhtml {\n    font-family: theme('fontFamily.sans');\n}\n\nbody {\n    background: var(--color-secondary);\n    color: var(--color-primary);\n}\n\n::selection {\n    background-color: var(--color-primary);\n    color: var(--color-secondary);\n    text-shadow: none;\n}\n\n* {\n    box-sizing: border-box;\n    margin: 0;\n    padding: 0;\n}\n\n/* Define a transition duration during page visits */\nhtml.is-changing .transition-fade {\n    transition: opacity 0.25s;\n    opacity: 1;\n}\n/* Define the styles for the unloaded pages */\nhtml.is-animating .transition-fade {\n    opacity: 0;\n}\n\nhtml[data-scroll-orientation='horizontal'] {\n    body {\n        width: fit-content;\n    }\n    main {\n        display: flex;\n    }\n}\n\n:root {\n    --color-1: #f4f4ed;\n    --color-2: #6decaf;\n    --color-3: #357ded;\n    --color-4: #5e239d;\n    --color-5: #f61067;\n}\n\n.c-scroll {\n    position: absolute;\n    top: 0;\n    left: 0;\n    width: 100%;\n    height: 100%;\n    overflow: auto;\n}\n\n.c-scroll_offset {\n    position: fixed;\n    top: 0;\n    left: 0;\n    width: 100%;\n    height: 100%;\n    pointer-events: none;\n\n    &:before,\n    &:after {\n        content: '';\n        position: absolute;\n        z-index: 1;\n\n        html[data-scroll-orientation='vertical'] & {\n            width: 100%;\n            height: 1px;\n        }\n        html[data-scroll-orientation='horizontal'] & {\n            width: 1px;\n            height: 100%;\n        }\n    }\n\n    &:before {\n        background-color: rgb(217, 66, 66);\n        html[data-scroll-orientation='vertical'] & {\n            bottom: var(--offset-start);\n        }\n        html[data-scroll-orientation='horizontal'] & {\n            right: var(--offset-start);\n        }\n    }\n\n    &:after {\n        background-color: rgb(74, 166, 215);\n        html[data-scroll-orientation='vertical'] & {\n            top: var(--offset-end);\n        }\n        html[data-scroll-orientation='horizontal'] & {\n            left: var(--offset-end);\n        }\n    }\n}\n\n.c-scroll_section {\n    width: 100%;\n    background-color: var(--color-1);\n\n    &.-full {\n        height: calc(100 * var(--svh));\n\n        html[data-scroll-orientation='horizontal'] & {\n            width: 100vw;\n            flex-shrink: 0;\n        }\n    }\n\n    &.-centered {\n        display: flex;\n        flex-direction: column;\n        align-items: center;\n        justify-content: center;\n    }\n\n    &.-row {\n        flex-direction: row;\n\n        html[data-scroll-orientation='horizontal'] & {\n            flex-direction: column;\n        }\n    }\n}\n\n.c-scroll_box {\n    position: relative;\n    display: flex;\n    justify-content: center;\n    align-items: center;\n    flex-direction: column;\n    width: 20vw;\n    height: 20vw;\n    max-width: 300px;\n    max-height: 300px;\n    overflow: hidden;\n\n    html[data-scroll-orientation='horizontal'] & {\n        width: 24vh;\n        height: 24vh;\n    }\n\n    img {\n        position: absolute;\n        top: 0;\n        left: 0;\n        width: 100%;\n        height: 100%;\n        object-fit: cover;\n    }\n}\n\n.c-scroll-opacity {\n    opacity: 1 !important;\n    transition: opacity 0.75s ease();\n}\n\n.c-scroll-rotate {\n    transform: rotate(2turn) !important;\n    transition: transform 0.75s ease();\n}\n\n.c-scroll-direction {\n    html[data-scroll-orientation='vertical'] & {\n        transform: scaleY(var(--scroll-direction));\n    }\n    html[data-scroll-orientation='horizontal'] & {\n        transform: scaleX(var(--scroll-direction)) rotate(-90deg);\n    }\n}\n\n.c-scroll-toggler {\n    position: fixed;\n    top: 0;\n    left: 0;\n    display: inline-block;\n    background-color: grey;\n    padding: 0.5em;\n}\n"
  },
  {
    "path": "packages/demo/src/styles/tools/functions.scss",
    "content": "// ==========================================================================\n// Tools / Functions\n// ==========================================================================\n\n// Returns calculation of a percentage of the viewport small height.\n//\n// ```scss\n// .c-box {\n//     height: svh(100);\n// }\n// ```\n//\n// @param  {number} $number - The percentage number\n// @return {function<number>} in svh\n@function svh($number) {\n    @return calc(#{$number} * var(--svh, 1svh));\n}\n\n// Returns calculation of a percentage of the viewport large height.\n//\n// ```scss\n// .c-box {\n//     height: lvh(100);\n// }\n// ```\n//\n// @param  {number} $number - The percentage number\n// @return {function<number>} in lvh\n@function lvh($number) {\n    @return calc(#{$number} * var(--lvh, 1lvh));\n}\n\n// Returns calculation of a percentage of the viewport dynamic height.\n//\n// ```scss\n// .c-box {\n//     height: dvh(100);\n// }\n// ```\n//\n// @param  {number} $number - The percentage number\n// @return {function<number>} in dvh\n@function dvh($number) {\n    @return calc(#{$number} * var(--dvh, 1dvh));\n}\n\n// Returns calculation of a percentage of the viewport width.\n//\n// ```scss\n// .c-box {\n//     width: vw(100);\n// }\n// ```\n//\n// @param  {number} $number - The percentage number\n// @return {function<number>} in vw\n\n@function vw($number) {\n    @return calc(#{$number} * var(--vw, 1vw));\n}\n"
  },
  {
    "path": "packages/demo/src/styles/tools/maths.scss",
    "content": "// ==========================================================================\n// Tools / Maths\n// ==========================================================================\n\n// Remove the unit of a length\n//\n// @param {Number} $number Number to remove unit from\n// @return {function<number>}\n@function strip-unit($value) {\n    @if type-of($value) != 'number' {\n        @error \"Invalid `#{type-of($value)}` type. Choose a number type instead.\";\n    } @else if type-of($value) == 'number' and not is-unitless($value) {\n        @return math.div($value, $value * 0 + 1);\n    }\n\n    @return $value;\n}\n\n// Returns the square root of the given number.\n//\n// @param  {number} $number The number to calculate.\n// @return {number}\n\n@function sqrt($number) {\n    $x: 1;\n    $value: $x;\n\n    @for $i from 1 through 10 {\n        $value: $x - math.div(($x * $x - abs($number)), (2 * $x));\n        $x: $value;\n    }\n\n    @return $value;\n}\n\n// Returns a number raised to the power of an exponent.\n//\n// @param  {number} $number The base number.\n// @param  {number} $exp    The exponent.\n// @return {number}\n\n@function pow($number, $exp) {\n    $value: 1;\n\n    @if $exp >0 {\n        @for $i from 1 through $exp {\n            $value: $value * $number;\n        }\n    } @else if $exp < 0 {\n        @for $i from 1 through -$exp {\n            $value: math.div($value, $number);\n        }\n    }\n\n    @return $value;\n}\n\n// Returns the factorial of the given number.\n//\n// @param  {number} $number The number to calculate.\n// @return {number}\n\n@function fact($number) {\n    $value: 1;\n\n    @if $number >0 {\n        @for $i from 1 through $number {\n            $value: $value * $i;\n        }\n    }\n\n    @return $value;\n}\n\n// Returns an approximation of pi, with 11 decimals.\n//\n// @return {number}\n\n@function pi() {\n    @return 3.14159265359;\n}\n\n// Converts the number in degrees to the radian equivalent .\n//\n// @param  {number} $angle  The angular value to calculate.\n// @return {number}         If $angle has the `deg` unit,\n//                          the radian equivalent is returned.\n//                          Otherwise, the unitless value of $angle is returned.\n\n@function rad($angle) {\n    $unit: unit($angle);\n    $angle: strip-units($angle);\n\n    // If the angle has `deg` as unit, convert to radians.\n    @if ($unit ==deg) {\n        @return math.div($angle, 180) * pi();\n    }\n\n    @return $angle;\n}\n\n// Returns the sine of the given number.\n//\n// @param  {number} $angle The angle to calculate.\n// @return {number}\n\n@function sin($angle) {\n    $sin: 0;\n    $angle: rad($angle);\n\n    @for $i from 0 through 10 {\n        $sin: $sin + pow(-1, $i) * math.div(pow($angle, (2 * $i + 1)), fact(2 * $i + 1));\n    }\n\n    @return $sin;\n}\n\n// Returns the cosine of the given number.\n//\n// @param  {string} $angle The angle to calculate.\n// @return {number}\n\n@function cos($angle) {\n    $cos: 0;\n    $angle: rad($angle);\n\n    @for $i from 0 through 10 {\n        $cos: $cos + pow(-1, $i) * math.div(pow($angle, 2 * $i), fact(2 * $i));\n    }\n\n    @return $cos;\n}\n\n// Returns the tangent of the given number.\n//\n// @param  {string} $angle The angle to calculate.\n// @return {number}\n\n@function tan($angle) {\n    @return math.div(sin($angle), cos($angle));\n}\n"
  },
  {
    "path": "packages/demo/tailwind.config.ts",
    "content": "import defaultTheme from 'tailwindcss/defaultTheme';\n\nimport type { Config } from 'tailwindcss';\n\nexport default {\n    content: ['./src/**/*.{astro,html,js,jsx,md,mdx,svelte,ts,tsx,vue}'],\n    prefix: 'u-',\n    corePlugins: {\n        container: false,\n    },\n    theme: {\n        extend: {\n            fontFamily: {\n                serif: [\n                    'Times New Roman',\n                    ...defaultTheme.fontFamily.serif\n                ],\n                sans: [\n                    'Arial',\n                    ...defaultTheme.fontFamily.sans\n                ],\n            },\n            colors: {\n                black:      '#000000',\n                white:      '#ffffff',\n                primary:    '#312dfb',\n            },\n            screens: {\n                'to-2xs':   { 'max': '339px' },\n                '2xs':      '340px',\n                'to-xs':    { 'max': '499px' },\n                'xs':       '500px',\n                'to-sm':    { 'max': '699px' },\n                'sm':       '700px',\n                'to-md':    { 'max': '999px' },\n                'md':       '1000px',\n                'to-lg':    { 'max': '1199px' },\n                'lg':       '1200px',\n                'to-xl':    { 'max': '1399px' },\n                'xl':       '1400px',\n                'to-2xl':   { 'max': '1599px' },\n                '2xl':      '1600px',\n                'to-3xl':   { 'max': '1799px' },\n                '3xl':      '1800px',\n                'to-4xl':   { 'max': '1999px' },\n                '4xl':      '2000px',\n                'to-5xl':   { 'max': '2399px' },\n                '5xl':      '2400px',\n            },\n            gap: {\n                gutter: '20px',\n                gutterMobile: '10px'\n            },\n            transitionDuration: {\n                fast:       '0.2s',\n                default:    '0.4s',\n                slow:       '0.6s',\n                slower:     '0.8s',\n                slowest:    '1s',\n            },\n            transitionTimingFunction: {\n                // Smooth\n                default:        'cubic-bezier(0.380, 0.005, 0.215, 1)',\n\n                // // Common easings\n                // power1: {\n                //     in:         'cubic-bezier(0.550, 0.085, 0.680, 0.530)',\n                //     out:        'cubic-bezier(0.250, 0.460, 0.450, 0.940)',\n                //     inOut:      'cubic-bezier(0.455, 0.030, 0.515, 0.955)',\n                // },\n                // power2: {\n                //     in:         'cubic-bezier(0.550, 0.055, 0.675, 0.190)',\n                //     out:        'cubic-bezier(0.215, 0.610, 0.355, 1.000)',\n                //     inOut:      'cubic-bezier(0.645, 0.045, 0.355, 1.000)',\n                // },\n                // power3: {\n                //     in:         'cubic-bezier(0.895, 0.030, 0.685, 0.220)',\n                //     out:        'cubic-bezier(0.165, 0.840, 0.440, 1.000)',\n                //     inOut:      'cubic-bezier(0.770, 0.000, 0.175, 1.000)',\n                // },\n                // power4: {\n                //     in:         'cubic-bezier(0.755, 0.050, 0.855, 0.060)',\n                //     out:        'cubic-bezier(0.230, 1.000, 0.320, 1.000)',\n                //     inOut:      'cubic-bezier(0.860, 0.000, 0.070, 1.000)',\n                // },\n                // expo: {\n                //     in:         'cubic-bezier(0.950, 0.050, 0.795, 0.035)',\n                //     out:        'cubic-bezier(0.190, 1.000, 0.220, 1.000)',\n                //     inOut:      'cubic-bezier(1.000, 0.000, 0.000, 1.000)',\n                // },\n                // back: {\n                //     in:         'cubic-bezier(0.600, -0.280, 0.735, 0.045)',\n                //     out:        'cubic-bezier(0.175, 00.885, 0.320, 1.275)',\n                //     inOut:      'cubic-bezier(0.680, -0.550, 0.265, 1.550)',\n                // },\n                // sine: {\n                //     in:         'cubic-bezier(0.470, 0.000, 0.745, 0.715)',\n                //     out:        'cubic-bezier(0.390, 0.575, 0.565, 1.000)',\n                //     inOut:      'cubic-bezier(0.445, 0.050, 0.550, 0.950)',\n                // },\n                // circ: {\n                //     in:         'cubic-bezier(0.600, 0.040, 0.980, 0.335)',\n                //     out:        'cubic-bezier(0.075, 0.820, 0.165, 1.000)',\n                //     inOut:      'cubic-bezier(0.785, 0.135, 0.150, 0.860)',\n                // },\n                // slow: {\n                //     out:        'cubic-bezier(.04,1.15,0.4,.99)',\n                // },\n                // bounce:         'cubic-bezier(0.17, 0.67, 0.3, 1.33)',\n                // smooth:         'cubic-bezier(0.380, 0.005, 0.215, 1)',\n            },\n            zIndex: {\n                modal:    '200',\n                header:   '100',\n                above:    '1',\n                default:  '0',\n                below:    '-1',\n            },\n        },\n    },\n    plugins: [],\n} satisfies Config;\n"
  },
  {
    "path": "packages/demo/tsconfig.json",
    "content": "{\n    \"extends\": \"astro/tsconfigs/strict\",\n    \"compilerOptions\": {\n        \"baseUrl\": \".\",\n        \"moduleResolution\": \"Bundler\",\n        \"paths\": {\n            \"@root/*\": [\n                \"./*\"\n            ],\n            \"@src/*\": [\n                \"./src/*\"\n            ],\n            \"@components/*\": [\n                \"./src/components/*\"\n            ],\n            \"@layouts/*\": [\n                \"./src/layouts/*\"\n            ],\n            \"@scripts/*\": [\n                \"./src/scripts/*\"\n            ],\n            \"@styles/*\": [\n                \"./src/styles/*\"\n            ],\n            \"@types/*\": [\n                \"types/*\"\n            ],\n            \"@data/*\": [\n                \"./src/data/*\"\n            ]\n        }\n    }\n}\n"
  },
  {
    "path": "packages/demo/types/global.d.ts",
    "content": "type Seo = {\n    title?: string;\n    description?: string;\n    social?: {\n        facebook?: {\n            title?: string;\n            image?: {\n                url?: string;\n            };\n            description?: string;\n        };\n        twitter?: {\n            creator?: string;\n            title?: string;\n            image?: {\n                url?: string;\n            };\n            description?: string;\n        };\n    },\n    advanced?: {\n        robots?: string[];\n        canonical?: string;\n    };\n};"
  },
  {
    "path": "packages/demo/types/swup.d.ts",
    "content": "type VisitType = {\n    fragmentVisit: any;\n    to: {\n        html: string;\n    };\n};\n"
  },
  {
    "path": "packages/docs/.gitignore",
    "content": "# Dependencies\n/node_modules\n\n# Production\n/build\n\n# Generated files\n.docusaurus\n.cache-loader\n\n# Misc\n.DS_Store\n.env.local\n.env.development.local\n.env.test.local\n.env.production.local\n\nnpm-debug.log*\nyarn-debug.log*\nyarn-error.log*\n"
  },
  {
    "path": "packages/docs/README.md",
    "content": "# Website\n\nThis website is built using [Docusaurus](https://docusaurus.io/), a modern static website generator.\n\n### Installation\n\n```\n$ yarn\n```\n\n### Local Development\n\n```\n$ yarn start\n```\n\nThis command starts a local development server and opens up a browser window. Most changes are reflected live without having to restart the server.\n\n### Build\n\n```\n$ yarn build\n```\n\nThis command generates static content into the `build` directory and can be served using any static contents hosting service.\n\n### Deployment\n\nUsing SSH:\n\n```\n$ USE_SSH=true yarn deploy\n```\n\nNot using SSH:\n\n```\n$ GIT_USER=<Your GitHub username> yarn deploy\n```\n\nIf you are using GitHub pages for hosting, this command is a convenient way to build the website and push to the `gh-pages` branch.\n"
  },
  {
    "path": "packages/docs/babel.config.js",
    "content": "module.exports = {\n  presets: [require.resolve('@docusaurus/core/lib/babel/preset')],\n};\n"
  },
  {
    "path": "packages/docs/docs/documentation/attributes.md",
    "content": "---\nsidebar_position: 3\n---\n\n# Attributes\n\n## data-scroll\n\nEnable viewport detection on an element.\n\n## data-scroll-position\n\n-   **Type:** `string`\n-   **Default:** `start,end`\n\n![Data Scroll Position](/assets/data-scroll-position.jpg)\n\nThis attribute specifies the trigger position of the element within the scroll container when using Locomotive Scroll. It accepts two values: one for the position when the element enters the viewport, and a second for the position when the element leaves the viewport.\n\nThe position is calculated relative to the **Lenis scroll container** (which defaults to `window`, but can be customized via `lenisOptions.wrapper`).\n\nAccepted values are: `'start'`, `'middle'`, `'end'`.\n\n### Examples\n\n![Data Scroll Position](/assets/data-scroll-position-example-1.jpg)\n![Data Scroll Position](/assets/data-scroll-position-example-2.jpg)\n\nHere's an example of using Locomotive Scroll's data-scroll-position attribute on an HTML element:\n\n```html\n<div data-scroll data-scroll-position=\"start, start\"></div>\n```\n\n## data-scroll-offset\n\n-   **Type:** `string`\n-   **Default:** `0,0`\n\n![Data Scroll Offset](/assets/scroll-offset-1.jpg)\n\nSpecifies the trigger offset of the element within the viewport when using the Locomotive Scroll library. It takes two values: one for the offset when the element enters the viewport, and a second for the offset when the element leaves the viewport.\n\nThe offset can be defined in two ways:\n\n-   If specified in percentages, it is relative to the viewport height.\n-   If specified in pixels, it is an absolute value.\n\nFor example:\n\n-   `'100,50%'` represents an offset of `100` pixels for the enter position and `50%` of the viewport height for the leave position.\n-   `'25%, 15%'` represents an offset of `25%` of the viewport height for the enter position and `15%` of the viewport height for the leave position.\n\n### Example\n\n![Data Scroll Offset](/assets/data-scroll-offset-example.jpg)\n\nHere's an example of using Locomotive Scroll's data-scroll-offset attribute on an HTML element:\n\n```html\n<div data-scroll data-scroll-offset=\"400, 200\"></div>\n```\n\n## data-scroll-class\n\n-   **Type:** `string`\n-   **Default:** `is-inview`\n\nSpecifies a custom class to be applied to the element when its offset intersects with the viewport. The default class used is `is-inview`.\n\nYou can provide your own class name as a string value to customize the styling or behavior of the element when it becomes visible within the viewport.\n\n## data-scroll-repeat\n\nSpecifies whether the element's in-view detection should repeat if it is declared.\n\nBy default, the in-view detection of elements is not repeated. **Simply declaring this attribute will enable the repeat behavior for in-view detection of the element.**\n\n## data-scroll-speed\n\n-   **Type:** `number`\n\nSpecifies the parallax speed for the element. The speed is relative to the scroll container size (not pixels), making it predictable across different viewport sizes.\n\n### How it works\n\nThe parallax displacement is calculated using:\n```\ndisplacement = progress × containerSize × speed × -1\n```\n\nWhere:\n- `containerSize` = Height (or width for horizontal) of the Lenis scroll container\n- `progress` = Element's progress through the viewport (`-1` to `1` for normal elements, `0` to `1` for in-fold elements)\n- `speed` = Your specified value\n\n### Examples\n\n**With `data-scroll-speed=\"1\"`:**\n- Normal element: Moves from `+containerHeight` to `-containerHeight` (total = 2× container height)\n- In-fold element: Moves from `0` to `-containerHeight` (total = 1× container height)\n\n**With `data-scroll-speed=\"0.5\"`:**\n- Normal element: Total displacement = 1× container height\n- In-fold element: Total displacement = 0.5× container height\n\n**With `data-scroll-speed=\"-0.3\"` (negative = reversed):**\n- Element moves in opposite direction\n- Total displacement = 0.6× container height\n\n### Touch devices\n\nParallax is **automatically disabled on touch devices** by default for better native scrolling performance. To enable it on mobile/tablets, add the [`data-scroll-enable-touch-speed`](#data-scroll-enable-touch-speed) attribute.\n\n:::tip\nStart with small values like `0.1` to `0.5` for subtle effects. The value is now relative to container size, so effects scale naturally with viewport changes.\n:::\n\n## data-scroll-call\n\n-   **Type:** `string`\n\nThe `data-scroll-call` attribute enables you to trigger a custom event when an element becomes visible within the viewport. This attribute requires a string value that specifies the name of the custom event that you want to trigger.\n\nBy utilizing the `data-scroll-call` attribute, you can define and trigger your own events to perform specific actions or handle certain behaviors when elements scroll into view. These events can be listened to and handled in your JavaScript code using event listeners or any event handling mechanism provided by your framework or library.\n\nHere's an example of how to use the `data-scroll-call` attribute:\n\n```html\n<div data-scroll data-scroll-call=\"scrollEvent\">Trigger</div>\n```\n\n```js\nwindow.addEventListener('scrollEvent', (e) => {\n    const { target, way, from } = e.detail;\n    console.log(`target: ${target}`, `way: ${way}`, `from: ${from}`);\n});\n```\n\n## data-scroll-css-progress\n\nIf you declare this attribute, it will add a CSS variable `--progress` to the element. This variable represents the current progress of the element and ranges between `0` and `1`.\n\nBy adding `--progress` as a CSS variable, you can utilize it in your CSS styles to create dynamic effects or animations based on the scrolling progress of the element.\n\n## data-scroll-event-progress\n\n-   **Type:** `string`\n\nWhen you declare this attribute, it will trigger the custom event that you specify. This event allows you to retrieve the current progress of the element, which ranges between `0` and `1`.\n\nBy utilizing the custom event, you can implement event handlers in your JavaScript code to perform actions or retrieve information based on the scrolling progress of the element.\n\n```html\n<div data-scroll data-scroll-event-progress=\"progressEvent\">\n    Progress custom event\n</div>\n```\n\n```js\nimport LocomotiveScroll from 'locomotive-scroll';\n\nconst locomotiveScroll = new LocomotiveScroll();\n\nwindow.addEventListener('progressEvent', (e) => {\n    const { target, progress } = e.detail;\n    console.log(`target: ${target}`, `progress: ${progress}`);\n});\n```\n\n## data-scroll-to\n\nPrevents the click event and initiates scrolling to a target. If the element is a link (`<a>`), it uses the `href` attribute as the target. Otherwise, if the element has the `data-scroll-to-href` attribute, it uses that as the target.\n\n## data-scroll-to-href\n\n-   **Type:** `string`\n\nSpecifies the target for the `data-scroll-to` action. If the element is a link, the `href` attribute is used as the target. Alternatively, you can specify a custom target using the `data-scroll-to-href` attribute.\n\n## data-scroll-to-offset\n\n-   **Type:** `number`\n\nSpecifies the scroll offset for the `data-scroll-to` action. The value is a number that represents the scroll padding top. It determines the vertical offset from the top of the target element when scrolling to it.\n\n## data-scroll-to-duration\n\n-   **Type:** `number`\n\nSpecifies the duration of the scroll animation for the `data-scroll-to` action. The value is a number representing the scroll duration in seconds. It determines how long the scrolling animation takes to reach the target element.\n\n## data-scroll-ignore-fold\n\nIf an element is within the fold (visible portion of the viewport), its offset is automatically adjusted to start its progress from its starting position. However, if you want to ignore this default behavior and prevent the offset adjustment, you can use the `data-scroll-ignore-fold` attribute.\n\nPlease note that by using the `data-scroll-ignore-fold` attribute, the element's progress will not be influenced by its position within the fold, and its offset will remain unchanged throughout the scrolling process.\n\n## data-scroll-enable-touch-speed\n\nBy default, the parallax effect (`data-scroll-speed`) is **automatically disabled on touch devices** to ensure smooth scrolling performance. Touch devices are detected using `'ontouchstart' in window || navigator.maxTouchPoints > 0`.\n\nIf you want to enable the parallax effect on touch devices, add the `data-scroll-enable-touch-speed` attribute to the element.\n\n**Example:**\n\n```html\n<!-- Parallax disabled on touch devices (default) -->\n<div data-scroll data-scroll-speed=\"0.5\">\n    Parallax only on desktop\n</div>\n\n<!-- Parallax enabled on all devices including touch -->\n<div data-scroll data-scroll-speed=\"0.5\" data-scroll-enable-touch-speed>\n    Parallax on desktop AND mobile\n</div>\n```\n\n**Note:** Enabling parallax on touch devices may impact scrolling smoothness, especially on lower-end mobile devices. Use this attribute judiciously and test thoroughly on target devices.\n"
  },
  {
    "path": "packages/docs/docs/documentation/methods.md",
    "content": "---\nsidebar_position: 2\n---\n\n# Methods\n\n## destroy()\n\nThe `destroy()` method allows you to destroy the Locomotive Scroll instance along with its associated events. It is useful when you want to remove Locomotive Scroll functionality from a specific element or completely clean up the instance.\n\n```js\nconst locomotiveScroll = new LocomotiveScroll();\nlocomotiveScroll.destroy();\n```\n\n## start()\n\nThe `start()` method allows you to manually start the scroll. By default, the scroll automatically starts when you create the Locomotive Scroll instance. However, there may be situations where you need to programmatically control when the scroll starts. In such cases, you can utilize the [autoStart](/documentation/options#autostart) option to have more flexibility and decide whether to initiate the scroll automatically or not.\n\n```js\nconst locomotiveScroll = new LocomotiveScroll({ autoStart: false });\n\n// Starting the locomotive scroll on the next frame\nrequestAnimationFrame(() => {\n    locomotiveScroll.start();\n});\n```\n\n> :bulb: **Tip**: If you prefer not to start Locomotive Scroll automatically, you can utilize the [autoStart](/documentation/options#autostart) option.\n\n## stop()\n\nThe `stop()` method allows you to manually stop the scroll. When you call this method, the scroll motion will come to a halt.\n\n```js\nconst locomotiveScroll = new LocomotiveScroll();\n\n// Stopping locomotive-scroll on the next frame\nrequestAnimationFrame(() => {\n    locomotiveScroll.stop();\n});\n```\n> :bulb: **Tip**: If you prefer not to start Locomotive Scroll automatically, you can utilize the [autoStart](/documentation/options#autostart) option.\n\n## resize()\n\nThe `resize()` method allows you to manually trigger the resize callback of the Locomotive Scroll instance. This is useful when you need to handle resizing events programmatically or when you want to manually update the scroll calculations after a layout change.\n\n> :bulb: **Note**: Locomotive Scroll automatically handles resize events by synchronizing with Lenis's internal ResizeObservers (`onContentResize` and `onWrapperResize`). Manual resizing is rarely needed unless you're making dynamic layout changes that Lenis doesn't detect.\n\n```js\nconst locomotiveScroll = new LocomotiveScroll();\nlocomotiveScroll.resize();\n```\n\n## removeScrollElements($oldContainer)\n\nThe `removeScrollElements($oldContainer)` method allows you to dynamically unobserve scroll elements (`[data-scroll]`) by providing their container. This is particularly useful when you're updating the DOM dynamically, such as through Ajax fetching or other operations that add or remove elements from the page.\n\n-   **Parameters:**\n    -   `$oldContainer` (_HTMLElement_): The `NodeElement` that has been removed from the DOM. This container should be the parent element that contains the scroll elements you want to unobserve.\n\nHere's an example of how to use the `removeScrollElements($oldContainer)` method:\n\n```js\nconst locomotiveScroll = new LocomotiveScroll();\nconst $oldContainer = document.getElementById('containerToRemove');\n\n// Call the method to remove scroll elements from the old container\nlocomotiveScroll.removeScrollElements($oldContainer);\n```\n\n## addScrollElements($newContainer)\n\nThe `addScrollElements($newContainer)` method allows you to dynamically observe scroll elements (`[data-scroll]`) by providing their container. This is particularly useful when you're updating the DOM dynamically, such as through Ajax fetching or other operations that add or remove elements from the page.\n\n-   **Parameters:**\n    -   `$newContainer` (_HTMLElement_): The `NodeElement` that has been added from the DOM. This container should be the parent element that contains the scroll elements you want to observe.\n\nHere's an example of how to use the `addScrollElements($newContainer)` method:\n\n```js\nconst locomotiveScroll = new LocomotiveScroll();\nconst $newContainer = document.getElementById('containerToAdd');\n\n// Call the method to add scroll elements from the new container\nlocomotiveScroll.addScrollElements($newContainer);\n```\n\n## scrollTo(target, options)\n\nThe `scrollTo(target, options)` method allows you to scroll to a specific target on the page.\n\n-   **Parameters:**\n    -   `target` (_optional, number / HTMLElement / string_): The target to scroll to. It can be a `number` (scroll position), `HTMLElement` (DOM element), or `string` (CSS selector or keyword: `top`, `left`, `start`, `bottom`, `right`, `end`).\n    -   `options` (_optional, ILenisScrollToOptions_): An options object that configures the scroll behavior. The available options are based on [Lenis's scroll-to options](https://github.com/darkroomengineering/lenis#instance-methods):\n        -   `offset` (_number_): A number equivalent to `scroll-padding-top`. Specifies the offset from the top of the target element.\n        -   `lerp` (_number_): Animation lerp intensity.\n        -   `duration` (_number_): The duration of the scroll animation in seconds.\n        -   `immediate` (_boolean_): If set to `true`, it ignores the duration and easing and performs an immediate scroll.\n        -   `lock` (_boolean_): Whether or not to prevent the user from scrolling until the target is reached.\n        -   `force` (_boolean_): Reach the target even if the instance is stopped.\n        -   `onComplete` (_function_): A callback function called when the target is reached.\n        -   `easing` (_function_): A smooth scroll easing function.\n\nBy calling `scrollTo(target, options)`, Locomotive Scroll will smoothly scroll to the specified target on the page, taking into account the provided options.\n\n```js\nimport LocomotiveScroll from 'locomotive-scroll';\n\nconst locomotiveScroll = new LocomotiveScroll();\nconst $target = document.getElementById('jsTarget');\n\nfunction scrollTo(params) {\n    const { target, options } = params;\n    locomotiveScroll.scrollTo(target, options);\n}\n\nscrollTo({ target: $target, options: {} });\n```\n"
  },
  {
    "path": "packages/docs/docs/documentation/options.md",
    "content": "---\nsidebar_position: 1\n---\n\n# Options\n\n## lenisOptions\n\n-   **Type:** `object`\n\n_(Optional)_ The `lenisOptions` parameter is an optional object that allows you to configure specific settings based on some of [Lenis's instance settings](https://github.com/darkroomengineering/lenis#instance-settings):\n\n-   `wrapper` (**HTMLElement|Window**): Specifies the element that will be used as the scroll container. Defaults to `window` for full-page scrolling. Can be set to a custom element for contained scrolling (e.g., `document.querySelector('.scroll-container')`).\n-   `content` (**HTMLElement**): Specifies the element that contains the content that will be scrolled, usually `wrapper`'s direct child. Defaults to `document.documentElement`. Can be set to a custom element when using a custom wrapper.\n-   `lerp` (**number**): Specifies the intensity of linear interpolation (lerp) between frames, ranging from 0 to 1.\n-   `duration` (**number**): Specifies the duration of the animation.\n-   `orientation` (**string**): Specifies whether the scrolling is `vertical` or `horizontal`. It adds a `data-scroll-orientation` attribute on the `<html>` tag.\n-   `gestureOrientation` (**boolean**): Specifies the orientation of the gestures. It can be set to `vertical`, `horizontal`, or `both`.\n-   `smoothWheel` (**boolean**): Specifies whether to enable smooth scrolling for mouse wheel events.\n-   `smoothTouch` (**boolean**): Specifies whether to enable smooth scrolling for touch events. Note that it is disabled by default because it is impossible to mimic the native smoothness of touch devices.\n-   `wheelMultiplier` (**number**): Specifies the multiplier to use for mouse wheel events.\n-   `touchMultiplier` (**number**): Specifies the multiplier to use for touch events.\n-   `normalizeWheel` (**boolean**): Specifies whether to normalize wheel inputs across different browsers.\n-   `easing` (**function**): Specifies the rate of change of a specific value. Our default easing is custom, but you can choose one from [Easings.net](https://easings.net/).\n\nHere's an example of using `lenisOptions` with its default values:\n\n```js\nconst locomotiveScroll = new LocomotiveScroll({\n    lenisOptions: {\n        wrapper: window,\n        content: document.documentElement,\n        lerp: 0.1,\n        duration: 1.2,\n        orientation: 'vertical',\n        gestureOrientation: 'vertical',\n        smoothWheel: true,\n        smoothTouch: false,\n        wheelMultiplier: 1,\n        touchMultiplier: 2,\n        normalizeWheel: true,\n        easing: (t) => Math.min(1, 1.001 - Math.pow(2, -10 * t)), // https://www.desmos.com/calculator/brs54l4xou\n    },\n});\n```\n\n### Custom Scroll Container\n\nYou can use a custom scroll container instead of the default full-page scroll:\n\n```js\nconst locomotiveScroll = new LocomotiveScroll({\n    lenisOptions: {\n        wrapper: document.querySelector('.scroll-container'),\n        content: document.querySelector('.scroll-content'),\n    },\n});\n```\n\n```html\n<div class=\"scroll-container\" style=\"height: 100vh; overflow: hidden;\">\n    <div class=\"scroll-content\">\n        <div data-scroll data-scroll-speed=\"0.5\">Parallax element</div>\n    </div>\n</div>\n```\n\n**Requirements:**\n- The `wrapper` must have a fixed height and `overflow: hidden` (or `auto`/`scroll`)\n- The `content` must be a direct child of the wrapper\n- Intersection Observers will automatically use the wrapper as their root\n- Resize detection is automatically synchronized with Lenis's ResizeObservers\n\n## triggerRootMargin\n\n-   **Type:** `string`\n-   **Default:** `'-1px -1px -1px -1px'`\n\n_(Optional)_ Specifies the root margin for scroll elements that need to be triggered by the [IntersectionObserver](https://developer.mozilla.org/en-US/docs/Web/API/IntersectionObserver/rootMargin).\n\n```js\n// Default Value\nconst locomotiveScroll = new LocomotiveScroll({\n    triggerRootMargin: '-1px -1px -1px -1px',\n});\n```\n\n## rafRootMargin\n\n-   **Type:** `string`\n-   **Default:** `'100% 100% 100% 100%'`\n\n_(Optional)_ Specifies the root margin for scroll elements that need to be triggered by the [IntersectionObserver](https://developer.mozilla.org/en-US/docs/Web/API/IntersectionObserver/rootMargin) based on a **RequestAnimationFrame**. This option is relevant for elements with any of the following attributes: `data-scroll-offset`, `data-scroll-position`, `data-scroll-css-progress`, `data-scroll-event-progress`, `data-scroll-speed`.\n\n```js\n// Default Value\nconst locomotiveScroll = new LocomotiveScroll({\n    rafRootMargin: '100% 100% 100% 100%',\n});\n```\n\n## autoStart\n\n-   Type: `boolean`\n-   Default: `true`\n\n_(Optional)_  Enable or disable the RAF (Request Animation Frame) starting. By default, the RAF starts automatically when Locomotive Scroll is initialized.\n\nIf you want to manually control when the RAF starts, you can set `autoStart` to `false`.\n\n```js\n// Default Value\nconst locomotiveScroll = new LocomotiveScroll({\n    autoStart: false,\n});\n\n// Manually start the RAF\nsetTimeout(() => {\n    locomotiveScroll.start();\n}, 2000)\n```\n\n## scrollCallback\n\n-   **Type:** `function`\n\n_(Optional)_ Specifies a callback function that can return an object with the following properties: `{ scroll, limit, velocity, direction, progress }`. This functionality is made possible by Lenis's scroll callback feature.\n\n```js\nimport LocomotiveScroll from 'locomotive-scroll';\n\nfunction onScroll({ scroll, limit, velocity, direction, progress }) {\n    console.log(scroll, limit, velocity, direction, progress);\n}\n\nconst locomotiveScroll = new LocomotiveScroll({\n    scrollCallback: onScroll,\n});\n```\n\n## initCustomTicker\n\n-   **Type:** `function`\n\n_(Optional)_ Specifies a callback function to initialize an external ticker instead of Locomotive Scroll's default request animation frame. The `destroyCustomTicker` function also needs to be declared.\n\nYou can use an external ticker by following this example, which overrides the default request animation frame used by Locomotive Scroll:\n\n```js\nimport LocomotiveScroll from 'locomotive-scroll';\nimport { gsap } from 'gsap/all';\n\nconst locomotiveScroll = new LocomotiveScroll({\n    initCustomTicker: (render) => {\n        gsap.ticker.add(render);\n    },\n    destroyCustomTicker: (render) => {\n        gsap.ticker.remove(render);\n    },\n});\n```\n\n## destroyCustomTicker\n\n-   **Type:** `function`\n\n_(Optional)_ Specifies a callback function to destroy an external ticker instead of Locomotive Scroll's default request animation frame. The `initCustomTicker` function also needs to be declared.\n\nYou can use an external ticker by following this example, which overrides the default request animation frame used by Locomotive Scroll:\n\n```js\nimport LocomotiveScroll from 'locomotive-scroll';\nimport { gsap } from 'gsap/all';\n\nconst locomotiveScroll = new LocomotiveScroll({\n    initCustomTicker: (render) => {\n        gsap.ticker.add(render);\n    },\n    destroyCustomTicker: (render) => {\n        gsap.ticker.remove(render);\n    },\n});\n```\n"
  },
  {
    "path": "packages/docs/docs/examples.md",
    "content": "---\nsidebar_position: 4\n---\n\n# Examples\n\nBelow are several CodeSandbox examples showcasing different usage scenarios:\n\n1. [Basic Usage](https://codesandbox.io/s/basic-76t7lh): Demonstrates the basic setup and usage of Locomotive Scroll with parallax effect on elements.\n2. [Scroll Call](https://codesandbox.io/s/scroll-call-k6eqen): Demonstrates how to trigger a custom event based on scroll position using Locomotive Scroll.\n3. [Progress](https://codesandbox.io/s/progress-srtqx9): Demonstrates how to extract the scroll progress of an element.\n4. [GSAP Timeline](https://codesandbox.io/s/gsap-timeline-4kk8dc): Demonstrates how to synchronize a GSAP animation with the scroll progress of an element.\n5. [Dynamic Content](https://codesandbox.io/p/sandbox/dynamic-content-5m30r6): Shows how to handle dynamic content and layout changes with Locomotive Scroll.\n6. [Next.js Integration](https://codesandbox.io/p/devbox/cocky-star-5vcklc?file=%2Fapp%2Fpage.tsx): Shows how to integrate Locomotive Scroll with Next.js.\n7. [Third Party Injected Popups](https://codesandbox.io/p/sandbox/third-party-injected-popups-xch5tq): Shows how to handle third party injected popups with Locomotive Scroll.\n8. [GSAP ScrollTrigger](https://codesandbox.io/p/sandbox/gsap-scrolltrigger-tt7sjd): Demonstrates how to synchronize a GSAP ScrollTrigger animation with the scroll progress of an element.\n\nFeel free to explore these examples to gain a better understanding of different use cases and how Locomotive Scroll can be utilized in your projects.\n"
  },
  {
    "path": "packages/docs/docs/extras/limitations.md",
    "content": "---\nsidebar_position: 1\n---\n\n# Limitations\n\n> We encourage the open-source community to develop and share their own solutions to overcome limitations in Locomotive Scroll.\n\n## Lenis\n\nLenis already have its own [considerations](https://github.com/darkroomengineering/lenis#considerations). We recommend reviewing them before using Locomotive Scroll to ensure a smooth integration and avoid any potential conflicts.\n\n## SSR\n\nDue to Locomotive Scroll's reliance on the window reference and Intersection Observer, it may not be fully compatible with server-side rendering setups. SSR typically involves rendering the web page on the server before sending it to the client, and certain client-side dependencies may not function properly in this context. Therefore, when using Locomotive Scroll with SSR, it's important to carefully consider and test its compatibility to ensure optimal functionality.\n\n## Third Party Injected Popups\n\nSome third-party JavaScript used on websites may inject popups or modals that require scrolling. In certain cases, conflicts can arise when the default Lenis `wrapper` (typically the `window`) captures the scroll event. Normally, we can [resolve this](https://github.com/darkroomengineering/lenis#use-the-data-lenis-prevent-attribute-on-nested-scroll-elements-in-addition-we-advise-you-to-add-overscroll-behavior-contain-on-this-element) by adding the `data-lenis-prevent` data attribute to the DOM element that requires inner scrolling, such as a popup. However, this solution cannot be used when the DOM is injected dynamically.\n\nSince Lenis v1.1.0, you can use the `prevent` option to manually prevent scroll smoothing based on elements traversed by events. If the function returns `true`, it will prevent the scroll from being smoothed.\n\nHTML:\n\n```html\n<main class=\"main\">\n    <h1 class=\"title\">Third Party Injected Popups</h1>\n\n    <!-- Injected popup DOM -->\n    <div id=\"modalSelector\">\n        <h2>Scroll inside the modal</h2>\n        <!-- Modal content -->\n    </div>\n</main>\n```\n\nJavaScript:\n\n```js\nimport LocomotiveScroll from 'locomotive-scroll';\n\nconst locomotiveScroll = new LocomotiveScroll({\n    lenisOptions: {\n        prevent: (node) => node.getAttribute('id') === 'modalSelector',\n    },\n});\n```\n\nYou can check out the [example](https://codesandbox.io/p/sandbox/third-party-injected-popups-xch5tq) for more details."
  },
  {
    "path": "packages/docs/docs/extras/migration-guide.md",
    "content": "---\nsidebar_position: 1\n---\n\n# Migration Guide: v4 to v5\n\nThis guide will help you migrate from Locomotive Scroll v4 to v5. Version 5 is a complete rewrite built on [Lenis](https://github.com/darkroomengineering/lenis), offering better performance, smaller bundle size, and improved TypeScript support.\n\n:::tip\nLocomotive Scroll v5 is simpler and more performant than v4, but it requires some changes to your code. Take your time to understand the new patterns.\n:::\n\n## Overview of Changes\n\n### What's New\n\n-   **Built on Lenis** — Modern smooth scroll engine instead of Virtual Scroll\n-   **Smaller Bundle** — 9.4kB (v5) vs ~12.1kB (v4) gzipped\n-   **TypeScript First** — Fully typed with better autocomplete\n-   **Simplified API** — Fewer options, clearer patterns\n-   **Better Performance** — Dual Intersection Observer strategy\n-   **Custom Scroll Containers** — Support for contained scrolling\n-   **Native Events** — CustomEvents instead of ModularJS\n\n### What's Removed\n\n-   ❌ **ModularJS support** — Use native CustomEvents instead\n-   ❌ **`data-scroll-container`** — No longer required\n-   ❌ **`data-scroll-section`** — No longer needed for performance\n-   ❌ **Custom scrollbar** — Use Lenis scrollbar or native scrollbar\n-   ❌ **`data-scroll-sticky`** — Use CSS `position: sticky` instead\n-   ❌ **`data-scroll-delay`** — No longer available\n-   ❌ **`data-scroll-direction`** — Parallax follows scroll orientation\n-   ❌ **`data-scroll-target`** — No longer available\n\n---\n\n## Installation\n\n### v4\n\n```bash\nnpm install locomotive-scroll@4.1.4\n```\n\n### v5\n\n```bash\nnpm install locomotive-scroll\n```\n\n---\n\n## Basic Setup\n\n### v4: Required Container\n\n```html\n<div data-scroll-container>\n    <div data-scroll-section>\n        <h1 data-scroll>Hey</h1>\n    </div>\n</div>\n```\n\n```js\nimport LocomotiveScroll from 'locomotive-scroll';\n\nconst scroll = new LocomotiveScroll({\n    el: document.querySelector('[data-scroll-container]'),\n    smooth: true,\n});\n```\n\n### v5: Simpler Setup\n\n```html\n<main>\n    <h1 data-scroll>Hey</h1>\n</main>\n```\n\n```js\nimport LocomotiveScroll from 'locomotive-scroll';\n\nconst scroll = new LocomotiveScroll();\n```\n\n:::info\nIn v5, smooth scrolling is enabled by default through Lenis. No need for `data-scroll-container` or `data-scroll-section`.\n:::\n\n---\n\n## Instance Options\n\n### v4 → v5 Mapping\n\n| v4 Option            | v5 Equivalent                  | Notes                                           |\n| -------------------- | ------------------------------ | ----------------------------------------------- |\n| `el`                 | `lenisOptions.wrapper`         | Now inside `lenisOptions`                       |\n| `smooth`             | ✅ Always enabled              | Smooth scrolling is default behavior            |\n| `direction`          | `lenisOptions.orientation`     | Values: `'vertical'` or `'horizontal'`          |\n| `lerp`               | `lenisOptions.lerp`            | Same concept, inside `lenisOptions`             |\n| `multiplier`         | `lenisOptions.wheelMultiplier` | Renamed for clarity                             |\n| `touchMultiplier`    | `lenisOptions.touchMultiplier` | Same, inside `lenisOptions`                     |\n| `class`              | ❌ Removed                     | Use `data-scroll-class` attribute instead       |\n| `offset`             | `triggerRootMargin`            | Now uses IntersectionObserver rootMargin format |\n| `repeat`             | `data-scroll-repeat`           | Now per-element attribute                       |\n| `initClass`          | ❌ Removed                     | No longer needed                                |\n| `scrollingClass`     | ❌ Removed                     | Use scroll event to detect scrolling            |\n| `getDirection`       | ✅ Available                   | Access via `lenisInstance.direction`            |\n| `getSpeed`           | ✅ Available                   | Access via `lenisInstance.velocity`             |\n| `scrollbarContainer` | ❌ Removed                     | Use Lenis scrollbar or native                   |\n| `scrollbarClass`     | ❌ Removed                     | Use Lenis scrollbar or native                   |\n\n### v4 Example\n\n```js\nconst scroll = new LocomotiveScroll({\n    el: document.querySelector('[data-scroll-container]'),\n    smooth: true,\n    direction: 'vertical',\n    lerp: 0.1,\n    multiplier: 1,\n    class: 'is-inview',\n    scrollbarClass: 'c-scrollbar',\n});\n```\n\n### v5 Equivalent\n\n```js\nconst scroll = new LocomotiveScroll({\n    lenisOptions: {\n        orientation: 'vertical',\n        lerp: 0.1,\n        wheelMultiplier: 1,\n    },\n});\n\n// Access Lenis directly for more control\nconsole.log(scroll.lenisInstance.direction); // Get direction\nconsole.log(scroll.lenisInstance.velocity); // Get speed\n```\n\n---\n\n## Data Attributes\n\n### Removed Attributes\n\n| v4 Attribute            | v5 Alternative                |\n| ----------------------- | ----------------------------- |\n| `data-scroll-container` | ❌ Remove it (not needed)     |\n| `data-scroll-section`   | ❌ Remove it (not needed)     |\n| `data-scroll-sticky`    | Use CSS `position: sticky`    |\n| `data-scroll-delay`     | ❌ Not available              |\n| `data-scroll-direction` | ❌ Follows scroll orientation |\n| `data-scroll-target`    | ❌ Not available              |\n\n### Modified Attributes\n\n| Attribute              | v4 Behavior                           | v5 Behavior                                                            |\n| ---------------------- | ------------------------------------- | ---------------------------------------------------------------------- |\n| `data-scroll-speed`    | Parallax effect with arbitrary values | ✅ **Recalculated based on scroll container size** (see details below) |\n| `data-scroll-call`     | Triggers ModularJS method             | Now triggers **native CustomEvent**                                    |\n| `data-scroll-offset`   | `\"bottom,top\"` format                 | ✅ Same format                                                         |\n| `data-scroll-position` | Based on window position              | Now based on **Lenis scroll container** position                       |\n\n### New Attributes\n\n| Attribute                        | Description                          |\n| -------------------------------- | ------------------------------------ |\n| `data-scroll-css-progress`       | Adds `--progress` CSS variable (0-1) |\n| `data-scroll-event-progress`     | Emits progress via CustomEvent       |\n| `data-scroll-enable-touch-speed` | Enable parallax on touch devices     |\n\n---\n\n## Parallax\n\n### v4\n\n```html\n<div data-scroll data-scroll-speed=\"2\">Fast parallax</div>\n```\n\n### v5\n\n```html\n<!-- Parallax disabled on touch by default -->\n<div data-scroll data-scroll-speed=\".5\">Fast parallax (desktop only)</div>\n\n<!-- Enable on touch devices -->\n<div data-scroll data-scroll-speed=\".5\" data-scroll-enable-touch-speed>\n    Fast parallax (all devices)\n</div>\n```\n\n:::warning Key Changes\n\n1. **Parallax is automatically disabled on touch devices in v5** to use native scrolling. Use `data-scroll-enable-touch-speed` to override this behavior.\n2. **Speed calculation completely redesigned** - Now based on scroll container size, not arbitrary values.\n   :::\n\n### How `data-scroll-speed` Works in v5\n\nThe parallax calculation has been **completely redesigned** in v5 to be more predictable and based on the scroll container size.\n\n**Formula:**\n\n```\ntranslateValue = progress × containerSize × speed × -1\n```\n\nWhere:\n\n-   `containerSize` = Height (vertical) or width (horizontal) of Lenis scroll container\n-   `progress` ranges from `-1` to `1` for normal elements\n-   `progress` ranges from `0` to `1` for elements visible on page load (in fold)\n\n**Examples:**\n\nWith `data-scroll-speed=\"1\"` and vertical scrolling:\n\n-   **Normal element**: Moves from `+containerHeight` to `-containerHeight` (total displacement = 2× container height)\n-   **In-fold element**: Moves from `0` to `-containerHeight` (total displacement = 1× container height)\n\nWith `data-scroll-speed=\"0.5\"`:\n\n-   **Normal element**: Moves from `+0.5×containerHeight` to `-0.5×containerHeight` (total = 1× container height)\n-   **In-fold element**: Moves from `0` to `-0.5×containerHeight` (total = 0.5× container height)\n\nWith `data-scroll-speed=\"-1\"` (reversed):\n\n-   **Normal element**: Moves from `-containerHeight` to `+containerHeight` (opposite direction)\n\n:::tip Migration Tip\n**v4 to v5 speed conversion:**\n\n-   v4 speeds were arbitrary values\n-   v5 speeds are relative to container size\n-   Start with smaller values (0.1 to 0.5) and adjust based on container size\n-   Test with different viewport sizes since it's now proportional\n    :::\n\n---\n\n## Events & Callbacks\n\n### v4: ModularJS Integration\n\n```html\n<div data-scroll data-scroll-call=\"myMethod, MyModule\">Trigger</div>\n```\n\n```js\nscroll.on('call', (func) => {\n    this.call(...func); // ModularJS\n});\n```\n\n### v5: Native CustomEvents\n\n```html\n<div data-scroll data-scroll-call=\"videoTrigger\">Trigger</div>\n```\n\n```js\nwindow.addEventListener('videoTrigger', (e) => {\n    const { target, way, from } = e.detail;\n    // way: 'enter' | 'leave'\n    // from: 'start' | 'end'\n\n    if (way === 'enter') {\n        target.querySelector('video').play();\n    }\n});\n```\n\n:::tip Migration Tip\nReplace all ModularJS `data-scroll-call` patterns with native CustomEvent listeners. It's simpler and has no dependencies!\n:::\n\n---\n\n## Scroll Events\n\n### v4\n\n```js\nscroll.on('scroll', (args) => {\n    console.log(args.scroll.y);\n    console.log(args.direction);\n    console.log(args.speed);\n});\n```\n\n### v5\n\n```js\nconst scroll = new LocomotiveScroll({\n    scrollCallback: ({ scroll, velocity, direction, progress }) => {\n        console.log(scroll); // Current scroll position\n        console.log(velocity); // Scroll speed\n        console.log(direction); // 1 (down/right), -1 (up/left), 0 (stopped)\n        console.log(progress); // 0 to 1\n    },\n});\n```\n\n---\n\n## Progress Tracking\n\n### v4: Using `data-scroll-id`\n\n```html\n<h1 data-scroll data-scroll-id=\"hero\">Hero</h1>\n```\n\n```js\nscroll.on('scroll', (args) => {\n    if (args.currentElements['hero']) {\n        let progress = args.currentElements['hero'].progress;\n        console.log(progress); // 0 to 1\n    }\n});\n```\n\n### v5: Using Progress Events\n\n```html\n<h1 data-scroll data-scroll-event-progress=\"heroProgress\">Hero</h1>\n```\n\n```js\nwindow.addEventListener('heroProgress', (e) => {\n    console.log(e.detail.progress); // 0 to 1\n});\n```\n\n### v5: Using CSS Variables\n\n```html\n<h1 data-scroll data-scroll-css-progress>Hero</h1>\n```\n\n```css\n[data-scroll-css-progress] {\n    opacity: calc(var(--progress) * 1);\n    transform: translateY(calc((1 - var(--progress)) * 100px));\n}\n```\n\n---\n\n## Methods\n\n### Updated Methods\n\n| Method             | v4  | v5                       | Notes                 |\n| ------------------ | --- | ------------------------ | --------------------- |\n| `destroy()`        | ✅  | ✅                       | Same API              |\n| `start()`          | ✅  | ✅                       | Same API              |\n| `stop()`           | ✅  | ✅                       | Same API              |\n| `scrollTo(target)` | ✅  | ✅                       | Delegated to Lenis    |\n| `update()`         | ✅  | ❌ Renamed to `resize()` | Manual resize trigger |\n| `init()`           | ✅  | ❌ Removed               | No longer needed      |\n\n### v4\n\n```js\nscroll.update();\nscroll.destroy();\nscroll.init(); // Reinitialize\n```\n\n### v5\n\n```js\nscroll.resize(); // Rarely needed (auto-synced with Lenis)\nscroll.destroy();\n// No init() - create new instance instead\n```\n\n---\n\n## Sticky Elements\n\n### v4: Using `data-scroll-sticky`\n\n```html\n<div data-scroll data-scroll-sticky data-scroll-target=\"#target\">\n    Sticky element\n</div>\n\n<div id=\"target\">Target</div>\n```\n\n### v5: Use CSS `position: sticky`\n\n```html\n<div class=\"sticky-element\">Sticky element</div>\n```\n\n```css\n.sticky-element {\n    position: sticky;\n    top: 0;\n}\n```\n\n:::info Why?\nCSS `position: sticky` is performant, native, and doesn't require JavaScript. v5 removed custom sticky implementation in favor of the native solution.\n:::\n\n---\n\n## Custom Scroll Containers\n\n### v4: Not Supported\n\nIn v4, you could only do full-page scrolling.\n\n### v5: Fully Supported\n\n```js\nconst scroll = new LocomotiveScroll({\n    lenisOptions: {\n        wrapper: document.querySelector('.scroll-container'),\n        content: document.querySelector('.scroll-content'),\n    },\n});\n```\n\n```html\n<div class=\"scroll-container\" style=\"height: 100vh; overflow: hidden;\">\n    <div class=\"scroll-content\">\n        <div data-scroll data-scroll-speed=\"0.5\">Parallax works here too!</div>\n    </div>\n</div>\n```\n\n---\n\n## Performance Improvements\n\n### v4 Performance Patterns\n\n```html\n<!-- Recommended: Split into sections for better performance -->\n<div data-scroll-container>\n    <div data-scroll-section>\n        <!-- Content here -->\n    </div>\n    <div data-scroll-section>\n        <!-- More content -->\n    </div>\n</div>\n```\n\n### v5 Performance (Automatic)\n\nv5 uses a **dual Intersection Observer strategy** that automatically optimizes performance:\n\n-   **Trigger IO** — For simple in-view detection (classes, callbacks)\n-   **RAF IO** — For continuous animations (parallax, progress)\n\nElements only subscribe to RAF when:\n\n1. They're **visible** (detected by IO)\n2. They need **continuous updates** (parallax, progress tracking)\n\n**No manual optimization needed!**\n\n---\n\n## Complete Migration Checklist\n\n### HTML Changes\n\n-   [ ] Remove all `data-scroll-container` attributes\n-   [ ] Remove all `data-scroll-section` attributes\n-   [ ] Remove `data-scroll-sticky` → use CSS `position: sticky`\n-   [ ] Remove `data-scroll-delay` → no replacement\n-   [ ] Remove `data-scroll-direction` → follows scroll orientation\n-   [ ] Remove `data-scroll-target` → no replacement\n-   [ ] Update ModularJS `data-scroll-call` → use simple event names\n-   [ ] Consider adding `data-scroll-enable-touch-speed` for mobile parallax\n\n### JavaScript Changes\n\n-   [ ] Remove `el` option → use `lenisOptions.wrapper` if needed\n-   [ ] Remove `smooth` option → always enabled\n-   [ ] Rename `direction` → `lenisOptions.orientation`\n-   [ ] Move scroll options into `lenisOptions` object\n-   [ ] Replace `scroll.on('call', ...)` → `window.addEventListener(eventName, ...)`\n-   [ ] Replace `scroll.on('scroll', ...)` → `scrollCallback` option\n-   [ ] Replace `scroll.update()` → `scroll.resize()` (rarely needed)\n-   [ ] Remove `scroll.init()` → recreate instance instead\n-   [ ] Remove custom scrollbar code → use native or Lenis scrollbar\n\n### CSS Changes\n\n-   [ ] Remove locomotive-scroll v4 CSS\n-   [ ] Add locomotive-scroll v5 CSS (minimal)\n-   [ ] Replace sticky elements → use `position: sticky`\n-   [ ] Update any custom scrollbar styles → use Lenis scrollbar\n\n---\n\n## Example: Complete v4 to v5 Migration\n\n### Before (v4)\n\n```html\n<div data-scroll-container>\n    <div data-scroll-section>\n        <h1 data-scroll data-scroll-id=\"hero\">Hero</h1>\n        <div data-scroll data-scroll-speed=\"2\">Parallax</div>\n        <div data-scroll data-scroll-call=\"videoPlay, VideoModule\">Video</div>\n        <div data-scroll-sticky data-scroll-target=\"#end\">Sticky</div>\n    </div>\n    <div id=\"end\" data-scroll-section>End</div>\n</div>\n```\n\n```js\nimport LocomotiveScroll from 'locomotive-scroll';\n\nconst scroll = new LocomotiveScroll({\n    el: document.querySelector('[data-scroll-container]'),\n    smooth: true,\n    direction: 'vertical',\n    lerp: 0.1,\n    class: 'is-inview',\n});\n\nscroll.on('scroll', (args) => {\n    if (args.currentElements['hero']) {\n        console.log(args.currentElements['hero'].progress);\n    }\n});\n\nscroll.on('call', (func) => {\n    this.call(...func); // ModularJS\n});\n```\n\n### After (v5)\n\n```html\n<main>\n    <h1 data-scroll data-scroll-event-progress=\"heroProgress\">Hero</h1>\n    <div data-scroll data-scroll-speed=\"2\">Parallax</div>\n    <div data-scroll data-scroll-call=\"videoPlay\">Video</div>\n    <div class=\"sticky\">Sticky</div>\n    <div>End</div>\n</main>\n```\n\n```js\nimport LocomotiveScroll from 'locomotive-scroll';\n\nconst scroll = new LocomotiveScroll({\n    lenisOptions: {\n        orientation: 'vertical',\n        lerp: 0.1,\n    },\n    scrollCallback: ({ scroll, velocity, direction, progress }) => {\n        // Global scroll callback if needed\n    },\n});\n\n// Progress tracking\nwindow.addEventListener('heroProgress', (e) => {\n    console.log(e.detail.progress);\n});\n\n// Video callback\nwindow.addEventListener('videoPlay', (e) => {\n    const { target, way } = e.detail;\n    if (way === 'enter') {\n        target.querySelector('video').play();\n    }\n});\n```\n\n```css\n.sticky {\n    position: sticky;\n    top: 0;\n}\n```\n\n---\n\n## Need Help?\n\n-   Check the [documentation](/documentation/options) for full API reference\n-   Review [examples](/examples) for common patterns\n-   Open an issue on [GitHub](https://github.com/locomotivemtl/locomotive-scroll/issues) for bugs\n\n**Happy scrolling with v5! 🚀**\n"
  },
  {
    "path": "packages/docs/docs/extras/showcase.md",
    "content": "---\nsidebar_position: 2\n---\n\n# Showcase\n\nHere is a curated list of websites that utilize Locomotive Scroll:\n\n- [Locomotive](https://locomotive.ca/)\n- [Destigmatize](https://2024.destigmatize.ca/)\n- [Scout Motors](https://www.scoutmotors.com/)\n- [Lightship](https://lightshiprv.com/)\n- [Vooban](https://vooban.com/)\n- [Construction Desourdy](https://www.constructiondesourdy.com/)\n- [GKC](https://gkc.ca/)\n- [Troa](https://www.troa.fr/)\n- [Vazzi](https://vazzi.fun/)\n- [21TSI](https://21tsi.com/)\n- [Eduard Bodak](https://www.eduardbodak.com/)\n- [Mindmarket](https://mindmarket.com/)\n\nPlease note that these websites are provided as examples to showcase the potential of Locomotive Scroll. Each website may have its own unique design, features, and implementation of Locomotive Scroll.\n\nFeel free to explore these websites to gain inspiration and insights on how Locomotive Scroll can be applied in various contexts."
  },
  {
    "path": "packages/docs/docs/getting-started/installation.md",
    "content": "---\nsidebar_position: 1\n---\n\n# Installation\n\nTo install Locomotive Scroll, you have two options:\n\n## NPM (Recommended)\n\nYou can install it via NPM by running the following command:\n\n```bash\nnpm install locomotive-scroll\n```\n\nThis will install the latest version.\n\n## CDN\n\nAlternatively, you can use a CDN to include Locomotive Scroll directly in your HTML:\n\n```html\n<script src=\"https://cdn.jsdelivr.net/npm/locomotive-scroll/bundled/locomotive-scroll.min.js\"></script>\n<script>\n    const locomotiveScroll = new LocomotiveScroll();\n</script>\n```\n\n## Package Information\n\nFor more details and package information, you can visit the [NPM package page](https://www.npmjs.com/package/locomotive-scroll).\n"
  },
  {
    "path": "packages/docs/docs/getting-started/usage.md",
    "content": "---\nsidebar_position: 2\n---\n\n# Usage\n\n## Javascript\n\n### With a bundler\n\n```js\nimport LocomotiveScroll from 'locomotive-scroll';\n\nconst locomotiveScroll = new LocomotiveScroll();\n```\n\n### Without a bundler\n\n```html\n<script src=\"https://cdn.jsdelivr.net/npm/locomotive-scroll/bundled/locomotive-scroll.min.js\"></script>\n<script>\n    const locomotiveScroll = new LocomotiveScroll();\n</script>\n```\n\n## CSS\n\n### Essential styles\n\nAdd the base styles to your CSS file:\n\n```css\n@import 'locomotive-scroll/dist/locomotive-scroll.css';\n```\n\nOr link directly to the bundled CSS:\n\n```html\n<link\n    rel=\"stylesheet\"\n    href=\"https://cdn.jsdelivr.net/npm/locomotive-scroll/bundled/locomotive-scroll.css\"\n/>\n```\n\nLearn more about styling considerations on [Lenis documentation](https://github.com/darkroomengineering/lenis#considerations).\n\n### Sass Import\n\n```scss\n// Vendors\n@import 'node_modules/locomotive-scroll/dist/locomotive-scroll';\n```\n\n### Horizontal styles\n\nIf you are utilizing the horizontal feature, we recommend applying the following CSS rules:\n\n```css\n/* Only necessary with horizontal scrolling */\nhtml[data-scroll-orientation='horizontal'] {\n    body {\n        width: fit-content;\n    }\n    [data-scroll-container] {\n        display: flex;\n    }\n}\n```\n\n## Let's try\n\n```html\n<main style=\"height: 150vh;\">\n    <div>\n        <h1>Hello 👋</h1>\n    </div>\n    <div>\n        <h2 data-scroll data-scroll-speed=\"0.5\">What's up?</h2>\n        <p data-scroll data-scroll-speed=\"0.8\">😬</p>\n    </div>\n</main>\n```\n\n```js\nimport LocomotiveScroll from 'locomotive-scroll';\nconst locomotiveScroll = new LocomotiveScroll();\n```\n"
  },
  {
    "path": "packages/docs/docs/intro.md",
    "content": "---\nslug: /\nsidebar_position: 1\ntitle: Introduction\n---\n\n# Locomotive Scroll v5\n\n> Detection of elements in viewport & smooth scrolling with parallax effects.\n\nLocomotive Scroll is a lightweight JavaScript library (9.4kB gzipped) that provides smooth scrolling animations and advanced scroll interactions for web applications. Built on top of [Lenis](https://github.com/darkroomengineering/lenis), it offers features such as smooth scrolling, parallax effects, and scroll-based animations with a focus on performance and accessibility.\n\n## What's New in V5\n\nVersion 5 is a complete rewrite with major improvements:\n\n-   **Lighter & Faster** — Built on Lenis 1.3.17, reduced to 9.4kB gzipped\n-   **TypeScript First** — Fully typed for better developer experience\n-   **Dual Intersection Observer Strategy** — Optimized detection for simple triggers vs. continuous animations\n-   **Smart Touch Detection** — Parallax automatically disabled on mobile for native scrolling.\n-   **Custom Scroll Containers** — Support for full-page or contained scrolling\n-   **No Layout Shifts** — No more greedy CSS transforms breaking your layouts\n-   **Improved Resize Handling** — Synchronized with Lenis's internal ResizeObservers for perfect timing\n\n## Key Features\n\n| Feature                | Description                                                                      |\n| ---------------------- | -------------------------------------------------------------------------------- |\n| **Viewport Detection** | Using browser's native Intersection Observer API with dual optimization strategy |\n| **Parallax Effects**   | Simple, performant parallax with `data-scroll-speed` attribute                   |\n| **Progress Tracking**  | Real-time scroll progress (0-1) as CSS variables or JavaScript events            |\n| **Custom Events**      | Trigger callbacks when elements enter/leave viewport                             |\n| **Accessibility**      | Native scrollbar, keyboard navigation, proper ARIA support                       |\n| **Performance**        | Elements only subscribe to RAF when visible **and** animating                    |\n\n## Quick Start\n\n```bash\nnpm install locomotive-scroll\n```\n\nReady to dive in? Start with our [Installation Guide](./getting-started/installation.md) to learn how to set up Locomotive Scroll in your project.\n\n## Dependencies\n\n| Name                                                  | Description          |\n| ----------------------------------------------------- | -------------------- |\n| [Lenis](https://github.com/darkroomengineering/lenis) | Smooth scroll engine |\n\n## Related\n\n-   [Lenis](https://github.com/darkroomengineering/lenis)\n"
  },
  {
    "path": "packages/docs/docusaurus.config.js",
    "content": "// @ts-check\n// `@type` JSDoc annotations allow editor autocompletion and type checking\n// (when paired with `@ts-check`).\n// There are various equivalent ways to declare your Docusaurus config.\n// See: https://docusaurus.io/docs/api/docusaurus-config\n\nimport { themes as prismThemes } from 'prism-react-renderer';\n\n/** @type {import('@docusaurus/types').Config} */\nconst config = {\n    title: 'Locomotive Scroll Documentation',\n    tagline:\n        'Detection of elements in viewport & smooth scrolling with parallax effects.',\n    favicon: 'img/favicon.ico',\n\n    // Set the production url of your site here\n    url: 'https://scroll.locomotive.ca',\n    // Set the /<baseUrl>/ pathname under which your site is served\n    // For GitHub pages deployment, it is often '/<projectName>/'\n    baseUrl: '/docs/',\n\n    // GitHub pages deployment config.\n    // If you aren't using GitHub pages, you don't need these.\n    organizationName: 'locomotivemtl', // Usually your GitHub org/user name.\n    projectName: 'docusaurus', // Usually your repo name.\n\n    onBrokenLinks: 'throw',\n\n    // Even if you don't use internationalization, you can use this field to set\n    // useful metadata like html lang. For example, if your site is Chinese, you\n    // may want to replace \"en\" with \"zh-Hans\".\n    i18n: {\n        defaultLocale: 'en',\n        locales: ['en'],\n    },\n\n    presets: [\n        [\n            'classic',\n            /** @type {import('@docusaurus/preset-classic').Options} */\n            ({\n                docs: {\n                    routeBasePath: '/',\n                    sidebarPath: './sidebars.js',\n                    // Please change this to your repo.\n                    // Remove this to remove the \"edit this page\" links.\n                    editUrl:\n                        'https://github.com/facebook/docusaurus/tree/main/packages/create-docusaurus/templates/shared/',\n                },\n                blog: false,\n                theme: {\n                    customCss: './src/css/custom.css',\n                },\n            }),\n        ],\n    ],\n    themes: [\n        [\n            require.resolve('@easyops-cn/docusaurus-search-local'),\n            {\n                hashed: true,\n                indexDocs: true,\n                indexBlog: false,\n                indexPages: false,\n                docsRouteBasePath: '/',\n            },\n        ],\n    ],\n    themeConfig:\n        /** @type {import('@docusaurus/preset-classic').ThemeConfig} */\n        ({\n            image: 'img/og-image.png',\n            metadata: [\n                {\n                    name: 'og:title',\n                    content: 'Locomotive Scroll Documentation',\n                },\n                {\n                    name: 'og:description',\n                    content:\n                        'Detection of elements in viewport & smooth scrolling with parallax effects.',\n                },\n                {\n                    name: 'og:image',\n                    content:\n                        'https://scroll.locomotive.ca/docs/img/og-image.png',\n                },\n                { name: 'og:type', content: 'website' },\n                { name: 'twitter:card', content: 'summary_large_image' },\n                {\n                    name: 'twitter:title',\n                    content: 'Locomotive Scroll Documentation',\n                },\n                {\n                    name: 'twitter:description',\n                    content:\n                        'Detection of elements in viewport & smooth scrolling with parallax effects.',\n                },\n                {\n                    name: 'twitter:image',\n                    content:\n                        'https://scroll.locomotive.ca/docs/img/og-image.png',\n                },\n            ],\n            colorMode: {\n                // defaultMode: 'light',\n                // disableSwitch: true,\n                respectPrefersColorScheme: true,\n            },\n            navbar: {\n                title: 'Locomotive Scroll',\n                items: [\n                    {\n                        href: 'https://scroll.locomotive.ca/',\n                        label: 'Landing',\n                        position: 'right',\n                    },\n                    {\n                        href: 'https://github.com/locomotivemtl/locomotive-scroll',\n                        label: 'GitHub',\n                        position: 'right',\n                    },\n                ],\n            },\n            footer: {\n                links: [\n                    {\n                        title: 'Docs',\n                        items: [\n                            {\n                                label: 'Getting Started',\n                                to: '/',\n                            },\n                            {\n                                label: 'Documentation',\n                                to: '/documentation/options',\n                            },\n                            {\n                                label: 'Examples',\n                                to: '/examples',\n                            },\n                            {\n                                label: 'Extras',\n                                to: '/extras/limitations',\n                            },\n                        ],\n                    },\n                    {\n                        title: 'About us',\n                        items: [\n                            {\n                                href: 'https://locomotive.ca',\n                                label: 'Website',\n                            },\n                            {\n                                label: 'Instagram',\n                                href: 'https://www.instagram.com/locomotivemtl/',\n                            },\n                            {\n                                label: 'Linkedin',\n                                href: 'https://www.linkedin.com/company/locomotive-mtl/',\n                            },\n                        ],\n                    },\n                    {\n                        title: 'More',\n                        items: [\n                            {\n                                href: 'https://scroll.locomotive.ca',\n                                label: 'Landing',\n                            },\n                            {\n                                href: 'https://github.com/locomotivemtl/locomotive-scroll',\n                                label: 'GitHub',\n                            },\n                        ],\n                    },\n                ],\n                copyright: `Copyright © ${new Date().getFullYear()} - <a href=\"https://locomotive.ca\">Locomotive</a>`,\n            },\n            prism: {\n                theme: prismThemes.github,\n                darkTheme: prismThemes.vsDark,\n            },\n        }),\n\n    plugins: [\n        [\n            'vercel-analytics',\n            {\n                debug: false,\n                mode: 'auto',\n            },\n        ],\n    ],\n};\n\nexport default config;\n"
  },
  {
    "path": "packages/docs/package.json",
    "content": "{\n  \"name\": \"docs-v-2\",\n  \"version\": \"0.0.0\",\n  \"private\": true,\n  \"scripts\": {\n    \"docusaurus\": \"docusaurus\",\n    \"start\": \"docusaurus start\",\n    \"build\": \"docusaurus build --out-dir ../../www/docs\",\n    \"swizzle\": \"docusaurus swizzle\",\n    \"deploy\": \"docusaurus deploy\",\n    \"clear\": \"docusaurus clear\",\n    \"serve\": \"docusaurus serve\",\n    \"write-translations\": \"docusaurus write-translations\",\n    \"write-heading-ids\": \"docusaurus write-heading-ids\"\n  },\n  \"dependencies\": {\n    \"@docusaurus/core\": \"^3.9.2\",\n    \"@docusaurus/plugin-vercel-analytics\": \"^3.9.2\",\n    \"@docusaurus/preset-classic\": \"^3.9.2\",\n    \"@easyops-cn/docusaurus-search-local\": \"^0.44.5\",\n    \"@mdx-js/react\": \"^3.0.0\",\n    \"clsx\": \"^2.0.0\",\n    \"prism-react-renderer\": \"^2.3.0\",\n    \"react\": \"^18.0.0\",\n    \"react-dom\": \"^18.0.0\"\n  },\n  \"devDependencies\": {\n    \"@docusaurus/module-type-aliases\": \"^3.9.2\",\n    \"@docusaurus/types\": \"^3.9.2\",\n    \"cssnano\": \"^7.0.2\",\n    \"postcss\": \"^8.4.38\"\n  },\n  \"browserslist\": {\n    \"production\": [\n      \">0.5%\",\n      \"not dead\",\n      \"not op_mini all\"\n    ],\n    \"development\": [\n      \"last 3 chrome version\",\n      \"last 3 firefox version\",\n      \"last 5 safari version\"\n    ]\n  },\n  \"engines\": {\n    \"node\": \">=18.0\"\n  }\n}\n"
  },
  {
    "path": "packages/docs/sidebars.js",
    "content": "/**\n * Creating a sidebar enables you to:\n - create an ordered group of docs\n - render a sidebar for each doc of that group\n - provide next/previous navigation\n\n The sidebars can be generated from the filesystem, or explicitly defined here.\n\n Create as many sidebars as you want.\n */\n\n// @ts-check\n\n/** @type {import('@docusaurus/plugin-content-docs').SidebarsConfig} */\nconst sidebars = {\n  // By default, Docusaurus generates a sidebar from the docs folder structure\n  //tutorialSidebar: [{type: 'autogenerated', dirName: '.'}],\n\n  // But you can create a sidebar manually\n  /*\n  tutorialSidebar: [\n    'intro',\n    'hello',\n    {\n      type: 'category',\n      label: 'Tutorial',\n      items: ['tutorial-basics/create-a-document'],\n    },\n  ],\n   */\n};\n\n//export default sidebars;\n\n\nexport default {\n  docs: [\n    'intro',\n    {\n      type: 'category',\n      label: 'Getting Started',\n      collapsible: true,\n      items: ['getting-started/installation', 'getting-started/usage'],\n    },\n    {\n      type: 'category',\n      label: 'Documentation',\n      collapsible: true,\n      items: ['documentation/options', 'documentation/methods', 'documentation/attributes'],\n    },\n    'examples',\n    {\n      type: 'category',\n      label: 'Extras',\n      collapsible: true,\n      items: ['extras/migration-guide', 'extras/limitations', 'extras/showcase'],\n    },\n  ],\n};"
  },
  {
    "path": "packages/docs/src/css/custom.css",
    "content": "/**\n * Any CSS included here will be global. The classic template\n * bundles Infima by default. Infima is a CSS framework designed to\n * work well for content-centric websites.\n */\n\n@font-face {\n  font-display: swap;\n  font-family: \"HelveticaNowDisplay\";\n  src: url(\"/fonts/HelveticaNowDisplay-Regular.woff2\") format(\"woff2\");\n  font-weight: 400;\n  font-style: normal\n}\n\n@font-face {\n  font-display: swap;\n  font-family: \"LocomotiveNew\";\n  src: url(\"/fonts/PPLocomotiveNew-Light.woff2\") format(\"woff2\");\n  font-weight: 400;\n  font-style: normal\n}\n\n/* You can override the default Infima variables here. */\n:root {\n  --ifm-color-primary: #312dfb;\n  --ifm-color-primary-dark: #1510fa;\n  --ifm-color-primary-darker: #0905f7;\n  --ifm-color-primary-darkest: #0804cb;\n  --ifm-color-primary-light: #4d4afc;\n  --ifm-color-primary-lighter: #5c59fc;\n  --ifm-color-primary-lightest: #8684fd;\n\n  --ifm-font-family-base: \"HelveticaNowDisplay\", sans-serif;\n  --ifm-font-weight-base: var(--ifm-font-weight-semibold);\n\n  --ifm-navbar-background-color: #202ded;\n  --ifm-navbar-link-color: white;\n  --ifm-navbar-search-input-background-color: #ffffff;\n  --ifm-navbar-search-input-placeholder-color: #29292dff;\n  --ifm-navbar-search-input-color: #29292dff;\n}\n\n/* For readability concerns, you should choose a lighter palette in dark mode. */\n[data-theme='dark'] {\n  --ifm-color-primary: #7299ff;\n  --ifm-color-primary-dark: #5b7bf9;\n  --ifm-color-primary-darker: #3d54ee;\n  --ifm-color-primary-darkest: #2f40d3;\n  --ifm-color-primary-light: #ffdede;\n  --ifm-color-primary-lighter: #fff4f4;\n  --ifm-color-primary-lightest: #ffffff;\n}\n\n/* Add logo */\n.navbar__title:before {\n  display: inline-block;\n  content: '🟠🔁';\n  font-family: \"LocomotiveNew\", sans-serif;\n  padding-right: .5rem;\n}\n\n.navbar__inner {\n  --ifm-color-emphasis-200: #ffffff;\n}\n\n.navbar__inner .clean-btn svg {\n  color: #ffffff;\n}\n\n.navbar__inner .clean-btn:hover svg {\n  color: #202ded;\n}\n"
  },
  {
    "path": "packages/docs/static/.nojekyll",
    "content": ""
  },
  {
    "path": "packages/landing/.browserslistrc",
    "content": "defaults\n"
  },
  {
    "path": "packages/landing/.editorconfig",
    "content": "# editorconfig.org\nroot = true\n\n[*]\ncharset = utf-8\nend_of_line = lf\nindent_size = 4\nindent_style = space\ninsert_final_newline = true\ntrim_trailing_whitespace = true\n\n[*.{md,markdown}]\ntrim_trailing_whitespace = false\n\n[*.{ms,mustache}]\ninsert_final_newline = false\n"
  },
  {
    "path": "packages/landing/.gitignore",
    "content": "node_modules\n.DS_Store\nThumbs.db\nloconfig.*.json\n!loconfig.example.json\n.prettierrc\nwww/**/*.html\n"
  },
  {
    "path": "packages/landing/.npmrc",
    "content": "//npm.greensock.com/:_authToken=8d111942-fc15-4353-9a4e-ee25d3f5d4da\n@gsap:registry=https://npm.greensock.com"
  },
  {
    "path": "packages/landing/.nvmrc",
    "content": "v20.10\n"
  },
  {
    "path": "packages/landing/LICENSE",
    "content": "The MIT License (MIT)\n\nCopyright (c) Locomotive, Inc.\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of\nthis software and associated documentation files (the \"Software\"), to deal in\nthe Software without restriction, including without limitation the rights to\nuse, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of\nthe Software, and to permit persons to whom the Software is furnished to do so,\nsubject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS\nFOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\nCOPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\nIN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\nCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "packages/landing/README.md",
    "content": "<p align=\"center\">\n    <a href=\"https://github.com/locomotivemtl/locomotive-boilerplate\">\n        <img src=\"https://user-images.githubusercontent.com/4596862/54868065-c2aea200-4d5e-11e9-9ce3-e0013c15f48c.png\" height=\"140\">\n    </a>\n</p>\n<h1 align=\"center\">Locomotive Boilerplate</h1>\n<p align=\"center\">Front-end boilerplate for projects by <a href=\"https://locomotive.ca/\">Locomotive</a>.</p>\n\n## Features\n\n* Uses a custom [task runner](docs/development.md) for handling assets.\n* Uses [BrowserSync] for fast development and testing in browsers.\n* Uses [Sass] for a feature rich superset of CSS.\n* Uses [ESBuild] for extremely fast processing of JS/ES modules.\n* Uses [SVG Mixer] for processing SVG files and generating spritesheets.\n* Uses [ITCSS] for a sane and scalable CSS architecture.\n* Uses [Locomotive Scroll] for smooth scrolling with parallax effects.\n* Uses a custom [grid system](docs/grid.md) for layout creation.\n\nLearn more about [languages and technologies](docs/technologies.md).\n\n## Getting started\n\nMake sure you have the following installed:\n\n* [Node] — at least 17.9, the latest LTS is recommended.\n* [NPM] — at least 8.0, the latest LTS is recommended.\n\n> 💡 You can use [NVM] to install and use different versions of Node via the command-line.\n\n```sh\n# Clone the repository.\ngit clone https://github.com/locomotivemtl/locomotive-boilerplate.git my-new-project\n\n# Enter the newly-cloned directory.\ncd my-new-project\n```\n\nThen replace the original remote repository with your project's repository.\n\nThen update the following files to suit your project:\n\n* [`README.md`](README.md):\n  The file you are currently reading.\n* [`package.json`](package.json):\n  * Package name: `@locomotivemtl/boilerplate`\n  * Package title: `Locomotive Boilerplate`\n* [`package-lock.json`](package-lock.json):\n  * Package name: `@locomotivemtl/boilerplate`\n* [`loconfig.json`](loconfig.json):\n  * BrowserSync proxy URL: `locomotive-boilerplate.test`\n    Remove `paths.url` to use BrowserSync's built-in server which uses `paths.dest`.\n  * View path: `./views/boilerplate/template`\n* [`environment.js`](assets/scripts/utils/environment.js):\n  * Application name: `Boilerplate`\n* [`site.webmanifest`](www/site.webmanifest):\n  * Manifest name: `Locomotive Boilerplate`\n  * Manifest short name: `Boilerplate`\n* HTML files:\n  * Page title: `Locomotive Boilerplate`\n\n## Installation\n\n```sh\n# Switch to recommended Node version from .nvmrc\nnvm use\n\n# Install dependencies from package.json\nnpm install\n```\n\n## Development\n\n```sh\n# Start development server, watch for changes, and compile assets\nnpm start\n\n# Compile and minify assets\nnpm run build\n```\n\nLearn more about [development and building](docs/development.md).\n\n## Documentation\n\n* [Development and building](docs/development.md)\n* [Languages and technologies](docs/technologies.md)\n* [Grid system](docs/grid.md)\n\n[BrowserSync]:       https://npmjs.com/package/browser-sync\n[ESBuild]:           https://npmjs.com/package/esbuild\n[ITCSS]:             https://itcss.io/\n[Locomotive Scroll]: https://npmjs.com/package/locomotive-scroll\n[modularJS]:         https://npmjs.com/package/modujs\n[modularLoad]:       https://npmjs.com/package/modularload\n[Sass]:              https://sass-lang.com/\n[SVG Mixer]:         https://npmjs.com/package/svg-mixer\n[Node]:              https://nodejs.org/\n[NPM]:               https://npmjs.com/\n[NVM]:               https://github.com/nvm-sh/nvm\n"
  },
  {
    "path": "packages/landing/assets/images/.gitkeep",
    "content": ""
  },
  {
    "path": "packages/landing/assets/images/sprite/.gitkeep",
    "content": ""
  },
  {
    "path": "packages/landing/assets/scripts/app.js",
    "content": "import modular from 'modujs';\nimport * as modules from './modules';\nimport globals from './globals';\nimport { debounce } from './utils/tickers';\nimport { $html } from './utils/dom';\nimport { ENV, FONT, CUSTOM_EVENT, CSS_CLASS } from './config';\nimport { isFontLoadingAPIAvailable, loadFonts } from './utils/fonts';\nimport { inject } from '@vercel/analytics';\n\n// Modules\nconst app = new modular({\n    modules: modules,\n});\n\nfunction init() {\n    // Bind global events\n    bindEvents();\n\n    // First resize\n    onResize();\n\n    // Set initial viewport height\n    document.documentElement.style.setProperty(\n        '--vh-initial',\n        `${window.innerHeight * 0.01}px`\n    );\n\n    globals();\n\n    app.init(app);\n\n    setTimeout(() => {\n        $html.classList.add(CSS_CLASS.FIRST_LOADED);\n        $html.classList.add(CSS_CLASS.LOADED);\n        $html.classList.remove(CSS_CLASS.LOADING);\n\n        setTimeout(() => {\n            $html.classList.add(CSS_CLASS.READY);\n        }, 100);\n    }, 100);\n\n    inject();\n\n    /**\n     * Eagerly load the following fonts.\n     */\n    if (isFontLoadingAPIAvailable) {\n        loadFonts(FONT.EAGER, ENV.IS_DEV).then((eagerFonts) => {\n            $html.classList.add(CSS_CLASS.FONTS_LOADED);\n\n            if (ENV.IS_DEV) {\n                console.group(\n                    'Eager fonts loaded!',\n                    eagerFonts.length,\n                    '/',\n                    document.fonts.size\n                );\n                console.group('State of eager fonts:');\n                eagerFonts.forEach((font) =>\n                    console.log(\n                        font.family,\n                        font.style,\n                        font.weight,\n                        font.status /*, font*/\n                    )\n                );\n                console.groupEnd();\n                console.group('State of all fonts:');\n                document.fonts.forEach((font) =>\n                    console.log(\n                        font.family,\n                        font.style,\n                        font.weight,\n                        font.status /*, font*/\n                    )\n                );\n                console.groupEnd();\n            }\n        });\n    }\n}\n\n////////////////\n// Global events\n////////////////\nfunction bindEvents() {\n    // Resize event\n    const resizeEndEvent = new CustomEvent(CUSTOM_EVENT.RESIZE_END);\n    window.addEventListener(\n        'resize',\n        debounce(\n            () => {\n                window.dispatchEvent(resizeEndEvent);\n            },\n            200,\n            false\n        )\n    );\n    window.addEventListener('resize', onResize);\n\n    // Orientation change event\n    window.addEventListener(\n        'orientationchange',\n        debounce(\n            () => {\n                onOnrientationChange();\n            },\n            200,\n            false\n        )\n    );\n}\n\n////////////////\n// Callbacks\n////////////////\nfunction onOnrientationChange() {\n    document.documentElement.style.setProperty(\n        '--vh-initial',\n        `${window.innerHeight * 0.01}px`\n    );\n}\n\nfunction onResize() {\n    let vw = $html.offsetWidth * 0.01;\n    let vh = window.innerHeight * 0.01;\n    document.documentElement.style.setProperty('--vw', `${vw}px`);\n    document.documentElement.style.setProperty('--vh', `${vh}px`);\n}\n\n////////////////\n// Execute\n////////////////\nwindow.addEventListener('load', (event) => {\n    init();\n});\n"
  },
  {
    "path": "packages/landing/assets/scripts/config.js",
    "content": "/**\n * > When using the esBuild API, all `process.env.NODE_ENV` expressions\n * > are automatically defined to `\"production\"` if all minification\n * > options are enabled and `\"development\"` otherwise. This only happens\n * > if `process`, `process.env`, and `process.env.NODE_ENV` are not already\n * > defined. This substitution is necessary to avoid code crashing instantly\n * > (since `process` is a Node API, not a web API).\n * > — https://esbuild.github.io/api/#platform\n */\n\nconst NODE_ENV = process.env.NODE_ENV\nconst IS_MOBILE = window.matchMedia('(any-pointer:coarse)').matches\n\n// Main environment variables\nconst ENV = Object.freeze({\n    // Node environment\n    NAME: NODE_ENV,\n    IS_PROD: NODE_ENV === 'production',\n    IS_DEV: NODE_ENV === 'development',\n\n    // Device\n    IS_MOBILE,\n    IS_DESKTOP: !IS_MOBILE,\n})\n\n// Main CSS classes used within the project\nconst CSS_CLASS = Object.freeze({\n    FIRST_LOADED: 'is-first-loaded',\n    LOADING: 'is-loading',\n    LOADED: 'is-loaded',\n    READY: 'is-ready',\n    FONTS_LOADED: 'fonts-loaded',\n    LAZY_CONTAINER: 'c-lazy',\n    LAZY_LOADED: '-lazy-loaded',\n    // ...\n})\n\n// Custom js events\nconst CUSTOM_EVENT = Object.freeze({\n    RESIZE_END: 'loco.resizeEnd',\n    // ...\n})\n\n// Fonts parameters\nconst FONT = Object.freeze({\n    EAGER: [\n        { family: 'PP Locomotive New', style: 'normal', weight: '300' },\n        { family:  'Helvetica Now Display', style: 'normal', weight: '400' },\n        { family: 'Helvetica Now Display', style: 'normal', weight: '500' }\n    ],\n})\n\nexport {\n    ENV,\n    CSS_CLASS,\n    CUSTOM_EVENT,\n    FONT,\n}\n"
  },
  {
    "path": "packages/landing/assets/scripts/globals.js",
    "content": "import svg4everybody from 'svg4everybody';\nimport { ENV } from './config';\n\n// Dynamic imports for development mode only\nlet gridHelper;\n(async () => {\n    if (ENV.IS_DEV) {\n        const gridHelperModule = await import('./utils/grid-helper');\n        gridHelper = gridHelperModule?.gridHelper;\n    }\n})();\n\nexport default function () {\n    /**\n     * Use external SVG spritemaps\n     */\n    svg4everybody();\n\n    /**\n     * Add grid helper\n     */\n    gridHelper?.();\n}\n"
  },
  {
    "path": "packages/landing/assets/scripts/modules/Example.js",
    "content": "import { module } from 'modujs';\nimport { FONT } from '../config';\nimport { whenReady } from '../utils/fonts';\n\nexport default class extends module {\n    constructor(m) {\n        super(m);\n    }\n\n    init() {\n        whenReady(FONT.EAGER).then((fonts) => this.onFontsLoaded(fonts));\n    }\n\n    onFontsLoaded(fonts) {\n        console.log('Example: Eager Fonts Loaded!', fonts)\n    }\n}\n"
  },
  {
    "path": "packages/landing/assets/scripts/modules/FadeInText.js",
    "content": "import { module } from 'modujs';\nimport gsap from \"gsap\";\nimport { SplitText } from \"gsap/all\";\ngsap.registerPlugin(SplitText);\n\nexport default class extends module {\n    constructor(m) {\n        super(m);\n\n        // Binding\n        this.onFadeinTextProgressBind = this.onFadeinTextProgress.bind(this);\n\n        // UI\n        this.$texts = this.el;\n\n        // Data\n        this.progress = 0;\n        this.metrics = [];\n        this.baseColor = getComputedStyle(this.el).getPropertyValue('--color-cta-fadein');\n        this.targetColor = getComputedStyle(this.el).getPropertyValue('--color');\n    }\n\n    ///////////////\n    // Lifecycle\n    ///////////////\n    init() {\n        // Bind\n        this.bindEvents();\n\n        // Split with autoSplit for automatic resize handling\n        this.splitText();\n    }\n\n    destroy() {\n        // Unbind\n        this.unbindEvents();\n\n        // Clean up split\n        if (this.split) {\n            this.split.revert();\n        }\n    }\n\n    ///////////////\n    // Events\n    ///////////////\n    bindEvents() {\n        window.addEventListener(\"fadeinTextProgress\", this.onFadeinTextProgressBind);\n    }\n\n    unbindEvents() {\n        window.removeEventListener(\"fadeinTextProgress\", this.onFadeinTextProgressBind);\n    }\n\n    ///////////////\n    // Callback\n    ///////////////\n    onFadeinTextProgress(e) {\n        const {target, progress} = e.detail;\n        if (!this.el.contains(target) || !this.split) return;\n        this.progress = progress;\n        this.computeProgress();\n    }\n\n    ///////////////\n    // Methods\n    ///////////////\n    splitText() {\n        // Use SplitText.create with autoSplit for automatic resize handling\n        this.split = SplitText.create(this.$texts, {\n            type: \"lines\",\n            linesClass: \"c-fadein-text_line\",\n            autoSplit: true,\n            onSplit: (self) => {\n                // This callback is called every time the text is split, including on resize\n                this.computeMetrics(self);\n\n                requestAnimationFrame(() => {\n                    this.computeProgress();\n                });\n            }\n        });\n\n        // Initial metrics computation\n        this.computeMetrics(this.split);\n    }\n\n    computeMetrics(split) {\n        // Reset metrics\n        this.metrics = [];\n\n        const widths = split.lines.map(line => line.getBoundingClientRect().width);\n        const totalWidth = widths.reduce((total, width) => total + width, 0);\n        let widthIncrementor = 0;\n\n        for (let index = 0; index < split.lines.length; index++) {\n            // Compute metrics\n            const from = widthIncrementor / totalWidth;\n            const ratio = widths[index] / totalWidth;\n            widthIncrementor += widths[index];\n            this.metrics.push({\n                from: from,\n                to: from + ratio\n            });\n        }\n    }\n\n    computeProgress() {\n        for (let index = 0; index < this.split.lines.length; index++) {\n            const $line = this.split.lines[index];\n            const { from, to } =  this.metrics[index];\n            const clampedProgress = gsap.utils.clamp(0, 1, gsap.utils.mapRange(from, to, 0, 1, this.progress))\n            $line.style.setProperty('--progress', `${clampedProgress}`)\n\n            this.updateGradient($line, clampedProgress)\n        }\n    }\n\n    updateGradient($item, progress) {\n        const offset = 100;\n        const x = progress;\n        const g1 = 0\n        const g5 = 100\n\n        const g3 = gsap.utils.mapRange(0, 1, -offset, 100 + offset, x)\n\n        const g2 = Math.max(g3 - offset, 0)\n        const g4 = Math.min(g3 + offset, 100)\n\n        const background = `linear-gradient(to right, ${this.targetColor} ${g1}%, ${this.targetColor} ${g2}%, ${this.targetColor} ${g3}%, ${this.baseColor} ${g4}%, ${this.baseColor} ${g5}%)`\n        $item.style.setProperty('--background', `${background}`)\n    }\n}\n"
  },
  {
    "path": "packages/landing/assets/scripts/modules/HoverShuffle.js",
    "content": "import { module } from 'modujs';\nimport { gsap } from 'gsap';\nconst DURATION = 0.25;\nconst SHUFFLE_PATTERN = /\\p{Extended_Pictographic}|\\r|\\n|./gu\n\nexport default class extends module {\n    constructor(m) {\n        super(m);\n    }\n\n    init() {\n        this.onItemEnterBind = this.onItemEnter.bind(this)\n        this.onItemLeaveBind = this.onItemLeave.bind(this)\n\n        this.update();\n    }\n\n    update() {\n        this.reset();\n        this.el.addEventListener('mouseenter', this.onItemEnterBind)\n        this.el.addEventListener('mouseleave', this.onItemLeaveBind)\n        \n    }\n\n    reset() {\n        this.el.removeEventListener('mouseenter', this.onItemEnterBind)\n        this.el.removeEventListener('mouseleave', this.onItemLeaveBind)\n    }\n\n    shuffle(input) {\n        var a = typeof input == 'string' ? input.split(\"\") : input,\n            n = a.length;\n    \n        for(var i = n - 1; i > 0; i--) {\n            var j = Math.floor(Math.random() * (i + 1));\n            var tmp = a[i];\n            a[i] = a[j];\n            a[j] = tmp;\n        }\n        return a.join(\"\");\n    }\n\n    onItemEnter(e) {\n        const $el = e.currentTarget;\n\n        let targets = [];\n        if($el.dataset.hoverShuffle == 'children') {\n            $el.querySelectorAll('[data-hover-shuffle-child]').forEach(child => {\n                targets.push(child)\n                child.setAttribute('aria-label', child.innerText)\n            })\n        } else {\n            targets = [$el]\n            $el.setAttribute('aria-label', $el.innerText)\n        }\n\n        this.tw = gsap.timeline({\n            onComplete: () => {\n                targets.forEach($target => {\n                    $target.innerText = $target.getAttribute('aria-label')\n                    $target.removeAttribute('aria-label')\n                })\n            }\n        })\n\n        const shufflePerSecond = 4;\n        const shuffleDelay = DURATION/shufflePerSecond\n\n        for(let i = 0; i < shufflePerSecond; i++) {\n            for(let $target of targets) {\n                this.tw.add(() => {\n                    this.shuffleElementTexts($target, this.shuffle)\n                }, shuffleDelay*i)\n            }\n        }\n    }\n\n    onItemLeave(e) {\n        this.tw && this.tw.kill()\n\n        const $el = e.currentTarget;\n        let targets = [];\n        if($el.dataset.hoverShuffle == 'children') {\n            $el.querySelectorAll('[data-hover-shuffle-child]').forEach(child => {\n                targets.push(child)\n            })\n        } else {\n            targets = [$el]\n        }\n\n        targets.forEach($target => {\n            if($target.getAttribute('aria-label')) $target.innerText = $target.getAttribute('aria-label')\n            $target.removeAttribute('aria-label')\n        })\n    }\n\n    shuffleElementTexts(item, shuffleFn) {\n        if(!item.children.length && item.innerText) {\n            // Wrap line breaks with spaces\n            const words = item.innerText.replace('\\n', ' \\n ').split(' ')\n            // Actually shuffle each \"word\"\n            for(let i=0;i<words.length;i++) {\n                const chars = [...words[i].matchAll(SHUFFLE_PATTERN)].map(item => item[0])\n                words[i] = shuffleFn(chars)\n            }\n            // Output result\n            item.innerText = words.join(' ')\n        }\n    }\n \n}\n"
  },
  {
    "path": "packages/landing/assets/scripts/modules/Load.js",
    "content": "import { module } from 'modujs';\nimport modularLoad from 'modularload';\n\nexport default class extends module {\n    constructor(m) {\n        super(m);\n    }\n\n    init() {\n        const load = new modularLoad({\n            enterDelay: 0,\n            transitions: {\n                customTransition: {}\n            }\n        });\n\n        load.on('loaded', (transition, oldContainer, newContainer) => {\n            this.call('destroy', oldContainer, 'app');\n            this.call('update', newContainer, 'app');\n        });\n    }\n}\n"
  },
  {
    "path": "packages/landing/assets/scripts/modules/MaskLines.js",
    "content": "import { module } from 'modujs';\nimport { whenReady } from \"../utils/fonts\";\nimport gsap from 'gsap';\nimport { SplitText } from 'gsap/SplitText';\nimport { ScrollTrigger } from 'gsap/ScrollTrigger';\nimport { FONT } from '../config.js';\ngsap.registerPlugin(SplitText);\ngsap.registerPlugin(ScrollTrigger);\n\nexport default class extends module {\n    constructor(m) {\n        super(m);\n\n        // Binding\n        this.onProgressBind = this.onProgress.bind(this);\n\n        // Options\n        this.delay = parseFloat(this.getData('delay')) || 0.0;\n        this.stagger = parseFloat(this.getData('stagger')) || 0.1;\n\n        // Data\n        this.metrics = [];\n    }\n\n    ///////////////\n    // Lifecycle\n    ///////////////\n    init() {\n        this.bindEvents();\n        whenReady(FONT.EAGER).then((fonts) => {\n            this.onFontsLoaded(fonts);\n        });\n    }\n\n    destroy() {\n        super.destroy();\n        this.unbindEvents();\n\n        // Clean up split\n        if (this.splitObject) {\n            this.splitObject.revert();\n        }\n    }\n\n    ///////////////\n    // Events\n    ///////////////\n    unbindEvents() {\n        window.removeEventListener('progressEvent', this.onProgressBind);\n    }\n\n    bindEvents() {\n        window.addEventListener('progressEvent', this.onProgressBind);\n    }\n    \n    ///////////////\n    // Callbacks\n    ///////////////\n    onFontsLoaded(fonts) {\n        this.split();\n    }\n\n    onProgress(e) {\n        if (!this.splitObject || !this.splitObject.lines) return;\n\n        const { progress } = e.detail;\n        this.splitObject.lines.forEach((line, i) => {\n            if (this.metrics[i]) {\n                const { from, to } = this.metrics[i];\n                const x = gsap.utils.clamp(-25, 0, gsap.utils.mapRange(from, to, -25, 0, progress));\n                const opacity = gsap.utils.clamp(0, 1, gsap.utils.mapRange(from, to, 0, 1, progress));\n                gsap.set(line, { x, opacity });\n            }\n        });\n    }\n\n    ///////////////\n    // Methods\n    ///////////////\n    split() {\n        // Use SplitText.create with autoSplit for automatic resize handling\n        this.splitObject = SplitText.create(this.el, {\n            type: \"lines\",\n            tag: \"span\",\n            autoSplit: true,\n            onSplit: (self) => {\n                // This callback is called every time the text is split, including on resize\n                this.computeMetrics(self);\n            }\n        });\n\n        // Initial metrics computation\n        this.computeMetrics(this.splitObject);\n    }\n\n    computeMetrics(split) {\n        this.metrics = split.lines.map((line, i, array) => {\n            const from = i / array.length;\n            const to = from + (1 / array.length);\n            return {\n                from,\n                to\n            };\n        });\n    }\n}\n"
  },
  {
    "path": "packages/landing/assets/scripts/modules/Rail.js",
    "content": "import { module as Module } from 'modujs';\nimport { whenReady } from '../utils/fonts';\nimport gsap from 'gsap';\nimport { CUSTOM_EVENT, FONT, ENV } from '../config';\n\nexport default class extends Module {\n    constructor(m) {\n        super(m);\n\n        // Binding\n        this.onUpdateBind = this.onUpdate.bind(this);\n        this.onResizeBind = this.onResize.bind(this);\n        this.onToggleBind = this.onToggle.bind(this);\n\n        // UI\n        this.$container = this.$('container')[0];\n        this.$pattern = this.$('pattern')[0];\n        this.prevCount = null;\n\n        // Data\n        this.currentTranslate = 0;\n        this.maxTranslate = this.$container.offsetWidth;\n        this.idleVelocity = 1;\n        this.scrollVelocity = 0.1;\n        this.scrollLerp = 0.8;\n        this.scrollDirection = 1;\n        this.railDirection = this.getData('direction');\n        this.showFrom = parseInt(this.getData('from')) || false;\n        this.showTo = parseInt(this.getData('to')) || false;\n\n        this.data = [];\n        this.$items = [];\n        this.glyphs = ['🛑', '🔝', '🍸', '⛺', '😖'];\n    }\n\n    ///////////////\n    // Lifecyle\n    ///////////////\n    init() {\n        this.bindEvents();\n        whenReady(FONT.EAGER).then((fonts) => {\n            this.onFontsLoaded(fonts);\n        });\n    }\n\n    destroy() {\n        super.destroy();\n        this.unbindEvents();\n        this.stop();\n    }\n\n    ///////////////\n    // Events\n    ///////////////\n    bindEvents() {\n        window.addEventListener(CUSTOM_EVENT.RESIZE_END, this.onResizeBind);\n        window.addEventListener('toggleRail', this.onToggleBind);\n    }\n\n    unbindEvents() {\n        window.removeEventListener(CUSTOM_EVENT.RESIZE_END, this.onResizeBind);\n        window.removeEventListener('toggleRail', this.onToggleBind);\n    }\n\n    ///////////////\n    // Callbacks\n    ///////////////\n    onResize() {\n        this.repeatPattern();\n    }\n\n    onFontsLoaded() {\n        this.repeatPattern();\n    }\n\n    onUpdate() {\n        this.currentTranslate =\n            (this.currentTranslate +\n                this.idleVelocity * this.scrollDirection * this.railDirection +\n                this.scrollVelocity *\n                    this.scrollDirection *\n                    this.railDirection) %\n            this.maxTranslate;\n\n        for (const [index, $items] of this.$items.entries()) {\n            let translate;\n            const right = this.data[index].left + this.data[index].width;\n\n            if (this.currentTranslate < right * -1) {\n                translate = this.maxTranslate;\n            } else if (this.currentTranslate > this.maxTranslate - right) {\n                translate = -this.maxTranslate;\n            } else {\n                translate = 0;\n            }\n\n            this.data[index].translate = translate;\n            $items.style.transform = `translate3d(${translate}px,0,0)`;\n        }\n\n        this.$container.style.transform = `translate3d(${this.currentTranslate}px,0,0)`;\n    }\n\n    onScroll(scrollData) {\n        const { velocity, direction } = scrollData;\n\n        if (ENV.IS_MOBILE) {\n            return;\n        }\n\n        this.scrollDirection =\n            direction != 0 ? direction : this.scrollDirection;\n        this.scrollDirection = this.scrollDirection * -1;\n        this.scrollVelocity = Math.round(Math.abs(velocity)) * this.scrollLerp;\n    }\n\n    onToggle(e) {\n        const { way } = e.detail;\n        way === 'enter' ? this.start() : this.stop();\n    }\n\n    ///////////////\n    // Methods\n    ///////////////\n    start() {\n        if (this.isPlaying) return;\n        this.isPlaying = true;\n        gsap.ticker.add(this.onUpdateBind);\n    }\n\n    stop() {\n        if (!this.isPlaying) return;\n        this.isPlaying = false;\n        gsap.ticker.remove(this.onUpdateBind);\n    }\n\n    computeMetrics(reset = false) {\n        if (reset) {\n            this.$items = this.el.querySelectorAll('[data-rail-item]');\n            this.data = [];\n            this.currentTranslate = 0;\n            for (const [index, $items] of this.$items.entries()) {\n                const { left, width } = $items.getBoundingClientRect();\n                this.data[index] = {\n                    left,\n                    width,\n                    translate: 0,\n                };\n            }\n        } else {\n            for (const [index, $items] of this.$items.entries()) {\n                const { left, width } = $items.getBoundingClientRect();\n                this.data[index].left =\n                    left - this.currentTranslate - this.data[index].translate;\n                this.data[index].width = width;\n            }\n        }\n    }\n\n    repeatPattern() {\n        if (\n            (this.showFrom && window.innerWidth < this.showFrom) ||\n            (this.showTo && window.innerWidth > this.showTo)\n        ) {\n            return;\n        }\n\n        const patternWidth = this.$pattern.offsetWidth;\n        const repeatCount = Math.ceil(window.innerWidth / patternWidth) + 1; // Add one more for security\n\n        this.maxTranslate = repeatCount * patternWidth;\n\n        if (repeatCount === this.prevCount) return this.computeMetrics();\n\n        this.prevCount = repeatCount;\n\n        const $currentClones = this.$container.querySelectorAll('[data-clone]');\n\n        for (const $currentClone of $currentClones) {\n            $currentClone.remove();\n        }\n\n        for (let index = 0; index < repeatCount - 1; index++) {\n            const $clone = this.$pattern.cloneNode(true);\n            // $clone.querySelector(\"p\").appendChild(this.createGlyph(0))\n            $clone.querySelector('.c-rail_glyph').innerHTML =\n                this.glyphs[index];\n            $clone.setAttribute('data-clone', '');\n            $clone.setAttribute('aria-hidden', 'true');\n            this.$container.appendChild($clone);\n        }\n\n        requestAnimationFrame(() => {\n            this.computeMetrics(true);\n        });\n    }\n}\n"
  },
  {
    "path": "packages/landing/assets/scripts/modules/Randomize.js",
    "content": "import { module } from 'modujs';\nimport gsap from \"gsap\";\nimport { ScrambleTextPlugin } from 'gsap/ScrambleTextPlugin';\n\ngsap.registerPlugin(ScrambleTextPlugin) \n\nexport default class Ramdomize extends module {\n    constructor(m) {\n        super(m);\n\n        // Binding\n        this.inViewBind = this.inView.bind(this)\n    }\n\n    init() {\n        this.bindEvents();\n    }\n\n    destroy() {\n        this.unbindEvents();\n    }\n\n    bindEvents() {\n        window.addEventListener(\"randomize\", this.inViewBind);\n    }\n\n    unbindEvents() {\n        window.removeEventListener(\"randomize\", this.inViewBind);\n    }\n\n    inView(args) {\n        const { target } = args.detail\n\n        const words = [...target.querySelectorAll(\"p\")]\n        words.forEach((word, i) => {\n            gsap.to(word, {opacity: 1, duration: 0, delay: 0.1 * i})\n            gsap.to(word, {scrambleText: word.innerHTML, duration: 1.5, delay: 0.1 * i})\n        })\n    }\n}\n"
  },
  {
    "path": "packages/landing/assets/scripts/modules/Scroll.js",
    "content": "import { module } from 'modujs'\nimport { $html } from '../utils/dom'\nimport LocomotiveScroll from '../../../../lib/index';\n\nexport default class Scroll extends module {\n    constructor(m) {\n        super(m);\n\n        // Binding\n        this.onScrollBind = this.onScroll.bind(this)\n        this.changeHeaderThemeBind = this.changeHeaderTheme.bind(this)\n    }\n\n    init() {\n        this.scroll = new LocomotiveScroll({\n            modularInstance: this,\n            scrollCallback: this.onScrollBind,\n        })\n\n        // Force scroll to top\n        if (history.scrollRestoration) {\n            history.scrollRestoration = 'manual'\n            window.scrollTo(0, 0)\n        }\n\n        // Bind events\n        this.bindEvents();\n    }\n\n    destroy() {\n        this.unbindEvents();\n        this.scroll.destroy();\n    }\n\n     ///////////////\n    // Events\n    ///////////////\n    bindEvents() {\n        window.addEventListener(\"changeHeaderTheme\", this.changeHeaderThemeBind);\n    }\n\n    unbindEvents() {\n        window.removeEventListener(\"changeHeaderTheme\", this.changeHeaderThemeBind);\n    }\n\n    ///////////////\n    // Callbacks\n    ///////////////\n    onScroll({ scroll, limit, velocity, direction, progress }) {\n        //get direction\n        if (progress > this.lastProgress) {\n            if (this.scrollDirection != 1) {\n                this.scrollDirection = 1;\n            }\n        } else {\n            if (this.scrollDirection != -1) {\n                this.scrollDirection = -1;\n            }\n        }\n\n        if (this.scrollDirection < 0) {\n            $html.classList.add(\"is-scrolling-up\");\n        } else {\n            $html.classList.remove(\"is-scrolling-up\");\n        }\n\n        this.lastProgress = progress;\n\n        // used by Rail.js\n        this.call('onScroll', { velocity, direction }, 'Rail');\n    }\n\n    ///////////////\n    // Methods\n    ///////////////\n    scrollTo(params) {\n        let { target, ...options } = params\n\n        options = Object.assign({\n            // Defaults\n            duration: 1,\n        }, options)\n\n        this.scroll?.scrollTo(target, options)\n    }\n\n    changeHeaderTheme(args) {\n        const { target, way } = args.detail\n        \n        if (way == 'enter') {\n            const theme = target?.parentNode?.getAttribute('data-theme')\n            theme && $html.setAttribute('data-header-theme', theme)\n        }\n    }\n\n    /**\n     * Observe new scroll elements\n     *\n     * @param $newContainer (HTMLElement)\n     */\n    addScrollElements($newContainer) {\n        this.scroll?.addScrollElements($newContainer);\n    }\n\n    /**\n     * Unobserve scroll elements\n     *\n     * @param $oldContainer (HTMLElement)\n     */\n    removeScrollElements($oldContainer) {\n        this.scroll?.removeScrollElements($oldContainer);\n    }\n}\n"
  },
  {
    "path": "packages/landing/assets/scripts/modules.js",
    "content": "export { default as Load } from './modules/Load';\nexport { default as Rail } from './modules/Rail';\nexport { default as Scroll } from './modules/Scroll';\nexport { default as Randomize } from './modules/Randomize';\nexport { default as MaskLines } from './modules/MaskLines';\nexport { default as FadeInText } from './modules/FadeInText';\nexport { default as HoverShuffle } from './modules/HoverShuffle';\n"
  },
  {
    "path": "packages/landing/assets/scripts/utils/dom.js",
    "content": "const $html = document.documentElement\nconst $body = document.body\n\nexport {\n    $html,\n    $body,\n}\n"
  },
  {
    "path": "packages/landing/assets/scripts/utils/fonts.js",
    "content": "/**\n * Font Faces\n *\n * Provides utilities to facilitate interactions with the CSS Font Loading API.\n *\n * Features functions to:\n *\n * - Retrieve one or more `FontFace` instances based on a font search query.\n * - Check if a `FontFace` instance matches a font search query.\n * - Eagerly load fonts that match a font search query.\n * - Wait until fonts that match a font search query are loaded.\n *\n * References:\n *\n * - {@link https://developer.mozilla.org/en-US/docs/Web/API/CSS_Font_Loading_API}\n */\n\n/**\n * @typedef {Object} FontFaceReference\n *\n * @property {string} family   - The name used to identify the font in our CSS.\n * @property {string} [style]  - The style used by the font in our CSS.\n * @property {string} [weight] - The weight used by the font in our CSS.\n */\n\nconst isFontLoadingAPIAvailable = ('fonts' in document);\n\n/**\n * Determines if the given font matches the given `FontFaceReference`.\n *\n * @param {FontFace}          font      - The font to inspect.\n * @param {FontFaceReference} criterion - The object of property values to match.\n *\n * @returns {boolean}\n */\nfunction conformsToReference(font, criterion)\n{\n    for (const [ key, value ] of Object.entries(criterion)) {\n        switch (key) {\n            case 'family': {\n                if (trim(font[key]) !== value) {\n                    return false;\n                }\n                break;\n            }\n\n            case 'weight': {\n                /**\n                 * Note concerning font weights:\n                 * Loose equality (`==`) is used to compare numeric weights,\n                 * a number (`400`) and a numeric string (`\"400\"`).\n                 * Comparison between numeric and keyword values is neglected.\n                 *\n                 * @link https://developer.mozilla.org/en-US/docs/Web/CSS/font-weight#common_weight_name_mapping\n                 */\n                if (font[key] != value) {\n                    return false;\n                }\n                break;\n            }\n\n            default: {\n                if (font[key] !== value) {\n                    return false;\n                }\n                break;\n            }\n        }\n    }\n\n    return true;\n}\n\n/**\n * Determines if the given font matches the given font shorthand.\n *\n * @param {FontFace} font      - The font to inspect.\n * @param {string}   criterion - The font shorthand to match.\n *\n * @returns {boolean}\n */\nfunction conformsToShorthand(font, criterion)\n{\n    const family = trim(font.family);\n\n    if (trim(family) === criterion) {\n        return true;\n    }\n\n    if (\n        criterion.endsWith(trim(family)) && (\n            criterion.match(font.weight) ||\n            criterion.match(font.style)\n        )\n    ) {\n        return true;\n    }\n\n    return true;\n}\n\n/**\n * Determines if the given font matches any of the given criteria.\n *\n * @param {FontFace}            font     - The font to inspect.\n * @param {FontFaceReference[]} criteria - A list of objects with property values to match.\n *\n * @returns {boolean}\n */\nfunction conformsToAnyReference(font, criteria)\n{\n    for (const criterion of criteria) {\n        if (conformsToReference(font, criterion)) {\n            return true;\n        }\n    }\n\n    return false;\n}\n\n/**\n * Returns an iterator of all `FontFace` from `document.fonts` that satisfy\n * the provided `FontFaceReference`.\n *\n * @param {FontFaceReference} font\n *\n * @returns {FontFace[]}\n */\nfunction findManyByReference(search)\n{\n    const found = [];\n\n    for (const font of document.fonts) {\n        if (conformsToReference(font, search)) {\n            found.push(font);\n        }\n    }\n\n    return found;\n}\n\n/**\n * Returns an iterator of all `FontFace` from `document.fonts` that satisfy\n * the provided font shorthand.\n *\n * @param {string} font\n *\n * @returns {FontFace[]}\n */\nfunction findManyByShorthand(search)\n{\n    const found = [];\n\n    for (const font of document.fonts) {\n        if (conformsToShorthand(font, search)) {\n            found.push(font);\n        }\n    }\n\n    return found;\n}\n\n/**\n * Returns the first `FontFace` from `document.fonts` that satisfies\n * the provided `FontFaceReference`.\n *\n * @param {FontFaceReference} font\n *\n * @returns {?FontFace}\n */\nfunction findOneByReference(search)\n{\n    for (const font of document.fonts) {\n        if (conformsToReference(font, criterion)) {\n            return font;\n        }\n    }\n\n    return null;\n}\n\n/**\n * Returns the first `FontFace` from `document.fonts` that satisfies\n * the provided font shorthand.\n *\n * Examples:\n *\n * - \"Roboto\"\n * - \"italic bold 16px Roboto\"\n *\n * @param {string} font\n *\n * @returns {?FontFace}\n */\nfunction findOneByShorthand(search)\n{\n    for (const font of document.fonts) {\n        if (conformsToShorthand(font, search)) {\n            return font;\n        }\n    }\n\n    return null;\n}\n\n/**\n * Returns a `FontFace` from `document.fonts` that satisfies\n * the provided query.\n *\n * @param {FontFaceReference|string} font - Either:\n *     - a `FontFaceReference` object\n *     - a font family name\n *     - a font specification, for example \"italic bold 16px Roboto\"\n *\n * @returns {?FontFace}\n *\n * @throws {TypeError}\n */\nfunction getAny(search) {\n    if (search) {\n        switch (typeof search) {\n            case 'string':\n                return findOneByShorthand(search);\n\n            case 'object':\n                return findOneByReference(search);\n        }\n    }\n\n    throw new TypeError(\n        'Expected font query to be font shorthand or font reference'\n    );\n}\n\n/**\n * Returns an iterator of all `FontFace` from `document.fonts` that satisfy\n * the provided queries.\n *\n * @param {FontFaceReference|string|(FontFaceReference|string)[]} queries\n *\n * @returns {FontFace[]}\n *\n * @throws {TypeError}\n */\nfunction getMany(queries) {\n    if (!Array.isArray(queries)) {\n        queries = [ queries ];\n    }\n\n    const found = new Set();\n\n    queries.forEach((search) => {\n        if (search) {\n            switch (typeof search) {\n                case 'string':\n                    found.add(...findManyByShorthand(search));\n                    return;\n\n                case 'object':\n                    found.add(...findManyByReference(search));\n                    return;\n            }\n        }\n\n        throw new TypeError(\n            'Expected font query to be font shorthand or font reference'\n        );\n    })\n\n    return [ ...found ];\n}\n\n/**\n * Determines if a font face is registered.\n *\n * @param {FontFace|FontFaceReference|string} search - Either:\n *     - a `FontFace` instance\n *     - a `FontFaceReference` object\n *     - a font family name\n *     - a font specification, for example \"italic bold 16px Roboto\"\n *\n * @returns {boolean}\n */\nfunction hasAny(search) {\n    if (search instanceof FontFace) {\n        return document.fonts.has(search);\n    }\n\n    return getAny(search) != null;\n}\n\n/**\n * Eagerly load fonts.\n *\n * Most user agents only fetch and load fonts when they are first needed\n * (\"lazy loaded\"), which can result in a perceptible delay.\n *\n * This function will \"eager load\" the fonts.\n *\n * @param {(FontFace|FontFaceReference)[]} fontsToLoad - List of fonts to load.\n * @param {boolean}             [debug]     - If TRUE, log details to the console.\n *\n * @returns {Promise}\n */\nasync function loadFonts(fontsToLoad, debug = false)\n{\n    if ((fontsToLoad.size ?? fontsToLoad.length) === 0) {\n        throw new TypeError(\n            'Expected at least one font'\n        );\n    }\n\n    return await loadFontsWithAPI([ ...fontsToLoad ], debug);\n}\n\n/**\n * Eagerly load a font using `FontFaceSet` API.\n *\n * @param {FontFace} font\n *\n * @returns {Promise}\n */\nasync function loadFontFaceWithAPI(font)\n{\n    return await (font.status === 'unloaded'\n        ? font.load()\n        : font.loaded\n    ).then((font) => font, (err) => font)\n}\n\n/**\n * Eagerly load fonts using `FontFaceSet` API.\n *\n * @param {FontFaceReference[]} fontsToLoad\n * @param {boolean}             [debug]\n *\n * @returns {Promise}\n */\nasync function loadFontsWithAPI(fontsToLoad, debug = false)\n{\n    debug && console.group('[loadFonts:API]', fontsToLoad.length, '/', document.fonts.size);\n\n    const fontsToBeLoaded = [];\n\n    for (const fontToLoad of fontsToLoad) {\n        if (fontToLoad instanceof FontFace) {\n            if (!document.fonts.has(fontToLoad)) {\n                document.fonts.add(fontToLoad);\n            }\n\n            fontsToBeLoaded.push(\n                loadFontFaceWithAPI(fontToLoad)\n            );\n        } else {\n            fontsToBeLoaded.push(\n                ...getMany(fontToLoad).map((font) => loadFontFaceWithAPI(font))\n            );\n        }\n    }\n\n    debug && console.groupEnd();\n\n    return await Promise.all(fontsToBeLoaded);\n}\n\n/**\n * Removes quotes from the the string.\n *\n * When a `@font-face` is declared, the font family is sometimes\n * defined in quotes which end up included in the `FontFace` instance.\n *\n * @param {string} value\n *\n * @returns {string}\n */\nfunction trim(value) {\n    return value.replace(/['\"]+/g, '');\n}\n\n/**\n * Returns a Promise that resolves with the specified fonts\n * when they are done loading or failed.\n *\n * @param {FontFaceReference|string|(FontFaceReference|string)[]} queries\n *\n * @returns {Promise}\n */\nasync function whenReady(queries)\n{\n    const fonts = getMany(queries);\n\n    // Handle each font's loaded promise, catching errors so that\n    // Promise.all doesn't reject if one font fails\n    return await Promise.all(\n        fonts.map((font) =>\n            font.loaded.then(\n                (loadedFont) => loadedFont,\n                (error) => {\n                    // Return the font even if it failed to load\n                    // This allows the promise to resolve instead of reject\n                    console.warn(`Font failed to load: ${font.family} ${font.style} ${font.weight}`, error);\n                    return font;\n                }\n            )\n        )\n    );\n}\n\nexport {\n    getAny,\n    getMany,\n    hasAny,\n    isFontLoadingAPIAvailable,\n    loadFonts,\n    whenReady,\n}\n"
  },
  {
    "path": "packages/landing/assets/scripts/utils/grid-helper.js",
    "content": "/**\n * Grid Helper\n *\n * Provides a grid based on the design guidelines and is helpful for web integration.\n *\n * - `Control + g` to toggle the grid\n *\n */\n\n/**\n * @typedef {Object} GridHelperReference\n *\n * @property {string} [gutterCssVar=GRID_HELPER_GUTTER_CSS_VAR] - CSS variable used to define grid gutters.\n * @property {string} [marginCssVar=GRID_HELPER_MARGIN_CSS_VAR] - CSS variable used to define grid margins.\n * @property {string} [rgbaColor=GRID_HELPER_RGBA_COLOR]        - RGBA color for the grid appearence.\n */\n\nconst GRID_HELPER_GUTTER_CSS_VAR = '--grid-gutter';\nconst GRID_HELPER_MARGIN_CSS_VAR = '--grid-margin';\nconst GRID_HELPER_RGBA_COLOR = 'rgba(255, 0, 0, .1)';\n\n/**\n * Create a grid helper\n *\n * @param {GridHelperReference}\n *\n */\nfunction gridHelper({\n    gutterCssVar = GRID_HELPER_GUTTER_CSS_VAR,\n    marginCssVar = GRID_HELPER_MARGIN_CSS_VAR,\n    rgbaColor = GRID_HELPER_RGBA_COLOR,\n} = {}) {\n    // Set grid container\n    const $gridContainer = document.createElement('div');\n    document.body.append($gridContainer);\n\n    // Set grid appearence\n    setGridHelperColumns($gridContainer, rgbaColor);\n    setGridHelperStyles($gridContainer, gutterCssVar, marginCssVar);\n\n    // Set grid interactivity\n    setGridEvents($gridContainer, rgbaColor);\n}\n\n/**\n * Set grid container styles\n *\n * @param {HTMLElement} $container - DOM Element that contains a list of generated columns\n * @param {string} gutterCssVar    - CSS variable used to define grid gutters.\n * @param {string} marginCssVar    - CSS variable used to define grid margins.\n *\n */\nfunction setGridHelperStyles($container, gutterCssVar, marginCssVar) {\n    const elStyles = $container.style;\n    elStyles.zIndex = '10000';\n    elStyles.position = 'fixed';\n    elStyles.top = '0';\n    elStyles.left = '0';\n    elStyles.display = 'flex';\n    elStyles.width = '100%';\n    elStyles.height = '100%';\n    elStyles.columnGap = `var(${gutterCssVar}, 0)`;\n    elStyles.paddingLeft = `var(${marginCssVar}, 0)`;\n    elStyles.paddingRight = `var(${marginCssVar}, 0)`;\n    elStyles.pointerEvents = 'none';\n    elStyles.visibility = 'hidden';\n}\n\n/**\n * Set grid columns\n *\n * @param {HTMLElement} $container - DOM Element that will contain a list of generated columns\n * @param {string} rgbaColor       - RGBA color to stylize the generated columns\n *\n */\nfunction setGridHelperColumns($container, rgbaColor) {\n    // Clear columns\n    $container.innerHTML = '';\n\n    // Loop through columns\n    const columns = Number(\n        window.getComputedStyle($container).getPropertyValue('--grid-columns')\n    );\n\n    let $col;\n    for (var i = 0; i < columns; i++) {\n        $col = document.createElement('div');\n        $col.style.flex = '1 1 0';\n        $col.style.backgroundColor = rgbaColor;\n        $container.appendChild($col);\n    }\n}\n\n/**\n * Set grid events\n *\n * Resize to rebuild columns\n * Keydown/Keyup to toggle the grid display\n *\n * @param {HTMLElement} $container - DOM Element that contains a list of generated columns\n * @param {string} rgbaColor       - RGBA color to stylize the generated columns\n *\n */\nfunction setGridEvents($container, rgbaColor) {\n    // Handle resize\n    window.addEventListener(\n        'resize',\n        setGridHelperColumns($container, rgbaColor)\n    );\n\n    // Toggle grid\n    let ctrlDown = false;\n    let isActive = false;\n\n    document.addEventListener('keydown', (e) => {\n        if (e.key == 'Control') {\n            ctrlDown = true;\n        } else {\n            if (ctrlDown && e.key == 'g') {\n                if (isActive) {\n                    $container.style.visibility = 'hidden';\n                } else {\n                    $container.style.visibility = 'visible';\n                }\n\n                isActive = !isActive;\n            }\n        }\n    });\n\n    document.addEventListener('keyup', (e) => {\n        if (e.key == 'Control') {\n            ctrlDown = false;\n        }\n    });\n}\n\nexport { gridHelper };\n"
  },
  {
    "path": "packages/landing/assets/scripts/utils/html.js",
    "content": "/**\n * Escape HTML string\n * @param {string}  str   - string to escape\n * @return {string} escaped string\n */\n\nconst escapeHtml = str =>\n    str.replace(/[&<>'\"]/g, tag => ({\n        '&': '&amp;',\n        '<': '&lt;',\n        '>': '&gt;',\n        \"'\": '&#39;',\n        '\"': '&quot;'\n    }[tag]))\n\n\n/**\n * Unescape HTML string\n * @param {string}  str   - string to unescape\n * @return {string} unescaped string\n */\n\nconst unescapeHtml = str =>\n    str.replace('&amp;', '&')\n        .replace('&lt;', '<')\n        .replace('&gt;', '>')\n        .replace('&#39;', \"'\")\n        .replace('&quot;', '\"')\n\n\n/**\n * Get element data attributes\n * @param {HTMLElement}  node   - node element\n * @return {array}       node data\n */\n\nconst getNodeData = node => {\n\n    // All attributes\n    const attributes = node.attributes\n\n    // Regex Pattern\n    const pattern = /^data\\-(.+)$/\n\n    // Output\n    const data = {}\n\n    for (let i in attributes) {\n        if (!attributes[i]) {\n            continue\n        }\n\n        // Attributes name (ex: data-module)\n        let name = attributes[i].name\n\n        // This happens.\n        if (!name) {\n            continue\n        }\n\n        let match = name.match(pattern)\n        if (!match) {\n            continue\n        }\n\n        // If this throws an error, you have some\n        // serious problems in your HTML.\n        data[match[1]] = getData(node.getAttribute(name))\n    }\n\n    return data;\n\n}\n\n\n\n\n/**\n * Parse value to data type.\n *\n * @link   https://github.com/jquery/jquery/blob/3.1.1/src/data.js\n * @param  {string} data - value to convert\n * @return {mixed}  value in its natural data type\n */\n\nconst rbrace = /^(?:\\{[\\w\\W]*\\}|\\[[\\w\\W]*\\])$/\nconst getData = data => {\n    if (data === 'true') {\n        return true\n    }\n\n    if (data === 'false') {\n        return false\n    }\n\n    if (data === 'null') {\n        return null\n    }\n\n    // Only convert to a number if it doesn't change the string\n    if (data === +data+'') {\n        return +data\n    }\n\n    if (rbrace.test(data)) {\n        return JSON.parse(data)\n    }\n\n    return data\n}\n\n\n/**\n * Returns an array containing all the parent nodes of the given node\n * @param  {HTMLElement}    $el     - DOM Element\n * @return {array}          parent nodes\n */\n\nconst getParents = $el => {\n\n    // Set up a parent array\n    let parents = []\n\n    // Push each parent element to the array\n    for (; $el && $el !== document; $el = $el.parentNode) {\n        parents.push($el)\n    }\n\n    // Return our parent array\n    return parents\n}\n\n\nexport {\n    escapeHtml,\n    unescapeHtml,\n    getNodeData,\n    getData,\n    getParents,\n}\n"
  },
  {
    "path": "packages/landing/assets/scripts/utils/image.js",
    "content": "import { CSS_CLASS } from '../config'\n\n/**\n * Get an image meta data\n *\n * @param {HTMLImageElement}    $img   - The image element.\n * @return {object}             The given image meta data\n */\n\nconst getImageMetadata = $img => ({\n    url: $img.src,\n    width: $img.naturalWidth,\n    height: $img.naturalHeight,\n    ratio: $img.naturalWidth / $img.naturalHeight,\n})\n\n\n/**\n * Load the given image.\n *\n * @param {string}  url         - The URI to lazy load into $el.\n * @param {object}  options     - An object of options\n * @return {void}\n */\n\nconst loadImage = (url, options = {}) => {\n    return new Promise((resolve, reject) => {\n        const $img = new Image()\n\n        if (options.crossOrigin) {\n            $img.crossOrigin = options.crossOrigin\n        }\n\n        const loadCallback = () => {\n            resolve({\n                element: $img,\n                ...getImageMetadata($img),\n            })\n        }\n\n        if($img.decode) {\n            $img.src = url\n            $img.decode().then(loadCallback).catch(e => {\n                reject(e)\n            })\n        } else {\n            $img.onload = loadCallback\n            $img.onerror = (e) => {\n                reject(e)\n            }\n            $img.src = url\n        }\n    })\n}\n\n\n/**\n * Lazy load the given image.\n *\n * @param {HTMLImageElement}    $el      - The image element.\n * @param {?string}             url      - The URI to lazy load into $el.\n *     If falsey, the value of the `data-src` attribute on $el will be used as the URI.\n * @param {?function}           callback - A function to call when the image is loaded.\n * @return {void}\n */\n\nconst LAZY_LOADED_IMAGES = []\nconst lazyLoadImage = async ($el, url, callback) => {\n    let src = url ? url : $el.dataset.src\n\n    let loadedImage = LAZY_LOADED_IMAGES.find(image => image.url === src)\n\n    if (!loadedImage) {\n        loadedImage = await loadImage(src)\n\n        if (!loadedImage.url) {\n            return\n        }\n\n        LAZY_LOADED_IMAGES.push(loadedImage)\n    }\n\n    if($el.src === src) {\n        return\n    }\n\n    if ($el.tagName === 'IMG') {\n        $el.src = loadedImage.url\n    } else {\n        $el.style.backgroundImage = `url(${loadedImage.url})`\n    }\n\n    requestAnimationFrame(() => {\n        let lazyParent = $el.closest(`.${CSS_CLASS.LAZY_CONTAINER}`)\n\n        if(lazyParent) {\n            lazyParent.classList.add(CSS_CLASS.LAZY_LOADED)\n            lazyParent.style.backgroundImage = ''\n        }\n\n        $el.classList.add(CSS_CLASS.LAZY_LOADED)\n\n        callback?.()\n    })\n}\n\n\nexport {\n    getImageMetadata,\n    loadImage,\n    lazyLoadImage\n}\n"
  },
  {
    "path": "packages/landing/assets/scripts/utils/is.js",
    "content": "/**\n * Determines if the argument is object-like.\n *\n * A value is object-like if it's not `null` and has a `typeof` result of \"object\".\n *\n * @param  {*} x - The value to be checked.\n * @return {boolean}\n */\n\nconst isObject = x => (x && typeof x === 'object')\n\n/**\n * Determines if the argument is a function.\n *\n * @param  {*} x - The value to be checked.\n * @return {boolean}\n */\n\nconst isFunction = x => typeof x === 'function'\n\n\nexport {\n    isObject,\n    isFunction\n}\n"
  },
  {
    "path": "packages/landing/assets/scripts/utils/maths.js",
    "content": "/**\n * Clamp value\n * @param {number}  min - start value\n * @param {number}  max - end value\n * @param {number}  a   - alpha value\n * @return {number} clamped value\n */\n\nconst clamp = (min = 0, max = 1, a) => Math.min(max, Math.max(min, a))\n\n\n/**\n * Calculate lerp\n * @param {number}  x   - start value\n * @param {number}  y   - end value\n * @param {number}  a   - alpha value\n * @return {number} lerp value\n */\n\nconst lerp = (x, y, a) => x * (1 - a) + y * a\n\n\n/**\n * Calculate inverted lerp\n * @param {number}  x   - start value\n * @param {number}  y   - end value\n * @param {number}  a   - alpha value\n * @return {number} inverted lerp value\n */\n\nconst invlerp = (x, y, a) => clamp((a - x)/(y - x))\n\n\n/**\n * Round number to the specified precision.\n *\n * This function is necessary because `Number.prototype.toPrecision()`\n * and `Number.prototype.toFixed()`\n *\n * @param  {number}  number      - The floating point number to round.\n * @param  {number}  [precision] - The number of digits to appear after the decimal point.\n * @return {number} The rounded number.\n */\nconst roundNumber = (number, precision = 2) => {\n    return Number.parseFloat(number.toPrecision(precision));\n}\n\n\nexport {\n    clamp,\n    lerp,\n    invlerp,\n    roundNumber\n}\n"
  },
  {
    "path": "packages/landing/assets/scripts/utils/tickers.js",
    "content": "/**\n * Creates a debounced function.\n *\n * A debounced function delays invoking `callback` until after\n * `delay` milliseconds have elapsed since the last time the\n * debounced function was invoked.\n *\n * Useful for behaviour that should only happen _before_ or\n * _after_ an event has stopped occurring.\n *\n * @template {function} T\n *\n * @param  {T}       callback    - The function to debounce.\n * @param  {number}  delay       - The number of milliseconds to wait.\n * @param  {boolean} [immediate] -\n *     If `true`, `callback` is invoked before `delay`.\n *     If `false`, `callback` is invoked after `delay`.\n * @return {function<T>} The new debounced function.\n */\n\nconst debounce = (callback, delay, immediate = false) => {\n    let timeout = null\n\n    return (...args) => {\n        clearTimeout(timeout)\n\n        const later = () => {\n            timeout = null\n            if (!immediate) {\n                callback(...args)\n            }\n        }\n\n        if (immediate && !timeout) {\n            callback(...args)\n        }\n\n        timeout = setTimeout(later, delay)\n    }\n}\n\n\n/**\n * Creates a throttled function.\n *\n * A throttled function invokes `callback` at most once per every\n * `delay` milliseconds.\n *\n * Useful for rate-limiting an event that occurs in quick succession.\n *\n * @template {function} T\n *\n * @param  {T}       callback - The function to throttle.\n * @param  {number}  delay    - The number of milliseconds to wait.\n * @return {function<T>} The new throttled function.\n */\n\nconst throttle = (callback, delay) => {\n    let timeout = false\n\n    return (...args) => {\n        if (!timeout) {\n            timeout = true\n\n            callback(...args)\n\n            setTimeout(() => {\n                timeout = false\n            }, delay)\n        }\n    }\n}\n\n\nexport {\n    debounce,\n    throttle\n}\n"
  },
  {
    "path": "packages/landing/assets/scripts/utils/transform.js",
    "content": "/**\n * Get translate function\n * @param {HTMLElement}     $el     - DOM Element\n * @return {number|object}  translate value\n */\n\nconst getTranslate = $el => {\n\n    if(!window.getComputedStyle) {\n        return\n    }\n\n    let translate\n    const style = getComputedStyle($el)\n    const transform = style.msTransform || style.webkitTransform || style.MozTransform || style.OTransform || style.transform\n\n    const matrix3D = transform.match(/^matrix3d\\((.+)\\)$/)\n    if(matrix3D) {\n        translate = parseFloat(matrix3D[1].split(', ')[13])\n    } else {\n        const matrix = transform.match(/^matrix\\((.+)\\)$/)\n        translate = {\n            x: matrix ? parseFloat(matrix[1].split(', ')[4]) : 0\n            y: matrix ? parseFloat(matrix[1].split(', ')[5]) : 0\n        }\n    }\n\n    return translate\n}\n\n\nexport {\n    transform,\n    getTranslate\n}\n"
  },
  {
    "path": "packages/landing/assets/scripts/utils/visibility.js",
    "content": "/**\n * The `PageVisibility` interface provides support for dispatching\n * a custom event derived from the value of {@see document.visibilityState}\n * when the \"visibilitychange\" event is fired.\n *\n * The custom events are:\n *\n * - \"visibilityhidden\" representing the \"hidden\" visibility state.\n * - \"visibilityvisible\" representing the \"visibile\" visibility state.\n *\n * Example:\n *\n * ```js\n * import pageVisibility from './utils/visibility.js';\n *\n * pageVisibility.enableCustomEvents();\n *\n * document.addEventListener('visibilityhidden', () => videoElement.pause());\n * ```\n *\n * The dispatched event object is the same from \"visibilitychange\"\n * and renamed according to the visibility state.\n *\n * The `PageVisibility` interface does not manage the attachment/detachment\n * of event listeners on the custom event types.\n *\n * Further reading:\n *\n * - {@link https://www.w3.org/TR/page-visibility/ W3 Specification}\n * - {@link https://developer.mozilla.org/en-US/docs/Web/API/Page_Visibility_API MDN Web Docs}\n */\nexport default new class PageVisibility {\n    /**\n     * Checks if the \"visibilitychange\" event listener has been registered.\n     *\n     * @return {boolean} Returns `false` if the event listener is not registered,\n     *     otherwise returns `true`.\n     */\n    get isEnabled() {\n        return isVisibilityChangeObserved;\n    }\n\n    /**\n     * Removes the \"visibilitychange\" event listener.\n     *\n     * @return {boolean} Returns `false` if the event listener was already unregistered,\n     *     otherwise returns `true`.\n     */\n    disableCustomEvents() {\n        if (isVisibilityChangeObserved) {\n            isVisibilityChangeObserved = false;\n            document.removeEventListener('visibilitychange', handleCustomVisibilityChange);\n            return true;\n        }\n\n        return false;\n    }\n\n    /**\n     * Registers the \"visibilitychange\" event listener.\n     *\n     * @return {boolean} Returns `false` if the event listener was already registered,\n     *     otherwise returns `true`.\n     */\n    enableCustomEvents() {\n        if (!isVisibilityChangeObserved) {\n            isVisibilityChangeObserved = true;\n            document.addEventListener('visibilitychange', handleCustomVisibilityChange);\n            return true;\n        }\n\n        return false;\n    }\n}\n\n/**\n * Tracks whether custom visibility event types\n * are available (`true`) or not (`false`).\n *\n * @type {boolean}\n */\nlet isVisibilityChangeObserved = false;\n\n/**\n * Dispatches a custom visibility event at the document derived\n * from the value of {@see document.visibilityState}.\n *\n * @listens document#visibilitychange\n *\n * @fires PageVisibility#visibilityhidden\n * @fires PageVisibility#visibilityvisible\n *\n * @param  {Event} event\n * @return {void}\n */\nfunction handleCustomVisibilityChange(event) {\n    document.dispatchEvent(new CustomEvent(`visibility${document.visibilityState}`, {\n        detail: {\n            cause: event\n        }\n    }));\n}\n\n/**\n * The \"visibilityhidden\" eveent is fired at the document when the contents\n * of its tab have become hidden.\n *\n * @event PageVisibility#visibilityhidden\n * @type  {Event}\n */\n\n/**\n * The \"visibilityvisible\" eveent is fired at the document when the contents\n * of its tab have become visible.\n *\n * @event PageVisibility#visibilityvisible\n * @type  {Event}\n */\n"
  },
  {
    "path": "packages/landing/assets/scripts/vendors/.gitkeep",
    "content": ""
  },
  {
    "path": "packages/landing/assets/styles/_core.scss",
    "content": "// ==========================================================================\n// Core\n// ==========================================================================\n\n@forward \"tools/maths\";\n@forward \"tools/functions\" hide $font-size, $context;\n@forward \"tools/mixins\";\n@forward \"tools/family\";\n@forward \"tools/layout\";\n@forward \"tools/widths\";\n\n@forward \"settings/config.colors\";\n@forward \"settings/config\";\n@forward \"settings/config.breakpoints\";\n@forward \"settings/config.eases\";\n@forward \"settings/config.fonts\";\n@forward \"settings/config.spacers\";\n@forward \"settings/config.timings\";\n@forward \"settings/config.zindexes\";\n@forward \"settings/config.variables\";\n"
  },
  {
    "path": "packages/landing/assets/styles/components/_button.scss",
    "content": "// ==========================================================================\n// Components / Buttons\n// ==========================================================================\n\n\n@use \"../core\" as *;\n@use \"text\" as *;\n.c-button {\n    --button-height: #{rem(56px)};\n    --button-padding: #{rem(16px)};\n    --button-gap: #{rem(16px)};\n\n    --button-color-text: var(--color-background);\n    --button-color-background: var(--color-text);\n    --button-color-stroke: var(--color-text);\n\n    --button-hover-color-text: var(--color-text);\n    --button-hover-color-background: var(--color-background);\n\n    position: relative;\n    overflow: hidden;\n    border-radius: 4px;\n    color: var(--button-color-text);\n    border: 1px solid var(--button-color-stroke);\n    background-color: var(--button-color-background);\n\n    &.-stroke {\n        --button-color-text: currentColor;\n        --button-color-background: transparent;\n\n        --button-hover-color-text: var(--color-background);\n        --button-hover-color-background: var(--color-text);\n    }\n}\n\n.c-button_wrap {\n    &:nth-child(2) {\n        position: absolute;\n        top: -1px;\n        left: -1px;\n        width: calc(100% + 2px);\n        height: calc(100% + 2px);\n        color: var(--button-hover-color-text);\n        background-color: var(--button-hover-color-background);\n        clip-path: inset(10% -100% 10% 100% round 4px 4px 4px 4px);\n        transition: clip-path t(normal) ease('power3.inOut');\n    }\n\n    .c-button:hover & {\n        &:nth-child(2) {\n            clip-path: inset(0 0 0 0 round 4px 4px 4px 4px);\n        }\n    }\n}\n\n.c-button_inner {\n    display: inline-flex;\n    align-items: center;\n    column-gap: var(--button-gap);\n    min-height: var(--button-height);\n    padding: 0 var(--button-padding);\n    transition: transform t(normal) ease('power3.inOut');\n\n    .c-button_wrap:nth-child(1) & {\n        .c-button:hover & {\n            transform: translate3d(calc(-1 * var(--icon-width) - var(--button-gap)), 0, 0)\n        }\n    }\n\n    .c-button_wrap:nth-child(2) & {\n        position: absolute;\n        top: -1px;\n        left: -1px;\n        width: calc(100% + 2px);\n        height: calc(100% + 2px);\n        flex-direction: row-reverse;\n        transform: translate3d(calc(var(--icon-width) + var(--button-gap)), 0, 0);\n\n        .c-button:hover & {\n            transform: translate3d(0, 0, 0);\n        }\n    }\n}\n\n.c-button_label {\n    @include text;\n    font-size: var(--font-size-label);\n}"
  },
  {
    "path": "packages/landing/assets/styles/components/_cascade.scss",
    "content": "// ==========================================================================\n// Components / Cascade\n// ==========================================================================\n\n\n@use \"../core\" as *;\n.c-cascade {\n    position: relative;\n}\n\n.c-cascade_text {\n    display: flex;\n    flex-direction: column;\n    max-width: rem(220px);\n\n    @media (max-width: $to-large) {\n        margin-left: 50%;\n        margin-bottom: spacingClamp('xl');\n    }\n\n    @media (min-width: $from-large) {\n        position: absolute;\n        top: 0;\n        left: calc((100% + var(--grid-gutter)) / 4 * 3);\n    }\n}\n\n.c-cascade_container {\n    display: flex;\n    justify-content: center;\n    margin-left: calc(-1 * var(--grid-margin));\n    margin-right: calc(-1 * var(--grid-margin));\n    overflow: hidden;\n}\n\n.c-cascade_inner {\n    width: auto;\n}\n\n.c-cascade_item {\n    .c-cascade_item + & {\n        margin-left: calc(var(--item-index) * 2.35em);\n        margin-top: calc(-1em);\n    }\n\n    &:nth-child(odd) {\n        opacity: 0.35;\n    }\n}\n\n.c-cascade_line {\n    display: block;\n    perspective: 100vw;\n    transform-style: preserve-3d;\n}\n\n.c-cascade_word {\n    display: inline-block;\n    white-space: nowrap;\n    transform: rotate3d(1, 0, 0, mapRangeClamp(var(--progress), calc(var(--item-index) / 8), calc(calc(var(--item-index) + 1) / 8), 90deg, 0deg, 0deg, 90deg));\n    opacity: mapRangeClamp(var(--progress), calc(var(--item-index) / 8), calc(calc(var(--item-index) + 1) / 8), 0, 1, 0, 1);\n    transform-origin: top;\n    clip-path: inset(0);\n}\n\n.c-cascade_glyph {\n    position: absolute;\n    bottom: 0;\n    left: 0;\n    font-size: var(--font-size-serif-medium);\n}\n"
  },
  {
    "path": "packages/landing/assets/styles/components/_fadeInText.scss",
    "content": "@use \"../core\" as *;\n\n.c-fadein-text_line {\n    background: var(--background);\n    -webkit-background-clip: text;\n    color: transparent;\n}\n\n.fadeInText{\n    &.-blue {\n        --color-cta-fadein: #898fe9;\n        --color: white;\n    }\n    &.-white {\n        --color-cta-fadein: #cacdff;\n        --color:  #{color(blue)};\n    }\n    &.-black {\n        --color-cta-fadein: #424242;\n        --color: white;\n    }\n}"
  },
  {
    "path": "packages/landing/assets/styles/components/_features-grid.scss",
    "content": "// ==========================================================================\n// Components / Features grid\n// ==========================================================================\n\n@use '../core' as *;\n$color-grid: 282828;\n\n.c-features-grid {\n    @media (max-width: $to-small) {\n        --rows: 6;\n        --columns: 2;\n        --cell-ratio: 180/220;\n        --grid-image: url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' xml:space='preserve' viewBox='0 0 361.5 1980'%3E%3Cpath fill='%23#{$color-grid}' fill-rule='evenodd' d='M173 1760H1.5c-.3 0-.5.2-.5.5s.2.5.5.5H173c4.4 0 8 3.6 8 8v211h1v-211c0-4.4 3.6-8 8-8h171.5v-1H190c-4.4 0-8-3.6-8-8v-203c0-4.4 3.6-8 8-8h171.5v-1H190c-4.4 0-8-3.6-8-8v-203c0-4.4 3.6-8 8-8h171.5v-1H190c-4.4 0-8-3.6-8-8v-203c0-4.4 3.6-8 8-8h171.5v-1H190c-4.4 0-8-3.6-8-8V889c0-4.4 3.6-8 8-8h171.5v-1H190c-4.4 0-8-3.6-8-8V669c0-4.4 3.6-8 8-8h171.5v-1H190c-4.4 0-8-3.6-8-8V449c0-4.4 3.6-8 8-8h171.5v-1H190c-4.4 0-8-3.6-8-8V229c0-4.4 3.6-8 8-8h171.5v-1H190c-4.4 0-8-3.6-8-8V.5c0-.3-.2-.5-.5-.5s-.5.2-.5.5V212c0 4.4-3.6 8-8 8H1.5c-.3 0-.5.2-.5.5s.2.5.5.5H173c4.4 0 8 3.6 8 8v203c0 4.4-3.6 8-8 8H1.5c-.3 0-.5.2-.5.5s.2.5.5.5H173c4.4 0 8 3.6 8 8v203c0 4.4-3.6 8-8 8H1.5c-.3 0-.5.2-.5.5s.2.5.5.5H173c4.4 0 8 3.6 8 8v203c0 4.4-3.6 8-8 8H1.5c-.3 0-.5.2-.5.5s.2.5.5.5H173c4.4 0 8 3.6 8 8v203c0 4.4-3.6 8-8 8H1.5c-.3 0-.5.2-.5.5s.2.5.5.5H173c4.4 0 8 3.6 8 8v203c0 4.4-3.6 8-8 8H1.5c-.3 0-.5.2-.5.5s.2.5.5.5H173c4.4 0 8 3.6 8 8v203c0 4.4-3.6 8-8 8H1.5c-.3 0-.5.2-.5.5s.2.5.5.5H173c4.4 0 8 3.6 8 8v203c0 4.4-3.6 8-8 8z' clip-rule='evenodd'/%3E%3C/svg%3E%0A\");\n    }\n    @media (min-width: $from-small) {\n        --rows: 6;\n        --columns: 4;\n        --cell-ratio: 1;\n        --grid-image: url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 1400 4198'%3E%3Cpath fill='%23#{$color-grid}' fill-rule='evenodd' d='M342 349a8 8 0 0 0 8-8V.5a.5.5 0 0 1 1 0V341a8 8 0 0 0 8 8h333.5a8 8 0 0 0 8-8V.5a.5.5 0 0 1 1 0V341a8 8 0 0 0 8 8h333a8 8 0 0 0 8-8V.5c0-.276.22-.5.5-.5s.5.224.5.5V341a8 8 0 0 0 8 8h340c.28 0 .5.224.5.5s-.22.5-.5.5h-340a8 8 0 0 0-8 8v333a8 8 0 0 0 8 8h340c.28 0 .5.224.5.5s-.22.5-.5.5h-340a8 8 0 0 0-8 8v333c0 4.42 3.58 8 8 8h339c.28 0 .5.22.5.5s-.22.5-.5.5h-339c-4.42 0-8 3.58-8 8v333c0 4.42 3.58 8 8 8h339c.28 0 .5.22.5.5s-.22.5-.5.5h-339c-4.42 0-8 3.58-8 8v333c0 4.42 3.58 8 8 8h339c.28 0 .5.22.5.5s-.22.5-.5.5h-339c-4.42 0-8 3.58-8 8v333c0 4.42 3.58 8 8 8h339c.28 0 .5.22.5.5s-.22.5-.5.5h-339c-4.42 0-8 3.58-8 8v333c0 4.42 3.58 8 8 8h339c.28 0 .5.22.5.5s-.22.5-.5.5h-339c-4.42 0-8 3.58-8 8v333c0 4.42 3.58 8 8 8h339c.28 0 .5.22.5.5s-.22.5-.5.5h-339c-4.42 0-8 3.58-8 8v333c0 4.42 3.58 8 8 8h339c.28 0 .5.22.5.5s-.22.5-.5.5h-339c-4.42 0-8 3.58-8 8v333c0 4.42 3.58 8 8 8h339c.28 0 .5.22.5.5s-.22.5-.5.5h-339c-4.42 0-8 3.58-8 8v333c0 4.42 3.58 8 8 8h339c.28 0 .5.22.5.5s-.22.5-.5.5h-339c-4.42 0-8 3.58-8 8v339.5c0 .28-.22.5-.5.5s-.5-.22-.5-.5V3858c0-4.42-3.58-8-8-8h-333a8 8 0 0 0-8 8v339.5c0 .28-.224.5-.5.5s-.5-.22-.5-.5V3858a8 8 0 0 0-8-8H359a8 8 0 0 0-8 8v339.5c0 .28-.224.5-.5.5s-.5-.22-.5-.5V3858a8 8 0 0 0-8-8H.5c-.276 0-.5-.22-.5-.5s.224-.5.5-.5H342a8 8 0 0 0 8-8v-333a8 8 0 0 0-8-8H.5c-.276 0-.5-.22-.5-.5s.224-.5.5-.5H342a8 8 0 0 0 8-8v-333a8 8 0 0 0-8-8H.5c-.276 0-.5-.22-.5-.5s.224-.5.5-.5H342a8 8 0 0 0 8-8v-333a8 8 0 0 0-8-8H.5c-.276 0-.5-.22-.5-.5s.224-.5.5-.5H342a8 8 0 0 0 8-8v-333a8 8 0 0 0-8-8H.5c-.276 0-.5-.22-.5-.5s.224-.5.5-.5H342a8 8 0 0 0 8-8v-333a8 8 0 0 0-8-8H.5c-.276 0-.5-.22-.5-.5s.224-.5.5-.5H342a8 8 0 0 0 8-8v-333a8 8 0 0 0-8-8H.5c-.276 0-.5-.22-.5-.5s.224-.5.5-.5H342a8 8 0 0 0 8-8v-333a8 8 0 0 0-8-8H.5c-.276 0-.5-.22-.5-.5s.224-.5.5-.5H342a8 8 0 0 0 8-8v-333a8 8 0 0 0-8-8H.5c-.276 0-.5-.22-.5-.5s.224-.5.5-.5H342a8 8 0 0 0 8-8V708a8 8 0 0 0-8-8H.5a.5.5 0 0 1 0-1H342a8 8 0 0 0 8-8V358a8 8 0 0 0-8-8H.5a.5.5 0 0 1 0-1H342Zm17 1a8 8 0 0 0-8 8v333a8 8 0 0 0 8 8h333.5a8 8 0 0 0 8-8V358a8 8 0 0 0-8-8H359Zm350.5 0a8 8 0 0 0-8 8v333a8 8 0 0 0 8 8h333a8 8 0 0 0 8-8V358a8 8 0 0 0-8-8h-333Zm341 358a8 8 0 0 0-8-8h-333a8 8 0 0 0-8 8v333a8 8 0 0 0 8 8h333c4.42 0 8-3.58 8-8V708Zm0 350c0-4.42-3.58-8-8-8h-333a8 8 0 0 0-8 8v333a8 8 0 0 0 8 8h333c4.42 0 8-3.58 8-8v-333Zm0 350c0-4.42-3.58-8-8-8h-333a8 8 0 0 0-8 8v333a8 8 0 0 0 8 8h333c4.42 0 8-3.58 8-8v-333Zm0 350c0-4.42-3.58-8-8-8h-333a8 8 0 0 0-8 8v333a8 8 0 0 0 8 8h333c4.42 0 8-3.58 8-8v-333Zm0 350c0-4.42-3.58-8-8-8h-333a8 8 0 0 0-8 8v333a8 8 0 0 0 8 8h333c4.42 0 8-3.58 8-8v-333Zm0 350c0-4.42-3.58-8-8-8h-333a8 8 0 0 0-8 8v333a8 8 0 0 0 8 8h333c4.42 0 8-3.58 8-8v-333Zm0 350c0-4.42-3.58-8-8-8h-333a8 8 0 0 0-8 8v333a8 8 0 0 0 8 8h333c4.42 0 8-3.58 8-8v-333Zm0 350c0-4.42-3.58-8-8-8h-333a8 8 0 0 0-8 8v333a8 8 0 0 0 8 8h333c4.42 0 8-3.58 8-8v-333Zm0 350c0-4.42-3.58-8-8-8h-333a8 8 0 0 0-8 8v333a8 8 0 0 0 8 8h333c4.42 0 8-3.58 8-8v-333Zm-358 341a8 8 0 0 0 8-8v-333a8 8 0 0 0-8-8H359a8 8 0 0 0-8 8v333a8 8 0 0 0 8 8h333.5ZM351 3491a8 8 0 0 0 8 8h333.5a8 8 0 0 0 8-8v-333a8 8 0 0 0-8-8H359a8 8 0 0 0-8 8v333Zm0-350a8 8 0 0 0 8 8h333.5a8 8 0 0 0 8-8v-333a8 8 0 0 0-8-8H359a8 8 0 0 0-8 8v333Zm0-350a8 8 0 0 0 8 8h333.5a8 8 0 0 0 8-8v-333a8 8 0 0 0-8-8H359a8 8 0 0 0-8 8v333Zm0-350a8 8 0 0 0 8 8h333.5a8 8 0 0 0 8-8v-333a8 8 0 0 0-8-8H359a8 8 0 0 0-8 8v333Zm0-350a8 8 0 0 0 8 8h333.5a8 8 0 0 0 8-8v-333a8 8 0 0 0-8-8H359a8 8 0 0 0-8 8v333Zm0-350a8 8 0 0 0 8 8h333.5a8 8 0 0 0 8-8v-333a8 8 0 0 0-8-8H359a8 8 0 0 0-8 8v333Zm0-350a8 8 0 0 0 8 8h333.5a8 8 0 0 0 8-8v-333a8 8 0 0 0-8-8H359a8 8 0 0 0-8 8v333Zm0-350a8 8 0 0 0 8 8h333.5a8 8 0 0 0 8-8V708a8 8 0 0 0-8-8H359a8 8 0 0 0-8 8v333Z' clip-rule='evenodd'/%3E%3C/svg%3E%0A\");\n    }\n\n    position: relative;\n\n    &:before {\n        content: '';\n        display: block;\n        width: 100%;\n        padding-top: calc(\n            (var(--rows) + 2) / var(--columns) * (1 / (var(--cell-ratio))) *\n                100%\n        );\n        pointer-events: none;\n    }\n\n    &:after {\n        content: '';\n        position: absolute;\n        top: 0;\n        left: 0;\n        width: 100%;\n        height: 100%;\n        // opacity: 0.15;\n        background-size: cover;\n        background-image: var(--grid-image);\n        pointer-events: none;\n    }\n}\n\n.c-features-grid_container {\n    position: absolute;\n    top: 0;\n    left: 0;\n    width: 100%;\n    height: 100%;\n    z-index: 1;\n\n    &::before,\n    &::after {\n        content: '';\n        position: absolute;\n        left: 0;\n        width: 100%;\n        padding-top: calc(\n            1 / var(--columns) * (1 / (var(--cell-ratio))) * 100%\n        );\n        background-color: var(--color-background);\n        z-index: 1;\n    }\n\n    &::before {\n        top: 0;\n        -webkit-mask-image: -webkit-linear-gradient(\n            bottom,\n            rgba(0, 0, 0, 0),\n            rgba(0, 0, 0, 1)\n        );\n    }\n\n    &::after {\n        bottom: 0;\n        -webkit-mask-image: -webkit-linear-gradient(\n            top,\n            rgba(0, 0, 0, 0),\n            rgba(0, 0, 0, 1)\n        );\n    }\n}\n\n.c-features-grid_inner {\n    position: relative;\n    display: grid;\n    grid-template-columns: repeat(var(--columns), 1fr);\n    grid-template-rows: repeat(var(--rows), 1fr);\n    width: 100%;\n    height: 100%;\n    padding-top: calc(1 / var(--columns) * (1 / (var(--cell-ratio))) * 100%);\n    padding-bottom: calc(1 / var(--columns) * (1 / (var(--cell-ratio))) * 100%);\n    pointer-events: none;\n\n    @media (max-width: $to-small) {\n        grid-template-areas:\n            'locomotive lenis'\n            '. scrollbar'\n            'normalized sticky'\n            'io sticky'\n            'direction scroll-to'\n            '. custom-easing';\n    }\n\n    @media (min-width: $from-small) {\n        grid-template-areas:\n            'scrollbar  . lenis locomotive'\n            '. normalized  . .'\n            '. . sticky .'\n            'io . sticky .'\n            '. scroll-to sticky direction'\n            '. custom-easing sticky direction';\n    }\n}\n\n.c-features-grid_cell {\n    position: relative;\n    text-align: left;\n\n    &.-lenis {\n        grid-area: lenis;\n    }\n    &.-locomotive {\n        grid-area: locomotive;\n    }\n    &.-scrollbar {\n        grid-area: scrollbar;\n    }\n    &.-normalized {\n        grid-area: normalized;\n    }\n    &.-sticky {\n        grid-area: sticky;\n    }\n    &.-io {\n        grid-area: io;\n    }\n    &.-scroll-to {\n        grid-area: scroll-to;\n    }\n    &.-direction {\n        grid-area: direction;\n    }\n    &.-custom-easing {\n        grid-area: custom-easing;\n    }\n\n    @media (min-width: $from-small) {\n        &.-io {\n            transition: transform t(slow) ease('power3.out');\n\n            &.is-inview {\n                transform: translate3d(100%, 0, 0);\n            }\n        }\n    }\n}\n\n.c-features-grid_cell_ratio {\n    display: flex;\n    aspect-ratio: var(--cell-ratio);\n    padding: rem(16px);\n    pointer-events: auto;\n\n    .c-features-grid_cell.-sticky & {\n        @media (min-width: $from-small) {\n            position: sticky;\n            top: calc(var(--header-height) + 1px);\n            z-index: 1;\n            &::before {\n                content: '';\n                position: absolute;\n                background-color: var(--color-background);\n                z-index: -1;\n                top: -1px;\n                left: 0px;\n                width: calc(100% + 1px);\n                height: calc(100% + 1px);\n                border: 1px solid #{'#' + $color-grid};\n                border-radius: calc(var(--vw, 1vw) * 0.6);\n            }\n        }\n    }\n\n    .c-features-grid_cell.-direction & {\n        position: relative;\n    }\n\n    @media (min-width: $from-small) {\n        .c-features-grid_cell.-io & {\n            z-index: 1;\n\n            &::before {\n                content: '';\n                position: absolute;\n                top: -1px;\n                left: 0px;\n                width: calc(100% + 1px);\n                height: calc(100% + 1px);\n                background-color: var(--color-background);\n                border-top: 1px solid #{'#' + $color-grid};\n                border-right: 1px solid #{'#' + $color-grid};\n                border-bottom: 1px solid #{'#' + $color-grid};\n                border-top-right-radius: calc(var(--vw, 1vw) * 0.6);\n                border-bottom-right-radius: calc(var(--vw, 1vw) * 0.6);\n                z-index: -1;\n            }\n        }\n        .c-features-grid_cell.-io.is-inview & {\n            &::before {\n                border-left: 1px solid #{'#' + $color-grid};\n                border-radius: calc(var(--vw, 1vw) * 0.6);\n            }\n        }\n    }\n}\n\n.c-features-grid_cell_inner {\n    position: relative;\n    display: flex;\n    flex-direction: column;\n    justify-content: space-between;\n    align-items: flex-start;\n    width: 100%;\n    padding-right: rem(30px);\n\n    &.-logo {\n        padding-right: 0;\n    }\n}\n\n// Link\n// ========================================\n.c-features-grid_link {\n    position: absolute;\n    top: 0;\n    left: 0;\n    width: 100%;\n    height: 100%;\n    z-index: 2;\n\n    @media (hover: hover) {\n        &::before {\n            content: '';\n            position: absolute;\n            top: 0;\n            left: 0;\n            width: 100%;\n            height: 100%;\n            opacity: 0.07;\n            background-color: currentColor;\n            clip-path: polygon(\n                80% 20%,\n                80% 20%,\n                80% 20%,\n                20% 80%,\n                20% 80%,\n                20% 80%,\n                20% 80%,\n                80% 20%\n            );\n            transition: clip-path t(fast) ease('power3.out');\n        }\n\n        &:hover {\n            &::before {\n                animation-play-state: running;\n                clip-path: polygon(\n                    15% 5%,\n                    85% 5%,\n                    95% 15%,\n                    95% 85%,\n                    85% 95%,\n                    15% 95%,\n                    5% 85%,\n                    5% 15%\n                );\n            }\n        }\n    }\n}\n\n// Content\n// ========================================\n.c-features-grid_title {\n    display: inline-block;\n    text-wrap: balance;\n\n    .c-features-grid_cell.-direction & {\n        transition: transform t(normal) ease('power3.out');\n\n        // html.is-scrolling-up & {\n        //     transform: scaleY(-100%);\n        //     animation: blink 100ms step-start 3;\n        // }\n    }\n    .c-features-grid_cell.-link & {\n        position: absolute;\n        bottom: 0;\n        left: 0;\n        clip-path: inset(0 #{rem(-16px)});\n    }\n}\n\n.c-features_direction_title {\n    display: flex;\n    gap: rem(10px);\n}\n\n.c-features_direction_arrows {\n    position: relative;\n    clip-path: inset(0);\n\n    span {\n        --translate: 0%;\n        display: block;\n        transition: transform t('medium') ease('power3.out');\n        &:nth-of-type(1) {\n            transform: translate3d(0, var(--translate), 0);\n        }\n        &:nth-of-type(2) {\n            position: absolute;\n            transform: translate3d(0, calc(var(--translate) + 100%), 0);\n            top: 0;\n            left: 0;\n        }\n\n        html.is-scrolling-up & {\n            --translate: -100%;\n        }\n    }\n}\n\n.c-features-grid_title_label {\n    display: inline-block;\n\n    @media (hover: none) {\n        &:nth-child(2) {\n            display: none;\n        }\n    }\n\n    @media (hover: hover) {\n        transition: transform t(normal) ease('power4.out');\n\n        &:nth-child(2) {\n            position: absolute;\n            top: 0;\n            left: 0;\n            transform: translate3d(#{rem(-16px)}, -100%, 0);\n        }\n\n        .c-features-grid_cell:hover & {\n            &:nth-child(1) {\n                transform: translate3d(#{rem(16px)}, 100%, 0);\n            }\n            &:nth-child(2) {\n                transform: translate3d(0, 0, 0);\n            }\n        }\n    }\n}\n\n.c-features-grid_desc {\n    max-width: rem(220px);\n\n    @media (max-width: $to-small) {\n        opacity: 0.6;\n    }\n}\n\n.c-features-grid_index {\n    position: absolute;\n    top: 0;\n    right: 0;\n}\n\n.c-features-grid_logo {\n    display: flex;\n    justify-content: center;\n    align-items: center;\n    width: 100%;\n    height: 100%;\n\n    @media (hover: hover) {\n        svg {\n            transition: transform t(normal) ease('power4.out');\n\n            .c-features-grid_cell:hover & {\n                transform: scale3d(0.95, 0.95, 1);\n                animation: blink 100ms step-start 3;\n            }\n        }\n    }\n}\n\n// Icon\n// ========================================\n.c-features-grid_icon-container {\n    position: absolute;\n    top: rem(10px);\n    right: rem(10px);\n    display: flex;\n    overflow: hidden;\n}\n\n.c-features-grid_icon {\n    padding: rem(6px);\n\n    &:nth-child(2) {\n        position: absolute;\n        top: 0;\n        left: 0;\n        width: 100%;\n        height: 100%;\n        transform: translate3d(-100%, 100%, 0);\n    }\n\n    html.is-first-loaded & {\n        transition: transform t(normal) ease('power4.out');\n    }\n\n    html.is-first-loaded .c-features-grid_cell:hover & {\n        &:nth-child(1) {\n            transform: translate3d(100%, -100%, 0);\n        }\n        &:nth-child(2) {\n            transform: translate3d(0, 0, 0);\n        }\n    }\n}\n\n// Keyframes\n// ========================================\n@keyframes blink {\n    50% {\n        opacity: 0;\n    }\n}\n"
  },
  {
    "path": "packages/landing/assets/styles/components/_footer.scss",
    "content": "@use \"../core\" as *;\n\n.c-footer_attributes {\n    align-items: flex-start;\n    div {\n        @media (max-width: $to-medium) {\n            white-space: nowrap;\n        }\n        p{\n            line-height: 1.25;\n            opacity: 0;\n        }\n        &:nth-of-type(1){\n            @media (max-width: $to-medium) {\n                grid-column: 3 / 1;\n            }\n        }\n        &:nth-of-type(2){\n            \n            @media (max-width: $to-medium) {\n                grid-column: 5 / 3;\n                margin-top: 10rem;\n            }\n\n            @media (min-width: $from-medium) {\n                margin-top: 15rem;\n            }\n        }\n        &:nth-of-type(3){\n            @media (max-width: $to-medium) {\n                grid-column: 5 / 2;\n                margin-top: 5rem;\n            }\n            @media (min-width: $from-medium) {\n                margin-top: 10rem;\n            }\n        }\n        &:nth-of-type(4){\n            @media (max-width: $to-medium) {\n                grid-column: 3 / 1;\n                margin-top: 5rem;\n            }\n            @media (min-width: $from-medium) {\n                margin-top: 25rem;\n            }\n        }\n    }\n}\n\n.c-footer_thanks {\n    grid-column: 5 / 2;\n    margin-top: calc(spacingClamp('3xl') * 1.5);\n\n   \n    // @for $i from 0 through 10 {\n    //     span {\n    //         &:nth-of-type(#{$i}) {\n    //             transform: translateX(calc(-100px + calc(100px * var(--progress))));\n    //         }\n    //     }\n    // }\n\n    // span {\n    //     transform: translateX(calc(-100px * var(--progress)));\n    // }\n\n    @media (min-width: $from-medium) {\n        grid-column: 5 / 3;\n        margin-top: spacingClamp('3xl');\n    }\n}\n\n.c-footer_website {\n    opacity: 0;\n    transform: translate3d(0,100%,0);\n    transition: transform t('slow') ease('power3.out'), opacity t('slow') ease('power3.out');\n\n    &.is-inview {\n        opacity: 1;\n        transform: translate3d(0,0,0);\n    }\n}\n"
  },
  {
    "path": "packages/landing/assets/styles/components/_form.scss",
    "content": "// ==========================================================================\n// Components / Form\n// ==========================================================================\n\n\n@use \"../core\" as *;\n@use \"sass:math\";\n\n.c-form {\n\n}\n\n.c-form_item {\n    position: relative;\n    margin-bottom: rem(30px);\n}\n\n// Label\n// ==========================================================================\n\n.c-form_label {\n    display: block;\n    margin-bottom: rem(10px);\n}\n\n// Input\n// ==========================================================================\n\n$input-icon-color: 424242; // No #\n\n.c-form_input {\n    padding: rem(10px);\n    border: 1px solid lightgray;\n    background-color: color(white);\n\n    &:hover {\n        border-color: darkgray;\n    }\n\n    &:focus {\n        border-color: dimgray;\n    }\n\n    &::placeholder {\n        color: gray;\n    }\n}\n\n// Checkbox\n// ==========================================================================\n\n$checkbox: rem(18px);\n$checkbox-icon-color: $input-icon-color;\n\n.c-form_checkboxLabel {\n    @extend .c-form_label;\n\n    position: relative;\n    display: inline-block;\n    margin-right: rem(10px);\n    margin-bottom: 0;\n    padding-left: ($checkbox + rem(10px));\n    cursor: pointer;\n\n    &::before, &::after {\n        position: absolute;\n        top: 50%;\n        left: 0;\n        display: inline-block;\n        margin-top: math.div(-$checkbox, 2);\n        padding: 0;\n        width: $checkbox;\n        height: $checkbox;\n        content: \"\";\n    }\n\n    &::before {\n        background-color: color(white);\n        border: 1px solid lightgray;\n    }\n\n    &::after {\n        border-color: transparent;\n        background-color: transparent;\n        background-image: url(\"data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20version%3D%221.1%22%20x%3D%220%22%20y%3D%220%22%20width%3D%2213%22%20height%3D%2210.5%22%20viewBox%3D%220%200%2013%2010.5%22%20enable-background%3D%22new%200%200%2013%2010.5%22%20xml%3Aspace%3D%22preserve%22%3E%3Cpath%20fill%3D%22%23#{$checkbox-icon-color}%22%20d%3D%22M4.8%205.8L2.4%203.3%200%205.7l4.8%204.8L13%202.4c0%200-2.4-2.4-2.4-2.4L4.8%205.8z%22%2F%3E%3C%2Fsvg%3E\");\n        background-position: center;\n        background-size: rem(12px);\n        background-repeat: no-repeat;\n        opacity: 0;\n    }\n\n    &:hover {\n        &::before {\n            border-color: darkgray;\n        }\n    }\n\n    .c-form_checkbox:focus + & {\n        &::before {\n            border-color: dimgray;\n        }\n    }\n\n    .c-form_checkbox:checked + & {\n        &::after {\n            opacity: 1;\n        }\n    }\n}\n\n.c-form_checkbox {\n    position: absolute;\n    width: 0;\n    opacity: 0;\n}\n\n// Radio\n// ==========================================================================\n\n$radio-icon-color: $input-icon-color;\n\n.c-form_radioLabel {\n    @extend .c-form_checkboxLabel;\n\n    &::before, &::after {\n        border-radius: 50%;\n    }\n\n    &::after {\n        background-image: url(\"data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20version%3D%221.1%22%20x%3D%220%22%20y%3D%220%22%20width%3D%2213%22%20height%3D%2213%22%20viewBox%3D%220%200%2013%2013%22%20enable-background%3D%22new%200%200%2013%2013%22%20xml%3Aspace%3D%22preserve%22%3E%3Ccircle%20fill%3D%22%23#{$radio-icon-color}%22%20cx%3D%226.5%22%20cy%3D%226.5%22%20r%3D%226.5%22%2F%3E%3C%2Fsvg%3E\");\n        background-size: rem(6px);\n    }\n}\n\n.c-form_radio {\n    @extend .c-form_checkbox;\n}\n\n// Select\n// =============================================================================\n\n$select-icon: rem(40px);\n$select-icon-color: $input-icon-color;\n\n.c-form_select {\n    position: relative;\n    cursor: pointer;\n\n    &::after {\n        position: absolute;\n        top: 0;\n        right: 0;\n        bottom: 0;\n        z-index: 2;\n        width: $select-icon;\n        background-image: url(\"data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20version%3D%221.1%22%20x%3D%220%22%20y%3D%220%22%20width%3D%2213%22%20height%3D%2211.3%22%20viewBox%3D%220%200%2013%2011.3%22%20enable-background%3D%22new%200%200%2013%2011.3%22%20xml%3Aspace%3D%22preserve%22%3E%3Cpolygon%20fill%3D%22%23#{$select-icon-color}%22%20points%3D%226.5%2011.3%203.3%205.6%200%200%206.5%200%2013%200%209.8%205.6%20%22%2F%3E%3C%2Fsvg%3E\");\n        background-position: center;\n        background-size: rem(8px);\n        background-repeat: no-repeat;\n        content: \"\";\n        pointer-events: none;\n    }\n}\n\n.c-form_select_input {\n    @extend .c-form_input;\n\n    position: relative;\n    z-index: 1;\n    padding-right: $select-icon;\n    cursor: pointer;\n}\n\n// Textarea\n// =============================================================================\n\n.c-form_textarea {\n    @extend .c-form_input;\n\n    min-height: rem(200px);\n}\n"
  },
  {
    "path": "packages/landing/assets/styles/components/_header.scss",
    "content": "// ==========================================================================\n// Components / Header\n// ==========================================================================\n\n\n@use \"../core\" as *;\n.c-header {\n    [data-header-theme=\"blue\"] & {\n        --color-header-text: #{color(white)};\n        --color-header-background: #{color(blue)};\n    }\n\n    [data-header-theme=\"black\"] & {\n        --color-header-text: #{color(white)};\n        --color-header-background: #{color(black)};\n    }\n\n    [data-header-theme=\"white\"] & {\n        --color-header-text: #{color(blue)};\n        --color-header-background: #{color(white)};\n    }\n\n    position: fixed;\n    top: 0;\n    width: 100%;\n    display: grid;\n    align-items: center;\n    grid-template-columns: repeat(3, 1fr);\n    column-gap: var(--grid-gutter);\n    color: var(--color-header-text);\n    background-color: var(--color-header-background);\n    padding: var(--grid-margin);    \n    z-index: z('header');\n\n    @media (max-width: $to-small) {\n        align-items: flex-start;\n    }\n\n    @media (min-width: $from-small) {\n        height: var(--header-height);\n    }\n\n    html.is-first-loaded & {\n        transition: color t(faster), background-color t(faster);\n    }\n}\n\n.c-header_col {\n    display: flex;\n    justify-content: space-between;\n    align-items: center;\n\n    &.-center {\n        justify-content: center;\n        align-items: center;\n    }\n\n    @media (max-width: $to-small) {\n        flex-direction: column;\n        align-items: flex-start;\n        gap: var(--grid-margin);\n\n        &:last-of-type {\n            align-items: flex-end;\n        }\n    }\n}\n\n.c-header-theme-toggler {\n    position: absolute;\n    top: calc(-1 * var(--header-height));\n    bottom: var(--header-height);\n    left: 0;\n    width: 100%;\n    pointer-events: none;\n}\n"
  },
  {
    "path": "packages/landing/assets/styles/components/_heading.scss",
    "content": "// ==========================================================================\n// Components / Headings\n// ==========================================================================\n\n// Font sizes\n// ==========================================================================\n\n@use \"../core\" as *;\n:root {\n    --font-size-serif-large:  #{responsive-value(100px, 300px, $from-figma)};\n    --font-size-serif-medium: #{responsive-value(40px, 120px, $from-figma)};\n\n    --font-size-h1:     #{responsive-value(54px, 120px, $from-figma)};\n    --font-size-h2:     #{responsive-value(32px, 90px, $from-figma)};\n    --font-size-h3:     #{responsive-value(14px, 28px, $from-figma)};\n}\n\n// Mixins\n// ==========================================================================\n@mixin heading {\n    font-family: ff('display');\n    font-weight: $font-weight-regular;\n    line-height: 1;\n    letter-spacing: -0.03em;\n}\n\n@mixin heading-serif {\n    font-family: ff('serif');\n    font-weight: $font-weight-light;\n    line-height: 0.85;\n    letter-spacing: -0.03em;\n}\n\n// Styles\n// ==========================================================================\n\n.c-heading {\n    @include heading;\n\n    &.-h1 {\n        font-size: var(--font-size-h1);\n    }\n\n    &.-h2 {\n        font-size: var(--font-size-h2);\n    }\n\n    &.-h3 {\n        font-size: var(--font-size-h3);\n    }\n}\n\n.c-heading-serif {\n    @include heading-serif;\n\n    &.-large {\n        font-size: var(--font-size-serif-large);\n    }\n\n    &.-medium {\n        font-size: var(--font-size-serif-medium);\n    }\n}\n"
  },
  {
    "path": "packages/landing/assets/styles/components/_hero.scss",
    "content": "@use \"../core\" as *;\n\n// Components / Hero\n// ==========================================================================\n\n@use \"sass:math\";\n@use \"heading\" as *;\n\n.c-hero_sticky {\n    position: sticky;\n    bottom: 0;\n}\n\n.c-hero_main {\n    display: grid;\n    gap: var(--grid-gutter);\n    align-items: flex-end;\n    min-height: 100svh;\n    padding-bottom: var(--grid-margin);\n    position: relative;\n    z-index: 10;\n    \n    &.-footer{\n        min-height: 100svh;\n    }\n\n    @media (max-width: $to-small) {\n        grid-template-rows: 1fr auto 1fr;\n    }\n\n    @media (min-width: $from-small) {\n        grid-template-columns: 1fr 1fr;\n    }\n}\n\n.c-hero_heading {\n    display: flex;\n    flex-direction: column;\n    row-gap: spacingClamp('md');\n    height: 100%;\n\n    @media (max-width: $to-small) {\n        grid-row: 2/3;\n    }\n\n    @media (min-width: $from-small) {\n        grid-column: 2/3;\n        grid-row: 1/2;\n    }\n}\n\n.c-hero_nav {\n    @media (max-width: $to-small) {\n        grid-row: 3/4;\n    }\n    @media (min-width: $from-small) {\n        grid-column: 1/2;\n        grid-row: 1/2;\n    }\n}\n\n.c-hero_title {\n    margin-block: auto;\n\n    .c-footer & {\n        margin-top: auto;\n        margin-bottom: 0;\n    }\n}\n\n.c-hero_links_item {\n    .c-hero_links_item + & {\n        margin-top: rem(8px);\n    }\n}\n\n.c-hero_description_container {\n    display: grid;\n    grid-template-columns: 1fr 1fr;\n    column-gap: var(--grid-gutter);\n    align-items: flex-end;\n}\n\n.c-hero_version {\n    display: flex;\n    justify-content: flex-end;\n    column-gap: .5em;\n\n    @media (max-width: $to-small) {\n        position: absolute;\n        bottom: var(--grid-margin);\n        right: 0;\n    }\n    \n    span {\n        transition: transform t('slow') ease('power3.out');\n        transform: translate3d(0,100%,0);\n\n        &:nth-child(1) {\n            position: relative;\n            top: .1em;\n        }\n    }\n    \n    &.is-inview {\n        span {\n            transform: translate3d(0,0,0);\n        }\n    }\n}\n\n.c-hero_line {\n    display: block;\n    clip-path: inset(-5% 0);\n}\n\n.c-hero_word {\n    display: inline-block;\n    transform: translate3d(0,-110%,0);\n\n    html.is-first-loaded & {\n        transition: transform t(medium) ease('power3.out');\n        transition-delay: calc(var(--index) * 0.1s);\n    }\n\n    &.-hero{\n        html.is-ready & {\n            transform: translate3d(0,0,0);\n        }\n    }\n    &.-footer{\n        .is-inview & {\n            transform: translate3d(0,0,0);\n        }\n    }\n}\n"
  },
  {
    "path": "packages/landing/assets/styles/components/_list.scss",
    "content": "// ==========================================================================\n// Components / Perks list\n// ==========================================================================\n\n\n@use \"../core\" as *;\n.c-list {\n    position: relative;\n\n    &::before {\n        content: \"\";\n        position: absolute;\n        top: 0;\n        left: 0;\n        width: 100%;\n        height: 1px;\n        background-color: currentColor;\n        transform-origin: top right;\n        transform: scale3d(0,1,1);\n    }\n\n    html.is-first-loaded & {\n        &::before {\n            transition: transform t() ease('power3.inOut');\n        }\n\n        &.is-inview::before {\n            transform: scale3d(1,1,1);\n            // transition-delay: var(--master-delay);\n        }\n    }\n\n    @media (min-width: $from-medium) {\n        display: grid;\n        grid-template-columns: repeat(4, 1fr);\n        column-gap: var(--grid-gutter);\n    }\n\n    *:focus-visible:not(input):not(textarea):not(select) {\n        [data-theme=\"dark\"] & {\n            @include u-focus-visible($color: #FFFFFF, $offset: -4px);\n        }\n        [data-theme=\"white\"] & {\n            @include u-focus-visible($color: #202ded, $offset: -4px);\n        }\n        [data-theme=\"blue\"] & {\n            @include u-focus-visible($color: #FFFFFF, $offset: -4px);\n        }\n        @include u-focus-visible();\n        padding-inline: rem(8px);\n    }\n}\n\n.c-list_inner {\n    font-size: 0;\n    \n    @media (min-width: $from-medium) {\n        grid-column: 2/-1;\n    }\n}\n\n.c-list_item {\n    \n}\n\n.c-list_item_inner {\n    position: relative;\n    clip-path: inset(0);\n    padding-block: rem(12px);\n\n    &::before {\n        content: \"\";\n        position: absolute;\n        top: 0;\n        left: 0;\n        width: 100%;\n        height: 1px;\n        background-color: currentColor;\n        transform-origin: top right;\n        transform: scale3d(0,1,1);\n\n        html.is-first-loaded & {\n            transition: transform t() ease('power3.inOut');\n        }\n\n        html.is-first-loaded .c-list.is-inview & {\n            transform: scale3d(1,1,1);\n            transition-delay: calc((var(--index) + 1) * 0.08s);\n        }\n    }\n\n    @media (max-width: $to-small) {\n        display: flex;\n        flex-direction: column;\n\n        .-showcase & {\n            display: grid;\n            grid-template-columns: 1fr;\n            gap: rem(15px);\n            padding-right: rem(30px);\n        }\n\n        .-perks & {\n            padding-block: rem(20px);\n        }\n    }\n\n    @media (min-width: $from-small) {\n        display: grid;\n        align-items: center;\n    }\n\n    @media (min-width: $from-small) and (max-width: $to-medium) {\n        grid-template-columns: 1fr 1fr;\n\n        .c-list.-showcase & {\n            grid-template-columns: 4fr 2fr 1fr;\n        }\n    }\n\n    @media (min-width: $from-medium) {\n        grid-template-columns: 1fr 2fr;\n\n        .c-list.-showcase & {\n            grid-template-columns: 4fr 2fr 1fr;\n        }\n    }\n\n    .c-list-anchor {\n        text-align: end;\n        @media (max-width: $to-small) {\n            position: absolute;\n            right: 0;\n            bottom: 0;\n            .-showcase & {\n                top: rem(10px);\n            }\n        }\n    }\n}\n    \n\n.c-list_title {\n    @media (max-width: $to-small) {\n        &.-body-regular{\n            --font-size-body-regular: var(--font-size-body-medium);\n        }\n    }\n    @media (min-width: $from-medium) {\n        grid-column: 1/2;\n    }\n}\n\n.c-list_description {\n    @media (max-width: $to-small) {\n        margin-top: rem(8px);\n\n        .-showcase & {\n            display: none;\n        }\n    }\n    @media (min-width: $from-medium) {\n        grid-column: 2/-1;\n\n        .c-list.-showcase & {\n            grid-column: auto;\n        }\n    }\n}\n\n.c-list_title,\n.c-list_description,\n.c-list-anchor {\n    opacity: 0;\n    transform: translate3d(0, 100%, 0);\n\n    html.is-first-loaded & {\n        transition: transform t(normal) ease('power3.out'), opacity t(normal) ease('power3.out');\n    }\n\n    html.is-first-loaded .c-list.is-inview & {\n        opacity: 1;\n        transform: translate3d(0,0,0);\n        transition-delay: calc((var(--index) + 1) * 0.08s + .25s);\n    }\n}"
  },
  {
    "path": "packages/landing/assets/styles/components/_perks-list.scss",
    "content": "// ==========================================================================\n// Components / Perks list\n// ==========================================================================\n\n.c-perks-list {\n    position: relative;\n\n    &::before {\n        content: \"\";\n        position: absolute;\n        top: 0;\n        left: 0;\n        width: 100%;\n        height: 1px;\n        background-color: currentColor;\n        transform-origin: top right;\n        transform: scale3d(0,1,1);\n    }\n\n    html.is-first-loaded & {\n        &::before {\n            transition: transform t() ease('power3.inOut');\n        }\n\n        &.is-inview::before {\n            transform: scale3d(1,1,1);\n            // transition-delay: var(--master-delay);\n        }\n    }\n\n    @media (min-width: $from-medium) {\n        display: grid;\n        grid-template-columns: repeat(4, 1fr);\n        column-gap: var(--grid-gutter);\n    }\n}\n\n.c-perks-list_inner {\n    @media (min-width: $from-medium) {\n        grid-column: 2/-1;\n    }\n}\n\n.c-perks-list_item {\n    position: relative;\n    padding: rem(8px) 0 rem(20px);\n    clip-path: inset(0);\n\n    &::before {\n        content: \"\";\n        position: absolute;\n        top: 0;\n        left: 0;\n        width: 100%;\n        height: 1px;\n        background-color: currentColor;\n        transform-origin: top right;\n        transform: scale3d(0,1,1);\n\n        html.is-first-loaded & {\n            transition: transform t() ease('power3.inOut');\n        }\n\n        html.is-first-loaded .c-perks-list.is-inview & {\n            transform: scale3d(1,1,1);\n            transition-delay: calc((var(--index) + 1) * 0.08s);\n        }\n    }\n\n    @media (max-width: $to-small) {\n        display: flex;\n        flex-direction: column;\n    }\n\n    @media (min-width: $from-small) {\n        display: grid;\n        align-items: flex-start;\n    }\n\n    @media (min-width: $from-small) and (max-width: $to-medium) {\n        grid-template-columns: 1fr 1fr;\n    }\n\n    @media (min-width: $from-medium) {\n        grid-template-columns: 1fr 2fr;\n    }\n}\n\n.c-perks-list_title {\n    @media (min-width: $from-medium) {\n        grid-column: 1/2;\n    }\n}\n\n.c-perks-list_description {\n    @media (max-width: $to-small) {\n        margin-top: rem($unit-small);\n    }\n    @media (min-width: $from-medium) {\n        grid-column: 2/-1;\n    }\n}\n\n.c-perks-list_title,\n.c-perks-list_description {\n    opacity: 0;\n    transform: translate3d(0, 100%, 0);\n\n    html.is-first-loaded & {\n        transition: transform t(normal) ease('power3.out'), opacity t(normal) ease('power3.out');\n    }\n\n    html.is-first-loaded .c-perks-list.is-inview & {\n        opacity: 1;\n        transform: translate3d(0,0,0);\n        transition-delay: calc((var(--index) + 1) * 0.08s + .5s);\n    }\n}\n"
  },
  {
    "path": "packages/landing/assets/styles/components/_preloader.scss",
    "content": "@use \"../core\" as *;\n\n.c-preloader {\n    position: fixed;\n    top: 0;\n    left: 0;\n    width: 100%;\n    height: 100%;\n    z-index: 1000;\n    cursor: wait;\n    background-color: #202ded;\n    pointer-events: none;\n\n    html.is-ready & {\n        transition: opacity 0.6s cubic-bezier(0.215, 0.610, 0.355, 1.000), visibility 0s 0.6s cubic-bezier(0.215, 0.610, 0.355, 1.000);\n        opacity: 0;\n        visibility: hidden;\n    }\n}"
  },
  {
    "path": "packages/landing/assets/styles/components/_rail.scss",
    "content": "// ==========================================================================\n// Components / Rail\n// ==========================================================================\n\n\n@use \"../core\" as *;\n@use \"heading\" as *;\n.c-rail {\n    position: relative;\n    overflow: hidden;\n    padding: spacingClamp('md') 0;\n}\n\n.c-rail_inner {\n    display: inline-flex;\n    align-items: center;\n    white-space: nowrap;\n}\n\n.c-rail_item {\n    @include heading-serif;\n    font-size: var(--font-size-serif-medium);\n    padding-right: 0.5em;\n\n    .c-icon {\n        transform: translateY(-0.075em);\n    }\n}\n\n.c-rail_glyph {\n    display: inline-block;\n    padding-left: 0.5em;\n    width: 100px;\n    text-align: center;\n\n    @media (min-width: $from-medium) {\n        width: 140px;\n    }\n    @media (min-width: $from-large) {\n        width: 170px;\n    }\n}"
  },
  {
    "path": "packages/landing/assets/styles/components/_scrollbar.scss",
    "content": "// ==========================================================================\n// Components / Scrollbar\n// ==========================================================================\n\n.c-scrollbar {\n    position: absolute;\n    right: 0;\n    top: 0;\n    width: 11px;\n    height: 100vh;\n    transform-origin: center right;\n    transition: transform t(normal), opacity t(normal);\n    opacity: 0;\n\n    &:hover {\n        transform: scaleX(1.45);\n    }\n\n    &:hover, .has-scroll-scrolling &, .has-scroll-dragging & {\n        opacity: 1;\n    }\n}\n\n.c-scrollbar_thumb {\n    position: absolute;\n    top: 0;\n    right: 0;\n    background-color: color(black);\n    opacity: 0.5;\n    width: 7px;\n    border-radius: 10px;\n    margin: 2px;\n    cursor: grab;\n\n    .has-scroll-dragging & {\n        cursor: grabbing;\n    }\n}\n"
  },
  {
    "path": "packages/landing/assets/styles/components/_section-heading.scss",
    "content": "// ==========================================================================\n// Components / Section heading\n// ==========================================================================\n\n\n@use \"../core\" as *;\n.c-section-heading {\n    display: flex;\n    flex-direction: column;\n}\n\n.c-section-heading_line {\n    .c-section-heading_line + & {\n        margin-top: 0.05em;\n    }\n\n    @media (max-width: $to-medium) {\n        display: flex;\n        flex-wrap: wrap;\n    }\n\n    &:last-child {\n        @media (min-width: $from-medium) {\n            display: grid;\n            grid-template-columns: 1fr auto 1fr;\n            column-gap: var(--grid-gutter);\n            align-items: flex-end;\n        }\n    }\n}\n\n.c-section-heading_word {\n    display: inline-block;\n    width: 100%;\n    text-align: center;\n\n    @media (max-width: $to-medium) {\n        .c-section-heading_line:last-child & {\n            margin-bottom: rem(50px);\n        }\n    }\n\n    @media (min-width: $from-medium) {\n        .c-section-heading_line:last-child & {\n            grid-column: 2/3;\n            margin-bottom: -0.02em;\n        }\n    }\n}\n\n.c-section-heading_label {\n    display: flex;\n    align-items: center;\n\n    @media (max-width: $to-medium) {\n        flex: 0 0 50%;\n\n        &.-left {\n            flex-direction: column;\n        }\n\n        &.-right {\n            flex-direction: column-reverse;\n        }\n    }\n\n    @media (min-width: $from-medium) {\n        justify-content: center;\n        column-gap: .5em;\n        grid-row: 1/2;\n\n        &.-left {\n            grid-column: 1/2;\n        }\n\n        &.-right {\n            grid-column: 3/4;\n        }\n    }\n}\n"
  },
  {
    "path": "packages/landing/assets/styles/components/_sticky-heading.scss",
    "content": "@use \"../core\" as *;\n@use \"heading\" as *;\n\n// Components / Sticky heading\n// ==========================================================================\n\n@use \"sass:math\";\n\n.c-sticky-heading {\n    height: 300vh;\n    @media (max-aspect-ratio: 1.25 / 1) {\n        height: auto;\n        padding-top: spacingClamp('2xl');\n    }\n}\n\n.c-sticky-heading_inner {\n    position: sticky;\n    top: 0;\n    display: flex;\n    align-items: flex-end;\n    width: 100%;\n    height: calc(var(--vh, 1vh) * 100);\n    overflow: hidden;\n\n    @media (max-aspect-ratio: 1.25 / 1) {\n        align-items: start;\n        height: auto;\n        position: relative;\n        padding-top: spacingClamp('xs');\n    }\n}\n\n.c-sticky-heading_title {\n    @include heading-serif;\n    font-size: calc(#{math.div(870, 1740)} * 100 * var(--vw, 1vw));\n    width: auto;\n    padding-right: calc(var(--grid-margin) * 2);\n    transform: translate3d(calc(-1 * (var(--progress) * (100% - (var(--vw, 1vw) * 100)))), 0, 0);\n    // @media (max-width: $to-small) {\n    //     font-size: calc(#{math.div(870, 1440)} * 125 * var(--vw, 1vw));\n    // }\n    @media (max-aspect-ratio: 1.25 / 1) {\n        font-size: calc(#{math.div(870, 1440)} * 49 * var(--vw, 1vw));\n        transform: none;\n    }\n}\n\n.c-sticky-heading_description {\n    margin-left: calc(100vw - 13.75rem - var(--grid-margin) * 2);\n    max-width: 13.75rem;\n    margin-bottom: spacingClamp('sm');\n\n    @media (min-width: $from-medium) {\n        max-width: 17.5rem;\n        margin-left: 50vw;\n        font-size: calc(#{math.div(870, 1740)} * 100 * var(--vw, 1vw));\n        margin-bottom: -.075em;\n    }\n\n    \n    \n}\n\n.c-sticky_scroll {\n    display: block;\n    position: absolute;\n    top: 0;\n    height: 100%;\n    width: 100%;\n}"
  },
  {
    "path": "packages/landing/assets/styles/components/_text.scss",
    "content": "// ==========================================================================\n// Components / Headings\n// ==========================================================================\n\n// Font sizes\n// ==========================================================================\n\n@use \"../core\" as *;\n:root {\n    --font-size-body-regular: #{rem(16px)};\n    --font-size-body-medium:  #{rem(21px)};\n    --font-size-label:        #{rem(16px)};\n    --font-size-label-small:  #{rem(12px)};\n}\n\n// Mixins\n// ==========================================================================\n@mixin text {\n    font-family: ff('display');\n    font-weight: $font-weight-medium;\n    line-height: 1.2;\n    letter-spacing: -0.01em;\n}\n\n// Styles\n// ==========================================================================\n\n.c-text {\n    @include text;\n\n    &.-body-regular {\n        font-size: var(--font-size-body-regular);\n    }\n\n    &.-body-medium {\n        font-size: var(--font-size-body-medium);\n    }\n\n    &.-label {\n        font-size: var(--font-size-label);\n    }\n\n    &.-label-small {\n        font-size: var(--font-size-label-small);\n    }\n}\n"
  },
  {
    "path": "packages/landing/assets/styles/components/_tool.scss",
    "content": "// ==========================================================================\n// Components / Tool\n// ==========================================================================\n\n@use '../core' as *;\n.c-tool {\n    position: relative;\n    background-color: color(blue);\n    overflow: hidden;\n\n    &.-parallax {\n        padding-bottom: spacingClamp('sm');\n\n        &:before {\n            content: '';\n            position: absolute;\n            bottom: 0;\n            left: 0;\n            width: 100%;\n            height: spacingClamp('xl');\n            background-image: linear-gradient(\n                to bottom,\n                hsla(236, 85%, 53%, 0) 0%,\n                hsla(236, 85%, 53%, 0.013) 8.1%,\n                hsla(236, 85%, 53%, 0.049) 15.5%,\n                hsla(236, 85%, 53%, 0.104) 22.5%,\n                hsla(236, 85%, 53%, 0.175) 29%,\n                hsla(236, 85%, 53%, 0.259) 35.3%,\n                hsla(236, 85%, 53%, 0.352) 41.2%,\n                hsla(236, 85%, 53%, 0.45) 47.1%,\n                hsla(236, 85%, 53%, 0.55) 52.9%,\n                hsla(236, 85%, 53%, 0.648) 58.8%,\n                hsla(236, 85%, 53%, 0.741) 64.7%,\n                hsla(236, 85%, 53%, 0.825) 71%,\n                hsla(236, 85%, 53%, 0.896) 77.5%,\n                hsla(236, 85%, 53%, 0.951) 84.5%,\n                hsla(236, 85%, 53%, 0.987) 91.9%,\n                hsla(236, 85%, 53%, 1) 100%\n            );\n\n            z-index: 1;\n        }\n    }\n}\n\n.c-tool_head {\n    position: relative;\n    display: grid;\n    column-gap: var(--grid-gutter);\n    z-index: 1;\n    padding-top: 0.5rem;\n    @media (max-width: $to-medium) {\n        grid-template-columns: repeat(4, 1fr);\n    }\n\n    @media (min-width: $from-medium) {\n        grid-template-columns: repeat(3, 1fr);\n    }\n\n    &::before {\n        content: '';\n        position: absolute;\n        top: 0;\n        left: 0;\n        width: 100%;\n        height: 1px;\n        background-color: currentColor;\n        transform-origin: top right;\n        transform: scale3d(0, 1, 1);\n\n        html.is-first-loaded & {\n            transition: transform t(slow) ease('power3.inOut');\n        }\n\n        html.is-first-loaded .c-tool.is-inview & {\n            transform: scale3d(1, 1, 1);\n        }\n    }\n\n    @media (min-width: $from-medium) {\n        margin-left: calc((100% + var(--grid-gutter)) / 4);\n    }\n}\n\n.c-tool_index {\n    @media (max-width: $to-medium) {\n        grid-column: span 2;\n    }\n    @media (min-width: $from-medium) {\n        grid-column: span 1;\n    }\n}\n\n.c-tool_label {\n    @media (max-width: $to-small) {\n        grid-column: span 2;\n    }\n    @media (min-width: $from-small) {\n        grid-column: span 1;\n    }\n}\n\n.c-tool_description {\n    @media (max-width: $to-small) {\n        grid-column: 1/-1;\n        grid-row: 3/4;\n        max-width: rem(280px);\n        margin-top: rem(10px);\n    }\n    @media (min-width: $from-small) {\n        grid-column: span 1;\n        grid-column-end: -1;\n    }\n}\n\n.c-tool_title {\n    grid-column: 1/-1;\n    max-width: rem(500px);\n\n    @media (max-width: $to-small) {\n        grid-row: 2/3;\n        margin-top: 0.8em;\n        margin-bottom: 0.4em;\n    }\n}\n\n.c-tool_playground {\n    /* position: absolute;\n    top: 0;\n    left: calc(-1 * var(--grid-margin));\n    width: calc(100% + 2 * var(--grid-margin));\n    height: 100%;\n    overflow: hidden;\n\n    @media (max-width: $to-medium) {\n        margin-top: 15%;\n    }\n\n    @media (max-width: $to-small) {\n        margin-top: 25%;\n    } */\n\n    .c-tool.-parallax & {\n        @media (max-width: $to-small) {\n            margin-top: spacingClamp('md');\n        }\n    }\n\n    position: relative;\n    aspect-ratio: var(--container-ratio);\n    width: 100%;\n}\n\n.c-tool_shape {\n    position: absolute;\n\n    // Inview\n    // ========================================\n    .c-tool.-inview & {\n        left: calc(var(--left, 0) / 1440 * 100%);\n        top: calc(var(--top, 0) / (1 / (var(--container-ratio)) * 1440) * 100%);\n        transform: translateX(-50%) translateY(-50%);\n\n        &.-first {\n            --top: 502;\n            --left: 90;\n        }\n        &.-second {\n            --top: 700;\n            --left: 355;\n        }\n        &.-third {\n            --top: 475;\n            --left: 655;\n        }\n        &.-fourth {\n            --top: 250;\n            --left: 987;\n        }\n        &.-fifth {\n            --top: 345;\n            --left: 1310;\n        }\n        &.-sixth {\n            --top: 750;\n            --left: 1050;\n        }\n\n        &.-first {\n            svg {\n                transform: rotate(calc(var(--progress) * -90deg));\n            }\n        }\n\n        &.-fifth {\n            svg {\n                transform: rotate(calc(var(--progress) * 150deg));\n            }\n        }\n    }\n\n    // Progress\n    // ========================================\n    .c-tool.-progress & {\n        top: 50%;\n        left: 50%;\n        transform: translateX(-50%) translateY(-50%);\n\n        &.-fourth {\n            z-index: 1;\n        }\n    }\n\n    // Parallax\n    // ========================================\n    .c-tool.-parallax & {\n        left: calc(var(--left, 0));\n        top: calc(var(--top, 0));\n        transform: translateX(-50%) translateY(-50%);\n\n        &.-first {\n            --top: 40%;\n            --left: 16%;\n        }\n        &.-second {\n            --top: 55%;\n            --left: 34%;\n        }\n        &.-third {\n            --top: 30%;\n            --left: 53%;\n        }\n        &.-fourth {\n            --top: 65%;\n            --left: 68%;\n        }\n        &.-fifth {\n            --top: 40%;\n            --left: 86%;\n        }\n    }\n}\n\n.c-tool_shape_svg {\n    // Inview\n    // ========================================\n    .c-tool.-inview & {\n        transform: scale3d(0, 0, 1);\n\n        html.is-first-loaded & {\n            transition: transform t(normal) ease('power3.out');\n        }\n    }\n\n    .c-tool.-inview .c-tool_shape.is-inview & {\n        transform: scale3d(1, 1, 1);\n    }\n\n    // Progress\n    // ========================================\n    .c-tool.-progress & {\n        display: block;\n        transform: translate3d(\n            calc((0.5 + 0.5 * var(--progress)) * var(--index) * 100%),\n            0,\n            0\n        );\n    }\n}\n\n// Keyframes\n@keyframes rotation {\n    from {\n        transform: rotate(0deg);\n    }\n    to {\n        transform: rotate(180deg);\n    }\n}\n"
  },
  {
    "path": "packages/landing/assets/styles/critical.scss",
    "content": "// ==========================================================================\n// Critical CSS\n// ==========================================================================\n\n$assets-path: \"assets/\";\n"
  },
  {
    "path": "packages/landing/assets/styles/elements/_document.scss",
    "content": "// ==========================================================================\n// Elements / Document\n// ==========================================================================\n\n\n@use \"../core\" as *;\n//\n// Simple page-level setup.\n//\n// 1. Includes fonts\n// 2. Ensure the page always fills at least the entire height of the viewport.\n// 3. Set the default `font-size` and `line-height` for the entire project,\n//    sourced from our default variables.\n\n@include font-faces($font-faces, $font-dir); // [1]\n\nhtml {\n    min-height: 100%; // [2]\n    line-height: $line-height; // [3]\n    font-family: ff('display');\n    color: $font-color;\n    -webkit-font-smoothing: antialiased;\n    -moz-osx-font-smoothing: grayscale;\n\n    @media (max-width: $to-small) {\n        font-size: $font-size - 2px;\n    }\n\n    @media (min-width: $from-small) and (max-width: $to-medium) {\n        font-size: $font-size - 2px;\n    }\n\n    @media (min-width: $from-medium) and (max-width: $to-large) {\n        font-size: $font-size - 1px;\n    }\n\n    @media (min-width: $from-large) and (max-width: $to-huge) {\n        font-size: $font-size; // [1]\n    }\n\n    @media (min-width: $from-huge) and (max-width: $to-gigantic) {\n        font-size: $font-size + 1px;\n    }\n\n    @media (min-width: $from-gigantic) and (max-width: $to-colossal) {\n        font-size: $font-size + 2px;\n    }\n\n    @media (min-width: $from-colossal) {\n        font-size: $font-size + 4px;\n    }\n\n    &.is-loading {\n        cursor: wait;\n    }\n}\n\nbody {\n}\n\n::selection {\n    background-color: $color-selection-background;\n    color: $color-selection-text;\n    text-shadow: none;\n}\n\na {\n    color: inherit;\n}\n\n*:focus-visible:not(input):not(textarea):not(select) {\n    [data-theme=\"dark\"] & {\n        @include u-focus-visible($color: #FFFFFF, $offset: 2px);\n    }\n    [data-theme=\"white\"] & {\n        @include u-focus-visible($color: #202ded, $offset: 2px);\n    }\n    [data-theme=\"blue\"] & {\n        @include u-focus-visible($color: #FFFFFF, $offset: 2px);\n    }\n    @include u-focus-visible();\n}\n\ninput, select, textarea {\n    &:focus-visible {\n        @include u-focus-visible($color: var(--color-theme-dark), $offset: 0px);\n    }\n}\n"
  },
  {
    "path": "packages/landing/assets/styles/generic/_button.scss",
    "content": "// ==========================================================================\n// Generic / Buttons\n// ==========================================================================\n\n\n@use \"../core\" as *;\n// 1. Allow us to style box model properties.\n// 2. Fixes odd inner spacing in IE7.\n// 3. Reset/normalize some styles.\n// 4. Line different sized buttons up a little nicer.\n// 5. Make buttons inherit font styles (often necessary when styling `input`s as buttons).\n// 6. Force all button-styled elements to appear clickable.\n\nbutton,\n.c-button {\n    @include u-hocus {\n        text-decoration: none;\n    }\n\n    display: inline-block; // [1]\n    overflow: visible; // [2]\n    margin: 0; // [3]\n    padding: 0;\n    outline: 0;\n    border: 0;\n    background: none transparent;\n    color: inherit;\n    vertical-align: middle; // [4]\n    text-align: center; // [3]\n    text-decoration: none;\n    text-transform: none;\n    font: inherit; // [5]\n    line-height: normal;\n    cursor: pointer; // [6]\n    user-select: none;\n}\n"
  },
  {
    "path": "packages/landing/assets/styles/generic/_form.scss",
    "content": "// ==========================================================================\n// Generic / Forms\n// ==========================================================================\n\ninput,\nselect,\ntextarea {\n    display: block;\n    margin: 0;\n    padding: 0;\n    width: 100%;\n    outline: 0;\n    border: 0;\n    border-radius: 0;\n    background: none transparent;\n    color: inherit;\n    font: inherit;\n    line-height: normal;\n    appearance: none;\n}\n\nselect {\n    text-transform: none;\n\n    &::-ms-expand {\n        display: none;\n    }\n\n    &::-ms-value {\n        background: none;\n        color: inherit;\n    }\n\n    // // Remove Firefox :focus dotted outline, breaks color inherit\n    // // &:-moz-focusring {\n    // //     color: transparent;\n    // //     text-shadow: 0 0 0 #000000; // Text :focus color\n    // // }\n}\n\ntextarea {\n    overflow: auto;\n    resize: vertical;\n}\n"
  },
  {
    "path": "packages/landing/assets/styles/generic/_generic.scss",
    "content": "// ==========================================================================\n// Generic\n// ==========================================================================\n\n\n@use \"../core\" as *;\nhtml {\n    box-sizing: border-box;\n}\n\n// Add the correct display in IE 10-.\n// 1. Add the correct display in IE.\n\ntemplate, // [1]\n[hidden] {\n    display: none;\n}\n\n*,\n:before,\n:after {\n    box-sizing: inherit;\n}\n\naddress {\n    font-style: inherit;\n}\n\ndfn,\ncite,\nem,\ni {\n    font-style: italic;\n}\n\nb,\nstrong {\n    font-weight: $font-weight-medium;\n}\n\na {\n    text-decoration: none;\n\n    svg {\n        pointer-events: none;\n    }\n}\n\nul,\nol {\n    margin: 0;\n    padding: 0;\n    list-style: none;\n}\n\np,\nfigure {\n    margin: 0;\n    padding: 0;\n}\n\nh1, h2, h3, h4, h5, h6 {\n    margin: 0;\n}\n\n// 1. Single taps should be dispatched immediately on clickable elements\n\na, area, button, input, label, select, textarea, [tabindex] {\n    -ms-touch-action: manipulation; // [1]\n    touch-action: manipulation;\n}\n\n[hreflang] > abbr[title] {\n    text-decoration: none;\n}\n\ntable {\n    border-spacing: 0;\n    border-collapse: collapse;\n}\n\nhr {\n    display: block;\n    margin: 1em 0;\n    padding: 0;\n    height: 1px;\n    border: 0;\n    border-top: 1px solid #CCCCCC;\n}\n"
  },
  {
    "path": "packages/landing/assets/styles/generic/_media.scss",
    "content": "// ==========================================================================\n// Generic / Media\n// ==========================================================================\n\n\n@use \"../core\" as *;\n// 1. Setting `vertical-align` removes the whitespace that appears under `img`\n//    elements when they are dropped into a page as-is. Safer alternative to\n//    using `display: block;`.\n\naudio,\ncanvas,\niframe,\nimg,\nsvg,\nvideo {\n    vertical-align: middle; // [1]\n}\n\n// Add the correct display in iOS 4-7.\n\naudio:not([controls]) {\n    display: none;\n    height: 0;\n}\n\n// 2. Fluid media for responsive purposes.\n\nimg,\nsvg {\n    // max-width: 100%; // [2]\n    height: auto;\n\n    // 4. If a `width` and/or `height` attribute have been explicitly defined,\n    //    let’s not make the image fluid.\n\n    &[width], // [4]\n    &[height] {\n        // [4]\n        max-width: none;\n    }\n}\n\n// 4. Offset `alt` text from surrounding copy.\n\nimg {\n    font-style: italic; // [4]\n}\n\n// 5. SVG elements should fallback to their surrounding text color.\n\nsvg {\n    fill: currentColor; // [5]\n}\n"
  },
  {
    "path": "packages/landing/assets/styles/main.scss",
    "content": "// ==========================================================================\n// Main\n// ==========================================================================\n// @use \"sass:math\";\n@use \"../../../../node_modules/normalize.css/normalize\";\n@use \"../../../../node_modules/lenis/dist/lenis.css\";\n\n// Generic\n// ==========================================================================\n\n@use \"generic/generic\";\n@use \"generic/media\";\n@use \"generic/button\" as generic-button;\n\n// Vendors\n// ==========================================================================\n\n// Elements\n// ==========================================================================\n\n@use \"elements/document\";\n\n// Objects\n// ==========================================================================\n\n@use \"objects/container\";\n@use \"objects/icons\";\n@use \"objects/grid\";\n\n// Components\n// ==========================================================================\n\n@use \"components/heading\";\n@use \"components/text\";\n@use \"components/button\";\n@use \"components/form\";\n@use \"components/header\";\n@use \"components/hero\";\n@use \"components/rail\";\n@use \"components/cascade\";\n@use \"components/section-heading\";\n@use \"components/tool\";\n@use \"components/features-grid\";\n@use \"components/sticky-heading\";\n@use \"components/list\";\n@use \"components/footer\";\n@use \"components/fadeInText\";\n@use \"components/preloader\";\n\n// Utilities\n// ==========================================================================\n\n@use \"utilities/grid-column\";\n@use \"utilities/theme\";\n@use \"utilities/helpers\";\n@use \"utilities/spacing\";\n\n"
  },
  {
    "path": "packages/landing/assets/styles/objects/_container.scss",
    "content": "// ==========================================================================\n// Objects / Container\n// ==========================================================================\n\n\n@use \"../core\" as *;\n// Page-level constraining and wrapping elements.\n//\n// > In programming languages the word *container* is generally used for structures\n// that can contain more than one element.\n// > A *wrapper* instead is something that wraps around a single object to provide\n// more functionalities and interfaces to it.\n// @link http://stackoverflow.com/a/13202141/140357\n\n.o-container {\n    margin-right: auto;\n    margin-left: auto;\n    padding-left: var(--grid-margin);\n    padding-right: var(--grid-margin);\n}\n"
  },
  {
    "path": "packages/landing/assets/styles/objects/_grid.scss",
    "content": "// ==========================================================================\n// Grid helper\n// ==========================================================================\n\n@use \"../core\" as *;\n// Help: https://css-tricks.com/snippets/css/complete-guide-grid/\n//\n/**\n * Usage:\n *\n * ```html\n * <div class=\"o-grid -col-4 -col-12@from-medium -gutters\">\n *     <div class=\"o-grid_item u-gc-1/2 u-gc-3/9@from-medium\">\n *         <p>Hello</p>\n *     </div>\n *     <div class=\"o-grid_item u-gc-3/4 u-gc-9/13@from-medium\">\n *         <p>Hello</p>\n *     </div>\n * </div>\n * ```\n */\n\n.o-grid {\n    display: grid;\n    width: 100%;\n\n    &:is(ul, ol) {\n        margin: 0;\n        padding: 0;\n        list-style: none;\n    }\n\n    // ==========================================================================\n    // Cols\n    // ==========================================================================\n\n    // Responsive grid columns based on `--grid-columns`\n    &.-cols {\n        grid-template-columns: repeat(var(--grid-columns), 1fr);\n    }\n\n    &.-col-#{$base-column-nb} {\n        grid-template-columns: repeat(#{$base-column-nb}, 1fr);\n    }\n\n    &.-col-2 {\n        grid-template-columns: repeat(2, 1fr);\n    }\n\n    &.-col-#{$base-column-nb}\\@from-medium {\n        @media (min-width: $from-medium) {\n            grid-template-columns: repeat(#{$base-column-nb}, 1fr);\n        }\n    }\n\n    // ==========================================================================\n    // Gutters\n    // ==========================================================================\n\n    // Gutters rows and columns\n    &.-gutters {\n        gap: var(--grid-gutter);\n        column-gap: var(--grid-gutter);\n    }\n\n    // ==========================================================================\n    // Modifiers\n    // ==========================================================================\n    &.-full-height {\n        height: 100%;\n    }\n\n    // ==========================================================================\n    // Aligns\n    // ==========================================================================\n\n    // ==========================================================================\n    // Items inside cells\n    //\n    &.-top-items {\n        align-items: start;\n    }\n    &.-right-items {\n        justify-items: end;\n    }\n    &.-bottom-items {\n        align-items: end;\n    }\n    &.-left-items {\n        justify-items: start;\n    }\n    &.-center-items {\n        align-items: center;\n        justify-items: center;\n    }\n    &.-center-items-x {\n        justify-items: center;\n    }\n    &.-center-items-y {\n        align-items: center;\n    }\n    &.-stretch-items {\n        align-items: stretch;\n        justify-items: stretch;\n    }\n\n    // ==========================================================================\n    // Cells\n    //\n    &.-top-cells {\n        align-content: start;\n    }\n    &.-right-cells {\n        justify-content: end;\n    }\n    &.-bottom-cells {\n        align-content: end;\n    }\n    &.-left-cells {\n        justify-content: start;\n    }\n    &.-center-cells {\n        align-content: center;\n        justify-content: center;\n    }\n    &.-center-cells-x {\n        justify-content: center;\n    }\n    &.-center-cells-y {\n        align-content: center;\n    }\n    &.-stretch-cells {\n        align-content: stretch;\n        justify-content: stretch;\n    }\n    &.-space-around-cells {\n        align-content: space-around;\n        justify-content: space-around;\n    }\n    &.-space-around-cells-x {\n        justify-content: space-around;\n    }\n    &.-space-around-cells-y {\n        align-content: space-around;\n    }\n    &.-space-between-cells {\n        justify-content: space-between;\n        align-content: space-between;\n    }\n    &.-space-between-cells-x {\n        justify-content: space-between;\n    }\n    &.-space-between-cells-y {\n        align-content: space-between;\n    }\n    &.-space-evenly-cells {\n        justify-content: space-evenly;\n        align-content: space-evenly;\n    }\n    &.-space-evenly-cells-x {\n        justify-content: space-evenly;\n    }\n    &.-space-evenly-cells-y {\n        align-content: space-evenly;\n    }\n}\n\n// ==========================================================================\n// Grid item\n// ==========================================================================\n// By default, a grid item takes full width of its parent.\n//\n.o-grid_item {\n    grid-column-start: var(--gc-start, 1);\n    grid-column-end: var(--gc-end, -1);\n\n    &.-align-end {\n        align-self: end;\n    }\n}\n"
  },
  {
    "path": "packages/landing/assets/styles/objects/_icons.scss",
    "content": "// ==========================================================================\n// Objects / SVG Icons\n// ==========================================================================\n\n// Markup\n//\n// 1. If icon is accessible and has a title\n// 2. If icon is decorative\n//\n// <i class=\"o-icon ${modifier}\">\n//     <svg\n//         class=\"svg-${icon-name}\"\n//         xmlns=\"http://www.w3.org/2000/svg\"\n//         role=\"img\" [1]\n//         aria-hidden=\"true\" [2]\n//         focusable=\"false\" [2]\n//         aria-labelledby=\"${id}\" [1]\n//     >\n//         <title id=\"${id}\"> [1]\n//             Locomotive\n//         </title>\n//         <use xlink:href=\"assets/images/sprite.svg#${icon-name}\" xmlns:xlink=\"http://www.w3.org/1999/xlink\"/>\n//     </svg>\n// </i>\n\n// Global styles for icones\n// ==========================================================================\n\n\n@use \"../core\" as *;\n// Default metrics\n:root {\n    --icon-width: #{rem(24px)};\n    --icon-ratio: 1;\n}\n\n.o-icon {\n    display: inline-block;\n    vertical-align: middle;\n\n    svg {\n        display: block;\n        width: var(--icon-width);\n        height: calc(var(--icon-width) * (1 / (var(--icon-ratio))));\n    }\n}\n\n// SVG sizes\n// ==========================================================================\n\n.svg-logo-lenis {\n    --icon-width: #{rem(67px)};\n    --icon-ratio: 67/72;\n}\n\n.svg-logo-locomotive {\n    --icon-width: #{rem(79px)};\n    --icon-ratio: 79/35;\n}\n\n.svg-arrow-external {\n    --icon-width: #{rem(12px)};\n}\n\n.svg-inview-01,\n.svg-inview-02,\n.svg-inview-03,\n.svg-inview-04,\n.svg-inview-05,\n.svg-inview-06 {\n    --icon-width: #{vw(24)};\n}\n\n.svg-progress-01,\n.svg-progress-02,\n.svg-progress-03,\n.svg-progress-04,\n.svg-progress-05 {\n    --icon-width: #{vw(24)};\n    --icon-ratio: 224/350;\n}\n\n.svg-parallax-01,\n.svg-parallax-02,\n.svg-parallax-03,\n.svg-parallax-04,\n.svg-parallax-05 {\n    --icon-width: #{vw(24)};\n}\n"
  },
  {
    "path": "packages/landing/assets/styles/objects/_layout.scss",
    "content": "// ==========================================================================\n// Objects / Layout\n// ==========================================================================\n\n////\n/// Grid-like layout system.\n///\n/// The layout object provides us with a column-style layout system. This file\n/// contains the basic structural elements, but classes should be complemented\n/// with width utilities, for example:\n///\n/// @example\n///   <div class=\"o-layout\">\n///     <div class=\"o-layout_item  u-1/1  u-1/3@medium\">\n///     </div>\n///     <div class=\"o-layout_item  u-1/2  u-1/3@medium\">\n///     </div>\n///     <div class=\"o-layout_item  u-1/2  u-1/3@medium\">\n///     </div>\n///   </div>\n///\n/// We can also manipulate entire layout systems by adding a series of modifiers\n/// to the `.o-layout` block. For example:\n///\n/// @example\n///   <div class=\"o-layout  -reverse\">\n///\n/// This will reverse the displayed order of the system so that it runs in the\n/// opposite order to our source, effectively flipping the system over.\n///\n/// @example\n///   <div class=\"o-layout  -[right|center]\">\n///\n/// This will cause the system to fill up from either the centre or the right\n/// hand side. Default behaviour is to fill up the layout system from the left.\n///\n/// @requires tools/layout\n/// @link https://github.com/inuitcss/inuitcss/blob/0420ba8/objects/_objects.layout.scss\n////\n\n.o-layout {\n    @include o-layout;\n\n    // Gutter modifiers\n    &.-gutter {\n        margin-left: rem(-$unit);\n    }\n\n    &.-gutter-small {\n        margin-left: rem(-$unit-small);\n    }\n\n    // Horizontal aligment modifiers\n    &.-center {\n        text-align: center;\n    }\n\n    &.-right {\n        text-align: right;\n    }\n\n    &.-reverse {\n        direction: rtl;\n\n        &.-flex {\n            flex-direction: row-reverse;\n        }\n    }\n\n    &.-flex {\n         display: flex;\n\n         &.-top {\n            align-items: flex-start;\n         }\n         &.-middle {\n            align-items: center;\n         }\n         &.-bottom {\n            align-items: flex-end;\n         }\n    }\n    &.-stretch {\n        align-items: stretch;\n    }\n}\n\n.o-layout_item {\n    @include o-layout_item;\n\n    // Gutter modifiers\n    .o-layout.-gutter > & {\n        padding-left: rem($unit);\n    }\n\n    .o-layout.-gutter-small > & {\n        padding-left: rem($unit-small);\n    }\n\n    // Vertical alignment modifiers\n    .o-layout.-middle > & {\n        vertical-align: middle;\n    }\n\n    .o-layout.-bottom > & {\n        vertical-align: bottom;\n    }\n\n    // Horizontal aligment modifiers\n    .o-layout.-center > &,\n    .o-layout.-right > &,\n    .o-layout.-reverse > & {\n        text-align: left;\n    }\n\n    .o-layout.-reverse > & {\n        direction: ltr;\n    }\n}\n"
  },
  {
    "path": "packages/landing/assets/styles/objects/_ratio.scss",
    "content": "// ==========================================================================\n// Objects / Ratio\n// ==========================================================================\n\n// Create ratio-bound content blocks, to keep media (e.g. images, videos) in\n// their correct aspect ratios.\n//\n// http://alistapart.com/article/creating-intrinsic-ratios-for-video\n//\n// 1. Default cropping is a 1:1 ratio (i.e. a perfect square).\n\n.o-ratio {\n    position: relative;\n    display: block;\n    overflow: hidden;\n\n    &:before {\n        display: block;\n        padding-bottom: 100%; // [1]\n        width: 100%;\n        content: \"\";\n    }\n}\n\n.o-ratio_content,\n    .o-ratio > img,\n    .o-ratio > iframe,\n    .o-ratio > embed,\n    .o-ratio > object {\n    position: absolute;\n    top: 0;\n    bottom: 0;\n    left: 0;\n    width: 100%;\n    // height: 100%;\n}\n"
  },
  {
    "path": "packages/landing/assets/styles/objects/_table.scss",
    "content": "// ==========================================================================\n// Objects / Tables\n// ==========================================================================\n\n.o-table {\n    width: 100%;\n\n    // Force all cells within a table to occupy the same width as each other.\n    //\n    // @link https://developer.mozilla.org/en-US/docs/Web/CSS/table-layout#Values\n\n    &.-fixed {\n        table-layout: fixed;\n    }\n}\n"
  },
  {
    "path": "packages/landing/assets/styles/settings/_config.breakpoints.scss",
    "content": "// ==========================================================================\n// Settings / Config / Breakpoints\n// ==========================================================================\n@use \"sass:map\";\n\n// Breakpoints\n// ==========================================================================\n\n$breakpoints: (\n    \"tiny\":     500px,\n    \"small\":    700px,\n    \"medium\":   1000px,\n    \"large\":    1200px,\n    \"big\":      1400px,\n    \"figma\":    1440px,\n    \"huge\":     1600px,\n    \"enormous\": 1800px,\n    \"gigantic\": 2000px,\n    \"colossal\": 2400px\n);\n\n// Functions\n// ==========================================================================\n\n// Creates a min-width or max-width media query expression.\n//\n// @param  {string} $breakpoint The breakpoint.\n// @param  {string} $type       Either \"min\" or \"max\".\n// @return {string}\n\n@function mq($breakpoint, $type: \"min\") {\n    @if not map.has-key($breakpoints, $breakpoint) {\n        @warn \"Unknown media query breakpoint: `#{$breakpoint}`\";\n    }\n\n    $value: map.get($breakpoints, $breakpoint);\n\n    @if ($type == \"min\") {\n        @return \"(min-width: #{$value})\";\n    }\n    @if ($type == \"max\") {\n        @return \"(max-width: #{$value - 1px})\";\n    }\n\n    @error \"Unknown media query type: #{$type}\";\n}\n\n// Creates a min-width media query expression.\n//\n// @param  {string} $breakpoint The breakpoint.\n// @return {string}\n\n@function mq-min($breakpoint) {\n    @return mq($breakpoint, \"min\");\n}\n\n// Creates a max-width media query expression.\n//\n// @param  {string} $breakpoint The breakpoint.\n// @return {string}\n\n@function mq-max($breakpoint) {\n    @return mq($breakpoint, \"max\");\n}\n\n// Creates a min-width and max-width media query expression.\n//\n// @param  {string} $from  The min-width breakpoint.\n// @param  {string} $until The max-width breakpoint.\n// @return {string}\n\n@function mq-between($breakpointMin, $breakpointMax) {\n    @return \"#{mq-min($breakpointMin)} and #{mq-max($breakpointMax)}\";\n}\n\n\n// Legacy\n// ==========================================================================\n\n$from-tiny:     map.get($breakpoints, \"tiny\")           !default;\n$to-tiny:       map.get($breakpoints, \"tiny\") - 1       !default;\n$from-small:    map.get($breakpoints, \"small\")          !default;\n$to-small:      map.get($breakpoints, \"small\") - 1      !default;\n$from-medium:   map.get($breakpoints, \"medium\")         !default;\n$to-medium:     map.get($breakpoints, \"medium\") - 1     !default;\n$from-large:    map.get($breakpoints, \"large\")          !default;\n$to-large:      map.get($breakpoints, \"large\") - 1      !default;\n$from-big:      map.get($breakpoints, \"big\")            !default;\n$to-big:        map.get($breakpoints, \"big\") - 1        !default;\n$from-figma:    map.get($breakpoints, \"figma\")          !default;\n$to-figma:      map.get($breakpoints, \"figma\") - 1      !default;\n$from-huge:     map.get($breakpoints, \"huge\")           !default;\n$to-huge:       map.get($breakpoints, \"huge\") - 1       !default;\n$from-enormous: map.get($breakpoints, \"enormous\")       !default;\n$to-enormous:   map.get($breakpoints, \"enormous\") - 1   !default;\n$from-gigantic: map.get($breakpoints, \"gigantic\")       !default;\n$to-gigantic:   map.get($breakpoints, \"gigantic\") - 1   !default;\n$from-colossal: map.get($breakpoints, \"colossal\")       !default;\n$to-colossal:   map.get($breakpoints, \"colossal\") - 1   !default;\n"
  },
  {
    "path": "packages/landing/assets/styles/settings/_config.colors.scss",
    "content": "// ==========================================================================\n// Settings / Config / Colors\n// ==========================================================================\n@use \"sass:map\";\n@use \"sass:color\";\n\n// Palette\n// ==========================================================================\n\n$colors: (\n    'blue':  #202ded,\n    'white': #FFFFFF,\n    'black': #000000,\n    'red':   #F4574D,\n);\n\n// Function\n// ==========================================================================\n\n// Returns color code.\n//\n// ```scss\n// .c-box {\n//     color: color(blue);\n// }\n// ```\n//\n// @param  {string} $key - The color key in $colors.\n// @param  {number} $alpha - The alpha for the color value.\n// @return {color}\n\n@function color($key, $alpha: 1) {\n    $key: #{$key}; // Force string conversion\n    @if not map.has-key($colors, $key) {\n        @error \"Unknown '#{$key}' in $colors.\";\n    }\n\n    @if($alpha < 0 or $alpha > 1) {\n        @error \"Alpha '#{$alpha}' must be in range [0, 1].\";\n    }\n\n    $color: map.get($colors, $key);\n\n    @return rgba($color, $alpha);\n}\n\n// Specifics\n// ==========================================================================\n\n// Link\n$color-link:           color(blue);\n$color-link-focus:     color(blue);\n$color-link-hover:     color.adjust(color(blue), $lightness: -10%);\n\n// Selection\n$color-selection-text:         color(black);\n$color-selection-background:   color(white);\n\n// Socials\n$color-facebook:    #3B5998;\n$color-instagram:   #E1306C;\n$color-youtube:     #CD201F;\n$color-twitter:     #1DA1F2;\n"
  },
  {
    "path": "packages/landing/assets/styles/settings/_config.eases.scss",
    "content": "// ==========================================================================\n// Settings / Config / Eases\n// ==========================================================================\n@use \"sass:map\";\n\n// Eases\n// ==========================================================================\n\n$eases: (\n    // Power 1\n    \"power1.in\":        cubic-bezier(0.550, 0.085, 0.680, 0.530),\n    \"power1.out\":       cubic-bezier(0.250, 0.460, 0.450, 0.940),\n    \"power1.inOut\":     cubic-bezier(0.455, 0.030, 0.515, 0.955),\n\n    // Power 2\n    \"power2.in\":        cubic-bezier(0.550, 0.055, 0.675, 0.190),\n    \"power2.out\":       cubic-bezier(0.215, 0.610, 0.355, 1.000),\n    \"power2.inOut\":     cubic-bezier(0.645, 0.045, 0.355, 1.000),\n\n    // Power 3\n    \"power3.in\":        cubic-bezier(0.895, 0.030, 0.685, 0.220),\n    \"power3.out\":       cubic-bezier(0.165, 0.840, 0.440, 1.000),\n    \"power3.inOut\":     cubic-bezier(0.770, 0.000, 0.175, 1.000),\n\n    // Power 4\n    \"power4.in\":        cubic-bezier(0.755, 0.050, 0.855, 0.060),\n    \"power4.out\":       cubic-bezier(0.230, 1.000, 0.320, 1.000),\n    \"power4.inOut\":     cubic-bezier(0.860, 0.000, 0.070, 1.000),\n\n    // Expo\n    \"expo.in\":          cubic-bezier(0.950, 0.050, 0.795, 0.035),\n    \"expo.out\":         cubic-bezier(0.190, 1.000, 0.220, 1.000),\n    \"expo.inOut\":       cubic-bezier(1.000, 0.000, 0.000, 1.000),\n\n    // Back\n    \"back.in\":          cubic-bezier(0.600, -0.280, 0.735, 0.045),\n    \"back.out\":         cubic-bezier(0.175, 00.885, 0.320, 1.275),\n    \"back.inOut\":       cubic-bezier(0.680, -0.550, 0.265, 1.550),\n\n    // Sine\n    \"sine.in\":          cubic-bezier(0.470, 0.000, 0.745, 0.715),\n    \"sine.out\":         cubic-bezier(0.390, 0.575, 0.565, 1.000),\n    \"sine.inOut\":       cubic-bezier(0.445, 0.050, 0.550, 0.950),\n\n    // Circ\n    \"circ.in\":          cubic-bezier(0.600, 0.040, 0.980, 0.335),\n    \"circ.out\":         cubic-bezier(0.075, 0.820, 0.165, 1.000),\n    \"circ.inOut\":       cubic-bezier(0.785, 0.135, 0.150, 0.860),\n\n    // Misc\n    \"bounce\":           cubic-bezier(0.17, 0.67, 0.3, 1.33),\n    \"slow.out\":         cubic-bezier(.04,1.15,0.4,.99),\n    \"smooth\":           cubic-bezier(0.380, 0.005, 0.215, 1),\n);\n\n// Default value for ease()\n$ease-default: \"power2.out\" !default;\n\n// Function\n// ==========================================================================\n\n// Returns ease curve.\n//\n// ```scss\n// .c-box {\n//     transition-timing-function: ease(\"power2.out\");\n// }\n// ```\n//\n// @param  {string} $key - The ease key in $eases.\n// @return {easing-function}\n\n@function ease($key: $ease-default) {\n    @if not map.has-key($eases, $key) {\n        @error \"Unknown '#{$key}' in $eases.\";\n    }\n\n    @return map.get($eases, $key);\n}\n"
  },
  {
    "path": "packages/landing/assets/styles/settings/_config.fonts.scss",
    "content": "// ==========================================================================\n// Settings / Config / Breakpoints\n// ==========================================================================\n@use \"sass:list\";\n@use \"sass:map\";\n@use \"sass:meta\";\n\n// Font fallbacks (retrieved from systemfontstack.com on 2022-05-31)\n// ==========================================================================\n\n$font-fallback-sans:    -apple-system, BlinkMacSystemFont, avenir next, avenir, segoe ui, helvetica neue, helvetica, Cantarell, Ubuntu, roboto, noto, arial, sans-serif;\n$font-fallback-serif:   Iowan Old Style, Apple Garamond, Baskerville, Times New Roman, Droid Serif, Times, Source Serif Pro, serif, Apple Color Emoji, Segoe UI Emoji, Segoe UI Symbol;\n$font-fallback-mono:    Menlo, Consolas, Monaco, Liberation Mono, Lucida Console, monospace;\n\n// Typefaces\n// ==========================================================================\n\n// List of custom font faces as tuples.\n//\n// ```\n// <font-name> <font-file-basename> <font-weight> <font-style>\n// ```\n$font-faces: (\n    (\"Helvetica Now Display\", \"HelveticaNowDisplay-Medium\", 500, normal),\n    (\"Helvetica Now Display\", \"HelveticaNowDisplay-Regular\", 400, normal),\n    (\"PP Locomotive New\", \"PPLocomotiveNew-Light\", 300, normal)\n);\n\n// Map of font families.\n//\n// ```\n// <font-id>: (<font-name>, <font-fallbacks>)\n// ```\n$font-families: (\n    display:  list.join(\"Helvetica Now Display\", $font-fallback-sans, $separator: comma),\n    serif: list.join(\"PP Locomotive New\", $font-fallback-sans, $separator: comma),\n);\n\n// Font directory\n$font-dir: \"../fonts/\";\n\n// Functions\n// ==========================================================================\n\n// Imports the custom font.\n//\n// The mixin expects font files to be woff and woff2.\n//\n// @param  {List}   $webfont - A custom font to import, as a tuple:\n//     `<font-name> <font-file-basename> <font-weight> <font-style>`.\n// @param  {String} $dir     - The webfont directory path.\n// @output The `@font-face` at-rule specifying the custom font.\n\n@mixin font-face($webfont, $dir) {\n    @font-face {\n        font-display: swap;\n        font-family: list.nth($webfont, 1);\n        src: url(\"#{$dir}#{list.nth($webfont, 2)}.woff2\") format(\"woff2\"),\n             url(\"#{$dir}#{list.nth($webfont, 2)}.woff\") format(\"woff\");\n        font-weight: #{list.nth($webfont, 3)};\n        font-style: #{list.nth($webfont, 4)};\n    }\n}\n\n// Imports the list of custom fonts.\n//\n// @require {mixin} font-face\n//\n// @param  {List<List>} $webfonts - List of custom fonts to import.\n//     See `font-face` mixin for details.\n// @param  {String}     $dir      - The webfont directory path.\n// @output The `@font-face` at-rules specifying the custom fonts.\n\n@mixin font-faces($webfonts, $dir) {\n    @if (list.length($webfonts) > 0) {\n        @if (meta.type-of(list.nth($webfonts, 1)) == \"list\") {\n            @each $webfont in $webfonts {\n                @include font-face($webfont, $dir);\n            }\n        } @else {\n            @include font-face($webfonts, $dir);\n        }\n    }\n}\n\n// Retrieves the font family stack for the given font ID.\n//\n// @require {variable} $font-families - See settings directory.\n//\n// @param  {String} $font-family - The custom font ID.\n// @throws Error if the $font-family does not exist.\n// @return {List} The font stack.\n\n@function ff($font-family) {\n    @if not map.has-key($font-families, $font-family) {\n        @error \"No font-family found in $font-families map for `#{$font-family}`.\";\n    }\n\n    $value: map.get($font-families, $font-family);\n    @return $value;\n}\n"
  },
  {
    "path": "packages/landing/assets/styles/settings/_config.scss",
    "content": "// ==========================================================================\n// Settings / Config\n// ==========================================================================\n@use \"sass:math\";\n@use \"config.colors\" as *;\n@use \"config.timings\" as *;\n@use \"config.eases\" as *;\n\n// Context\n// =============================================================================\n\n// The current stylesheet context. Available values: frontend, editor.\n$context: frontend  !default;\n\n// Path is relative to the stylesheets directory.\n$assets-path: \"../\"  !default;\n\n// Typography\n// =============================================================================\n\n// Base\n$font-size:     16px;\n$line-height:   math.div(24px, $font-size);\n$font-color:    color(black);\n\n// Weights\n$font-weight-light:     300;\n$font-weight-regular:    400;\n$font-weight-medium:    500;\n\n// Transition defaults\n// =============================================================================\n$speed:     t(normal);\n$easing:    ease(\"power3.out\");\n\n// Spacing Units\n// =============================================================================\n$unit:       60px;\n$unit-small: 20px;\n\n// Container\n// ==========================================================================\n$padding:         $unit;\n\n// Grid\n// ==========================================================================\n$base-column-nb: 4;\n"
  },
  {
    "path": "packages/landing/assets/styles/settings/_config.spacers.scss",
    "content": "// ==========================================================================\n// Settings / Config / Spacers\n// ==========================================================================\n@use \"sass:map\";\n@use \"../tools/functions\" as *;\n\n:root {\n    --spacing-2xs-mobile: 6;\n    --spacing-2xs-desktop: 10;\n\n    --spacing-xs-mobile: 14;\n    --spacing-xs-desktop: 16;\n\n    --spacing-sm-mobile: 28;\n    --spacing-sm-desktop: 32;\n\n    --spacing-md-mobile: 42;\n    --spacing-md-desktop: 56;\n\n    --spacing-lg-mobile: 72;\n    --spacing-lg-desktop: 96;\n\n    --spacing-xl-mobile: 90;\n    --spacing-xl-desktop: 120;\n\n    --spacing-2xl-mobile: 96;\n    --spacing-2xl-desktop: 160;\n\n    --spacing-3xl-mobile: 112;\n    --spacing-3xl-desktop: 224;\n}\n\n// Spacers\n// ==========================================================================\n\n$spacers: (\n    'gutter':   var(--grid-gutter),\n    '2xs':      #{spacingClamp('2xs')},\n    'xs':       #{spacingClamp('xs')},\n    'sm':       #{spacingClamp('sm')},\n    'md':       #{spacingClamp('md')},\n    'lg':       #{spacingClamp('lg')},\n    'xl':       #{spacingClamp('xl')},\n    '2xl':      #{spacingClamp('2xl')},\n    '3xl':      #{spacingClamp('3xl')},\n);\n\n// Function\n// ==========================================================================\n\n// Returns spacer.\n//\n// ```scss\n// .c-box {\n//     margin-top: spacer(gutter);\n// }\n// ```\n//\n// @param  {string} $key - The spacer key in $spacers.\n// @param  {number} $multiplier - The multiplier of the spacer value.\n// @return {size}\n\n@function spacer($spacer: $spacer-default, $multiplier: 1) {\n    @if not map.has-key($spacers, $spacer) {\n        @error \"Unknown master spacer: #{$spacer}\";\n    }\n\n    $index: map.get($spacers, $spacer);\n\n    @return calc(#{$index} * #{$multiplier});\n}\n"
  },
  {
    "path": "packages/landing/assets/styles/settings/_config.timings.scss",
    "content": "// ==========================================================================\n// Settings / Config / Timings\n// ==========================================================================\n@use \"sass:map\";\n\n// Timings\n// ==========================================================================\n\n$timings: (\n    fastest:    0.1s,\n    faster:     0.15s,\n    fast:       0.25s,\n    normal:     0.5s,\n    medium:     0.6s,\n    slow:       0.75s,\n    slower:     1s,\n    slowest:    2s,\n);\n\n// Default timing for t()\n$timing-default: \"normal\" !default;\n\n// Function\n// ==========================================================================\n\n// Returns timing.\n//\n// ```scss\n// .c-box {\n//     transition-duration: t(slow);\n// }\n// ```\n//\n// @param  {string} $key - The timing key in $timings.\n// @return {duration}\n\n@function t($key: $timing-default) {\n    @if not map.has-key($timings, $key) {\n        @error \"Unknown '#{$key}' in $timings.\";\n    }\n\n    @return map.get($timings, $key);\n}\n"
  },
  {
    "path": "packages/landing/assets/styles/settings/_config.variables.scss",
    "content": "// ==========================================================================\n// Settings / Config / CSS VARS\n// ==========================================================================\n@use '../tools/functions' as *;\n@use 'config.breakpoints' as *;\n:root {\n    // Grid\n    --grid-columns: 4;\n    --grid-gutter: #{rem(10px)};\n    --grid-margin: #{rem(10px)};\n\n    // Container\n    --container-width: calc(100% - 2 * var(--grid-margin));\n\n    @media (max-width: $to-small) {\n        --header-height: #{rem(34px)};\n    }\n\n    @media (min-width: $from-small) {\n        --grid-gutter: #{rem(16px)};\n        --grid-margin: #{rem(20px)};\n        --header-height: #{rem(60px)};\n    }\n}\n"
  },
  {
    "path": "packages/landing/assets/styles/settings/_config.zindexes.scss",
    "content": "// ==========================================================================\n// Settings / Config / Z-indexes\n// ==========================================================================\n@use \"sass:map\";\n\n// Timings\n// ==========================================================================\n\n$z-indexes: (\n    \"header\":   200,\n    \"above\":    1,\n    \"default\":  0,\n    \"below\":    -1\n);\n\n// Default z-index for z()\n$z-index-default: \"above\" !default;\n\n// Function\n// ==========================================================================\n\n// Retrieves the z-index from the {@see $layers master list}.\n//\n// @link on http://css-tricks.com/handling-z-index/\n//\n// @param  {string} $layer    The name of the z-index.\n// @param  {number} $modifier A positive or negative modifier to apply\n//     to the returned z-index value.\n// @throw  Error if the $layer does not exist.\n// @throw  Warning if the $modifier might overlap another master z-index.\n// @return {number}           The computed z-index of $layer and $modifier.\n\n@function z($layer: $z-index-default, $modifier: 0) {\n    @if not map.has-key($z-indexes, $layer) {\n        @error \"Unknown master z-index layer: #{$layer}\";\n    }\n\n    @if ($modifier >= 50 or $modifier <= -50) {\n        @warn \"Modifier may overlap the another master z-index layer: #{$modifier}\";\n    }\n\n    $index: map.get($z-indexes, $layer);\n\n    @return $index + $modifier;\n}\n"
  },
  {
    "path": "packages/landing/assets/styles/tools/_family.scss",
    "content": "// ==========================================================================\n// Tools / Family\n// ==========================================================================\n@use \"sass:math\";\n\n// DOCS : https://lukyvj.github.io/family.scss/\n//\n// Select all children from the first to `$num`.\n// @group with-arguments\n// @content [Write the style you want to apply to the children, and it will be added within the @content directive]\n// @param {number} $num - id of the child\n\n@mixin first($num) {\n    @if $num == 1 {\n        &:first-child {\n            @content;\n        }\n    } @else {\n        &:nth-child(-n + #{$num}) {\n            @content;\n        }\n    }\n}\n\n// Select all children from the last to `$num`.\n// @group with-arguments\n// @content [Write the style you want to apply to the children, and it will be added within the @content directive]\n// @param {number} $num - id of the child\n\n@mixin last($num) {\n    &:nth-last-child(-n + #{$num}) {\n        @content;\n    }\n}\n\n// Select all children after the first to `$num`.\n// @group with-arguments\n// @content [Write the style you want to apply to the children, and it will be added within the @content directive]\n// @param {number} $num - id of the child\n\n@mixin after-first($num) {\n    &:nth-child(n + #{$num + 1}) {\n        @content;\n    }\n}\n\n// Select all children before `$num` from the last.\n// @group with-arguments\n// @content [Write the style you want to apply to the children, and it will be added within the @content directive]\n// @param {number} $num - id of the child\n\n@mixin from-end($num) {\n    &:nth-last-child(#{$num}) {\n        @content;\n    }\n}\n\n// Select all children between `$first` and `$last`.\n// @group with-arguments\n// @content [Write the style you want to apply to the children, and it will be added within the @content directive]\n\n@mixin between($first, $last) {\n    &:nth-child(n + #{$first}):nth-child(-n + #{$last}) {\n        @content;\n    }\n}\n\n// Select all even children between `$first` and `$last`.\n// @group with-arguments\n// @content [Write the style you want to apply to the children, and it will be added within the @content directive]\n\n@mixin even-between($first, $last) {\n    &:nth-child(even):nth-child(n + #{$first}):nth-child(-n + #{$last}) {\n        @content;\n    }\n}\n\n// Select all odd children between `$first` and `$last`.\n// @group with-arguments\n// @content [Write the style you want to apply to the children, and it will be added within the @content directive]\n\n@mixin odd-between($first, $last) {\n    &:nth-child(odd):nth-child(n + #{$first}):nth-child(-n + #{$last}) {\n        @content;\n    }\n}\n\n// Select all `$num` children between `$first` and `$last`.\n// @group with-arguments\n// @content [Write the style you want to apply to the children, and it will be added within the @content directive]\n\n@mixin n-between($num, $first, $last) {\n    &:nth-child(#{$num}n):nth-child(n + #{$first}):nth-child(-n + #{$last}) {\n        @content;\n    }\n}\n\n// Select all children but `$num`.\n// @group with-arguments\n// @content [Write the style you want to apply to the children, and it will be added within the @content directive]\n// @param {number} $num - id of the child\n\n@mixin all-but($num) {\n    &:not(:nth-child(#{$num})) {\n        @content;\n    }\n}\n\n// Select children each `$num`.\n// @group with-arguments\n// @content [Write the style you want to apply to the children, and it will be added within the @content directive]\n// @param {number} $num - id of the child\n// @alias every\n\n@mixin each($num) {\n    &:nth-child(#{$num}n) {\n        @content;\n    }\n}\n\n// Select children each `$num`.\n// @group with-arguments\n// @content [Write the style you want to apply to the children, and it will be added within the @content directive]\n// @param {number} $num - id of the child\n\n@mixin every($num) {\n    &:nth-child(#{$num}n) {\n        @content;\n    }\n}\n\n// Select the `$num` child from the start and the `$num` child from the last.\n// @group with-arguments\n// @content [Write the style you want to apply to the children, and it will be added within the @content directive]\n// @param {number} $num - id of the child\n\n@mixin from-first-last($num) {\n    &:nth-child(#{$num}),\n    &:nth-last-child(#{$num}) {\n        @content;\n    }\n}\n\n// Select the item in the middle of `$num` child. Only works with odd number\n// chain.\n// @group with-arguments\n// @content [Write the style you want to apply to the children, and it will be added within the @content directive]\n// @param {number} $num - id of the child\n\n@mixin middle($num) {\n    &:nth-child(#{round(math.div($num, 2))}) {\n        @content;\n    }\n}\n\n// Select all children between the `$num` first and the `$num` last.\n// @group with-arguments\n// @content [Write the style you want to apply to the children, and it will be added within the @content directive]\n// @param {number} $num - id of the child\n\n@mixin all-but-first-last($num) {\n    &:nth-child(n + #{$num}):nth-last-child(n + #{$num}) {\n        @content;\n    }\n}\n\n// This quantity-query mixin will only select the first of `$limit` items. It will not\n// work if there is not as much as item as you set in `$limit`.\n// @group Quantity queries\n// @param {number} $limit\n// @content [Write the style you want to apply to the children, and it will be added within the @content directive]\n\n@mixin first-of($limit) {\n    &:nth-last-child(#{$limit}):first-child {\n        @content;\n    }\n}\n\n// This quantity-query mixin will only select the last of `$limit` items. It will not\n// if there is not as much as item as you set in `$limit`.\n// @group Quantity queries\n// @param {number} $limit\n// @content [Write the style you want to apply to the children, and it will be added within the @content directive]\n\n@mixin last-of($limit) {\n    &:nth-of-type(#{$limit}):nth-last-of-type(1) {\n        @content;\n    }\n}\n\n// This quantity-query mixin will select every items if there is at least `$num` items. It will not\n// if there is not as much as item as you set in `$num`.\n// @group Quantity queries\n// @param {number} $limit\n// @content [Write the style you want to apply to the children, and it will be added within the @content directive]\n\n@mixin at-least($num) {\n    $selector: &;\n    $child: nth(nth($selector, -1), -1);\n\n    &:nth-last-child(n + #{$num}),\n    &:nth-last-child(n + #{$num}) ~ #{$child} {\n        @content;\n    }\n}\n\n// This quantity-query mixin will select every items if there is at most `$num` items. It will not\n// if there is not as much as item as you set in `$num`.\n// @group Quantity queries\n// @param {number} $limit\n// @content [Write the style you want to apply to the children, and it will be added within the @content directive]\n\n@mixin at-most($num) {\n    $selector: &;\n    $child: nth(nth($selector, -1), -1);\n\n    &:nth-last-child(-n + #{$num}):first-child,\n    &:nth-last-child(-n + #{$num}):first-child ~ #{$child} {\n        @content;\n    }\n}\n\n// This quantity-query mixin will select every items only if there is between `$min` and `$max` items.\n// @group Quantity queries\n// @param {number} $limit\n// @content [Write the style you want to apply to the children, and it will be added within the @content directive]\n\n@mixin in-between($min, $max) {\n    $selector: &;\n    $child: nth(nth($selector, -1), -1);\n\n    &:nth-last-child(n + #{$min}):nth-last-child(-n + #{$max}):first-child,\n    &:nth-last-child(n + #{$min}):nth-last-child(-n + #{$max}):first-child ~ #{$child} {\n        @content;\n    }\n}\n\n// Select the first exact child\n// @group no-arguments\n// @content [Write the style you want to apply to the children, and it will be added within the @content directive]\n\n@mixin first-child() {\n    &:first-of-type {\n        @content\n    }\n}\n\n// Select the last exact child\n// @group no-arguments\n// @content [Write the style you want to apply to the children, and it will be added within the @content directive]\n\n@mixin last-child() {\n    &:last-of-type {\n        @content\n    }\n}\n\n// Select all even children.\n// @group no-arguments\n// @content [Write the style you want to apply to the children, and it will be added within the @content directive]\n\n@mixin even() {\n    &:nth-child(even) {\n        @content;\n    }\n}\n\n// Select all odd children.\n// @group no-arguments\n// @content [Write the style you want to apply to the children, and it will be added within the @content directive]\n\n@mixin odd() {\n    &:nth-child(odd) {\n        @content;\n    }\n}\n\n// Select only the first and last child.\n// @group no-arguments\n// @content [Write the style you want to apply to the children, and it will be added within the @content directive]\n\n@mixin first-last() {\n    &:first-child,\n    &:last-child {\n        @content;\n    }\n}\n\n// Will only select the child if it’s unique.\n// @group no-arguments\n// @content [Write the style you want to apply to the children, and it will be added within the @content directive]\n// @alias only\n\n@mixin unique() {\n    &:only-child {\n        @content;\n    }\n}\n\n// Will only select the child if it’s unique.\n// @group no-arguments\n// @content [Write the style you want to apply to the children, and it will be added within the @content directive]\n\n@mixin only() {\n    &:only-child {\n        @content;\n    }\n}\n\n// Will only select children if they are not unique. Meaning if there is at\n// least 2 children, the style is applied.\n// @group no-arguments\n// @content [Write the style you want to apply to the children, and it will be added within the @content directive]\n\n@mixin not-unique() {\n    &:not(:only-child) {\n        @content;\n    }\n}\n\n// This mixin is used to automatically sort z-index in numerical order. But it\n// can also sort them in anti-numerical order, depending the parameters you use.\n// @group using functions\n// @content [Write the style you want to apply to the children, and it will be added within the @content directive]\n// @param {number} $num - Number of children\n// @param {string} $direction [forward] - Direction of the sort\n// @param {number} $index [0] - Index of the sorting\n\n@mixin child-index($num, $direction: 'forward', $index: 0) {\n    @for $i from 1 through $num {\n        @if ($direction == 'forward') {\n            &:nth-child(#{$i}) {\n                z-index: order-index($i, $index);\n                @content;\n            }\n        } @else if ($direction == 'backward') {\n            &:nth-last-child(#{$i}) {\n                z-index: order-index($i, $index);\n                @content;\n            }\n        }\n    }\n}\n\n// Used by the child-index mixin. It will returned the proper sorted numbers\n// depending on the `$index` value.\n// @access private\n// @param {number} $num - Number of children\n// @param {number} $index - Index of the sorting\n\n@function order-index($i, $index) {\n    @return ($index + $i);\n}\n"
  },
  {
    "path": "packages/landing/assets/styles/tools/_functions.scss",
    "content": "// ==========================================================================\n// Tools / Functions\n// ==========================================================================\n@use \"sass:math\";\n@use \"sass:meta\";\n@use \"sass:list\";\n@use \"maths\" as *;\n\n// Default font size for em() and rem() functions\n$font-size: 16px !default;\n\n// Check if the given value is a number in pixel\n//\n// @param  {Number} $number - The value to check\n// @return {Boolean}\n\n@function is-pixel-number($number) {\n    @return meta.type-of($number) == number and math.unit($number) == \"px\";\n}\n\n// Converts the given pixel value to its EM quivalent.\n//\n// @param  {Number} $size                     - The pixel value to convert.\n// @param  {Number} $base [$font-size] - The assumed base font size.\n// @return {Number} Scalable pixel value in EMs.\n\n@function em($size, $base: $font-size) {\n    @if not is-pixel-number($size) {\n        @error \"`#{$size}` needs to be a number in pixel.\";\n    }\n\n    @if not is-pixel-number($base) {\n        @error \"`#{$base}` needs to be a number in pixel.\";\n    }\n\n    @return math.div($size, $base) * 1em;\n}\n\n// Converts the given pixel value to its REM quivalent.\n//\n// @param  {Number} $size                     - The pixel value to convert.\n// @param  {Number} $base [$font-size] - The assumed base font size.\n// @return {Number} Scalable pixel value in REMs.\n\n@function rem($size, $base: $font-size) {\n\n    @if not is-pixel-number($size) {\n        @error \"`#{$size}` needs to be a number in pixel.\";\n    }\n\n    @if not is-pixel-number($base) {\n        @error \"`#{$base}` needs to be a number in pixel.\";\n    }\n\n    @return math.div($size, $base) * 1rem;\n}\n\n// Converts a number to a percentage.\n//\n// @alias  percentage()\n// @link   http://sassdoc.com/annotations/#alias\n// @param  {Number} $number - The value to convert.\n// @return {Number} A percentage.\n\n@function span($number) {\n    @return percentage($number);\n}\n\n// Checks if a list contains a value(s).\n//\n// @link   https://github.com/thoughtbot/bourbon/blob/master/core/bourbon/validators/_contains.scss\n// @param  {List} $list   - The list to check against.\n// @param  {List} $values - A single value or list of values to check for.\n// @return {Boolean}\n// @access private\n\n@function list-contains(\n    $list,\n    $values...\n) {\n    @each $value in $values {\n        @if meta.type-of(list.index($list, $value)) != \"number\" {\n            @return false;\n        }\n    }\n\n    @return true;\n}\n\n// Resolve whether a rule is important or not.\n//\n// @param  {Boolean}     $flag - Whether a rule is important (TRUE) or not (FALSE).\n// @return {String|Null} Returns `!important` or NULL.\n\n@function important($flag: false) {\n    @if ($flag == true) {\n        @return !important;\n    } @else if ($flag == false) {\n        @return null;\n    } @else {\n        @error \"`#{$flag}` needs to be `true` or `false`.\";\n    }\n}\n\n// Determine if the current context is for a WYSIWYG editor.\n//\n// @requires {String} $context - The global context of the stylesheet.\n// @return   {Boolean} If the $context is set to \"editor\".\n\n@function is-editor() {\n    @return ('editor' == $context);\n}\n\n// Determine if the current context is for the front-end.\n//\n// @requires {String} $context - The global context of the stylesheet.\n// @return   {Boolean} If the $context is set to \"frontend\".\n\n@function is-frontend() {\n    @return ('frontend' == $context);\n}\n\n$context: 'frontend' !default;\n\n// Returns calculation of a percentage of the grid cell width\n// with optional inset of grid gutter.\n//\n// ```scss\n// .c-box {\n//     width: grid-space(6/12);\n//     margin-left: grid-space(1/12, 1);\n// }\n// ```\n//\n// @param  {number} $number - The percentage spacer\n// @param  {number} $inset  - The grid gutter inset\n// @return {function<number>}\n@function grid-space($percentage, $inset: 0) {\n    @return calc(#{$percentage} * (100vw - 2 * var(--grid-margin, 0px)) - (1 - #{$percentage}) * var(--grid-gutter, 0px) + #{$inset} * var(--grid-gutter, 0px));\n}\n\n// Returns calculation of a percentage of the viewport height.\n//\n// ```scss\n// .c-box {\n//     height: vh(100);\n// }\n// ```\n//\n// @param  {number} $number - The percentage number\n// @return {function<number>} in vh\n@function vh($number) {\n    @return calc(#{$number} * var(--vh, 1vh));\n}\n\n// Returns calculation of a percentage of the viewport width.\n//\n// ```scss\n// .c-box {\n//     width: vw(100);\n// }\n// ```\n//\n// @param  {number} $number - The percentage number\n// @return {function<number>} in vw\n\n@function vw($number) {\n    @return calc(#{$number} * var(--vw, 1vw));\n}\n\n// Returns calculation of a percentage of the viewport width.\n//\n// ```scss\n// .c-box {\n//     width: vw(100);\n// }\n// ```\n//\n// @param  {number} $number - The percentage number\n// @return {function<number>} in vw\n\n$vw-viewport: 1440;\n@function vw($number) {\n    @return calc(#{$number} * var(--vw, 1vw));\n}\n\n\n@function clampWithMax($min, $size, $max) {\n    $vw-context: $vw-viewport * 0.01;\n    @return clamp(#{$min}, calc(#{$size} / #{$vw-context} * 1vw), #{$max});\n}\n\n@function spacingClamp($size) {\n    @return clampWithMax(\n        calc(#{rem(1px)} * var(--spacing-#{$size}-mobile)),\n        var(--spacing-#{$size}-desktop),\n        calc(#{rem(1px)} * var(--spacing-#{$size}-desktop))\n    );\n}\n\n// Returns clamp of calculated preferred responsive font size\n// within a font size and breakpoint range.\n//\n// ```scss\n// .c-heading.-h1 {\n//     font-size: responsive-value(30px, 60px, 1800);\n// }\n//\n// .c-heading.-h2 {\n//     font-size: responsive-value(20px, 40px, $from-big);\n// }\n// ```\n//\n// @param  {number} $min-size   - Minimum font size in pixels.\n// @param  {number} $max-size   - Maximum font size in pixels.\n// @param  {number} $breakpoint - Maximum breakpoint.\n// @return {function<number, function<number>, number>}\n@function responsive-value($min-size, $max-size, $breakpoint) {\n    $delta: math.div($max-size, $breakpoint);\n    @return clamp($min-size, calc(#{strip-unit($delta)} * #{vw(100)}), $max-size);\n}\n"
  },
  {
    "path": "packages/landing/assets/styles/tools/_layout.scss",
    "content": "// ==========================================================================\n// Tools / Layout\n// ==========================================================================\n@use \"sass:meta\";\n\n// Grid-like layout system.\n//\n// The layout tools provide a column-style layout system. This file contains\n// the mixins to generate basic structural elements.\n//\n// @link https://github.com/inuitcss/inuitcss/blob/0420ba8/objects/_objects.layout.scss\n//\n//\n// Generate the layout container.\n//\n// 1. Use the negative margin trick for multi-row grids:\n//    http://csswizardry.com/2011/08/building-better-grid-systems/\n//\n// @requires {function} u-list-reset\n// @output   `font-size`, `margin`, `padding`, `list-style`\n\n@mixin o-layout($gutter: 0, $fix-whitespace: true) {\n    margin: 0;\n    padding: 0;\n    list-style: none;\n\n    @if ($fix-whitespace) {\n        font-size: 0;\n    }\n\n    @if (meta.type-of($gutter) == number) {\n        margin-left: -$gutter; // [1]\n    }\n}\n\n// Generate the layout item.\n//\n// 1. Required in order to combine fluid widths with fixed gutters.\n// 2. Allows us to manipulate grids vertically, with text-level properties,\n//    etc.\n// 3. Default item alignment is with the tops of each other, like most\n//    traditional grid/layout systems.\n// 4. By default, all layout items are full-width (mobile first).\n// 5. Gutters provided by left padding:\n//    http://csswizardry.com/2011/08/building-better-grid-systems/\n\n@mixin o-layout_item($gutter: 0, $fix-whitespace: true) {\n    display: inline-block; // [2]\n    width: 100%; // [4]\n    vertical-align: top; // [3]\n\n    @if ($fix-whitespace) {\n        font-size: 1rem;\n    }\n\n    @if (meta.type-of($gutter) == number) {\n        padding-left: $gutter; // [5]\n    }\n}\n"
  },
  {
    "path": "packages/landing/assets/styles/tools/_maths.scss",
    "content": "// ==========================================================================\n// Tools / Maths\n// ==========================================================================\n@use \"sass:meta\";\n@use \"sass:math\";\n\n// Remove the unit of a length\n//\n// @param {Number} $number Number to remove unit from\n// @return {function<number>}\n@function strip-unit($value) {\n    @if meta.type-of($value) != \"number\" {\n        @error \"Invalid `#{meta.type-of($value)}` type. Choose a number type instead.\";\n    } @else if meta.type-of($value) == \"number\" and not math.is-unitless($value) {\n        @return math.div($value, $value * 0 + 1);\n    }\n\n    @return $value;\n}\n\n// Returns the square root of the given number.\n//\n// @param  {number} $number The number to calculate.\n// @return {number}\n\n@function sqrt($number) {\n    $x: 1;\n    $value: $x;\n\n    @for $i from 1 through 10 {\n        $value: $x - math.div(($x * $x - abs($number)), (2 * $x));\n        $x: $value;\n    }\n\n    @return $value;\n}\n\n// Returns a number raised to the power of an exponent.\n//\n// @param  {number} $number The base number.\n// @param  {number} $exp    The exponent.\n// @return {number}\n\n@function pow($number, $exp) {\n    $value: 1;\n\n    @if $exp > 0 {\n        @for $i from 1 through $exp {\n            $value: $value * $number;\n        }\n    } @else if $exp < 0 {\n        @for $i from 1 through -$exp {\n            $value: math.div($value, $number);\n        }\n    }\n\n    @return $value;\n}\n\n// Returns the factorial of the given number.\n//\n// @param  {number} $number The number to calculate.\n// @return {number}\n\n@function fact($number) {\n    $value: 1;\n\n    @if $number > 0 {\n        @for $i from 1 through $number {\n            $value: $value * $i;\n        }\n    }\n\n    @return $value;\n}\n\n// Returns an approximation of pi, with 11 decimals.\n//\n// @return {number}\n\n@function pi() {\n    @return 3.14159265359;\n}\n\n// Converts the number in degrees to the radian equivalent .\n//\n// @param  {number} $angle  The angular value to calculate.\n// @return {number}         If $angle has the `deg` unit,\n//                          the radian equivalent is returned.\n//                          Otherwise, the unitless value of $angle is returned.\n\n@function rad($angle) {\n    $unit: math.unit($angle);\n    $angle: strip-units($angle);\n\n    // If the angle has `deg` as unit, convert to radians.\n    @if ($unit == deg) {\n        @return math.div($angle, 180) * pi();\n    }\n\n    @return $angle;\n}\n\n// Returns the sine of the given number.\n//\n// @param  {number} $angle The angle to calculate.\n// @return {number}\n\n@function sin($angle) {\n    $sin: 0;\n    $angle: rad($angle);\n\n    @for $i from 0 through 10 {\n        $sin: $sin + pow(-1, $i) * math.div(pow($angle, (2 * $i + 1)), fact(2 * $i + 1));\n    }\n\n    @return $sin;\n}\n\n// Returns the cosine of the given number.\n//\n// @param  {string} $angle The angle to calculate.\n// @return {number}\n\n@function cos($angle) {\n    $cos: 0;\n    $angle: rad($angle);\n\n    @for $i from 0 through 10 {\n        $cos: $cos + pow(-1, $i) * math.div(pow($angle, 2 * $i), fact(2 * $i));\n    }\n\n    @return $cos;\n}\n\n// Returns the tangent of the given number.\n//\n// @param  {string} $angle The angle to calculate.\n// @return {number}\n\n@function tan($angle) {\n    @return math.div(sin($angle), cos($angle));\n}\n\n@function mapRangePx($css-var, $min0, $max0, $min1, $max1) {\n    @return calc((#{$min1} + (( #{$css-var} - #{$min0}) / (#{$max0} - #{$min0})) * (#{$max1} - #{$min1})) * 1px);\n}\n\n@function mapRange($css-var, $min0, $max0, $min1, $max1) {\n    @return calc(#{$min1} + (( #{$css-var} - #{$min0}) / (#{$max0} - #{$min0})) * (#{$max1} - #{$min1}));\n}\n\n@function mapRangeClampPx($css-var, $min0, $max0, $min1, $max1, $clampMin, $clampMax) {\n    @return calc(clamp( (#{$clampMin}) * 1px, (#{$min1} + (( #{$css-var} - #{$min0}) / (#{$max0} - #{$min0})) * (#{$max1} - #{$min1})) * 1px, (#{$clampMax}) * 1px));\n}\n\n@function mapRangeClamp($css-var, $min0, $max0, $min1, $max1, $clampMin, $clampMax) {\n    @return calc(clamp( #{$clampMin}, #{$min1} + (( #{$css-var} - #{$min0}) / (#{$max0} - #{$min0})) * (#{$max1} - #{$min1}), #{$clampMax}));\n}"
  },
  {
    "path": "packages/landing/assets/styles/tools/_mixins.scss",
    "content": "// ==========================================================================\n// Tools / Mixins\n// ==========================================================================\n@use \"sass:meta\";\n@use \"sass:math\";\n@use \"functions\" as *;\n\n// Set the color of the highlight that appears over a link while it's being tapped.\n//\n// By default, the highlight is suppressed.\n//\n// @param  {Color} $value [rgba(0, 0, 0, 0)] - The value of the highlight.\n// @output `-webkit-tap-highlight-color`\n\n@mixin tap-highlight-color($value: rgba(0, 0, 0, 0)) {\n    -webkit-tap-highlight-color: $value;\n}\n\n// Set whether or not touch devices use momentum-based scrolling for the given element.\n//\n// By default, applies momentum-based scrolling for the current element.\n//\n// @param  {String} $value [rgba(0, 0, 0, 0)] - The type of scrolling.\n// @output `-webkit-overflow-scrolling`\n\n@mixin overflow-scrolling($value: touch) {\n    -webkit-overflow-scrolling: $value;\n}\n\n// Micro clearfix rules for containing floats.\n//\n// @link   http://www.cssmojo.com/the-very-latest-clearfix-reloaded/\n// @param  {List} $supports The type of clearfix to generate.\n// @output Injects `:::after` pseudo-element.\n\n@mixin u-clearfix($supports...) {\n    &::after {\n        display: meta.if(list-contains($supports, table), table, block);\n        clear: both;\n        content: meta.if(list-contains($supports, opera), \" \", \"\");\n    }\n}\n\n// Generate a font-size and baseline-compatible line-height.\n//\n// @link   https://github.com/inuitcss/inuitcss/c14029c/tools/_tools.font-size.scss\n// @param  {Number}  $font-size           - The size of the font.\n// @param  {Number}  $line-height [auto]  - The line box height.\n// @param  {Boolean} $important   [false] - Whether the font-size is important.\n// @output `font-size`, `line-height`\n\n@mixin font-size($font-size, $line-height: auto, $important: false) {\n    $important: important($important);\n    font-size: rem($font-size) $important;\n\n    @if ($line-height == \"auto\") {\n        line-height: ceil(math.div($font-size, $line-height)) * math.div($line-height, $font-size) $important;\n    }\n    @else {\n        @if (meta.type-of($line-height) == number or $line-height == \"inherit\" or $line-height == \"normal\") {\n            line-height: $line-height $important;\n        }\n        @else if ($line-height != \"none\" and $line-height != false) {\n            @error \"D’oh! `#{$line-height}` is not a valid value for `$line-height`.\";\n        }\n    }\n}\n\n// Vertically-center the direct descendants of the current element.\n//\n// Centering is achieved by displaying children as inline-blocks. Any whitespace\n// between elements is nullified by redefining the font size of the container\n// and its children.\n//\n// @output `font-size`, `display`, `vertical-align`\n\n@mixin o-vertical-center {\n    font-size: 0;\n\n    &::before {\n        display: inline-block;\n        height: 100%;\n        content: \"\";\n        vertical-align: middle;\n    }\n\n    > * {\n        display: inline-block;\n        vertical-align: middle;\n        font-size: 1rem;\n    }\n}\n\n// Generate `:hover` and `:focus` styles in one go.\n//\n// @link    https://github.com/inuitcss/inuitcss/blob/master/tools/_tools.mixins.scss\n// @content Wrapped in `:focus` and `:hover` pseudo-classes.\n// @output  Wraps the given content in `:focus` and `:hover` pseudo-classes.\n\n@mixin u-hocus {\n    &:focus,\n    &:hover {\n        @content;\n    }\n}\n\n// Generate `:active` and `:focus` styles in one go.\n//\n// @see     {Mixin} u-hocus\n// @content Wrapped in `:focus` and `:active` pseudo-classes.\n// @output  Wraps the given content in `:focus` and `:hover` pseudo-classes.\n\n@mixin u-actus {\n    &:focus,\n    &:active {\n        @content;\n    }\n}\n\n// Prevent text from wrapping onto multiple lines for the current element.\n//\n// An ellipsis is appended to the end of the line.\n//\n// 1. Ensure that the node has a maximum width after which truncation can occur.\n// 2. Fix for IE 8/9 if `word-wrap: break-word` is in effect on ancestor nodes.\n//\n// @param  {Number} $width [100%] - The maximum width of element.\n// @output `max-width`, `word-wrap`, `white-space`, `overflow`, `text-overflow`\n\n@mixin u-truncate($width: 100%) {\n    overflow: hidden;\n    text-overflow: ellipsis;\n    white-space: nowrap;\n    word-wrap: normal;  // [2]\n    @if $width {\n        max-width: $width; // [1]\n    }\n}\n\n// Applies accessible hiding to the current element.\n//\n// @param  {Boolean} $important [true] - Whether the visibility is important.\n// @output Properties for removing the element from the document flow.\n\n@mixin u-accessibly-hidden($important: true) {\n    $important: important($important);\n    position: absolute $important;\n    overflow: hidden;\n    clip: rect(0 0 0 0);\n    margin: 0;\n    padding: 0;\n    width: 1px;\n    height: 1px;\n    border: 0;\n}\n\n// Allows an accessibly hidden element to be focusable via keyboard navigation.\n//\n// @content For styling the now visible element.\n// @output  Injects `:focus`, `:active` pseudo-classes.\n\n@mixin u-accessibly-focusable {\n    @include u-actus {\n        clip: auto;\n        width: auto;\n        height: auto;\n\n        @content;\n    }\n}\n\n// Hide the current element from all.\n//\n// The element will be hidden from screen readers and removed from the document flow.\n//\n// @link   http://juicystudio.com/article/screen-readers-display-none.php\n// @param  {Boolean} $important [true] - Whether the visibility is important.\n// @output `display`, `visibility`\n\n@mixin u-hidden($important: true) {\n    $important: important($important);\n    display: none   $important;\n    visibility: hidden $important;\n}\n\n// Show the current element for all.\n//\n// The element will be accessible from screen readers and visible in the document flow.\n//\n// @param  {String}  $display   [block] - The rendering box used for the element.\n// @param  {Boolean} $important [true]  - Whether the visibility is important.\n// @output `display`, `visibility`\n\n@mixin u-shown($display: block, $important: true) {\n    $important: important($important);\n    display: $display $important;\n    visibility: visible  $important;\n}\n\n// Aspect-ratio polyfill\n//\n// @param  {Number}  $ratio     [19/6]  - The ratio of the element.\n// @param  {Number}  $width     [100%]  - The fallback width of element.\n// @param  {Boolean} $children  [false] - Whether the element contains children for the fallback properties.\n// @output Properties for maintaining aspect-ratio\n\n@mixin aspect-ratio($ratio: math.div(16, 9), $width: 100%, $children: false) {\n\n    @supports (aspect-ratio: 1) {\n        aspect-ratio: $ratio;\n    }\n\n    @supports not (aspect-ratio: 1) {\n        height: 0;\n        padding-top: calc(#{$width} * #{math.div(1, $ratio)});\n\n        @if ($children == true) {\n            position: relative;\n\n            > * {\n                position: absolute;\n                top: 0;\n                left: 0;\n            }\n        }\n    }\n}\n\n// Add focus state to focused element\n@mixin u-focus-visible (\n    $color: currentColor,\n    $style: solid,\n    $width: 2px,\n    $offset: 2px,\n    ) {\n    outline-color: $color;\n    outline-style: $style;\n    outline-width: $width;\n    outline-offset: $offset;\n}\n"
  },
  {
    "path": "packages/landing/assets/styles/tools/_widths.scss",
    "content": "// ==========================================================================\n// Tools / Widths\n// ==========================================================================\n@use \"sass:math\";\n@use \"functions\" as *;\n\n// Optionally, the boilerplate can generate classes to offset items by a\n// certain width. Would you like to generate these types of class as well? E.g.:\n//\n// @example css\n//   .u-push-1/3\n//   .u-pull-2/4\n//   .u-pull-1/5\n//   .u-push-2/3\n\n$widths-offsets: false !default;\n\n// By default, the boilerplate uses fractions-like classes like `<div class=\"u-1/4\">`.\n// You can change the `/` to whatever you fancy with this variable.\n\n$fractions-delimiter: \\/ !default;\n\n// When using Sass-MQ, this defines the separator for the breakpoints suffix\n// in the class name. By default, we are generating the responsive suffixes\n// for the classes with a `@` symbol so you get classes like:\n// <div class=\"u-3/12@mobile\">\n\n$breakpoint-delimiter: \\@ !default;\n\n// Generate a series of width helper classes\n//\n// @example scss\n//     @include widths(12);\n//\n// @example html\n//    <div class=\"u-7/12\">\n//\n// @example scss\n//     @include widths(3 4, -mobile);\n//\n// @example html\n//    <div class=\"u-2/3-mobile\">\n//\n// @link     https://github.com/inuitcss/inuitcss/commit/6eb574f/utilities/_utilities.widths.scss\n// @requires {Function} important\n// @requires {Function} $widths-offsets\n// @requires {Function} $fractions-delimiter\n// @requires {Function} $breakpoint-delimiter\n// @param    {List}     $colums     - The columns we want the widths to have.\n// @param    {String}   $breakpoint - Optional suffix for responsive widths.\n// @output   `width`, `position`, `right`, `left`\n\n@mixin widths($columns, $breakpoint: null, $important: true) {\n    $important: important($important);\n\n    // Loop through the number of columns for each denominator of our fractions.\n    @each $denominator in $columns {\n        // Begin creating a numerator for our fraction up until we hit the\n        // denominator.\n        @for $numerator from 1 through $denominator {\n            // Build a class in the format `.u-3/4[@<breakpoint>]`.\n            .u-#{$numerator}#{$fractions-delimiter}#{$denominator}#{$breakpoint} {\n                width: math.div($numerator, $denominator) * 100% $important;\n            }\n\n            @if ($widths-offsets == true) {\n                // Build a class in the format `.u-push-1/2[@<breakpoint>]`.\n                .u-push-#{$numerator}#{$fractions-delimiter}#{$denominator}#{$breakpoint} {\n                    position: relative $important;\n                    right: auto $important;\n                    left: math.div($numerator, $denominator) * 100% $important;\n                }\n\n                // Build a class in the format `.u-pull-5/6[@<breakpoint>]`.\n                .u-pull-#{$numerator}#{$fractions-delimiter}#{$denominator}#{$breakpoint} {\n                    position: relative $important;\n                    right: math.div($numerator, $denominator) * 100% $important;\n                    left: auto $important;\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "packages/landing/assets/styles/utilities/_align.scss",
    "content": "// ==========================================================================\n// Utilities / Alignment\n// ==========================================================================\n\n// Floats\n// ==========================================================================\n\n.u-float-left {\n    float: left !important;\n}\n\n.u-float-right {\n    float: right !important;\n}\n\n// Horizontal Text\n// ==========================================================================\n\n.u-text-center {\n    text-align: center !important;\n}\n\n.u-text-left {\n    text-align: left !important;\n}\n\n.u-text-right {\n    text-align: right !important;\n}\n\n// Vertical Text\n// ==========================================================================\n\n.u-align-baseline {\n    vertical-align: baseline !important;\n}\n\n.u-align-bottom {\n    vertical-align: bottom !important;\n}\n\n.u-align-middle {\n    vertical-align: middle !important;\n}\n\n.u-align-top {\n    vertical-align: top !important;\n}\n\n.u-vertical-center {\n    @include o-vertical-center;\n}\n"
  },
  {
    "path": "packages/landing/assets/styles/utilities/_grid-column.scss",
    "content": "// ==========================================================================\n// Tools / Grid Columns\n// ==========================================================================\n\n\n@use \"../core\" as *;\n//\n// Grid layout system.\n//\n// This tool generates columns for all needed media queries.\n// Unused classes will be purge by the css post-processor.\n//\n\n$colsMax: $base-column-nb + 1;\n\n@each $breakpoint, $mediaquery in $breakpoints {\n    @for $fromIndex from 1 through $colsMax {\n        @for $toIndex from 1 through $colsMax {\n\n            // Columns without media query\n            @if $breakpoint == \"tiny\" {\n                .u-gc-#{$fromIndex}\\/#{$toIndex} {\n                    --gc-start: #{$fromIndex};\n                    --gc-end: #{$toIndex};\n                }\n            }\n\n            // Columns min-width breakpoints `@from-*`\n            .u-gc-#{$fromIndex}\\/#{$toIndex}\\@from-#{$breakpoint} {\n                @media #{mq-min($breakpoint)} {\n                    --gc-start: #{$fromIndex};\n                    --gc-end: #{$toIndex};\n                }\n            }\n\n            // Columns max-width breakpoints @to-*`\n            .u-gc-#{$fromIndex}\\/#{$toIndex}\\@to-#{$breakpoint} {\n                @media #{mq-max($breakpoint)} {\n                    --gc-start: #{$fromIndex};\n                    --gc-end: #{$toIndex};\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "packages/landing/assets/styles/utilities/_helpers.scss",
    "content": "// ==========================================================================\n// Utilities / Helpers\n// ==========================================================================\n\n// Layout\n// ==========================================================================\n\n@use '../core' as *;\n.u-relative {\n    position: relative;\n}\n\n.u-clipped {\n    clip-path: polygon(0% 0, 100% 00%, 100% 100%, 0 100%);\n}\n\n.u-max {\n    &-w300 {\n        max-width: rem(300px);\n    }\n    &-w440 {\n        max-width: rem(440px);\n    }\n}\n\n.u-glyph {\n    font-family: ff('serif');\n    font-feature-settings: 'dlig' on, 'ss01' on, 'salt' on;\n    font-weight: $font-weight-regular;\n}\n\n.u-hover-underline {\n    position: relative;\n\n    @media (hover: hover) {\n        &::before {\n            content: '';\n            position: absolute;\n            bottom: -0.1em;\n            left: 0;\n            width: 100%;\n            height: 1px;\n            background-color: currentColor;\n            transform: scale3d(0, 1, 1);\n            transition: transform t(fast) ease('power3.out');\n            transform-origin: top right;\n        }\n\n        &:hover,\n        .u-hover:hover & {\n            &::before {\n                transform: scale3d(1, 1, 1);\n                transform-origin: top left;\n            }\n        }\n    }\n}\n\n// Completely remove from the flow but leave available to screen readers.\n.u-screen-reader-text {\n    @include u-accessibly-hidden;\n}\n\n@media not print {\n    .u-screen-reader-text\\@screen {\n        @include u-accessibly-hidden;\n    }\n}\n\n// Extends the `.screen-reader-text` class to allow the element\n// to be focusable when navigated to via the keyboard.\n//\n// @link https://www.drupal.org/node/897638\n// @todo Define styles when focused.\n\n.u-screen-reader-text.-focusable {\n    @include u-accessibly-focusable;\n}\n\n.u-external-icon {\n    font-size: 0.85em;\n}\n\n.u-text-balance {\n    text-wrap: balance;\n}\n\n.u-hidden-md {\n    @media (max-width: $to-medium) {\n        display: none;\n    }\n}\n"
  },
  {
    "path": "packages/landing/assets/styles/utilities/_print.scss",
    "content": "// ==========================================================================\n// Utilities / Print Mode\n// ==========================================================================\n\n////\n/// Very crude, reset-like styles taken from the HTML5 Boilerplate:\n/// - https://github.com/h5bp/html5-boilerplate/blob/5.3.0/dist/doc/css.md#print-styles\n/// - https://github.com/h5bp/html5-boilerplate/blob/master/dist/css/main.css#L205-L282\n///\n/// @link https://github.com/inuitcss/inuitcss/blob/c27993f/utilities/_utilities.print.scss\n////\n\n@media print {\n\n    // 1. Black prints faster: http://www.sanbeiji.com/archives/953\n\n    *,\n    *:before,\n    *:after,\n    *:first-letter,\n    *:first-line {\n        background: transparent !important;\n        box-shadow: none !important;\n        color: #000000 !important; // [1]\n        text-shadow: none !important;\n    }\n\n    a,\n    a:visited {\n        text-decoration: underline;\n    }\n\n    a[href]:after {\n        content: \" (\" attr(href) \")\";\n    }\n\n    abbr[title]:after {\n        content: \" (\" attr(title) \")\";\n    }\n\n    // Don't show links that are fragment identifiers, or use the `javascript:`\n    // pseudo protocol.\n\n    a[href^=\"#\"]:after,\n    a[href^=\"javascript:\"]:after {\n        content: \"\";\n    }\n\n    pre,\n    blockquote {\n        border: 1px solid #999999;\n        page-break-inside: avoid;\n    }\n\n    // Printing Tables: http://css-discuss.incutio.com/wiki/Printing_Tables\n\n    thead {\n        display: table-header-group;\n    }\n\n    tr,\n    img {\n        page-break-inside: avoid;\n    }\n\n\n    img {\n        max-width: 100% !important;\n    }\n\n    p,\n    h2,\n    h3 {\n        orphans: 3;\n        widows: 3;\n    }\n\n    h2,\n    h3 {\n        page-break-after: avoid;\n    }\n}\n"
  },
  {
    "path": "packages/landing/assets/styles/utilities/_ratio.scss",
    "content": "// ==========================================================================\n// Utilities / Ratio\n// ==========================================================================\n@use \"sass:meta\";\n\n// @link https://github.com/inuitcss/inuitcss/blob/19d0c7e/objects/_objects.ratio.scss\n\n// A list of aspect ratios that get generated as modifier classes.\n$aspect-ratios: (\n    (2:1),\n    (4:3),\n    (16:9),\n) !default;\n\n/* stylelint-disable */\n\n// Generate a series of ratio classes to be used like so:\n//\n// @example\n//   <div class=\"o-ratio u-16:9\">\n\n@each $ratio in $aspect-ratios {\n    @each $antecedent, $consequent in $ratio {\n        @if (meta.type-of($antecedent) != number) {\n            @error \"`#{$antecedent}` needs to be a number.\"\n        }\n\n        @if (meta.type-of($consequent) != number) {\n            @error \"`#{$consequent}` needs to be a number.\"\n        }\n\n        .u-#{$antecedent}\\:#{$consequent}::before {\n            padding-bottom: math.div($consequent, $antecedent) * 100%;\n        }\n    }\n}\n\n/* stylelint-enable */\n"
  },
  {
    "path": "packages/landing/assets/styles/utilities/_spacing.scss",
    "content": "// ==========================================================================\n// Utilities / Spacing\n// ==========================================================================\n\n@use \"../core\" as *;\n@use \"sass:list\";\n\n////\n/// Utility classes to put specific spacing values onto elements. The below loop\n/// will generate us a suite of classes like:\n///\n/// @example\n///   .u-margin-top {}\n///   .u-padding-left-large {}\n///   .u-margin-right-small {}\n///   .u-padding {}\n///   .u-padding-right-none {}\n///   .u-padding-horizontal {}\n///   .u-padding-vertical-small {}\n///\n/// @link https://github.com/inuitcss/inuitcss/blob/512977a/utilities/_utilities.spacing.scss\n////\n\n/* stylelint-disable string-quotes */\n\n$spacing-directions: (\n    null:          null,\n    '-top':        '-top',\n    '-right':      '-right',\n    '-bottom':     '-bottom',\n    '-left':       '-left',\n    '-x':          '-left' '-right',\n    '-y':          '-top'  '-bottom',\n) !default;\n\n$spacing-properties: (\n    'padding': 'padding',\n    'margin':  'margin',\n) !default;\n\n$spacing-sizes: list.join($spacers, (\n    null:       var(--grid-gutter),\n    'none':    0\n));\n\n@each $breakpoint, $mediaquery in $breakpoints {\n    @each $property-namespace, $property in $spacing-properties {\n        @each $direction-namespace, $directions in $spacing-directions {\n            @each $size-namespace, $size in $spacing-sizes {\n\n                // Prepend \"-\" to spacing sizes if not null\n                @if ($size-namespace != null) {\n                    $size-namespace: \"-\" + $size-namespace;\n                }\n\n                // Base class\n                $base-class: \".u-\" + #{$property-namespace}#{$direction-namespace}#{$size-namespace};\n\n                // Spacer without media query\n                @if $breakpoint == \"tiny\" {\n                    #{$base-class} {\n                        @each $direction in $directions {\n                            #{$property}#{$direction}: $size !important;\n                        }\n                    }\n                }\n\n                // Spacer min-width breakpoints `@from-*`\n                #{$base-class}\\@from-#{$breakpoint} {\n                    @media #{mq-min($breakpoint)} {\n                        @each $direction in $directions {\n                            #{$property}#{$direction}: $size !important;\n                        }\n                    }\n                }\n\n                // Spacer max-width breakpoints @to-*`\n                #{$base-class}\\@to-#{$breakpoint} {\n                    @media #{mq-max($breakpoint)} {\n                        @each $direction in $directions {\n                            #{$property}#{$direction}: $size !important;\n                        }\n                    }\n                }\n            }\n        }\n    }\n}\n\n/* stylelint-enable string-quotes */\n"
  },
  {
    "path": "packages/landing/assets/styles/utilities/_states.scss",
    "content": "// ==========================================================================\n// Utilities / States\n// ==========================================================================\n\n// ARIA roles display visual cursor hints\n\n[aria-busy=\"true\"] {\n    cursor: progress;\n}\n\n[aria-controls] {\n    cursor: pointer;\n}\n\n[aria-disabled] {\n    cursor: default;\n}\n\n// Control visibility without affecting flow.\n\n.is-visible {\n    visibility: visible !important;\n    opacity: 1 !important;\n}\n\n.is-invisible {\n    visibility: hidden !important;\n    opacity: 0 !important;\n}\n\n// Completely remove from the flow and screen readers.\n\n.is-hidden {\n    @include u-hidden;\n}\n\n@media not print {\n    .is-hidden\\@screen {\n        @include u-hidden;\n    }\n}\n\n@media print {\n    .is-hidden\\@print {\n        @include u-hidden;\n    }\n}\n\n// .is-hidden\\@to-large {\n//     @media (max-width: $to-large) {\n//         display: none;\n//     }\n// }\n//\n// .is-hidden\\@from-large {\n//     @media (min-width: $from-large) {\n//         display: none;\n//     }\n// }\n\n// // Display a hidden-by-default element.\n//\n// .is-shown {\n//     @include u-shown;\n// }\n//\n// table.is-shown {\n//     display: table !important;\n// }\n//\n// tr.is-shown {\n//     display: table-row !important;\n// }\n//\n// td.is-shown,\n// th.is-shown {\n//     display: table-cell !important;\n// }\n"
  },
  {
    "path": "packages/landing/assets/styles/utilities/_theme.scss",
    "content": "// ==========================================================================\n// Utilities / Theme\n// ==========================================================================\n\n\n@use \"../core\" as *;\n:root {\n    --color-text: #{color(blue)};\n    --color-background: #{color(white)};\n}\n\n[data-theme=\"white\"] {\n    color: var(--color-text);\n    background-color: var(--color-background);\n}\n\n[data-theme=\"blue\"] {\n    --color-text: #{color(white)};\n    --color-background: #{color(blue)};\n\n    color: var(--color-text);\n    background-color: var(--color-background);\n}\n\n[data-theme=\"black\"] {\n    --color-text: #{color(white)};\n    --color-background: #{color(black)};\n\n    color: var(--color-text);\n    background-color: var(--color-background);\n}\n"
  },
  {
    "path": "packages/landing/assets/styles/utilities/_widths.scss",
    "content": "// ==========================================================================\n// Utilities / Widths\n// ==========================================================================\n\n////\n/// @link https://github.com/inuitcss/inuitcss/blob/6eb574f/utilities/_utilities.widths.scss\n///\n///\n/// Which fractions would you like in your grid system(s)?\n/// By default, the boilerplate provides fractions of one whole, halves, thirds,\n/// quarters, and fifths, e.g.:\n///\n/// @example css\n///   .u-1/2\n///   .u-2/5\n///   .u-3/4\n///   .u-2/3\n////\n\n$widths-fractions: 1 2 3 4 5 !default;\n\n@include widths($widths-fractions);\n\n.u-1\\/2\\@from-small {\n    @media (min-width: $from-small) {\n        width: span(1/2);\n    }\n}\n"
  },
  {
    "path": "packages/landing/assets/styles/vendors/.gitkeep",
    "content": ""
  },
  {
    "path": "packages/landing/assets.json",
    "content": "{\n    \"version\": 1767911710101\n}"
  },
  {
    "path": "packages/landing/build/build.js",
    "content": "import buildEleventy from './tasks/eleventy.js';\nimport concatFiles from './tasks/concats.js';\nimport compileScripts from './tasks/scripts.js';\nimport compileStyles from './tasks/styles.js';\nimport compileSVGs from './tasks/svgs.js';\nimport bumpVersions from './tasks/versions.js';\n\nbuildEleventy();\nconcatFiles();\ncompileScripts();\ncompileStyles();\ncompileSVGs();\nbumpVersions();\n"
  },
  {
    "path": "packages/landing/build/helpers/config.js",
    "content": "/**\n * @file Provides simple user configuration options.\n */\n\nimport loconfig from '../../loconfig.json' with { type: 'json' };\nimport { merge } from '../utils/index.js';\n\nlet usrconfig;\n\ntry {\n    usrconfig = await import('../../loconfig.local.json', {\n        with: { type: 'json' },\n    });\n    usrconfig = usrconfig.default;\n\n    merge(loconfig, usrconfig);\n} catch (err) {\n    // do nothing\n}\n\nexport default loconfig;\n\nexport {\n    loconfig,\n};\n"
  },
  {
    "path": "packages/landing/build/helpers/glob.js",
    "content": "/**\n * @file Retrieve the first available glob library.\n *\n * Note that options vary between libraries.\n *\n * Candidates:\n *\n * - {@link https://npmjs.com/package/tiny-glob tiny-glob} [1][5][6]\n * - {@link https://npmjs.com/package/globby globby} [2][5]\n * - {@link https://npmjs.com/package/fast-glob fast-glob} [3]\n * - {@link https://npmjs.com/package/glob glob} [1][4][5]\n *\n * Notes:\n *\n * - [1] The library's function accepts only a single pattern.\n * - [2] The library's function accepts only an array of patterns.\n * - [3] The library's function accepts either a single pattern\n *       or an array of patterns.\n * - [4] The library's function does not return a Promise but will be\n *       wrapped in a function that does return a Promise.\n * - [5] The library's function will be wrapped in a function that\n *       supports a single pattern and an array of patterns.\n * - [6] The library's function returns files and directories but will be\n *       preconfigured to return only files.\n */\n\nimport { promisify } from 'node:util';\n\n/**\n * @callback GlobFn\n *\n * @param {string|string[]} patterns - A string pattern\n *     or an array of string patterns.\n * @param {object}          options\n *\n * @returns {Promise<string[]>}\n */\n\n/**\n * @typedef {object} GlobOptions\n */\n\n/**\n * @type {GlobFn|undefined} The discovered glob function.\n */\nlet glob;\n\n/**\n * @type {string[]} A list of packages to attempt import.\n */\nconst candidates = [\n    'tiny-glob',\n    'globby',\n    'fast-glob',\n    'glob',\n];\n\ntry {\n    glob = await importGlob();\n} catch (err) {\n    // do nothing\n}\n\n/**\n * @type {boolean} Whether a glob function was discovered (TRUE) or not (FALSE).\n */\nconst supportsGlob = (typeof glob === 'function');\n\n/**\n * Imports the first available glob function.\n *\n * @throws {TypeError} If no glob library was found.\n *\n * @returns {GlobFn}\n */\nasync function importGlob() {\n    for (let name of candidates) {\n        try {\n            let globModule = await import(name);\n\n            if (typeof globModule.default !== 'function') {\n                throw new TypeError(`Expected ${name} to be a function`);\n            }\n\n            /**\n             * Wrap the function to ensure\n             * a common pattern.\n             */\n            switch (name) {\n                case 'tiny-glob':\n                    /** [1][5] */\n                    return createArrayableGlob(\n                        /** [6] */\n                        createPresetGlob(globModule.default, {\n                            filesOnly: true\n                        })\n                    );\n\n                case 'globby':\n                    /** [2][5] - If `patterns` is a string, wraps into an array. */\n                    return (patterns, options) => globModule.default([].concat(patterns), options);\n\n                case 'glob':\n                    /** [1][5] */\n                    return createArrayableGlob(\n                        /** [4] */\n                        promisify(globModule.default)\n                    );\n\n                default:\n                    return globModule.default;\n            }\n        } catch (err) {\n            // swallow this error; skip to the next candidate.\n        }\n    }\n\n    throw new TypeError(\n        `No glob library was found, expected one of: ${candidates.join(', ')}`\n    );\n}\n\n/**\n * Creates a wrapper function for the glob function\n * to provide support for arrays of patterns.\n *\n * @param {function} globFn - The glob function.\n *\n * @returns {GlobFn}\n */\nfunction createArrayableGlob(globFn) {\n    return (patterns, options) => {\n        /** [2] If `patterns` is a string, wraps into an array. */\n        patterns = [].concat(patterns);\n\n        const globs = patterns.map((pattern) => globFn(pattern, options));\n\n        return Promise.all(globs).then((files) => {\n            return [].concat.apply([], files);\n        });\n    };\n}\n\n/**\n * Creates a wrapper function for the glob function\n * to define new default options.\n *\n * @param {function}    globFn  - The glob function.\n * @param {GlobOptions} presets - The glob function options to preset.\n *\n * @returns {GlobFn}\n */\nfunction createPresetGlob(globFn, presets) {\n    return (patterns, options) => globFn(patterns, Object.assign({}, presets, options));\n}\n\nexport default glob;\n\nexport {\n    glob,\n    supportsGlob,\n};\n"
  },
  {
    "path": "packages/landing/build/helpers/message.js",
    "content": "/**\n * @file Provides a decorator for console messages.\n */\n\nimport kleur from 'kleur';\n\n/**\n * Outputs a message to the console.\n *\n * @param {string} text      - The message to output.\n * @param {string} [type]    - The type of message.\n * @param {string} [timerID] - The console time label to output.\n */\nfunction message(text, type, timerID) {\n    switch (type) {\n        case 'success':\n            console.log('✅ ', kleur.bgGreen().black(text));\n            break;\n\n        case 'chore':\n            console.log('🧹 ', kleur.bgGreen().black(text));\n            break;\n\n        case 'notice':\n            console.log('ℹ️  ', kleur.bgBlue().black(text));\n            break;\n\n        case 'error':\n            console.log('❌ ', kleur.bgRed().black(text));\n            break;\n\n        case 'warning':\n            console.log('⚠️  ', kleur.bgYellow().black(text));\n            break;\n\n        case 'waiting':\n            console.log('⏱ ', kleur.blue().italic(text));\n\n            if (timerID != null) {\n                console.timeLog(timerID);\n                timerID = null;\n            }\n            break;\n\n        default:\n            console.log(text);\n            break;\n    }\n\n    if (timerID != null) {\n        console.timeEnd(timerID);\n    }\n\n    console.log('');\n}\n\nexport default message;\n\nexport {\n    message,\n};\n"
  },
  {
    "path": "packages/landing/build/helpers/notification.js",
    "content": "/**\n * @file Provides a decorator for cross-platform notification.\n */\n\nimport notifier from 'node-notifier';\n\n/**\n * Sends a cross-platform native notification.\n *\n * Wraps around node-notifier to assign default values.\n *\n * @param  {string|object} options         - The notification options or a message.\n * @param  {string}        options.title   - The notification title.\n * @param  {string}        options.message - The notification message.\n * @param  {string}        options.icon    - The notification icon.\n * @param  {function}      callback        - The notification callback.\n * @return {void}\n */\nfunction notification(options, callback) {\n    if (typeof options === 'string') {\n        options = {\n            message: options\n        };\n    } else if (!options.title && !options.message) {\n        throw new TypeError(\n            'Notification expects at least a \\'message\\' parameter'\n        );\n    }\n\n    if (typeof options.icon === 'undefined') {\n        options.icon = 'https://user-images.githubusercontent.com/4596862/54868065-c2aea200-4d5e-11e9-9ce3-e0013c15f48c.png';\n    }\n\n    // If notification does not use a callback,\n    // shorten the wait before timing out.\n    if (typeof callback === 'undefined') {\n        if (typeof options.wait === 'undefined') {\n            if (typeof options.timeout === 'undefined') {\n                options.timeout = 5;\n            }\n        }\n    }\n\n    notifier.notify(options, callback);\n}\n\nexport default notification;\n\nexport {\n    notification,\n};\n"
  },
  {
    "path": "packages/landing/build/helpers/postcss.js",
    "content": "/**\n * @file If available, returns the PostCSS Processor creator and\n * any the Autoprefixer PostCSS plugin.\n */\n\n/**\n * @typedef {import('autoprefixer').autoprefixer.Options} AutoprefixerOptions\n */\n\n/**\n * @typedef {import('postcss').AcceptedPlugin} AcceptedPlugin\n */\n\n/**\n * @typedef {import('postcss').Postcss} Postcss\n */\n\n/**\n * @typedef {import('postcss').ProcessOptions} ProcessOptions\n */\n\n/**\n * @typedef {import('postcss').Processor} Processor\n */\n\n/**\n * @typedef {AcceptedPlugin[]} PluginList\n */\n\n/**\n * @typedef {object<string, AcceptedPlugin>} PluginMap\n */\n\n/**\n * @typedef {PluginList|PluginMap} PluginCollection\n */\n\n/**\n * @typedef {object} PostCSSOptions\n *\n * @property {ProcessOptions}      processor    - The `Processor#process()` options.\n * @property {AutoprefixerOptions} autoprefixer - The `autoprefixer()` options.\n */\n\n/**\n * @type {Postcss|undefined}        postcss      - The discovered PostCSS function.\n * @type {AcceptedPlugin|undefined} autoprefixer - The discovered Autoprefixer function.\n */\nlet postcss, autoprefixer;\n\ntry {\n    postcss = await import('postcss');\n    postcss = postcss.default;\n\n    autoprefixer = await import('autoprefixer');\n    autoprefixer = autoprefixer.default;\n} catch (err) {\n    // do nothing\n}\n\n/**\n * @type {boolean} Whether PostCSS was discovered (TRUE) or not (FALSE).\n */\nconst supportsPostCSS = (typeof postcss === 'function');\n\n/**\n * @type {PluginList} A list of supported plugins.\n */\nconst pluginsList = [\n    autoprefixer,\n];\n\n/**\n * @type {PluginMap} A map of supported plugins.\n */\nconst pluginsMap = {\n    'autoprefixer': autoprefixer,\n};\n\n/**\n * Attempts to create a PostCSS Processor with the given plugins and options.\n *\n * @param {PluginCollection} pluginsListOrMap - A list or map of plugins.\n *     If a map of plugins, the plugin name looks up `options`.\n * @param {PostCSSOptions}   options - The PostCSS wrapper options.\n *\n * @returns {Processor|null}\n */\nfunction createProcessor(pluginsListOrMap, options)\n{\n    if (!postcss) {\n        return null;\n    }\n\n    const plugins = parsePlugins(pluginsListOrMap, options);\n\n    return postcss(plugins);\n}\n\n/**\n * Parses the PostCSS plugins and options.\n *\n * @param {PluginCollection} pluginsListOrMap - A list or map of plugins.\n *     If a map of plugins, the plugin name looks up `options`.\n * @param {PostCSSOptions}   options - The PostCSS wrapper options.\n *\n * @returns {PluginList}\n */\nfunction parsePlugins(pluginsListOrMap, options)\n{\n    if (Array.isArray(pluginsListOrMap)) {\n        return pluginsListOrMap;\n    }\n\n    /** @type {PluginList} */\n    const plugins = [];\n\n    for (let [ name, plugin ] of Object.entries(pluginsListOrMap)) {\n        if (name in options) {\n            plugin = plugin[name](options[name]);\n        }\n\n        plugins.push(plugin);\n    }\n\n    return plugins;\n}\n\nexport default postcss;\n\nexport {\n    autoprefixer,\n    createProcessor,\n    parsePlugins,\n    pluginsList,\n    pluginsMap,\n    postcss,\n    supportsPostCSS,\n};\n"
  },
  {
    "path": "packages/landing/build/helpers/template.js",
    "content": "/**\n * @file Provides simple template tags.\n */\n\nimport loconfig from './config.js';\nimport {\n    escapeRegExp,\n    flatten\n} from '../utils/index.js';\n\nconst templateData = flatten({\n    paths: loconfig.paths\n});\n\n/**\n * Replaces all template tags from a map of keys and values.\n *\n * If replacement pairs contain a mix of substrings, regular expressions,\n * and functions, regular expressions are executed last.\n *\n * @param  {*}      input  - The value being searched and replaced on.\n *     If input is, or contains, a string, tags will be resolved.\n *     If input is, or contains, an object, it is mutated directly.\n *     If input is, or contains, an array, a shallow copy is returned.\n *     Otherwise, the value is left intact.\n * @param  {object} [data] - An object in the form `{ 'from': 'to', … }`.\n * @return {*} Returns the transformed value.\n */\nfunction resolve(input, data = templateData) {\n    switch (typeof input) {\n        case 'string': {\n            return resolveValue(input, data);\n        }\n\n        case 'object': {\n            if (input == null) {\n                break;\n            }\n\n            if (Array.isArray(input)) {\n                return input.map((value) => resolve(value, data));\n            } else {\n                for (const key in input) {\n                    input[key] = resolve(input[key], data);\n                }\n            }\n        }\n    }\n\n    return input;\n}\n\n/**\n * Replaces all template tags in a string from a map of keys and values.\n *\n * If replacement pairs contain a mix of substrings, regular expressions,\n * and functions, regular expressions are executed last.\n *\n * @param  {string} input  - The string being searched and replaced on.\n * @param  {object} [data] - An object in the form `{ 'from': 'to', … }`.\n * @return {string} Returns the translated string.\n */\nfunction resolveValue(input, data = templateData) {\n    const tags = [];\n\n    if (data !== templateData) {\n        data = flatten(data);\n    }\n\n    for (let tag in data) {\n        tags.push(escapeRegExp(tag));\n    }\n\n    if (tags.length === 0) {\n        return input;\n    }\n\n    const search = new RegExp('\\\\{%\\\\s*(' + tags.join('|') + ')\\\\s*%\\\\}', 'g');\n    return input.replace(search, (match, key) => {\n        let value = data[key];\n\n        switch (typeof value) {\n            case 'function':\n                /**\n                 * Retrieve the offset of the matched substring `args[0]`\n                 * and the whole string being examined `args[1]`.\n                 */\n                let args = Array.prototype.slice.call(arguments, -2);\n                return value.call(data, match, args[0], args[1]);\n\n            case 'string':\n            case 'number':\n                return value;\n        }\n\n        return '';\n    });\n}\n\nexport default resolve;\n\nexport {\n    resolve,\n    resolveValue,\n};\n"
  },
  {
    "path": "packages/landing/build/migrate_imports.js",
    "content": "\nimport fs from 'fs';\nimport path from 'path';\nimport { fileURLToPath } from 'url';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = path.dirname(__filename);\n\nconst files = [\n    'generic/_generic.scss',\n    'generic/_media.scss',\n    'generic/_button.scss',\n    'elements/_document.scss',\n    'objects/_container.scss',\n    'objects/_icons.scss',\n    'objects/_grid.scss',\n    'components/_heading.scss',\n    'components/_text.scss',\n    'components/_button.scss',\n    'components/_form.scss',\n    'components/_header.scss',\n    'components/_hero.scss',\n    'components/_rail.scss',\n    'components/_cascade.scss',\n    'components/_section-heading.scss',\n    'components/_tool.scss',\n    'components/_features-grid.scss',\n    'components/_sticky-heading.scss',\n    'components/_list.scss',\n    'components/_footer.scss',\n    'components/_fadeInText.scss',\n    'components/_preloader.scss',\n    'utilities/_grid-column.scss',\n    'utilities/_theme.scss',\n    'utilities/_helpers.scss',\n    'utilities/_spacing.scss'\n];\n\nconst basePath = '/Users/arnvvd/Projects/locomotive-scroll/packages/landing/assets/styles';\n\nfiles.forEach(file => {\n    const filePath = path.join(basePath, file);\n    if (fs.existsSync(filePath)) {\n        let content = fs.readFileSync(filePath, 'utf8');\n        \n        // Check if already has @use\n        if (content.includes('@use \"../core\"')) {\n            console.log(`Skipping ${file}, already has @use`);\n            return;\n        }\n\n        // Try to find the header block\n        const headerRegex = /^(\\/\\/ =+[\\r\\n]+(?:\\/\\/.*[\\r\\n]+)*\\/\\/ =+[\\r\\n]+)/;\n        const match = content.match(headerRegex);\n\n        if (match) {\n            // Insert after header\n            const header = match[1];\n            const newContent = content.replace(header, header + '\\n@use \"../core\" as *;\\n');\n            fs.writeFileSync(filePath, newContent, 'utf8');\n            console.log(`Updated ${file}`);\n        } else {\n            // Prepend to top\n            const newContent = '@use \"../core\" as *;\\n\\n' + content;\n            fs.writeFileSync(filePath, newContent, 'utf8');\n            console.log(`Updated ${file} (prepended)`);\n        }\n    } else {\n        console.error(`File not found: ${filePath}`);\n    }\n});\n"
  },
  {
    "path": "packages/landing/build/tasks/concats.js",
    "content": "import loconfig from '../helpers/config.js';\nimport glob, { supportsGlob } from '../helpers/glob.js';\nimport message from '../helpers/message.js';\nimport notification from '../helpers/notification.js';\nimport resolve from '../helpers/template.js';\nimport { merge } from '../utils/index.js';\nimport concat from 'concat';\nimport {\n    basename,\n    normalize,\n} from 'node:path';\n\n/**\n * @const {object} defaultGlobOptions     - The default shared glob options.\n * @const {object} developmentGlobOptions - The predefined glob options for development.\n * @const {object} productionGlobOptions  - The predefined glob options for production.\n */\nexport const defaultGlobOptions = {\n};\nexport const developmentGlobOptions = Object.assign({}, defaultGlobOptions);\nexport const productionGlobOptions  = Object.assign({}, defaultGlobOptions);\n\n/**\n * @typedef  {object} ConcatOptions\n * @property {boolean} removeDuplicates - Removes duplicate paths from\n *     the array of matching files and folders.\n *     Only the first occurrence of each path is kept.\n */\n\n/**\n * @const {ConcatOptions} defaultConcatOptions     - The default shared concatenation options.\n * @const {ConcatOptions} developmentConcatOptions - The predefined concatenation options for development.\n * @const {ConcatOptions} productionConcatOptions  - The predefined concatenation options for production.\n */\nexport const defaultConcatOptions = {\n    removeDuplicates: true,\n};\nexport const developmentConcatOptions = Object.assign({}, defaultConcatOptions);\nexport const productionConcatOptions  = Object.assign({}, defaultConcatOptions);\n\n/**\n * @const {object} developmentConcatFilesArgs - The predefined `concatFiles()` options for development.\n * @const {object} productionConcatFilesArgs  - The predefined `concatFiles()` options for production.\n */\nexport const developmentConcatFilesArgs = [\n    developmentGlobOptions,\n    developmentConcatOptions,\n];\nexport const productionConcatFilesArgs  = [\n    productionGlobOptions,\n    productionConcatOptions,\n];\n\n/**\n * Concatenates groups of files.\n *\n * @todo Add support for minification.\n *\n * @async\n * @param  {object|boolean} [globOptions=null]   - Customize the glob options.\n *     If `null`, default production options are used.\n *     If `false`, the glob function will be ignored.\n * @param  {object}         [concatOptions=null] - Customize the concatenation options.\n *     If `null`, default production options are used.\n * @return {Promise}\n */\nexport default async function concatFiles(globOptions = null, concatOptions = null) {\n    if (supportsGlob) {\n        if (globOptions == null) {\n            globOptions = productionGlobOptions;\n        } else if (\n            globOptions !== false &&\n            globOptions !== developmentGlobOptions &&\n            globOptions !== productionGlobOptions\n        ) {\n            globOptions = merge({}, defaultGlobOptions, globOptions);\n        }\n    }\n\n    if (concatOptions == null) {\n        concatOptions = productionConcatOptions;\n    } else if (\n        concatOptions !== developmentConcatOptions &&\n        concatOptions !== productionConcatOptions\n    ) {\n        concatOptions = merge({}, defaultConcatOptions, concatOptions);\n    }\n\n    /**\n     * @async\n     * @param  {object}   entry          - The entrypoint to process.\n     * @param  {string[]} entry.includes - One or more paths to process.\n     * @param  {string}   entry.outfile  - The file to write to.\n     * @param  {?string}  [entry.label]  - The task label.\n     *     Defaults to the outfile name.\n     * @return {Promise}\n     */\n    loconfig.tasks.concats?.forEach(async ({\n        includes,\n        outfile,\n        label = null\n    }) => {\n        if (!label) {\n            label = basename(outfile || 'undefined');\n        }\n\n        const timeLabel = `${label} concatenated in`;\n        console.time(timeLabel);\n\n        try {\n            if (!Array.isArray(includes)) {\n                includes = [ includes ];\n            }\n\n            includes = resolve(includes);\n            outfile  = resolve(outfile);\n\n            if (supportsGlob && globOptions) {\n                includes = await glob(includes, globOptions);\n            }\n\n            if (concatOptions.removeDuplicates) {\n                includes = includes.map((path) => normalize(path));\n                includes = [ ...new Set(includes) ];\n            }\n\n            await concat(includes, outfile);\n\n            if (includes.length) {\n                message(`${label} concatenated`, 'success', timeLabel);\n            } else {\n                message(`${label} is empty`, 'notice', timeLabel);\n            }\n        } catch (err) {\n            message(`Error concatenating ${label}`, 'error');\n            message(err);\n\n            notification({\n                title:   `${label} concatenation failed 🚨`,\n                message: `${err.name}: ${err.message}`\n            });\n        }\n    });\n};\n"
  },
  {
    "path": "packages/landing/build/tasks/eleventy.js",
    "content": "import message from '../helpers/message.js';\nimport { merge } from '../utils/index.js';\nimport Eleventy from \"@11ty/eleventy\";\n\nexport const defaultEleventyOptions = {\n    production: true\n}\n\nexport const developmentEleventyOptions = {\n    production: false\n}\n\nexport const productionEleventyOptions = {\n    production: true\n}\n\nlet elev;\nexport default async function buildEleventy(eleventyOptions = null) {\n    if (eleventyOptions == null) {\n        eleventyOptions = productionEleventyOptions;\n    } else if (\n        eleventyOptions !== developmentEleventyOptions &&\n        eleventyOptions !== productionEleventyOptions\n    ) {\n        eleventyOptions = merge({}, defaultEleventyOptions, eleventyOptions);\n    }\n\n    const { production } = eleventyOptions;\n    const timeLabel = `11ty compiled in`;\n    console.time(timeLabel);\n\n    try {\n\n        if(!elev) {\n            elev = new Eleventy();\n\n            if(!production) {\n                await elev.watch();\n            }\n        }\n\n        // Disable caching to ensure a fresh build each time\n        await elev.write();\n\n        message(`11ty compiled`, 'success', timeLabel);\n    } catch(err) {\n        console.error(err)\n        message(err, 'error', timeLabel);\n    }\n}\n"
  },
  {
    "path": "packages/landing/build/tasks/scripts.js",
    "content": "import loconfig from '../helpers/config.js';\nimport message from '../helpers/message.js';\nimport notification from '../helpers/notification.js';\nimport resolve from '../helpers/template.js';\nimport { merge } from '../utils/index.js';\nimport esbuild from 'esbuild';\nimport { basename } from 'node:path';\n\n/**\n * @const {object} defaultESBuildOptions     - The default shared ESBuild options.\n * @const {object} developmentESBuildOptions - The predefined ESBuild options for development.\n * @const {object} productionESBuildOptions  - The predefined ESBuild options for production.\n */\nexport const defaultESBuildOptions = {\n    bundle: true,\n    color: true,\n    sourcemap: true,\n    target: [\n        'es2015',\n    ],\n};\nexport const developmentESBuildOptions = Object.assign({}, defaultESBuildOptions);\nexport const productionESBuildOptions  = Object.assign({}, defaultESBuildOptions, {\n    logLevel: 'warning',\n    minify: true,\n});\n\n/**\n * @const {object} developmentScriptsArgs - The predefined `compileScripts()` options for development.\n * @const {object} productionScriptsArgs  - The predefined `compileScripts()` options for production.\n */\nexport const developmentScriptsArgs = [\n    developmentESBuildOptions,\n];\nexport const productionScriptsArgs  = [\n    productionESBuildOptions,\n];\n\n/**\n * Bundles and minifies main JavaScript files.\n *\n * @async\n * @param  {object} [esBuildOptions=null] - Customize the ESBuild build API options.\n *     If `null`, default production options are used.\n * @return {Promise}\n */\nexport default async function compileScripts(esBuildOptions = null) {\n    if (esBuildOptions == null) {\n        esBuildOptions = productionESBuildOptions;\n    } else if (\n        esBuildOptions !== developmentESBuildOptions &&\n        esBuildOptions !== productionESBuildOptions\n    ) {\n        esBuildOptions = merge({}, defaultESBuildOptions, esBuildOptions);\n    }\n\n    /**\n     * @async\n     * @param  {object}   entry           - The entrypoint to process.\n     * @param  {string[]} entry.includes  - One or more paths to process.\n     * @param  {string}   [entry.outdir]  - The directory to write to.\n     * @param  {string}   [entry.outfile] - The file to write to.\n     * @param  {?string}  [entry.label]   - The task label.\n     *     Defaults to the outdir or outfile name.\n     * @throws {TypeError} If outdir and outfile are missing.\n     * @return {Promise}\n     */\n    loconfig.tasks.scripts?.forEach(async ({\n        includes,\n        outdir = '',\n        outfile = '',\n        label = null\n    }) => {\n        if (!label) {\n            label = basename(outdir || outfile || 'undefined');\n        }\n\n        const timeLabel = `${label} compiled in`;\n        console.time(timeLabel);\n\n        try {\n            if (!Array.isArray(includes)) {\n                includes = [ includes ];\n            }\n\n            includes = resolve(includes);\n\n            if (outdir) {\n                outdir = resolve(outdir);\n            } else if (outfile) {\n                outfile = resolve(outfile);\n            } else {\n                throw new TypeError(\n                    'Expected \\'outdir\\' or \\'outfile\\''\n                );\n            }\n\n            await esbuild.build(Object.assign({}, esBuildOptions, {\n                entryPoints: includes,\n                outdir,\n                outfile,\n            }));\n\n            message(`${label} compiled`, 'success', timeLabel);\n        } catch (err) {\n            // errors managments (already done in esbuild)\n            notification({\n                title:   `${label} compilation failed 🚨`,\n                message: `${err.errors[0].text} in ${err.errors[0].location.file} line ${err.errors[0].location.line}`\n            });\n        }\n    });\n};\n"
  },
  {
    "path": "packages/landing/build/tasks/styles.js",
    "content": "import loconfig from '../helpers/config.js';\nimport message from '../helpers/message.js';\nimport notification from '../helpers/notification.js';\nimport {\n    createProcessor,\n    pluginsMap as postcssPluginsMap,\n    supportsPostCSS\n} from '../helpers/postcss.js';\nimport resolve from '../helpers/template.js';\nimport { merge } from '../utils/index.js';\nimport { writeFile } from 'node:fs/promises';\nimport { basename } from 'node:path';\nimport { promisify } from 'node:util';\nimport * as sass from 'sass';\nimport { PurgeCSS } from 'purgecss';\n\nconst sassRender = promisify(sass.render);\n\nlet postcssProcessor;\n\n/**\n * @const {object} defaultSassOptions     - The default shared Sass options.\n * @const {object} developmentSassOptions - The predefined Sass options for development.\n * @const {object} productionSassOptions  - The predefined Sass options for production.\n */\nexport const defaultSassOptions = {\n    omitSourceMapUrl: true,\n    sourceMap: true,\n    sourceMapContents: true,\n};\n\nexport const developmentSassOptions = Object.assign({}, defaultSassOptions, {\n    outputStyle: 'expanded',\n});\nexport const productionSassOptions = Object.assign({}, defaultSassOptions, {\n    outputStyle: 'compressed',\n});\n\n/**\n * @const {object} defaultPostCSSOptions     - The default shared PostCSS options.\n * @const {object} developmentPostCSSOptions - The predefined PostCSS options for development.\n * @const {object} productionPostCSSOptions  - The predefined PostCSS options for production.\n */\nexport const defaultPostCSSOptions = {\n    processor: {\n        map: {\n            annotation: false,\n            inline: false,\n            sourcesContent: true,\n        },\n    },\n};\nexport const developmentPostCSSOptions = Object.assign({}, defaultPostCSSOptions);\nexport const productionPostCSSOptions  = Object.assign({}, defaultPostCSSOptions);\n\n/**\n * @const {object|boolean} developmentStylesArgs - The predefined `compileStyles()` options for development.\n * @const {object|boolean} productionStylesArgs  - The predefined `compileStyles()` options for production.\n */\nexport const developmentStylesArgs = [\n    developmentSassOptions,\n    developmentPostCSSOptions,\n    false\n];\nexport const productionStylesArgs  = [\n    productionSassOptions,\n    productionPostCSSOptions,\n    true\n];\n\n/**\n * Compiles and minifies main Sass files to CSS.\n *\n * @todo Add deep merge of `postcssOptions` to better support customization\n *     of default processor options.\n *\n * @async\n * @param  {object}         [sassOptions=null]    - Customize the Sass render API options.\n *     If `null`, default production options are used.\n * @param  {object|boolean} [postcssOptions=null] - Customize the PostCSS processor API options.\n *     If `null`, default production options are used.\n *     If `false`, PostCSS processing will be ignored.\n * @return {Promise}\n */\nexport default async function compileStyles(sassOptions = null, postcssOptions = null, purge = true) {\n    if (sassOptions == null) {\n        sassOptions = productionSassOptions;\n    } else if (\n        sassOptions !== developmentSassOptions &&\n        sassOptions !== productionSassOptions\n    ) {\n        sassOptions = merge({}, defaultSassOptions, sassOptions);\n    }\n\n    if (supportsPostCSS) {\n        if (postcssOptions == null) {\n            postcssOptions = productionPostCSSOptions;\n        } else if (\n            postcssOptions !== false &&\n            postcssOptions !== developmentPostCSSOptions &&\n            postcssOptions !== productionPostCSSOptions\n        ) {\n            postcssOptions = merge({}, defaultPostCSSOptions, postcssOptions);\n        }\n    }\n\n    /**\n     * @async\n     * @param  {object}   entry         - The entrypoint to process.\n     * @param  {string[]} entry.infile  - The file to process.\n     * @param  {string}   entry.outfile - The file to write to.\n     * @param  {?string}  [entry.label] - The task label.\n     *     Defaults to the outfile name.\n     * @return {Promise}\n     */\n    loconfig.tasks.styles?.forEach(async ({\n        infile,\n        outfile,\n        label = null\n    }) => {\n        const filestem = basename((outfile || 'undefined'), '.css');\n\n        const timeLabel = `${label || `${filestem}.css`} compiled in`;\n        console.time(timeLabel);\n\n        try {\n            infile  = resolve(infile);\n            outfile = resolve(outfile);\n\n            let result = await sassRender(Object.assign({}, sassOptions, {\n                file: infile,\n                outFile: outfile,\n            }));\n\n            if (supportsPostCSS && postcssOptions) {\n                if (typeof postcssProcessor === 'undefined') {\n                    postcssProcessor = createProcessor(\n                        postcssPluginsMap,\n                        postcssOptions\n                    );\n                }\n\n                result = await postcssProcessor.process(\n                    result.css,\n                    Object.assign({}, postcssOptions.processor, {\n                        from: outfile,\n                        to: outfile,\n                    })\n                );\n\n                if (result.warnings) {\n                    const warnings = result.warnings();\n                    if (warnings.length) {\n                        message(`Error processing ${label || `${filestem}.css`}`, 'warning');\n                        warnings.forEach((warn) => {\n                            message(warn.toString());\n                        });\n                    }\n                }\n            }\n\n            try {\n                await writeFile(outfile, result.css).then(() => {\n                    // Purge CSS once file exists.\n                    if (outfile && purge) {\n                        purgeUnusedCSS(outfile, `${label || `${filestem}.css`}`);\n                    }\n                });\n\n                if (result.css) {\n                    message(`${label || `${filestem}.css`} compiled`, 'success', timeLabel);\n                } else {\n                    message(`${label || `${filestem}.css`} is empty`, 'notice', timeLabel);\n                }\n            } catch (err) {\n                message(`Error compiling ${label || `${filestem}.css`}`, 'error');\n                message(err);\n\n                notification({\n                    title:   `${label || `${filestem}.css`} save failed 🚨`,\n                    message: `Could not save stylesheet to ${label || `${filestem}.css`}`\n                });\n            }\n\n            if (result.map) {\n                try {\n                    await writeFile(outfile + '.map', result.map.toString());\n                } catch (err) {\n                    message(`Error compiling ${label || `${filestem}.css.map`}`, 'error');\n                    message(err);\n\n                    notification({\n                        title:   `${label || `${filestem}.css.map`} save failed 🚨`,\n                        message: `Could not save sourcemap to ${label || `${filestem}.css.map`}`\n                    });\n                }\n            }\n        } catch (err) {\n            message(`Error compiling ${label || `${filestem}.scss`}`, 'error');\n            message(err.formatted || err);\n\n            notification({\n                title:   `${label || `${filestem}.scss`} compilation failed 🚨`,\n                message: (err.formatted || `${err.name}: ${err.message}`)\n            });\n        }\n    });\n};\n\n/**\n * Purge unused styles from CSS files.\n *\n * @async\n *\n * @param  {string} outfile - The path of a css file\n *      If missing the function stops.\n * @param  {string} label   - The CSS file label or name.\n * @return {Promise}\n */\nasync function purgeUnusedCSS(outfile, label) {\n    const contentFiles = loconfig.tasks.purgeCSS?.content;\n    if (!Array.isArray(contentFiles) || !contentFiles.length) {\n        return;\n    }\n\n    label = label ?? basename(outfile);\n\n    const timeLabel = `${label} purged in`;\n    console.time(timeLabel);\n\n    const purgeCSSResults = await (new PurgeCSS()).purge({\n        content: contentFiles,\n        css: [ outfile ],\n        defaultExtractor: content => content.match(/[a-z0-9_\\-\\\\\\/\\@]+/gi) || [],\n        fontFaces: true,\n        keyframes: true,\n        safelist: {\n            // Keep all except .u-gc-* | .u-margin-* | .u-padding-*\n            standard: [ /^(?!.*\\b(u-gc-|u-margin|u-padding)).*$/ ],\n            // Preserve CSS variables and their content in these selectors\n            deep: [ /fadeInText/ ]\n        },\n        // Disable variable purging to preserve all CSS custom properties\n        variables: false,\n    })\n\n    for (let result of purgeCSSResults) {\n        await writeFile(outfile, result.css)\n\n        message(`${label} purged`, 'chore', timeLabel);\n    }\n}\n"
  },
  {
    "path": "packages/landing/build/tasks/svgs.js",
    "content": "import loconfig from '../helpers/config.js';\nimport message from '../helpers/message.js';\nimport notification from '../helpers/notification.js';\nimport resolve from '../helpers/template.js';\nimport { merge } from '../utils/index.js';\nimport { basename } from 'node:path';\nimport mixer from 'svg-mixer';\n\n/**\n * @const {object} defaultMixerOptions     - The default shared Mixer options.\n * @const {object} developmentMixerOptions - The predefined Mixer options for development.\n * @const {object} productionMixerOptions  - The predefined Mixer options for production.\n */\nexport const defaultMixerOptions = {\n    spriteConfig: {\n        usages: false,\n    },\n};\nexport const developmentMixerOptions = Object.assign({}, defaultMixerOptions);\nexport const productionMixerOptions  = Object.assign({}, defaultMixerOptions);\n\n/**\n * @const {object} developmentSVGsArgs - The predefined `compileSVGs()` options for development.\n * @const {object} productionSVGsArgs  - The predefined `compileSVGs()` options for production.\n */\nexport const developmentSVGsArgs = [\n    developmentMixerOptions,\n];\nexport const productionSVGsArgs  = [\n    productionMixerOptions,\n];\n\n/**\n * Generates and transforms SVG spritesheets.\n *\n * @async\n * @param  {object} [mixerOptions=null] - Customize the Mixer API options.\n *     If `null`, default production options are used.\n * @return {Promise}\n */\nexport default async function compileSVGs(mixerOptions = null) {\n    if (mixerOptions == null) {\n        mixerOptions = productionMixerOptions;\n    } else if (\n        mixerOptions !== developmentMixerOptions &&\n        mixerOptions !== productionMixerOptions\n    ) {\n        mixerOptions = merge({}, defaultMixerOptions, mixerOptions);\n    }\n\n    /**\n     * @async\n     * @param  {object}   entry          - The entrypoint to process.\n     * @param  {string[]} entry.includes - One or more paths to process.\n     * @param  {string}   entry.outfile  - The file to write to.\n     * @param  {?string}  [entry.label]  - The task label.\n     *     Defaults to the outfile name.\n     * @return {Promise}\n     */\n    loconfig.tasks.svgs?.forEach(async ({\n        includes,\n        outfile,\n        label = null\n    }) => {\n        if (!label) {\n            label = basename(outfile || 'undefined');\n        }\n\n        const timeLabel = `${label} compiled in`;\n        console.time(timeLabel);\n\n        try {\n            if (!Array.isArray(includes)) {\n                includes = [ includes ];\n            }\n\n            includes = resolve(includes);\n            outfile  = resolve(outfile);\n\n            const result = await mixer(includes, mixerOptions);\n\n            await result.write(outfile);\n\n            message(`${label} compiled`, 'success', timeLabel);\n        } catch (err) {\n            message(`Error compiling ${label}`, 'error');\n            message(err);\n\n            notification({\n                title:   `${label} compilation failed 🚨`,\n                message: `${err.name}: ${err.message}`\n            });\n        }\n    });\n};\n"
  },
  {
    "path": "packages/landing/build/tasks/versions.js",
    "content": "import loconfig from '../helpers/config.js';\nimport message from '../helpers/message.js';\nimport resolve from '../helpers/template.js';\nimport { merge } from '../utils/index.js';\nimport { randomBytes } from 'node:crypto';\nimport events from 'node:events';\nimport {\n    createReadStream,\n    createWriteStream,\n} from 'node:fs';\nimport {\n    mkdir,\n    rename,\n    rm,\n    readFile,\n    writeFile,\n} from 'node:fs/promises';\nimport {\n    basename,\n    dirname,\n} from 'node:path';\nimport readline from 'node:readline';\n\nexport const REGEXP_SEMVER = /^(?<major>0|[1-9]\\d*)\\.(?<minor>0|[1-9]\\d*)\\.(?<patch>0|[1-9]\\d*)(?:-(?<prerelease>(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\+(?<buildmetadata>[0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*))?$/;\n\n/**\n * @typedef  {object} VersionOptions\n * @property {string|number|null} prettyPrint   - A string or number to insert\n *     white space into the output JSON string for readability purposes.\n * @property {string}             versionFormat - The version number format.\n * @property {string|RegExp}      versionKey    - Either:\n *     - A string representing the JSON field name assign the version number to.\n *\n *       Explicit:\n *\n *       ```json\n *       \"key\": \"json:version\"\n *       ```\n *\n *       Implicit:\n *\n *       ```json\n *       \"key\": \"version\"\n *       ```\n *\n *     - A `RegExp` object or regular expression string prefixed with `regexp:`.\n *\n *       ```json\n *       \"key\": \"regexp:(?<=^const ASSETS_VERSION = ')(?<version>\\\\d+)(?=';$)\"\n *       ```\n *\n *       ```js\n *       key: new RegExp('(?<=^const ASSETS_VERSION = ')(?<version>\\\\d+)(?=';$)')\n *       ```\n *\n *       ```js\n *       key: /(?<=^const ASSETS_VERSION = ')(?<version>\\d+)(?=';$)/\n *       ```\n */\n\n/**\n * @const {VersionOptions} defaultVersionOptions     - The default shared version options.\n * @const {VersionOptions} developmentVersionOptions - The predefined version options for development.\n * @const {VersionOptions} productionVersionOptions  - The predefined version options for production.\n */\nexport const defaultVersionOptions = {\n    prettyPrint:   4,\n    versionFormat: 'timestamp',\n    versionKey:    'version',\n};\nexport const developmentVersionOptions = Object.assign({}, defaultVersionOptions);\nexport const productionVersionOptions  = Object.assign({}, defaultVersionOptions);\n\n/**\n * @const {object} developmentVersionFilesArgs - The predefined `bumpVersion()` options for development.\n * @const {object} productionVersionFilesArgs  - The predefined `bumpVersion()` options for production.\n */\nexport const developmentVersionFilesArgs = [\n    developmentVersionOptions,\n];\nexport const productionVersionFilesArgs  = [\n    productionVersionOptions,\n];\n\n/**\n * Bumps version numbers in file.\n *\n * @async\n * @param  {object} [versionOptions=null] - Customize the version options.\n *     If `null`, default production options are used.\n * @return {Promise}\n */\nexport default async function bumpVersions(versionOptions = null) {\n    if (versionOptions == null) {\n        versionOptions = productionVersionOptions;\n    } else if (\n        versionOptions !== developmentVersionOptions &&\n        versionOptions !== productionVersionOptions\n    ) {\n        versionOptions = merge({}, defaultVersionOptions, versionOptions);\n    }\n\n    const queue = new Map();\n\n    /**\n     * @async\n     * @param  {object}         entry          - The entrypoint to process.\n     * @param  {string}         entry.outfile  - The file to write to.\n     * @param  {?string}        [entry.label]  - The task label.\n     *     Defaults to the outfile name.\n     * @param  {?string}        [entry.format] - The version number format.\n     * @param  {?string}        [entry.key]    - The JSON field name assign the version number to.\n     * @param  {?string|number} [entry.pretty] - The white space to use to format the JSON file.\n     * @return {Promise}\n     */\n    loconfig.tasks.versions?.forEach(({\n        outfile,\n        label = null,\n        ...options\n    }) => {\n        if (!label) {\n            label = basename(outfile || 'undefined');\n        }\n\n        options.pretty = (options.pretty ?? versionOptions.prettyPrint);\n        options.format = (options.format ?? versionOptions.versionFormat);\n        options.key    = (options.key ?? versionOptions.versionKey);\n\n        if (queue.has(outfile)) {\n            queue.get(outfile).then(() => handleBumpVersion(outfile, label, options));\n        } else {\n            queue.set(outfile, handleBumpVersion(outfile, label, options));\n        }\n    });\n};\n\n/**\n * Creates a formatted version number or string.\n *\n * @param  {string}  format     - The version format.\n * @param  {?string} [oldValue] - The old version value.\n * @return {string|number}\n * @throws TypeError If the format or value are invalid.\n */\nfunction createVersionNumber(format, oldValue = null) {\n    let [ type, modifier ] = format.split(':', 2);\n\n    switch (type) {\n        case 'hex':\n        case 'hexadecimal':\n            try {\n                modifier = Number.parseInt(modifier);\n\n                if (Number.isNaN(modifier)) {\n                    modifier = 6;\n                }\n\n                return randomBytes(modifier).toString('hex');\n            } catch (err) {\n                throw new TypeError(\n                    `${err.message} for \\'format\\' type \"hexadecimal\"`,\n                    { cause: err }\n                );\n            }\n\n        case 'inc':\n        case 'increment':\n            try {\n                if (modifier === 'semver') {\n                    return incrementSemVer(oldValue, [ 'buildmetadata', 'patch' ]);\n                }\n\n                return incrementNumber(oldValue, modifier);\n            } catch (err) {\n                throw new TypeError(\n                    `${err.message} for \\'format\\' type \"increment\"`,\n                    { cause: err }\n                );\n            }\n\n        case 'regex':\n        case 'regexp':\n            try {\n                return new RegExp(modifier);\n            } catch (err) {\n                throw new TypeError(\n                    `${err.message} for \\'format\\' type \"regexp\"`,\n                    { cause: err }\n                );\n            }\n\n        case 'timestamp':\n            return Date.now().valueOf();\n    }\n\n    throw new TypeError(\n        'Expected \\'format\\' to be either \"timestamp\", \"increment\", or \"hexadecimal\"'\n    );\n}\n\n/**\n * @async\n * @param  {string} outfile\n * @param  {string} label\n * @param  {object} options\n * @return {Promise}\n */\nasync function handleBumpVersion(outfile, label, options) {\n    const timeLabel = `${label} bumped in`;\n    console.time(timeLabel);\n\n    try {\n        options.key = parseVersionKey(options.key);\n\n        if (options.key instanceof RegExp) {\n            await handleBumpVersionWithRegExp(outfile, label, options);\n        } else {\n            await handleBumpVersionInJson(outfile, label, options);\n        }\n\n        message(`${label} bumped`, 'success', timeLabel);\n    } catch (err) {\n        message(`Error bumping ${label}`, 'error');\n        message(err);\n\n        notification({\n            title:   `${label} bumping failed 🚨`,\n            message: `${err.name}: ${err.message}`\n        });\n    }\n}\n\n/**\n * Changes the version number for the provided JSON key in file.\n *\n * @async\n * @param  {string} outfile\n * @param  {string} label\n * @param  {object} options\n * @param  {string} options.key\n * @return {Promise}\n */\nasync function handleBumpVersionInJson(outfile, label, options) {\n    outfile = resolve(outfile);\n\n    let json;\n\n    try {\n        json = JSON.parse(await readFile(outfile, { encoding: 'utf8' }));\n    } catch (err) {\n        json = {};\n\n        message(`${label} is a new file`, 'notice');\n\n        await mkdir(dirname(outfile), { recursive: true });\n    }\n\n    json[options.key] = createVersionNumber(options.format, json?.[options.key]);\n\n    return await writeFile(\n        outfile,\n        JSON.stringify(json, null, options.pretty),\n        { encoding: 'utf8' }\n    );\n}\n\n/**\n * Changes the version number for the provided RegExp in file.\n *\n * @async\n * @param  {string} outfile\n * @param  {string} label\n * @param  {object} options\n * @param  {RegExp} options.key\n * @return {Promise}\n */\nasync function handleBumpVersionWithRegExp(outfile, label, options) {\n    outfile = resolve(outfile);\n\n    const bckfile = `${outfile}~`;\n\n    await rename(outfile, bckfile);\n\n    try {\n        const rl = readline.createInterface({\n            input: createReadStream(bckfile),\n        });\n\n        let newVersion = null;\n\n        const writeStream = createWriteStream(outfile, { encoding: 'utf8' });\n\n        rl.on('line', (line) => {\n            const found = line.match(options.key);\n\n            if (found) {\n                const groups      = (found.groups ?? {});\n                const oldVersion  = (groups.build ?? groups.version ?? found[1] ?? found[0]);\n                const newVersion  = createVersionNumber(options.format, oldVersion);\n                const replacement = found[0].replace(oldVersion, newVersion);\n\n                line = line.replace(found[0], replacement);\n            }\n\n            writeStream.write(line + \"\\n\");\n        });\n\n        await events.once(rl, 'close');\n\n        await rm(bckfile);\n    } catch (err) {\n        await rm(outfile, { force: true });\n\n        await rename(bckfile, outfile);\n\n        throw err;\n    }\n}\n\n/**\n * Increments the given integer.\n *\n * @param  {string|int} value         - The number to increment.\n * @param  {string|int} [increment=1] - The amount to increment by.\n * @return {int}\n * @throws TypeError If the version number is invalid.\n */\nfunction incrementNumber(value, increment = 1) {\n    const version = Number.parseInt(value);\n    if (Number.isNaN(version)) {\n        throw new TypeError(\n            `Expected an integer version number, received [${value}]`\n        );\n    }\n\n    increment = Number.parseInt(increment);\n    if (Number.isNaN(increment)) {\n        throw new TypeError(\n            'Expected an integer increment number'\n        );\n    }\n\n    return (version + increment);\n}\n\n/**\n * Increments the given SemVer version number.\n *\n * @param  {string}          value     - The version to mutate.\n * @param  {string|string[]} [target]  - The segment to increment, one of:\n *     'major', 'minor', 'patch', ~~'prerelease'~~, 'buildmetadata'.\n * @param  {string|int}      [increment=1] - The amount to increment by.\n * @return {string}\n * @throws TypeError If the version or target are invalid.\n */\nfunction incrementSemVer(value, target = 'patch', increment = 1) {\n    const found = value.match(REGEXP_SEMVER);\n    if (!found) {\n        throw new TypeError(\n            `Expected a SemVer version number, received [${value}]`\n        );\n    }\n\n    if (Array.isArray(target)) {\n        for (const group of target) {\n            if (found.groups[group] != null) {\n                target = group;\n                break;\n            }\n        }\n    }\n\n    if (!target || !found.groups[target]) {\n        throw new TypeError(\n            `Expected a supported SemVer segment, received [${target}]`\n        );\n    }\n\n    const segments = {\n        'major':         '',\n        'minor':         '.',\n        'patch':         '.',\n        'prerelease':    '-',\n        'buildmetadata': '+',\n    };\n\n    let replacement = '';\n\n    for (const [ segment, delimiter ] of Object.entries(segments)) {\n        if (found.groups?.[segment] != null) {\n            const newVersion = (segment === target)\n                ? incrementNumber(found.groups[segment], increment)\n                : found.groups[segment];\n\n            replacement += `${delimiter}${newVersion}`;\n        }\n    }\n\n    return value.replace(found[0], replacement);\n}\n\n/**\n * Parses the version key.\n *\n * @param  {*} key - The version key.\n * @return {string|RegExp}\n */\nfunction parseVersionKey(key) {\n    if (key instanceof RegExp) {\n        return key;\n    }\n\n    if (typeof key !== 'string') {\n        throw new TypeError(\n            'Expected \\'key\\' to be either a string or a RegExp'\n        );\n    }\n\n    const delimiter = key.indexOf(':');\n\n    if (delimiter === -1) {\n        // Assumes its a JSON key\n        return key;\n    }\n\n    const type  = key.slice(0, delimiter);\n    const value = key.slice(delimiter + 1);\n\n    switch (type) {\n        case 'json':\n            return value;\n\n        case 'regex':\n        case 'regexp':\n            return new RegExp(value);\n    }\n\n    throw new TypeError(\n        'Expected \\'key\\' type to be either \"json\" or \"regexp\"'\n    );\n}\n"
  },
  {
    "path": "packages/landing/build/utils/index.js",
    "content": "/**\n * @file Provides generic functions and constants.\n */\n\n/**\n * @type {RegExp} - Match all special characters.\n */\nconst regexUnescaped = /[\\[\\]\\{\\}\\(\\)\\-\\*\\+\\?\\.\\,\\\\\\^\\$\\|\\#\\s]/g;\n\n/**\n * Quotes regular expression characters.\n *\n * @param  {string} str - The input string.\n * @return {string} Returns the quoted (escaped) string.\n */\nfunction escapeRegExp(str) {\n    return str.replace(regexUnescaped, '\\\\$&');\n}\n\n/**\n * Creates a new object with all nested object properties\n * concatenated into it recursively.\n *\n * Nested keys are flattened into a property path:\n *\n * ```js\n * {\n *   a: {\n *     b: {\n *       c: 1\n *     }\n *   },\n *   d: 1\n * }\n * ```\n *\n * ```js\n * {\n *   \"a.b.c\": 1,\n *   \"d\": 1\n * }\n * ```\n *\n * @param  {object} input  - The object to flatten.\n * @param  {string} prefix - The parent key prefix.\n * @param  {object} target - The object that will receive the flattened properties.\n * @return {object} Returns the `target` object.\n */\nfunction flatten(input, prefix, target = {}) {\n    for (const key in input) {\n        const field = (prefix ? prefix + '.' + key : key);\n\n        if (isObjectLike(input[key])) {\n            flatten(input[key], field, target);\n        } else {\n            target[field] = input[key];\n        }\n    }\n\n    return target;\n}\n\n/**\n * Determines whether the passed value is an `Object`.\n *\n * @param  {*} value - The value to be checked.\n * @return {boolean} Returns `true` if the value is an `Object`,\n *     otherwise `false`.\n */\nfunction isObjectLike(value) {\n    return (value != null && typeof value === 'object');\n}\n\n/**\n * Creates a new object with all nested object properties\n * merged into it recursively.\n *\n * @param  {object}   target     - The target object.\n * @param  {object[]} ...sources - The source object(s).\n * @throws {TypeError} If the target and source are the same.\n * @return {object} Returns the `target` object.\n */\nfunction merge(target, ...sources) {\n    for (const source of sources) {\n        if (target === source) {\n            throw new TypeError(\n                'Cannot merge, target and source are the same'\n            );\n        }\n\n        for (const key in source) {\n            if (source[key] != null) {\n                if (isObjectLike(source[key]) && isObjectLike(target[key])) {\n                    merge(target[key], source[key]);\n                    continue;\n                } else if (Array.isArray(source[key]) && Array.isArray(target[key])) {\n                    target[key] = target[key].concat(source[key]);\n                    continue;\n                }\n            }\n\n            target[key] = source[key];\n        }\n    }\n\n    return target;\n}\n\nexport {\n    escapeRegExp,\n    flatten,\n    isObjectLike,\n    merge,\n    regexUnescaped,\n};\n"
  },
  {
    "path": "packages/landing/build/watch.js",
    "content": "import concatFiles, { developmentConcatFilesArgs } from './tasks/concats.js';\nimport compileScripts, { developmentScriptsArgs } from './tasks/scripts.js';\nimport compileStyles, { developmentStylesArgs } from './tasks/styles.js' ;\nimport compileSVGs, { developmentSVGsArgs } from './tasks/svgs.js';\nimport buildEleventy, { developmentEleventyOptions } from './tasks/eleventy.js';\nimport loconfig from './helpers/config.js';\nimport message from './helpers/message.js';\nimport notification from './helpers/notification.js';\nimport resolve from './helpers/template.js';\nimport { merge } from './utils/index.js';\nimport browserSync from 'browser-sync';\nimport { join } from 'node:path';\n\n// Match a URL protocol.\nconst regexUrlStartsWithProtocol = /^[a-z0-9\\-]:\\/\\//i;\n\n// Build scripts, compile styles, concat files,\n// and generate spritesheets on first hit\nconcatFiles(...developmentConcatFilesArgs);\ncompileScripts(...developmentScriptsArgs);\ncompileStyles(...developmentStylesArgs);\ncompileSVGs(...developmentSVGsArgs);\nawait buildEleventy(developmentEleventyOptions);\n\n// Create a new BrowserSync instance\nconst server = browserSync.create();\n\n// Start the BrowserSync server\nserver.init(createServerOptions(loconfig), (err) => {\n    if (err) {\n        message('Error starting development server', 'error');\n        message(err);\n\n        notification({\n            title:   'Development server failed',\n            message: `${err.name}: ${err.message}`\n        });\n    }\n});\n\nconfigureServer(server, loconfig);\n\n/**\n * Configures the BrowserSync options.\n *\n * @param  {BrowserSync} server         - The BrowserSync API.\n * @param  {object}      loconfig       - The project configset.\n * @param  {object}      loconfig.paths - The paths options.\n * @param  {object}      loconfig.tasks - The tasks options.\n * @return {void}\n */\nfunction configureServer(server, { paths, tasks }) {\n    const views = createViewsArray(paths.views);\n\n    // Reload on any changes to views or processed files\n    server.watch(\n        [\n            join(paths.dest, '**/*')\n        ]\n    ).on('change', server.reload);\n\n    // Watch source scripts\n    server.watch(\n        [\n            join(paths.scripts.src, '**/*.js'),\n        ]\n    ).on('change', () => {\n        compileScripts(...developmentScriptsArgs);\n    });\n\n    // Watch source concats\n    if (tasks.concats?.length) {\n        server.watch(\n            resolve(\n                tasks.concats.reduce(\n                    (patterns, { includes }) => patterns.concat(includes),\n                    []\n                )\n            )\n        ).on('change', () => {\n            concatFiles(...developmentConcatFilesArgs);\n        });\n    }\n\n    // Watch source styles\n    server.watch(\n        [\n            join(paths.styles.src, '**/*.scss'),\n        ]\n    ).on('change', () => {\n        compileStyles(...developmentStylesArgs);\n    });\n\n    // Watch source SVGs\n    server.watch(\n        [\n            join(paths.svgs.src, '*.svg'),\n        ]\n    ).on('change', () => {\n        compileSVGs(...developmentSVGsArgs);\n    });\n}\n\n/**\n * Creates a new object with all the BrowserSync options.\n *\n * @param  {object} loconfig        - The project configset.\n * @param  {object} loconfig.paths  - The paths options.\n * @param  {object} loconfig.server - The server options.\n * @return {object} Returns the server options.\n */\nfunction createServerOptions({\n    paths,\n    server: options\n}) {\n    const config = {\n        open: false,\n        notify: false,\n        ghostMode: false\n    };\n\n    // Resolve the URL for the BrowserSync server\n    if (isNonEmptyString(paths.url)) {\n        // Use proxy\n        config.proxy = paths.url;\n    } else if (isNonEmptyString(paths.dest)) {\n        // Use base directory\n        config.server = {\n            baseDir: paths.dest\n        };\n    }\n\n    merge(config, resolve(options));\n\n    // If HTTPS is enabled, prepend `https://` to proxy URL\n    if (options?.https) {\n        if (isNonEmptyString(config.proxy?.target)) {\n            config.proxy.target = prependSchemeToUrl(config.proxy.target, 'https');\n        } else if (isNonEmptyString(config.proxy)) {\n            config.proxy = prependSchemeToUrl(config.proxy, 'https');\n        }\n    }\n\n    return config;\n}\n\n/**\n * Creates a new array (shallow-copied) from the views configset.\n *\n * @param  {*} views - The views configset.\n * @throws {TypeError} If views is invalid.\n * @return {array} Returns the views array.\n */\nfunction createViewsArray(views) {\n    if (Array.isArray(views)) {\n        return Array.from(views);\n    }\n\n    switch (typeof views) {\n        case 'string':\n            return [ views ];\n\n        case 'object':\n            if (views != null) {\n                return Object.values(views);\n            }\n    }\n\n    throw new TypeError(\n        'Expected \\'views\\' to be a string, array, or object'\n    );\n}\n\n/**\n * Prepends the scheme to the URL.\n *\n * @param  {string} url      - The URL to mutate.\n * @param  {string} [scheme] - The URL scheme to prepend.\n * @return {string} Returns the mutated URL.\n */\nfunction prependSchemeToUrl(url, scheme = 'http') {\n    if (regexUrlStartsWithProtocol.test(url)) {\n        return url.replace(regexUrlStartsWithProtocol, `${scheme}://`);\n    }\n\n    return `${scheme}://${url}`;\n}\n\n/**\n * Determines whether the passed value is a string with at least one character.\n *\n * @param  {*} value - The value to be checked.\n * @return {boolean} Returns `true` if the value is a non-empty string,\n *     otherwise `false`.\n */\nfunction isNonEmptyString(value) {\n    return (typeof value === 'string' && value.length > 0);\n}\n"
  },
  {
    "path": "packages/landing/data/features.json",
    "content": "{\n    \"title\": \"Features\",\n    \"description\": \"Locomotive Scroll is a thin, opinionated wrapper around Lenis. You get all of Lenis's power plus our detection and animation layer.\",\n    \"scrollbar\": {\n        \"title\": \"Native scrollbar\",\n        \"description\": \"Real browser scrollbar. No fake alternatives. Accessible, performant, and familiar to users.\"\n    },\n    \"normalized\": {\n        \"title\": \"Smooth easing\",\n        \"description\": \"Configurable lerp, duration, and custom easing functions thanks to Lenis options.\"\n    },\n    \"sticky\": {\n        \"title\": \"CSS sticky\",\n        \"description\": \"Works perfectly with position: sticky. No conflicts, no workarounds.\"\n    },\n    \"intersectionObserver\": {\n        \"title\": \"Intersection Observer API\",\n        \"description\": \"Browser-native detection. No polling, no performance hits, just efficient viewport tracking.\"\n    },\n    \"scrollTo\": {\n        \"title\": \"Scroll to\",\n        \"description\": \"Programmatic scrolling to any element, selector, or pixel value via Lenis. Supports offset, duration, and custom easing.\"\n    },\n    \"direction\": {\n        \"title\": \"Scroll direction\",\n        \"description\": \"Track direction changes in real-time thanks to Lenis. Perfect for hiding/showing headers or reversing animations.\"\n    },\n    \"layoutShifts\": {\n        \"title\": \"No layout shifts\",\n        \"description\": \"No more greedy CSS transforms breaking your layouts. Plays nice with position: sticky, fixed headers, and existing CSS.\"\n    }\n}\n"
  },
  {
    "path": "packages/landing/data/general.json",
    "content": "{\n    \"title\": \"Locomotive Scroll\",\n    \"description\": \"A lightweight scroll library for modern web experiences. Detection, animation, and smooth scrolling — all in 9.4kB. Built on top of Lenis.\",\n    \"github\": \"https://github.com/locomotivemtl/locomotive-scroll\",\n    \"documentation\": \"https://scroll.locomotive.ca/docs\",\n    \"website\": \"https://locomotive.ca\",\n    \"version\": \"5.0\"\n}\n"
  },
  {
    "path": "packages/landing/data/metadata.json",
    "content": "{\n    \"title\": \"Locomotive Scroll — Detection of elements in viewport & smooth scrolling with parallax effects\",\n    \"description\": \"Locomotive Scroll is a lightweight JavaScript library that provides smooth scrolling animations and advanced scroll interactions for web applications.\",\n    \"ogImage\": \"https://scroll.locomotive.ca/assets/images/og-image.png\",\n    \"ogImageWidth\": \"1200\",\n    \"ogImageHeight\": \"630\",\n    \"url\": \"https://scroll.locomotive.ca\"\n}\n"
  },
  {
    "path": "packages/landing/data/perks.json",
    "content": "{\n    \"bigText\": \"Version 5 is a complete rewrite. Designed for modern workflows, built on top of Lenis, and optimized for production.\",\n    \"smallText\": \"This library has evolved considerably over the years. From jQuery to vanilla ES6, from custom engines to Lenis foundation.\",\n    \"items\": [\n        {\n            \"title\": \"Built on top of Lenis\",\n            \"description\": \"Latest stable release with improved touch handling and performance fixes. No more greedy CSS transforms!\"\n        },\n        {\n            \"title\": \"TypeScript First\",\n            \"description\": \"Fully typed. Better autocomplete, fewer bugs, happier developers.\"\n        },\n        {\n            \"title\": \"Dual Intersection Observers\",\n            \"description\": \"Separate observers for simple triggers vs. continuous animations. No wasted RAF cycles.\"\n        },\n        {\n            \"title\": \"Smart Touch Detection\",\n            \"description\": \"Parallax auto-disabled on mobile. Opt-in with one attribute.\"\n        },\n        {\n            \"title\": \"Production Ready\",\n            \"description\": \"Accessible by default. Native scrollbar, keyboard nav, and proper cleanup for SPAs.\"\n        },\n        {\n            \"title\": \"Lightweight\",\n            \"description\": \"Only 9.4kB gzipped\"\n        }\n    ]\n\n}\n"
  },
  {
    "path": "packages/landing/data/showcase.json",
    "content": "{\n    \"title\": \"Showcase\",\n    \"description\": \"Real projects built with Locomotive Scroll by leading studios and developers.\",\n    \"items\": [\n        {\n            \"title\": \"Locomotive\",\n            \"description\": \"https://locomotive.ca\",\n            \"url\": \"https://locomotive.ca\"\n        },\n        {\n            \"title\": \"Destigmatize\",\n            \"description\": \"https://2024.destigmatize.ca/\",\n            \"url\": \"https://2024.destigmatize.ca/\"\n        },\n        {\n            \"title\": \"Scout Motors\",\n            \"description\": \"https://scoutmotors.com/\",\n            \"url\": \"https://scoutmotors.com/\"\n        },\n        {\n            \"title\": \"Lightship\",\n            \"description\": \"https://lightshiprv.com/\",\n            \"url\": \"https://lightshiprv.com/\"\n        },\n        {\n            \"title\": \"Vooban\",\n            \"description\": \"https://vooban.com/\",\n            \"url\": \"https://vooban.com/\"\n        },\n        {\n            \"title\": \"Construction Desourdy\",\n            \"description\": \"https://constructiondesourdy.com/\",\n            \"url\": \"https://constructiondesourdy.com/\"\n        },\n        {\n            \"title\": \"GKC\",\n            \"description\": \"https://gkc.ca/\",\n            \"url\": \"https://gkc.ca/\"\n        },\n        {\n            \"title\": \"Troa\",\n            \"description\": \"https://www.troa.fr/\",\n            \"url\": \"https://www.troa.fr/\"\n        },\n        {\n            \"title\": \"Vazzi\",\n            \"description\": \"https://vazzi.fun/\",\n            \"url\": \"https://vazzi.fun/\"\n        },\n        {\n            \"title\": \"21TSI\",\n            \"description\": \"https://21tsi.com/\",\n            \"url\": \"https://21tsi.com/\"\n        },\n        {\n            \"title\": \"Eduard Bodak\",\n            \"description\": \"https://www.eduardbodak.com/\",\n            \"url\": \"https://www.eduardbodak.com/\"\n        },\n        {\n            \"title\": \"Mindmarket\",\n            \"description\": \"https://mindmarket.com/\",\n            \"url\": \"https://mindmarket.com/\"\n        }\n    ]\n}\n"
  },
  {
    "path": "packages/landing/data/tools.json",
    "content": "{\n    \"inview\": {\n        \"title\": \"In-view detection\",\n        \"description\": \"Add classes, trigger callbacks, or fire custom events when elements enter the viewport. Built on Intersection Observer for native performance.\"\n    },\n    \"progress\": {\n        \"title\": \"Progress tracking\",\n        \"description\": \"Get real-time scroll progress (0-1) as CSS variables or JavaScript events. Perfect for progress bars, scroll-driven animations, or custom interactions.\"\n    },\n    \"parallax\": {\n        \"title\": \"Parallax effects\",\n        \"description\": \"Create smooth parallax effects instantly with a single data-scroll-speed attribute. No complex setup, no math, just add a number and it works.\"\n    }\n}\n"
  },
  {
    "path": "packages/landing/docs/development.md",
    "content": "# Development\n\n* [Installation](#installation)\n* [Usage](#usage)\n* [Configuration](#configuration)\n  * [Environment Configuration](#environment-configuration)\n  * [Development Configuration](#development-configuration)\n    * [`paths` option](#paths-option)\n    * [`paths.url` option](#pathsurl-option)\n    * [`paths.dest` option](#pathsdest-option)\n    * [`tasks` option](#tasks-option)\n    * [`server` option](#server-option)\n* [Tasks](#tasks)\n  * [`concats`](#concats)\n  * [`scripts`](#scripts)\n  * [`styles`](#styles)\n  * [`svgs`](#svgs)\n  * [`versions`](#versions)\n\n---\n\nThe boilerplate provides a custom, easily configured, and very simple,\ntask runner for [Node] to process assets and test quickly in browsers.\n\nLearn more about the boilerplate's [tasks](#tasks) below.\n\n## Installation\n\nMake sure you have the following installed:\n\n* [Node] — at least 14.17, the latest LTS is recommended.\n* [NPM] — at least 8.0, the latest LTS is recommended.\n\n> 💡 You can use [NVM] to install and use different versions of Node via the command-line.\n\n```sh\n# Switch to recommended Node version from .nvmrc\nnvm use\n\n# Install dependencies from package.json\nnpm install\n```\n\n## Usage\n\n```sh\n# Start development server, watch for changes, and compile assets\nnpm start\n\n# Compile and minify assets\nnpm run build\n```\n\nSee [`build.js`](../build/build.js) and [`watch.js`](../build/watch.js)\nfor details.\n\n## Configuration\n\nFor development, most configuration values for processing front-end assets\nare defined in the [`loconfig.json`](../loconfig.json) file that exists at\nthe root directory of your project.\n\n### Environment Configuration\n\nIf any configuration options vary depending on whether your project is\nrunning on your computer, a collaborator's computer, or on a web server,\nthese values should be stored in a `loconfig.local.json` file.\n\nIn fresh copy of the boilerplate, the root directory of your project\nwill contain a [`loconfig.example.json`](../loconfig.example.json) file.\n\n> 💡 The boilerplate's default example customizes the development server\n> to use a custom SSL certificate.\n\nThat file can be copied to `loconfig.local.json` and customized to suit\nyour local environment.\n\nYour `loconfig.local.json` _should not_ be committed to your project's\nsource control.\n\n> 💡 If you are developing with a team, you may wish to continue\n> including a `loconfig.example.json` file with your project.\n\n### Development Configuration\n\nThe boilerplate provides a few configuration settings to control the\nbehaviour for processing front-end assets.\n\n#### `paths` option\n\nThe `paths` option defines URIs and file paths.\n\nIt is primarily used for template tags to reference any configuration\nproperties to reduce repetition.\n\nTemplate tags are specified using `{%  %}` delimiters. They will be\nautomatically expanded when tasks process paths.\n\n```jsonc\n{\n    \"paths\": {\n        \"styles\": {\n            \"src\": \"./assets/styles\",\n            \"dest\": \"./www/assets/styles\"\n        }\n    },\n    \"tasks\": {\n        \"styles\": [\n            {\n                \"infile\": \"{% paths.styles.src %}/main.scss\", // → ./assets/styles/main.scss\n                \"outfile\": \"{% paths.styles.dest %}/main.css\" // → ./www/assets/styles/main.css\n            }\n        ]\n    }\n}\n```\n\n#### `paths.url` option\n\nThe `paths.url` option defines the base URI of the project.\n\nBy default, it is used by the development server as a proxy\nfor an existing virtual host.\n\n```json\n{\n    \"paths\": {\n        \"url\": \"locomotive-boilerplate.test\"\n    }\n}\n```\n\n#### `paths.dest` option\n\nThe `paths.dest` option defines the public web directory of the project.\n\nBy default, it is used by the development server as the base directory\nto serve the website from if a proxy URI is not provided.\n\n```json\n{\n    \"paths\": {\n        \"dest\": \"./www\"\n    }\n}\n```\n\n#### `tasks` option\n\nWhich assets and how they should be processed can be configured via\nthe `tasks` option:\n\n```json\n{\n    \"tasks\": {\n        \"scripts\": [\n            {\n                \"includes\": [\n                    \"./assets/scripts/app.js\"\n                ],\n                \"outfile\": \"./www/assets/scripts/app.js\"\n            }\n        ],\n        \"styles\": [\n            {\n                \"infile\": \"./assets/styles/main.scss\",\n                \"outfile\": \"./www/assets/styles/main.css\"\n            }\n        ]\n    }\n}\n```\n\nSee [tasks](#tasks) section, below, for details.\n\n#### `server` option\n\nThe development server (BrowserSync) can be configured via\nthe `server` option:\n\n```json\n{\n    \"server\": {\n        \"open\": true,\n        \"https\": {\n            \"key\": \"~/.config/valet/Certificates/{% paths.url %}.key\",\n            \"cert\": \"~/.config/valet/Certificates/{% paths.url %}.crt\"\n        }\n    }\n}\n```\n\nVisit [BrowserSync's documentation](https://browsersync.io/docs/options)\nfor all options.\n\n## Tasks\n\nThe boilerplate provides a handful of tasks for handling\nthe most commonly processed assets.\n\n### `concats`\n\nA wrapper around [concat] (with optional support for globbing) for concatenating multiple files.\n\nBy default, [tiny-glob] is installed with the boilerplate.\n\nExample:\n\n```json\n{\n    \"concats\": [\n        {\n            \"label\": \"Application Vendors\",\n            \"includes\": [\n                \"{% paths.scripts.src %}/vendors/*.js\",\n                \"node_modules/focus-visible/dist/focus-visible.min.js\",\n                \"node_modules/vue/dist/vue.min.js\",\n                \"node_modules/vuelidate/dist/vuelidate.min.js\",\n                \"node_modules/vuelidate/dist/validators.min.js\"\n            ],\n            \"outfile\": \"{% paths.scripts.dest %}/app/vendors.js\"\n        },\n        {\n            \"label\": \"Public Site Vendors\",\n            \"includes\": [\n                \"{% paths.scripts.src %}/vendors/*.js\",\n                \"node_modules/focus-visible/dist/focus-visible.min.js\"\n            ],\n            \"outfile\": \"{% paths.scripts.dest %}/site/vendors.js\"\n        }\n    ]\n}\n```\n\nSee [`concats.js`](../build/tasks/concats.js) for details.\n\n### `scripts`\n\nA wrapper around [esbuild] for bundling and minifying modern JS/ES modules.\n\nExample:\n\n```json\n{\n    \"scripts\": [\n        {\n            \"label\": \"Application Dashboard JS\",\n            \"includes\": [\n                \"{% paths.scripts.src %}/app/dashboard.js\"\n            ],\n            \"outfile\": \"{% paths.scripts.dest %}/app/dashboard.js\"\n        },\n        {\n            \"label\": \"Public Site JS\",\n            \"includes\": [\n                \"{% paths.scripts.src %}/site/main.js\"\n            ],\n            \"outfile\": \"{% paths.scripts.dest %}/site/main.js\"\n        }\n    ]\n}\n```\n\nSee [`scripts.js`](../build/tasks/scripts.js) for details.\n\n### `styles`\n\nA wrapper around [sass] (with optional support for [Autoprefixer]\nvia [PostCSS]) for compiling and minifying Sass into CSS.\n\nBy default, [PostCSS] and [Autoprefixer] are installed with the boilerplate.\n\nExample:\n\n```json\n{\n    \"styles\": [\n        {\n            \"label\": \"Text Editor CSS\",\n            \"infile\": \"{% paths.styles.src %}/app/editor.scss\",\n            \"outfile\": \"{% paths.styles.dest %}/app/editor.css\"\n        },\n        {\n            \"label\": \"Application Dashboard CSS\",\n            \"infile\": \"{% paths.styles.src %}/app/dashboard.scss\",\n            \"outfile\": \"{% paths.styles.dest %}/app/dashboard.css\"\n        },\n        {\n            \"label\": \"Public Site Critical CSS\",\n            \"infile\": \"{% paths.styles.src %}/site/critical.scss\",\n            \"outfile\": \"{% paths.styles.dest %}/site/critical.css\"\n        },\n        {\n            \"label\": \"Public Site CSS\",\n            \"infile\": \"{% paths.styles.src %}/site/main.scss\",\n            \"outfile\": \"{% paths.styles.dest %}/site/main.css\"\n        }\n    ]\n}\n```\n\nSee [`styles.js`](../build/tasks/styles.js) for details.\n\nThe task also supports [PurgeCSS] to remove unused CSS.\nSee the [documentation on our Grid System](grid.md#build-tasks) for details.\n\n### `svgs`\n\nA wrapper around [SVG Mixer] for transforming and minifying SVG files\nand generating spritesheets.\n\nExample:\n\n```json\n{\n    \"svgs\": [\n        {\n            \"label\": \"Application Spritesheet\",\n            \"includes\": [\n                \"{% paths.images.src %}/app/*.svg\"\n            ],\n            \"outfile\": \"{% paths.svgs.dest %}/app/sprite.svg\"\n        },\n        {\n            \"label\": \"Public Site Spritesheet\",\n            \"includes\": [\n                \"{% paths.images.src %}/site/*.svg\"\n            ],\n            \"outfile\": \"{% paths.svgs.dest %}/site/sprite.svg\"\n        }\n    ]\n}\n```\n\nSee [`svgs.js`](../build/tasks/svgs.js) for details.\n\n### `versions`\n\nA task to create and update values for use in versioning assets.\n\nCan generate a hexadecimal value (using random bytes), use the current timestamp,\nor increment a number.\n\nExample:\n\n```json\n{\n    \"versions\": [\n        {\n            \"format\": \"timestamp\",\n            \"key\": \"now\",\n            \"outfile\": \"./assets.json\"\n        },\n        {\n            \"format\": \"hex:8\",\n            \"key\": \"hex\",\n            \"outfile\": \"./assets.json\"\n        },\n        {\n            \"format\": \"inc:semver\",\n            \"key\": \"inc\",\n            \"outfile\": \"./assets.json\"\n        }\n    ]\n}\n```\n\n```json\n{\n    \"now\": 1665071717350,\n    \"hex\": \"6ef54181c4ba\",\n    \"hex\": \"1.0.2\"\n}\n```\n\nThe task supports replacing the value of a data key in a JSON file or replacing\na string in a file using a [regular expression](RegExp).\n\n* Explicit JSON field name:\n    ```json\n    {\n        \"key\": \"json:version\"\n    }\n    ```\n* Implicit JSON field name:\n    ```json\n    {\n        \"key\": \"version\"\n    }\n    ```\n\nThe regular expression can be a `RegExp` object or a pattern prefixed with `regexp:`.\n\n* ```json\n  {\n      \"key\": \"regexp:(?<=^const ASSETS_VERSION = ')(?<build>\\\\d+)(?=';$)\"\n  }\n  ```\n\n* ```js\n  {\n      key: new RegExp('(?<=^const ASSETS_VERSION = ')(?<version>\\\\d+)(?=';$)')\n  }\n  ```\n* ```js\n  {\n      key: /^ \\* Version: +(?:.+?)\\+(.+?)$/\n  }\n  ```\n\nThe regular expression pattern will match the first occurrence and replace\nthe first match in the following order: `build` (named capture), `version`\n(named capture), `1` (first capture), or `0` (whole match).\n\nSee [`versions.js`](../build/tasks/versions.js) for details.\n\n[Autoprefixer]: https://npmjs.com/package/autoprefixer\n[BrowserSync]:  https://npmjs.com/package/browser-sync\n[concat]:       https://npmjs.com/package/concat\n[esbuild]:      https://npmjs.com/package/esbuild\n[fast-glob]:    https://npmjs.com/package/fast-glob\n[glob]:         https://npmjs.com/package/glob\n[globby]:       https://npmjs.com/package/globby\n[Node]:         https://nodejs.org/\n[sass]:         https://npmjs.com/package/sass\n[NPM]:          https://npmjs.com/\n[NVM]:          https://github.com/nvm-sh/nvm\n[PostCSS]:      https://npmjs.com/package/postcss\n[PurgeCSS]:     https://purgecss.com/\n[RegExp]:       https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp\n[SVG Mixer]:    https://npmjs.com/package/svg-mixer\n[tiny-glob]:    https://npmjs.com/package/tiny-glob\n"
  },
  {
    "path": "packages/landing/docs/grid.md",
    "content": "# Grid system\n\n* [Architectures](#architecture)\n  * [Build tasks](#build-tasks)\n    * [Configuration](#configuration)\n* [Usage](#usage)\n  * [Example](#example)\n\n## Architecture\n\nThe boilerplate's grid system is meant to be simple and easy to use. The goal is to create a light, flexible, and reusable way to build layouts.\nThe following styles are needed to work properly:\n\n* [`o-grid`](../assets/styles/objects/_grid.scss) — Object file where the default grid styles are set such as column numbers, modifiers, and options.\n* [`u-grid-columns`](../assets/styles/utilities/_grid-column.scss) — Utility file that generates the styles for every possible column based on an array of media queries and column numbers.\n\n### Build tasks\n\nThe columns generated by [`u-grid-columns`](../assets/styles/utilities/_grid-column.scss) adds a lot of styles to the compiled CSS file. To mitigate that, [PurgeCSS] is integrated into the `styles` build task to purge unused CSS.\n\n#### Configuration\n\nDepending on your project, you will need to specify all the files that include CSS classes from the grid system. These files will be scanned by [PurgeCSS] to your compiled CSS files.\n\nExample of a Charcoal project:\n\n```jsonc\n\"purgeCSS\": {\n    \"content\": [\n        \"./views/app/template/**/*.mustache\",\n        \"./src/App/Template/*.php\",\n        \"./assets/scripts/**/*\" // use case: `el.classList.add('u-gc-1/2')`\n    ]\n}\n```\n\n## Usage\n\nThe first step is to set intial SCSS values in the following files :\n\n- [`settings/_config.scss`](../assets/styles/settings/_config.scss)\n\n    ```scss\n    // Grid\n    // ==========================================================================\n    $base-column-nb: 12;\n    $base-column-gap: $unit-small;\n    ```\n\n    You can create multiple column layouts depending on media queries.\n\n- [`objects/_grid.scss`](../assets/styles/objects/_grid.scss)\n\n    ```scss\n    .o-grid {\n        display: grid;\n        width: 100%;\n        margin: 0;\n        padding: 0;\n        list-style: none;\n\n        // ==========================================================================\n        // Cols\n        // ==========================================================================\n        &.-col-#{$base-column-nb} {\n            grid-template-columns: repeat(#{$base-column-nb}, 1fr);\n        }\n\n        &.-col-4 {\n            grid-template-columns: repeat(4, 1fr);\n        }\n\n        &.-col-#{$base-column-nb}\\@from-medium {\n            @media (min-width: $from-medium) {\n                grid-template-columns: repeat(#{$base-column-nb}, 1fr);\n            }\n        }\n        // …\n    ```\n\n### Example\n\nThe following layout has 4 columns at `>=999px` and 12 columns at `<1000px`.\n\n```html\n<div class=\"o-container\">\n    <h1 class=\"c-heading -h1\">Hello</h1>\n\n    <div class=\"o-grid -col-4 -col-12@from-medium -gutters\">\n        <div class=\"o-grid_item u-gc-1/8@from-medium\">\n            <h2 class=\"c-heading -h2\">This grid has 4 columns and 12 columns from `medium` MQ</h2>\n        </div>\n\n        <div class=\"o-grid_item u-gc-1/5@from-medium\">\n            <p>Lorem, ipsum dolor sit amet consectetur adipisicing elit. Expedita provident distinctio deleniti eaque cumque doloremque aut quo dicta porro commodi, temporibus totam dolor autem tempore quasi ullam sed suscipit vero?</p>\n        </div>\n\n        <div class=\"o-grid_item u-gc-5/9@from-medium\">\n            <p>Lorem, ipsum dolor sit amet consectetur adipisicing elit. Expedita provident distinctio deleniti eaque cumque doloremque aut quo dicta porro commodi, temporibus totam dolor autem tempore quasi ullam sed suscipit vero?</p>\n        </div>\n\n        <div class=\"o-grid_item u-gc-9/13@from-medium\">\n            <p>Lorem, ipsum dolor sit amet consectetur adipisicing elit. Expedita provident distinctio deleniti eaque cumque doloremque aut quo dicta porro commodi, temporibus totam dolor autem tempore quasi ullam sed suscipit vero?</p>\n        </div>\n    </div>\n</div>\n```\n\n[PurgeCSS]: https://purgecss.com/\n"
  },
  {
    "path": "packages/landing/docs/technologies.md",
    "content": "# Technologies\n\n* [Styles](#styles)\n  * [CSS Architecture](#css-architecture)\n  * [CSS Naming Convention](#css-naming-convention)\n  * [CSS Namespacing](#css-namespacing)\n  * [Example](#example-1)\n* [Scripts](#scripts)\n  * [Example](#example-2)\n* [Page transitions](#page-transitions)\n  * [Example](#example-3)\n* [Scroll detection](#scroll-detection)\n  * [Example](#example-4)\n\n## Styles\n\n[SCSS][Sass] is a superset of CSS that adds many helpful features to improve\nand modularize our styles.\n\nWe use [node-sass] (LibSass) for processing and minifying SCSS into CSS.\n\nWe also use [PostCSS] and [Autoprefixer] to parse our CSS and add\nvendor prefixes for experimental features.\n\n### CSS Architecture\n\nThe boilerplate's CSS architecture is based on [Inuit CSS][inuitcss] and [ITCSS].\n\n* `settings`: Global variables, site-wide settings, config switches, etc.\n* `tools`: Site-wide mixins and functions.\n* `generic`: Low-specificity, far-reaching rulesets (e.g. resets).\n* `elements`: Unclassed HTML elements (e.g. `a {}`, `blockquote {}`, `address {}`).\n* `objects`: Objects, abstractions, and design patterns (e.g. `.o-layout {}`).\n* `components`: Discrete, complete chunks of UI (e.g. `.c-carousel {}`).\n* `utilities`: High-specificity, very explicit selectors. Overrides and helper\n  classes (e.g. `.u-hidden {}`)\n\nLearn more about [Inuit CSS](https://github.com/inuitcss/inuitcss#css-directory-structure).\n\n### CSS Naming Convention\n\nWe use a simplified [BEM] (Block, Element, Modifier) syntax:\n\n* `.block`\n* `.block_element`\n* `.-modifier`\n\n### CSS Namespacing\n\nWe namespace our classes for more UI transparency:\n\n* `o-`: Object that it may be used in any number of unrelated contexts to the one you can currently see it in. Making modifications to these types of class could potentially have knock-on effects in a lot of other unrelated places.\n* `c-`: Component is a concrete, implementation-specific piece of UI. All of the changes you make to its styles should be detectable in the context you’re currently looking at. Modifying these styles should be safe and have no side effects.\n* `u-`: Utility has a very specific role (often providing only one declaration) and should not be bound onto or changed. It can be reused and is not tied to any specific piece of UI.\n* `s-`: Scope creates a new styling context. Similar to a Theme, but not necessarily cosmetic, these should be used sparingly—they can be open to abuse and lead to poor CSS if not used wisely.\n* `is-`, `has-`: Is currently styled a certain way because of a state or condition. It tells us that the DOM currently has a temporary, optional, or short-lived style applied to it due to a certain state being invoked.\n\nLearn about [namespacing](https://csswizardry.com/2015/03/more-transparent-ui-code-with-namespaces/).\n\n### Example \\#1\n\n```html\n<div class=\"c-block -large\">\n    <div class=\"c-block_layout o-layout\">\n        <div class=\"o-layout_item u-1/2@from-medium\">\n            <div class=\"c-block_heading o-h -medium\">Heading</div>\n        </div>\n        <div class=\"o-layout_item u-1/2@from-medium\">\n           <a class=\"c-block_button o-button -outline\" href=\"#\">Button</a>\n        </div>\n    </div>\n</div>\n```\n\n```scss\n.c-block {\n    &.-large {\n        padding: rem(60px);\n    }\n}\n\n.c-block_heading {\n    @media (max-width: $to-medium) {\n        .c-block.-large & {\n            margin-bottom: rem(40px);\n        } \n    }\n}\n```\n\n## Scripts\n\nWe use [esbuild] for bundling and minifying JavaScript/ES modules.\n\n[modularJS] is a small framework we use on top of ES modules.\n\n* Automatically init visible modules.\n* Easily call other modules methods.\n* Quickly set scoped events with delegation.\n* Simply select DOM elements scoped in their module.\n\n[_source_](https://npmjs.com/package/modujs#why)\n\n### Example \\#2\n\n```html\n<div data-module-example>\n    <div data-example=\"main\">\n        <h2>Example</h2>\n    </div>\n    <button data-example=\"load\">More</button>\n</div>\n```\n\n```js\nimport { module } from 'modujs';\n\nexport default class extends module {\n    constructor(m) {\n        super(m);\n\n        this.events = {\n            click: {\n                load: 'loadMore'\n            }\n        };\n    }\n\n    loadMore() {\n        this.$('main')[0].classList.add('is-loading');\n    }\n}\n```\n\nLearn more about [modularJS].\n\n## Page transitions\n\n[modularLoad] is used for page transitions and lazy loading.\n\n### Example \\#3\n\n```html\n<nav>\n    <a href=\"/\">Home</a>\n    <a href=\"/page\" data-load=\"transitionName\">Page</a>\n</nav>\n<div data-load-container>\n    <img data-load-src=\"assets/images/hello.jpg\">\n</div>\n```\n```js\nimport modularLoad from 'modularload';\n\nthis.load = new modularLoad({\n    enterDelay: 300,\n    transitions: {\n        transitionName: {\n            enterDelay: 450\n        }\n    }\n});\n```\n\nLearn more about [modularLoad].\n\n## Scroll detection\n\n[Locomotive Scroll][locomotive-scroll] is used for elements in viewport\ndetection and smooth scrolling with parallax.\n\n### Example \\#4\n\n```html\n<div data-module-scroll>\n    <div data-scroll>Trigger</div>\n    <div data-scroll data-scroll-speed=\"1\">Parallax</div>\n</div>\n```\n\n```js\nimport LocomotiveScroll from 'locomotive-scroll';\n\nthis.scroll = new LocomotiveScroll({})\n````\n\nLearn more about [Locomotive Scroll][locomotive-scroll].\n\n[Autoprefixer]:      https://npmjs.com/package/autoprefixer\n[BEM]:               https://bem.info/\n[BrowserSync]:       https://npmjs.com/package/browser-sync\n[esbuild]:           https://npmjs.com/package/esbuild\n[inuitcss]:          https://github.com/inuitcss/inuitcss\n[ITCSS]:             https://itcss.io/\n[locomotive-scroll]: https://npmjs.com/package/locomotive-scroll\n[modularJS]:         https://npmjs.com/package/modujs\n[modularLoad]:       https://npmjs.com/package/modularload\n[node-sass]:         https://npmjs.com/package/node-sass\n[PostCSS]:           https://npmjs.com/package/postcss\n[Sass]:              https://sass-lang.com/\n[svg-mixer]:         https://npmjs.com/package/svg-mixer\n[Node]:              https://nodejs.org/\n[NPM]:               https://npmjs.com/\n[NVM]:               https://github.com/nvm-sh/nvm\n"
  },
  {
    "path": "packages/landing/eleventy.config.cjs",
    "content": "// Import required modules\nconst twig = require(\"twig\");\nconst fs = require('fs');\nconst path = require('path');\nconst eleventyPluginTwig = require(\"@factorial/eleventy-plugin-twig\");\n\n// Export Eleventy configuration\nmodule.exports = function(eleventyConfig) {\n    // Load assets.json version\n    const assetsJsonPath = path.resolve(__dirname, '../../www/landing/assets.json');\n    let assetsVersion = null;\n\n    function getAssetsVersion() {\n        if (assetsVersion === null) {\n            try {\n                const assetsData = JSON.parse(fs.readFileSync(assetsJsonPath, 'utf-8'));\n                assetsVersion = assetsData.version;\n            } catch(error) {\n                console.warn('Could not load assets.json, using timestamp instead');\n                assetsVersion = Date.now();\n            }\n        }\n        return assetsVersion;\n    }\n\n    eleventyConfig.setServerOptions({\n        enabled: false,\n    });\n\n    eleventyConfig.addWatchTarget(\"views/**/*\");\n\n    // Use twig\n    eleventyConfig.addPlugin(eleventyPluginTwig, {\n        twig: {\n            namespaces: {\n                layouts: \"views/layouts\",\n                partials: \"views/partials\",\n                snippets: \"views/snippets\"\n            }\n        },\n        dir: {\n            input: 'views/templates',\n            output: '../../www/landing'\n        }\n    });\n\n    twig.extendFilter(\"log\", function(value) {\n        return '<pre>'+JSON.stringify(value)+'</pre>';\n    });\n\n    twig.extendFilter(\"slug\", function(str) {\n        return str\n            .toLowerCase() // Convert the string to lowercase\n            .replace(/\\s+/g, '-') // Replace spaces with dashes\n            .replace(/[^\\w-]/g, '') // Remove non-word characters\n            .replace(/--+/g, '-') // Replace consecutive dashes with a single dash\n            .trim(); // Trim any leading or trailing dashes\n    });\n\n    // Add a filter to append the version to asset URLs from assets.json\n    twig.extendFilter('asset', function(url) {\n        const version = getAssetsVersion();\n        return `${url}?v=${version}`;\n    });\n\n    // Add global data for assets version\n    eleventyConfig.addGlobalData('assetsVersion', function() {\n        return getAssetsVersion();\n    });\n\n    twig.extendFunction(\"critical_css\", function() {\n        try {\n            return fs.readFileSync('../../www/landing/assets/styles/critical.css', 'utf-8')\n        } catch(error) {\n            return '';\n        }\n    });\n\n    // Configure and return Eleventy settings\n    return {\n        templateFormats: ['twig'],\n        dir: {\n            input: 'views/templates',\n            output: '../../www/landing',\n            data: '../../data'\n        }\n    };\n};\n"
  },
  {
    "path": "packages/landing/loconfig.example.json",
    "content": "{\n    \"server\": {\n        \"https\": {\n            \"key\": \"~/.config/valet/Certificates/{% paths.url %}.key\",\n            \"cert\": \"~/.config/valet/Certificates/{% paths.url %}.crt\"\n        }\n    }\n}\n"
  },
  {
    "path": "packages/landing/loconfig.json",
    "content": "{\n    \"paths\": {\n        \"url\": \"locomotive-scroll-website.test\",\n        \"src\": \"./assets\",\n        \"dest\": \"../../www/landing\",\n        \"images\": {\n            \"src\": \"./assets/images\"\n        },\n        \"styles\": {\n            \"src\": \"./assets/styles\",\n            \"dest\": \"../../www/landing/assets/styles\"\n        },\n        \"scripts\": {\n            \"src\": \"./assets/scripts\",\n            \"dest\": \"../../www/landing/assets/scripts\"\n        },\n        \"svgs\": {\n            \"src\": \"./assets/images/sprite\",\n            \"dest\": \"../../www/landing/assets/images\"\n        },\n        \"views\": {\n            \"src\": \"./views/\"\n        },\n        \"data\": {\n            \"src\": \"./data/\"\n        }\n    },\n    \"tasks\": {\n        \"concats\": [\n            {\n                \"includes\": [\n                    \"{% paths.scripts.src %}/vendors/*.js\"\n                ],\n                \"outfile\": \"{% paths.scripts.dest %}/vendors.js\"\n            }\n        ],\n        \"scripts\": [\n            {\n                \"includes\": [\n                    \"{% paths.scripts.src %}/app.js\"\n                ],\n                \"outfile\": \"{% paths.scripts.dest %}/app.js\"\n            }\n        ],\n        \"styles\": [\n            {\n                \"infile\": \"{% paths.styles.src %}/critical.scss\",\n                \"outfile\": \"{% paths.styles.dest %}/critical.css\"\n            },\n            {\n                \"infile\": \"{% paths.styles.src %}/main.scss\",\n                \"outfile\": \"{% paths.styles.dest %}/main.css\"\n            }\n        ],\n        \"svgs\": [\n            {\n                \"includes\": [\n                    \"{% paths.svgs.src %}/*.svg\"\n                ],\n                \"outfile\": \"{% paths.svgs.dest %}/sprite.svg\"\n            }\n        ],\n        \"purgeCSS\": {\n            \"content\": [\n                \"../../www/landing/**/*.html\",\n                \"./views/**/*.twig\",\n                \"../../www/landing/assets/scripts/**/*\"\n            ]\n        },\n        \"versions\": [\n            {\n                \"outfile\": \"../../www/landing/assets.json\"\n            }\n        ]\n    }\n}\n"
  },
  {
    "path": "packages/landing/package.json",
    "content": "{\n    \"private\": true,\n    \"name\": \"@locomotivemtl/boilerplate\",\n    \"title\": \"Locomotive Boilerplate\",\n    \"version\": \"1.0.0\",\n    \"author\": \"Locomotive <info@locomotive.ca>\",\n    \"type\": \"module\",\n    \"engines\": {\n        \"node\": \">=20.1\",\n        \"npm\": \">=8.0\"\n    },\n    \"scripts\": {\n        \"start\": \"node --experimental-json-modules --no-warnings build/watch.js\",\n        \"build\": \"node --experimental-json-modules --no-warnings build/build.js\"\n    },\n    \"dependencies\": {\n        \"@11ty/eleventy-img\": \"^4.0.2\",\n        \"@vercel/analytics\": \"^1.6.1\",\n        \"gsap\": \"^3.14.2\",\n        \"modujs\": \"^1.4.2\",\n        \"modularload\": \"^1.2.6\",\n        \"normalize.css\": \"^8.0.1\",\n        \"svg4everybody\": \"^2.1.9\"\n    },\n    \"devDependencies\": {\n        \"@11ty/eleventy\": \"^2.0.1\",\n        \"@factorial/eleventy-plugin-twig\": \"^0.1.2\",\n        \"autoprefixer\": \"^10.4.13\",\n        \"browser-sync\": \"^3.0.2\",\n        \"concat\": \"^1.0.3\",\n        \"esbuild\": \"^0.17.6\",\n        \"kleur\": \"^4.1.5\",\n        \"node-notifier\": \"^10.0.1\",\n        \"postcss\": \"^8.4.21\",\n        \"purgecss\": \"^5.0.0\",\n        \"sass\": \"^1.69.5\",\n        \"svg-mixer\": \"~2.3.14\",\n        \"tiny-glob\": \"^0.2.9\",\n        \"twig\": \"^1.16.0\"\n    },\n    \"overrides\": {\n        \"browser-sync\": {\n            \"ua-parser-js\": \"~1.0.33\"\n        },\n        \"svg-mixer\": {\n            \"postcss\": \"^8.4.20\"\n        }\n    }\n}\n"
  },
  {
    "path": "packages/landing/views/layouts/base.twig",
    "content": "<!doctype html>\n<html class=\"is-loading\" lang=\"en\" data-header-theme=\"blue\">\n    <head>\n        <meta charset=\"utf-8\">\n\n\n\n        <title>{% if title %}{{ title }} | {% endif %}{{ metadata.title }}</title>\n        <meta name=\"description\" content=\"{% if description %}{{ description }}{% else %}{{ metadata.description }}{% endif %}\">\n        <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n\n        {# Open Graph meta tags #}\n        <meta property=\"og:title\" content=\"{% if title %}{{ title }} | {% endif %}{{ metadata.title }}\">\n        <meta property=\"og:description\" content=\"{% if description %}{{ description }}{% else %}{{ metadata.description }}{% endif %}\">\n        <meta property=\"og:type\" content=\"website\">\n        <meta property=\"og:url\" content=\"{{ metadata.url }}{% if ogUrl %}{{ ogUrl }}{% endif %}\">\n        <meta property=\"og:image\" content=\"{% if ogImage %}{{ ogImage }}{% else %}{{ metadata.ogImage }}{% endif %}\">\n        <meta property=\"og:image:width\" content=\"{{ metadata.ogImageWidth }}\">\n        <meta property=\"og:image:height\" content=\"{{ metadata.ogImageHeight }}\">\n        <meta property=\"og:image:alt\" content=\"{% if ogImageAlt %}{{ ogImageAlt }}{% else %}{{ metadata.title }}{% endif %}\">\n\n        {# Twitter Card meta tags #}\n        <meta name=\"twitter:card\" content=\"summary_large_image\">\n        <meta name=\"twitter:title\" content=\"{% if title %}{{ title }} | {% endif %}{{ metadata.title }}\">\n        <meta name=\"twitter:description\" content=\"{% if description %}{{ description }}{% else %}{{ metadata.description }}{% endif %}\">\n        <meta name=\"twitter:image\" content=\"{% if ogImage %}{{ ogImage }}{% else %}{{ metadata.ogImage }}{% endif %}\">\n        <meta name=\"twitter:image:alt\" content=\"{% if ogImageAlt %}{{ ogImageAlt }}{% else %}{{ metadata.title }}{% endif %}\">\n\n        <meta name=\"theme-color\" content=\"#ffffff\">\n        <meta name=\"msapplication-TileColor\" content=\"#ffffff\">\n        <link rel=\"manifest\" href=\"assets/site.webmanifest\">\n        <link rel=\"apple-touch-icon\" sizes=\"180x180\" href=\"assets/images/favicons/apple-touch-icon.png\">\n        <link rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"assets/images/favicons/favicon-32x32.png\">\n        <link rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"assets/images/favicons/favicon-16x16.png\">\n        <link rel=\"mask-icon\" href=\"assets/images/favicons/safari-pinned-tab.svg\" color=\"#000000\">\n        <link id=\"main-css\" rel=\"stylesheet\" href=\"{{ 'assets/styles/main.css' | asset }}\">\n    </head>\n    <body data-module-load>\n        <!-- Preloader -->\n        <div class=\"c-preloader\"></div>\n\n        <div data-load-container>\n            {% block beforeMain %}\n                <div data-module-scroll=\"main\">\n                    {% include \"@partials/header.twig\" %}\n                    {% endblock %}\n\n                        <main>\n                            {% block content %}{% endblock %}\n\n                            {% block afterContent %}\n                                {% include \"@partials/footer.twig\" %}\n                            {% endblock %}\n                        </main>\n\n                    {% block afterMain %}\n                </div>\n            {% endblock %}\n        </div>\n\n        <script nomodule src=\"https://cdnjs.cloudflare.com/ajax/libs/babel-polyfill/7.6.0/polyfill.min.js\" crossorigin=\"anonymous\"></script>\n        <script nomodule src=\"https://polyfill.io/v3/polyfill.min.js?features=Element.prototype.remove%2CElement.prototype.append%2Cfetch%2CCustomEvent%2CElement.prototype.matches%2CNodeList.prototype.forEach%2CAbortController\" crossorigin=\"anonymous\"></script>\n\n        <script src=\"{{ 'assets/scripts/vendors.js' | asset }}\" defer></script>\n        <script src=\"{{ 'assets/scripts/app.js' | asset }}\" defer></script>\n    </body>\n</html>\n"
  },
  {
    "path": "packages/landing/views/layouts/features.twig",
    "content": "<section class=\"u-relative || o-container\" data-theme=\"black\" id=\"features\">\n\n    <div\n        class=\"c-header-theme-toggler\"\n        data-scroll\n        data-scroll-repeat\n        data-scroll-call=\"changeHeaderTheme\"\n        data-scroll-offset=\"100%\"\n    ></div>\n\n    {% include \"@partials/section-heading.twig\" with {\n        \"title\": [\n            'Features'\n        ],\n        \"attr\": {\n            'data-scroll': true,\n            'data-scroll-speed': -0.1\n        }\n    } %}\n\n    <div class=\"o-grid -col-2 -gutters\">\n        <div class=\"o-grid_item u-gc-2/3\">\n            <div class=\"u-max-w300 || c-text -body-medium || fadeInText -black\">\n                <span class=\"u-glyph\" aria-hidden=\"true\">⛵</span>\n                <div role=\"group\" class=\"u-margin-top-sm\" data-module-fade-in-text data-scroll data-scroll-offset=\"0, 25%\" data-scroll-event-progress=\"fadeinTextProgress\">{{ features.description }}</div>\n            </div>\n        </div>\n    </div>\n\n    <div class=\"c-features-grid\">\n        <div class=\"c-features-grid_container\">\n            <div class=\"c-features-grid_inner\">\n\n                <div class=\"c-features-grid_cell -lenis -link\">\n                    <div class=\"c-features-grid_cell_ratio\">\n                        <a href=\"https://lenis.darkroom.engineering/\" class=\"c-features-grid_link\" target=\"_blank\">\n                            <span class=\"u-screen-reader-text\">Visit Lenis website</span>\n                            <span class=\"c-features-grid_icon-container\">\n                                {% include \"@snippets/icon.twig\" with {\n                                    icon: 'arrow-external',\n                                    classes: 'c-features-grid_icon'\n                                } %}\n                                {% include \"@snippets/icon.twig\" with {\n                                    icon: 'arrow-external',\n                                    classes: 'c-features-grid_icon'\n                                } %}\n                            </span>\n                        </a>\n                        <div class=\"c-features-grid_cell_inner -logo\">\n                            <span class=\"c-features-grid_title || c-text -body-regular\" aria-hidden=\"true\">\n                                <span class=\"c-features-grid_title_label\">Lenis</span>\n                                <span class=\"c-features-grid_title_label\">Lenis</span>\n                            </span>\n                            {% include \"@snippets/icon.twig\" with {\n                                icon: 'logo-lenis',\n                                classes: 'c-features-grid_logo'\n                            } %}\n                        </div>\n                    </div>\n                </div>\n\n                <div class=\"c-features-grid_cell -locomotive -link\">\n                    <div class=\"c-features-grid_cell_ratio\">\n                        <a href=\"https://locomotive.ca/\" class=\"c-features-grid_link\" target=\"_blank\">\n                            <span class=\"u-screen-reader-text\">Visit Locomotive website</span>\n                            <span class=\"c-features-grid_icon-container\">\n                                {% include \"@snippets/icon.twig\" with {\n                                    icon: 'arrow-external',\n                                    classes: 'c-features-grid_icon'\n                                } %}\n                                {% include \"@snippets/icon.twig\" with {\n                                    icon: 'arrow-external',\n                                    classes: 'c-features-grid_icon'\n                                } %}\n                            </span>\n                        </a>\n                        <div class=\"c-features-grid_cell_inner -logo\">\n                            <span class=\"c-features-grid_title || c-text -body-regular\" aria-hidden=\"true\">\n                                <span class=\"c-features-grid_title_label\">Locomotive</span>\n                                <span class=\"c-features-grid_title_label\">Locomotive</span>\n                            </span>\n                            {% include \"@snippets/icon.twig\" with {\n                                icon: 'logo-locomotive',\n                                classes: 'c-features-grid_logo'\n                            } %}\n                        </div>\n                    </div>\n                </div>\n\n                <div class=\"c-features-grid_cell -scrollbar\">\n                    <div class=\"c-features-grid_cell_ratio\">\n                        <div class=\"c-features-grid_cell_inner\">\n                            <span class=\"c-features-grid_index || c-text -label-small\">01</span>\n                            <h3 class=\"c-features-grid_title || c-heading -h3\">{{ features.scrollbar.title }}</h3>\n                            <p class=\"c-features-grid_desc || c-text -body-regular\">{{ features.scrollbar.description }}</p>\n                        </div>\n                    </div>\n                </div>\n\n                <div class=\"c-features-grid_cell -normalized\">\n                    <div class=\"c-features-grid_cell_ratio\">\n                        <div class=\"c-features-grid_cell_inner\">\n                            <span class=\"c-features-grid_index || c-text -label-small\">02</span>\n                            <h3 class=\"c-features-grid_title || c-heading -h3\">{{ features.normalized.title }}</h3>\n                            <p class=\"c-features-grid_desc || c-text -body-regular\">{{ features.normalized.description }}</p>\n                        </div>\n                    </div>\n                </div>\n\n                <div class=\"c-features-grid_cell -sticky\">\n                    <div class=\"c-features-grid_cell_ratio\">\n                        <div class=\"c-features-grid_cell_inner\">\n                            <span class=\"c-features-grid_index || c-text -label-small\">03</span>\n                            <h3 class=\"c-features-grid_title || c-heading -h3\">{{ features.sticky.title }}</h3>\n                            <p class=\"c-features-grid_desc || c-text -body-regular\">{{ features.sticky.description }}</p>\n                        </div>\n                    </div>\n                </div>\n\n                <div class=\"c-features-grid_cell -io\" data-scroll data-scroll-offset=\"60%\" data-scroll-repeat>\n                    <div class=\"c-features-grid_cell_ratio\">\n                        <div class=\"c-features-grid_cell_inner\">\n                            <span class=\"c-features-grid_index || c-text -label-small\">04</span>\n                            <h3 class=\"c-features-grid_title || c-heading -h3\">{{ features.intersectionObserver.title }}</h3>\n                            <p class=\"c-features-grid_desc || c-text -body-regular\">{{ features.intersectionObserver.description }}</p>\n                        </div>\n                    </div>\n                </div>\n\n                <div data-scroll class=\"c-features-grid_cell -scroll-to\">\n                    <span class=\"c-features-grid_cell_ratio\">\n                        <span class=\"c-features-grid_cell_inner\">\n                            <span class=\"c-features-grid_index || c-text -label-small\">05</span>\n                            <span class=\"c-features-grid_title || c-heading -h3\">{{ features.scrollTo.title }}</span>\n                            <span class=\"c-features-grid_desc || c-text -body-regular\">{{ features.scrollTo.description }}</span>\n                        </span>\n                    </span>\n                </div>\n\n                <div class=\"c-features-grid_cell -direction\">\n                    <div class=\"c-features-grid_cell_ratio\">\n                        <div class=\"c-features-grid_cell_inner\">\n                            <span class=\"c-features-grid_index || c-text -label-small\">06</span>\n                            <div class=\"c-features_direction_title\">\n                                <h3 class=\"c-features-grid_title || c-heading -h3\">{{ features.direction.title }}</h3>\n                                <div class=\"c-heading -h3 || c-features_direction_arrows\">\n                                    <span>↓</span>\n                                    <span>↑</span>\n                                </div>\n                            </div>\n                            <p class=\"c-features-grid_desc || c-text -body-regular\">{{ features.direction.description }}</p>\n                        </div>\n                    </div>\n                </div>\n\n                <div class=\"c-features-grid_cell -custom-easing\">\n                    <div class=\"c-features-grid_cell_ratio\">\n                        <div class=\"c-features-grid_cell_inner\">\n                            <span class=\"c-features-grid_index || c-text -label-small\">07</span>\n                            <h3 class=\"c-features-grid_title || c-heading -h3\">{{ features.layoutShifts.title }}</h3>\n                            <p class=\"c-features-grid_desc || c-text -body-regular\">{{ features.layoutShifts.description }}</p>\n                        </div>\n                    </div>\n                </div>\n\n            </div>\n        </div>\n    </div>\n</section>\n"
  },
  {
    "path": "packages/landing/views/layouts/hero.twig",
    "content": "<section class=\"o-container || u-relative\" data-theme=\"blue\">\n\n    <div\n        class=\"c-header-theme-toggler -hero\"\n        data-scroll\n        data-scroll-repeat\n        data-scroll-call=\"changeHeaderTheme\"\n        data-scroll-ignore-fold\n    ></div>\n\n    <div class=\"c-hero\">\n        <div class=\"c-hero_sticky\">\n\n            <div class=\"c-hero_main\">\n                <div class=\"c-hero_heading\">\n                    <h1 class=\"c-hero_title || c-heading -h1\">\n                        <span class=\"c-hero_line\" style=\"--index: 0\">\n                            <span class=\"u-glyph || c-hero_word || -hero\" aria-hidden=\"true\">🟦🔁</span>\n                        </span>\n                        <span class=\"c-hero_line\" style=\"--index: 1\">\n                            <span class=\"c-hero_word || -hero\">Locomotive®</span>\n                        </span>\n                        <span class=\"c-hero_line\" style=\"--index: 2\">\n                            <span class=\"c-hero_word || -hero\">Scroll</span>\n                        </span>\n                    </h1>\n\n                    <div class=\"c-hero_description_container || fadeInText -blue\">\n                        <div role=\"group\" class=\"c-text -body-medium || u-max-w440 || c-hero_description\" data-module-fade-in-text data-scroll data-scroll-offset=\"10%,30%\" data-scroll-event-progress=\"fadeinTextProgress\">\n                            {{ general.description }}\n                        </div>\n                        <p class=\"c-hero_version || c-text -body-medium || u-clipped\" data-scroll data-scroll-offset=\"25%\">\n                            <span class=\"u-glyph\" aria-hidden=\"true\">🔻</span>\n                            <span>Version {{ general.version }}</span>\n                        </p>\n                    </div>\n                </div>\n                <nav class=\"c-hero_nav\">\n                    <ul class=\"c-hero_links\">\n                        <li class=\"c-hero_links_item\">\n                            {% include \"@snippets/button.twig\" with {\n                                label: \"View on Github\",\n                                icon: \"github\",\n                                href: general.github,\n                                attr: 'data-load=\"false\"'\n                            } %}\n                        </li>\n                        <li class=\"c-hero_links_item\">\n                            {% include \"@snippets/button.twig\" with {\n                                label: \"Read documentation\",\n                                icon: \"doc\",\n                                href: general.documentation,\n                                modifiers: '-stroke',\n                                attr: 'data-load=\"false\"'\n                            } %}\n                        </li>\n                    </ul>\n                </nav>\n            </div>\n        </div>\n    </div>\n</section>\n"
  },
  {
    "path": "packages/landing/views/layouts/perks.twig",
    "content": "<section class=\"u-relative\" data-theme=\"white\">\n\n    <div\n        class=\"c-header-theme-toggler\"\n        data-scroll\n        data-scroll-repeat\n        data-scroll-call=\"changeHeaderTheme\"\n        data-scroll-offset=\"100%,0\"\n        data-scroll-ignore-fold\n    ></div>\n\n    {% include \"@partials/rail.twig\" %}\n\n\n    <div class=\"o-container\">\n        {# List #}\n\n        {% include \"@partials/list.twig\" with {\n            items: perks.items,\n            modifiers: \"-perks\"\n        } %}\n\n        {# Big text #}\n        <div class=\"o-grid -gutters -col-4@from-medium || u-margin-top-xl u-margin-bottom-3xl\">\n            <div class=\"o-grid_item u-gc-2/5@from-medium\">\n                <p class=\"c-heading -h2\">\n                    {{ perks.bigText }}\n                </p>\n            </div>\n        </div>\n\n        {# Cascade #}\n        <div class=\"c-cascade || u-margin-3xl-top\" aria-hidden=\"true\">\n            <div class=\"c-cascade_text || || fadeInText -white\">\n                <span class=\"u-glyph\" aria-hidden=\"true\">⛵</span>\n                <div class=\"c-text -body-medium || u-margin-top-2xs\" role=\"group\" data-module-fade-in-text data-scroll data-scroll-offset=\"0, 25%\" data-scroll-event-progress=\"fadeinTextProgress\">{{ perks.smallText }}</div>\n            </div>\n            <div class=\"c-cascade_container\" data-scroll data-scroll-css-progress data-scroll-offset=\"10%, 60%\">\n                <div class=\"c-cascade_inner\">\n                    {% for index in 1..8 %}\n                        <div class=\"c-cascade_item || c-heading -h2\" style=\"--item-index: {{ loop.index0 }}\">\n                            <span class=\"c-cascade_line\">\n                                <span class=\"c-cascade_word\">Locomotive®</span>\n                            </span>\n                            <span class=\"c-cascade_line\">\n                                <span class=\"c-cascade_word\">Scroll</span>\n                            </span>\n                        </div>\n                    {% endfor %}\n                </div>\n            </div>\n            <p class=\"c-cascade_glyph || u-glyph\" aria-hidden=\"true\">👀</p>\n        </div>\n    </div>\n\n\n\n</section>\n"
  },
  {
    "path": "packages/landing/views/layouts/showcase.twig",
    "content": "<section class=\"u-relative || u-padding-bottom-2xl\" data-theme=\"white\" id=\"showcase\">\n\n    <div\n        class=\"c-header-theme-toggler\"\n        data-scroll\n        data-scroll-repeat\n        data-scroll-call=\"changeHeaderTheme\"\n        data-scroll-offset=\"100%\"\n    ></div>\n\n    <div class=\"c-sticky-heading\" data-scroll data-scroll-offset=\"100%, 100%\" data-scroll-css-progress>\n        <div class=\"c-sticky-heading_inner || o-container\">\n            <div class=\"c-sticky-heading_text\">\n                <div class=\"c-sticky-heading_description || fadeInText -white\">\n                    <div class=\"c-text -body-medium\">\n                        <span class=\"u-glyph\" aria-hidden=\"true\">⛵</span>\n                        <div class=\"u-margin-top-2xs\" role=\"group\" data-module-fade-in-text data-scroll data-scroll-offset=\"0, 25%\"  data-scroll-event-progress=\"fadeinTextProgress\">\n                            {{showcase.description}}\n                        </div>\n                    </div>\n                </div>\n                <h2 class=\"c-sticky-heading_title\">\n                    {{showcase.title}}\n                </h2>\n            </div>\n        </div>\n    </div>\n\n    <div class=\"o-container || u-margin-top-sm\">\n        {% include \"@partials/list.twig\" with {\n            items: showcase.items,\n            modifiers: \"-showcase\",\n            link: true\n        } %}\n    </div>\n</section>\n"
  },
  {
    "path": "packages/landing/views/layouts/tools.twig",
    "content": "<section class=\"u-relative || u-clipped || u-padding-bottom-2xl\" data-theme=\"blue\">\n\n    <div\n        class=\"c-header-theme-toggler\"\n        data-scroll\n        data-scroll-repeat\n        data-scroll-call=\"changeHeaderTheme\"\n        data-scroll-offset=\"100%\"\n    ></div>\n\n    {% include \"@partials/section-heading.twig\" with {\n        title: [\n            'Built-in',\n            'Tools'\n        ],\n        labelLeft: '<span class=\"u-glyph\" aria-hidden=\"true\">🔴</span>Work faster',\n        labelRight: 'Work smarter<span class=\"u-glyph\" aria-hidden=\"true\">🔴</span>',\n    } %}\n\n    <div class=\"c-tool -inview\" data-scroll data-scroll-offset=\"5%\">\n        <div class=\"o-container\">\n            <div class=\"c-tool_head\">\n                <span class=\"c-tool_index\">01</span>\n                <span class=\"c-tool_label\">{{ tools.inview.title }}</span>\n                <span class=\"c-tool_description\">{{ tools.inview.description }}</span>\n                <h3 class=\"c-tool_title || c-heading -h2\">\n                    {{ tools.inview.title }}\n                </h3>\n            </div>\n        </div>\n\n        <div class=\"c-tool_playground\" style=\"--container-ratio: 7/5\">\n            <div class=\"c-tool_shape -first\" data-scroll data-scroll-offset=\"10%\" data-scroll-repeat>\n                <div class=\"c-tool_shape_inner\" data-scroll data-scroll-speed=\"0.01\" data-scroll-css-progress>\n                    {% include \"@snippets/icon.twig\" with { icon: 'inview-01', modifiers: 'c-tool_shape_svg' } %}\n                </div>\n            </div>\n            <div class=\"c-tool_shape -second\" data-scroll data-scroll-offset=\"30%\" data-scroll-repeat>\n                <div class=\"c-tool_shape_inner\" data-scroll data-scroll-speed=\"0.1\">\n                    {% include \"@snippets/icon.twig\" with { icon: 'inview-02', modifiers: 'c-tool_shape_svg' } %}\n                </div>\n            </div>\n            <div class=\"c-tool_shape -third\" data-scroll data-scroll-offset=\"25%\" data-scroll-repeat>\n                <div class=\"c-tool_shape_inner\" data-scroll data-scroll-speed=\"0.02\">\n                    {% include \"@snippets/icon.twig\" with { icon: 'inview-03', modifiers: 'c-tool_shape_svg' } %}\n                </div>\n            </div>\n            <div class=\"c-tool_shape -fourth\" data-scroll data-scroll-offset=\"45%\" data-scroll-repeat>\n                <div class=\"c-tool_shape_inner\" data-scroll data-scroll-speed=\"0.05\">\n                    {% include \"@snippets/icon.twig\" with { icon: 'inview-04', modifiers: 'c-tool_shape_svg' } %}\n                </div>\n            </div>\n            <div class=\"c-tool_shape -fifth\" data-scroll data-scroll-offset=\"20%\" data-scroll-repeat>\n                <div class=\"c-tool_shape_inner\" data-scroll data-scroll-speed=\"0.15\" data-scroll-css-progress>\n                    {% include \"@snippets/icon.twig\" with { icon: 'inview-05', modifiers: 'c-tool_shape_svg' } %}\n                </div>\n            </div>\n            <div class=\"c-tool_shape -sixth\" data-scroll data-scroll-offset=\"60%\" data-scroll-repeat>\n                <div class=\"c-tool_shape_inner\" data-scroll data-scroll-speed=\"0.05\">\n                    {% include \"@snippets/icon.twig\" with { icon: 'inview-06', modifiers: 'c-tool_shape_svg' } %}\n                </div>\n            </div>\n        </div>\n    </div>\n\n    <div class=\"c-tool -progress\" data-scroll data-scroll-offset=\"5%\">\n        <div class=\"o-container\">\n            <div class=\"c-tool_head\">\n                <span class=\"c-tool_index\">02</span>\n                <span class=\"c-tool_label\">{{ tools.progress.title }}</span>\n                <span class=\"c-tool_description\">{{ tools.progress.description }}</span>\n                <h3 class=\"c-tool_title || c-heading -h2\">\n                    {{ tools.progress.title }}\n                </h3>\n            </div>\n        </div>\n\n        <div class=\"c-tool_playground\" style=\"--container-ratio: 12/5\">\n            <div class=\"c-tool_shape -first\" style=\"--index: -2\" data-scroll data-scroll-css-progress>\n                <div class=\"c-tool_shape_inner\">\n                    {% include \"@snippets/icon.twig\" with { icon: 'progress-01', modifiers: 'c-tool_shape_svg' } %}\n                </div>\n            </div>\n            <div class=\"c-tool_shape -second\" style=\"--index: -1\" data-scroll data-scroll-css-progress>\n                <div class=\"c-tool_shape_inner\">\n                    {% include \"@snippets/icon.twig\" with { icon: 'progress-02', modifiers: 'c-tool_shape_svg' } %}\n                </div>\n            </div>\n            <div class=\"c-tool_shape -third\" style=\"--index: 0\" data-scroll data-scroll-css-progress>\n                <div class=\"c-tool_shape_inner\">\n                    {% include \"@snippets/icon.twig\" with { icon: 'progress-03', modifiers: 'c-tool_shape_svg' } %}\n                </div>\n            </div>\n            <div class=\"c-tool_shape -fourth\" style=\"--index: 1\" data-scroll data-scroll-css-progress>\n                <div class=\"c-tool_shape_inner\">\n                    {% include \"@snippets/icon.twig\" with { icon: 'progress-04', modifiers: 'c-tool_shape_svg' } %}\n                </div>\n            </div>\n            <div class=\"c-tool_shape -fifth\" style=\"--index: 2\" data-scroll data-scroll-css-progress>\n                <div class=\"c-tool_shape_inner\">\n                    {% include \"@snippets/icon.twig\" with { icon: 'progress-05', modifiers: 'c-tool_shape_svg' } %}\n                </div>\n            </div>\n        </div>\n    </div>\n\n    <div class=\"c-tool -parallax\" data-scroll data-scroll-offset=\"5%\">\n        <div class=\"o-container\">\n            <div class=\"c-tool_head\">\n                <span class=\"c-tool_index\">02</span>\n                <span class=\"c-tool_label\">{{ tools.parallax.title }}</span>\n                <span class=\"c-tool_description\">{{ tools.parallax.description }}</span>\n                <h3 class=\"c-tool_title || c-heading -h2\">\n                    {{ tools.parallax.title }}\n                </h3>\n            </div>\n        </div>\n\n        <div class=\"c-tool_playground\" style=\"--container-ratio: 10/5\">\n            <div class=\"c-tool_shape -first\">\n                <div class=\"c-tool_shape_inner\" data-scroll data-scroll-speed=\"0.04\" data-scroll-enable-touch-speed>\n                    {% include \"@snippets/icon.twig\" with { icon: 'parallax-01', modifiers: 'c-tool_shape_svg' } %}\n                </div>\n            </div>\n            <div class=\"c-tool_shape -second\">\n                <div class=\"c-tool_shape_inner\" data-scroll data-scroll-speed=\"0.2\" data-scroll-enable-touch-speed>\n                    {% include \"@snippets/icon.twig\" with { icon: 'parallax-02', modifiers: 'c-tool_shape_svg' } %}\n                </div>\n            </div>\n            <div class=\"c-tool_shape -third\">\n                <div class=\"c-tool_shape_inner\" data-scroll data-scroll-speed=\"0.3\" data-scroll-enable-touch-speed>\n                    {% include \"@snippets/icon.twig\" with { icon: 'parallax-03', modifiers: 'c-tool_shape_svg' } %}\n                </div>\n            </div>\n            <div class=\"c-tool_shape -fourth\">\n                <div class=\"c-tool_shape_inner\" data-scroll data-scroll-speed=\"0.15\" data-scroll-enable-touch-speed>\n                    {% include \"@snippets/icon.twig\" with { icon: 'parallax-04', modifiers: 'c-tool_shape_svg' } %}\n                </div>\n            </div>\n            <div class=\"c-tool_shape -fifth\">\n                <div class=\"c-tool_shape_inner\" data-scroll data-scroll-speed=\"0.25\" data-scroll-enable-touch-speed>\n                    {% include \"@snippets/icon.twig\" with { icon: 'parallax-05', modifiers: 'c-tool_shape_svg' } %}\n                </div>\n            </div>\n        </div>\n        </div>\n    </div>\n</section>\n"
  },
  {
    "path": "packages/landing/views/partials/footer.twig",
    "content": "<footer class=\"u-relative || c-footer || o-container || u-padding-top-sm\" data-theme=\"blue\">\n\n    <div\n        class=\"c-header-theme-toggler\"\n        data-scroll\n        data-scroll-repeat\n        data-scroll-call=\"changeHeaderTheme\"\n        data-scroll-offset=\"100%\"\n    ></div>\n\n    <div aria-hidden data-module-randomize class=\"c-footer_attributes || o-grid -cols\">\n        <div data-scroll data-scroll-position=\"end\" data-scroll-call=\"randomize\">\n            <p>npm</p>\n            <p>npm install</p>\n            <p>npm install locomotive-scroll</p>\n            <p>npm install</p>\n            <p>npm</p>\n        </div>\n        <div data-scroll data-scroll-position=\"end\" data-scroll-call=\"randomize\">\n            <p>locomotive</p>\n            <p>locomotive-scroll</p>\n            <p>locomotive-scroll v5.x</p>\n            <p>locomotive-scroll v5.x</p>\n            <p>locomotive-scroll</p>\n            <p>locomotive</p>\n        </div>\n        <div data-scroll data-scroll-position=\"end\" data-scroll-call=\"randomize\">\n            <p>data</p>\n            <p>data-scroll</p>\n            <p>data-scroll-speed</p>\n            <p>data-scroll-class</p>\n            <p>data-scroll-repeat</p>\n        </div>\n        <div data-scroll data-scroll-position=\"end\" data-scroll-call=\"randomize\">\n            <p>data</p>\n            <p>data-scroll</p>\n            <p>data-scroll-position</p>\n            <p>data-scroll-call</p>\n            <p>data-scroll-event-progress</p>\n        </div>\n    </div>\n\n    <div class=\"o-grid -cols u-padding-top-lg\">\n        <h2\n            data-module-mask-lines\n            data-scroll\n            data-scroll-event-progress=\"progressEvent\"\n            data-scroll-position=\"start, end\"\n            data-scroll-offset=\"100px, 75%\"\n            class=\"c-footer_thanks || c-hero_title || c-heading -h1\">\n            We hope that you enjoy our library.\n        </h2>\n    </div>\n\n\n    <div class=\"c-hero_main || -footer || u-padding-bottom-lg\">\n        <div class=\"c-hero_heading\">\n            <p class=\"c-hero_title || c-heading -h1\" data-scroll data-scroll-position=\"end\" data-scroll-repeat>\n                <span class=\"c-hero_line\" style=\"--index: 0\">\n                    <span class=\"u-glyph || c-hero_word || -footer\" aria-hidden=\"true\">🟦🔁</span>\n                </span>\n                <span class=\"c-hero_line\" style=\"--index: 1\">\n                    <span class=\"c-hero_word || -footer\">Locomotive®</span>\n                </span>\n                <span class=\"c-hero_line\" style=\"--index: 2\">\n                    <span class=\"c-hero_word || -footer\">Scroll</span>\n                </span>\n            </p>\n\n            <p class=\"c-text -body-regular || c-footer_website\" data-scroll data-scroll-position=\"end\" data-scroll-repeat>\n                Made by <a class=\"u-hover-underline\" href=\"{{ general.website }}\" target=\"_blank\" data-module-hover-shuffle>Locomotive</a>\n            </p>\n        </div>\n        <nav class=\"c-hero_nav\">\n            <ul class=\"c-hero_links\">\n                <li class=\"c-hero_links_item\">\n                    {% include \"@snippets/button.twig\" with {\n                        label: \"View on Github\",\n                        icon: \"github\",\n                        href: general.github,\n                        attr: 'data-load=\"false\"'\n                    } %}\n                </li>\n                <li class=\"c-hero_links_item\">\n                    {% include \"@snippets/button.twig\" with {\n                        label: \"Read documentation\",\n                        icon: \"doc\",\n                        href: general.documentation,\n                        modifiers: '-stroke',\n                        attr: 'data-load=\"false\"'\n                    } %}\n                </li>\n            </ul>\n        </nav>\n    </div>\n\n\n</footer>\n"
  },
  {
    "path": "packages/landing/views/partials/header.twig",
    "content": "<header class=\"c-header\">\n    <div class=\"c-header_col\">\n        <p class=\"c-text -body-regular\">{{ general.title }}</p>\n        <p class=\"c-text -body-regular || u-hidden-md\">Version {{ general.version }}</p>\n    </div>\n    <div class=\"c-header_col  || -center\">\n        <a class=\"c-text -body-regular || u-hover-underline\" href=\"{{ general.github }}\" data-load=\"false\"><span data-module-hover-shuffle>Github</span><span class=\"u-external-icon\">↗</span></a>\n    </div>\n    <div class=\"c-header_col\">\n        <a class=\"c-text -body-regular || u-hover-underline\" href=\"{{ general.documentation }}\" data-load=\"false\"><span data-module-hover-shuffle>Documentation</span><span class=\"u-external-icon\">↗</span></a>\n        <p class=\"u-hidden-md\">©2026</p>\n    </div>\n</header>\n"
  },
  {
    "path": "packages/landing/views/partials/list.twig",
    "content": "{# List #}\n{% set _items     = items %}\n{% set _classes   = classes | default(null) %}\n{% set _modifiers = modifiers | default(null) %}\n{% set _link      = link | default(null) %}\n\n<div class=\"c-list {{ _modifiers }} {{ _classes }}\" data-scroll>\n    <ul class=\"c-list_inner\">\n        {% for item in _items %}\n            <li class=\"c-list_item | c-text -body-regular\" style=\"--index: {{ loop.index0}}\">\n                {% if _link %}\n                    <a class=\"c-list_item_inner u-hover-underline\" href={{item.url}} target=\"_blank\" data-module-hover-shuffle data-hover-shuffle=\"children\">\n                        <span class=\"c-list_title || c-text -body-regular\" data-hover-shuffle-child>{{ item.title }}</span>\n                        <span class=\"c-list_description || c-text -body-regular\" data-hover-shuffle-child>{{ item.description }}</span>\n                        <span class=\"c-list-anchor\">↗</span>\n                    </a>\n                {% else %}\n                    <div class=\"c-list_item_inner\">\n                        <p class=\"c-list_title || c-text -body-regular\">{{ item.title }}</p>\n                        <p class=\"c-list_description || c-text -body-regular\">{{ item.description }}</p>\n                    </div>\n                {% endif %}\n            </li>\n        {% endfor %}\n    </ul>\n</div>"
  },
  {
    "path": "packages/landing/views/partials/rail.twig",
    "content": "<div\n    class=\"c-rail\"\n    data-module-rail\n    data-values=\"rail\"\n    data-rail-direction=\"-1\"\n    data-scroll\n    data-scroll-call=\"toggleRail\"    \n    data-scroll-repeat\n>\n    <div class=\"c-rail_inner\" data-rail=\"container\" aria-hidden=\"true\">\n        <div data-rail=\"pattern\">\n            <p class=\"c-rail_item\" data-rail-item>\n                Version ({{ general.version }})\n                <span class=\"c-rail_glyph\" aria-hidden=\"true\">🏢</span>\n            </p>\n        </div>\n    </div>\n</div>\n"
  },
  {
    "path": "packages/landing/views/partials/section-heading.twig",
    "content": "<h2 class=\"c-heading-serif -large || c-section-heading || u-padding-bottom-3xl u-padding-top-md\">\n    <span class=\"c-section-heading_line\">\n        <span class=\"c-section-heading_word\">\n            {{ title[0] }}\n        </span>\n    </span>\n    <span class=\"c-section-heading_line\">\n        <span class=\"c-section-heading_word\">\n            {{ title[1] }}\n        </span>\n\n        {% if labelLeft %}\n            <span class=\"c-text -body-medium || c-section-heading_label -left\">\n                {{ labelLeft|raw }}\n            </span>\n        {% endif %}\n\n        {% if labelRight %}\n            <span class=\"c-text -body-medium || c-section-heading_label -right\">\n                {{ labelRight|raw }}\n            </span>\n        {% endif %}\n\n    </span>\n</h2>\n"
  },
  {
    "path": "packages/landing/views/snippets/button.twig",
    "content": "{# --- Parameters ------------------------- #}\n\n{% set _tag             = tag | default('button') %}\n{% set _href            = href | default(null) %}\n{% set _external        = external ?? false %}\n{% set _classes         = classes | default(null) %}\n{% set _modifiers       = modifiers | default(null) %}\n{% set _label           = label | default(null) %}\n{% set _icon            = icon | default(null) %}\n{% set _attr            = attr | default('') %}\n\n{# --- Computed --------------------------- #}\n\n{% if _href != null %}\n    {% set _tag = 'a' %}\n{% elseif _tag == 'a' %}\n    {% set _tag = 'span' %}\n{% endif %}\n\n{% set _button_classes = 'c-button' %}\n\n{% if _modifiers %}\n    {% set _button_classes = _button_classes ~ ' ' ~ _modifiers %}\n{% endif %}\n\n{% if _classes %}\n    {% set _button_classes = _button_classes ~ ' ' ~ _classes %}\n{% endif %}\n\n\n{# ---------------------------------------- #}\n\n<{{ _tag }}\n    class=\"{{ _button_classes }}\"\n    {% if _href %}href=\"{{ _href }}\"{% endif %}\n    {% if _external %}target=\"_blank\" rel=\"noopener noreferrer\"{% endif %}\n    {% if _attr %}{{ _attr|raw }}{% endif %}\n    >\n        {% for index in 1..2 %}\n            <span\n                class=\"c-button_wrap\"\n                {% if loop.index == 2 %}\n                    aria-hidden=\"true\"\n                {% endif %}\n            >\n                <span class=\"c-button_inner\">\n                    {% if _icon %}\n                        {% include \"@snippets/icon.twig\" with {\n                            icon: _icon,\n                            classes: 'c-button_icon',\n                        } only %}\n                    {% endif %}\n\n                    {% if _label %}\n                        <span class=\"c-button_label\">\n                            {{ _label }}\n                        </span>\n                    {% endif %}\n                </span>\n            </span>\n        {% endfor %}\n</{{ _tag }}>\n"
  },
  {
    "path": "packages/landing/views/snippets/icon.twig",
    "content": "{# --- Parameters ------------------------- #}\n\n{% set _icon      = icon %}\n{% set _classes   = classes | default(null) %}\n{% set _modifiers = modifiers | default(null) %}\n\n{# ---------------------------------------- #}\n\n{% if _icon %}\n    <span class=\"o-icon {{ _modifiers }} {{ _classes }}\">\n        <svg class=\"svg-{{ _icon }}\" focusable=\"false\" aria-hidden=\"true\">\n            <use xlink:href=\"{{ 'assets/images/sprite.svg' | asset }}#{{ _icon }}\"></use>\n        </svg>\n    </span>\n{% endif %}\n"
  },
  {
    "path": "packages/landing/views/templates/index.twig",
    "content": "\n{% extends \"@layouts/base.twig\" %}\n\n{% block content %}\n\n    {% include \"@layouts/hero.twig\" %}\n    {% include \"@layouts/perks.twig\" %}\n    {% include \"@layouts/tools.twig\" %}\n    {% include \"@layouts/features.twig\" %}\n    {% include \"@layouts/showcase.twig\" %}\n\n{% endblock %}\n"
  },
  {
    "path": "packages/lib/README.md",
    "content": "# Locomotive Scroll\n\n[![npm version](https://img.shields.io/npm/v/locomotive-scroll.svg)](https://www.npmjs.com/package/locomotive-scroll)\n[![npm downloads](https://img.shields.io/npm/dm/locomotive-scroll.svg)](https://www.npmjs.com/package/locomotive-scroll)\n[![bundle size](https://img.shields.io/bundlephobia/minzip/locomotive-scroll)](https://bundlephobia.com/package/locomotive-scroll)\n\nA **lightweight** & **modern** scroll library for detection, animation, and smooth scrolling. Built on top of [Lenis](https://github.com/darkroomengineering/lenis).\n\n## Documentation\n\nFull documentation available at [scroll.locomotive.ca/docs](https://scroll.locomotive.ca/docs).\n\n## Quick Start\n\n```bash\nnpm install locomotive-scroll\n```\n\n```js\nimport LocomotiveScroll from 'locomotive-scroll';\n\nconst scroll = new LocomotiveScroll();\n```\n\n```css\n@import 'locomotive-scroll/dist/locomotive-scroll.css';\n```\n\n```html\n<div data-scroll data-scroll-speed=\"0.5\">I move at half speed</div>\n```\n\n## Features\n\n-   **Lightweight** — Only 9.4kB gzipped\n-   **TypeScript First** — Fully typed\n-   **Built on Lenis** — Latest stable release with improved performance\n-   **Dual Intersection Observers** — Optimized detection for triggers vs. animations\n-   **Smart Touch Detection** — Parallax auto-disabled on mobile\n-   **Accessible** — Native scrollbar, keyboard navigation, proper ARIA support\n\n## Demo\n\nCheck out the [examples and playground](https://scroll.locomotive.ca/docs/examples)\n\n## Support\n\n[GitHub Issues](https://github.com/locomotivemtl/locomotive-scroll/issues)\n"
  },
  {
    "path": "packages/lib/bundled/locomotive-scroll.css",
    "content": "html.lenis,html.lenis body{height:auto}.lenis:not(.lenis-autoToggle).lenis-stopped{overflow:clip}.lenis [data-lenis-prevent-touch],.lenis [data-lenis-prevent-wheel],.lenis [data-lenis-prevent]{overscroll-behavior:contain}.lenis.lenis-smooth iframe{pointer-events:none}.lenis.lenis-autoToggle{transition-behavior:allow-discrete;transition-duration:1ms;transition-property:overflow}"
  },
  {
    "path": "packages/lib/bundled/locomotive-scroll.js",
    "content": "(function (global, factory) {\n  typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :\n  typeof define === 'function' && define.amd ? define(factory) :\n  (global = global || self, global.LocomotiveScroll = factory());\n})(this, (function () {\n  function _arrayLikeToArray(r, a) {\n    (null == a || a > r.length) && (a = r.length);\n    for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e];\n    return n;\n  }\n  function _createForOfIteratorHelperLoose(r, e) {\n    var t = \"undefined\" != typeof Symbol && r[Symbol.iterator] || r[\"@@iterator\"];\n    if (t) return (t = t.call(r)).next.bind(t);\n    if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && \"number\" == typeof r.length) {\n      t && (r = t);\n      var o = 0;\n      return function () {\n        return o >= r.length ? {\n          done: !0\n        } : {\n          done: !1,\n          value: r[o++]\n        };\n      };\n    }\n    throw new TypeError(\"Invalid attempt to iterate non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.\");\n  }\n  function _extends() {\n    return _extends = Object.assign ? Object.assign.bind() : function (n) {\n      for (var e = 1; e < arguments.length; e++) {\n        var t = arguments[e];\n        for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]);\n      }\n      return n;\n    }, _extends.apply(null, arguments);\n  }\n  function _unsupportedIterableToArray(r, a) {\n    if (r) {\n      if (\"string\" == typeof r) return _arrayLikeToArray(r, a);\n      var t = {}.toString.call(r).slice(8, -1);\n      return \"Object\" === t && r.constructor && (t = r.constructor.name), \"Map\" === t || \"Set\" === t ? Array.from(r) : \"Arguments\" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0;\n    }\n  }\n\n  var version$1 = \"5.0.0\";\n\n  // package.json\n  var version = \"1.3.17\";\n\n  // packages/core/src/maths.ts\n  function clamp$1(min, input, max) {\n    return Math.max(min, Math.min(input, max));\n  }\n  function lerp(x, y, t) {\n    return (1 - t) * x + t * y;\n  }\n  function damp(x, y, lambda, deltaTime) {\n    return lerp(x, y, 1 - Math.exp(-lambda * deltaTime));\n  }\n  function modulo(n, d) {\n    return (n % d + d) % d;\n  }\n\n  // packages/core/src/animate.ts\n  var Animate = class {\n    isRunning = false;\n    value = 0;\n    from = 0;\n    to = 0;\n    currentTime = 0;\n    // These are instanciated in the fromTo method\n    lerp;\n    duration;\n    easing;\n    onUpdate;\n    /**\n     * Advance the animation by the given delta time\n     *\n     * @param deltaTime - The time in seconds to advance the animation\n     */\n    advance(deltaTime) {\n      if (!this.isRunning) return;\n      let completed = false;\n      if (this.duration && this.easing) {\n        this.currentTime += deltaTime;\n        const linearProgress = clamp$1(0, this.currentTime / this.duration, 1);\n        completed = linearProgress >= 1;\n        const easedProgress = completed ? 1 : this.easing(linearProgress);\n        this.value = this.from + (this.to - this.from) * easedProgress;\n      } else if (this.lerp) {\n        this.value = damp(this.value, this.to, this.lerp * 60, deltaTime);\n        if (Math.round(this.value) === this.to) {\n          this.value = this.to;\n          completed = true;\n        }\n      } else {\n        this.value = this.to;\n        completed = true;\n      }\n      if (completed) {\n        this.stop();\n      }\n      this.onUpdate?.(this.value, completed);\n    }\n    /** Stop the animation */\n    stop() {\n      this.isRunning = false;\n    }\n    /**\n     * Set up the animation from a starting value to an ending value\n     * with optional parameters for lerping, duration, easing, and onUpdate callback\n     *\n     * @param from - The starting value\n     * @param to - The ending value\n     * @param options - Options for the animation\n     */\n    fromTo(from, to, { lerp: lerp2, duration, easing, onStart, onUpdate }) {\n      this.from = this.value = from;\n      this.to = to;\n      this.lerp = lerp2;\n      this.duration = duration;\n      this.easing = easing;\n      this.currentTime = 0;\n      this.isRunning = true;\n      onStart?.();\n      this.onUpdate = onUpdate;\n    }\n  };\n\n  // packages/core/src/debounce.ts\n  function debounce(callback, delay) {\n    let timer;\n    return function(...args) {\n      let context = this;\n      clearTimeout(timer);\n      timer = setTimeout(() => {\n        timer = void 0;\n        callback.apply(context, args);\n      }, delay);\n    };\n  }\n\n  // packages/core/src/dimensions.ts\n  var Dimensions = class {\n    constructor(wrapper, content, { autoResize = true, debounce: debounceValue = 250 } = {}) {\n      this.wrapper = wrapper;\n      this.content = content;\n      if (autoResize) {\n        this.debouncedResize = debounce(this.resize, debounceValue);\n        if (this.wrapper instanceof Window) {\n          window.addEventListener(\"resize\", this.debouncedResize, false);\n        } else {\n          this.wrapperResizeObserver = new ResizeObserver(this.debouncedResize);\n          this.wrapperResizeObserver.observe(this.wrapper);\n        }\n        this.contentResizeObserver = new ResizeObserver(this.debouncedResize);\n        this.contentResizeObserver.observe(this.content);\n      }\n      this.resize();\n    }\n    width = 0;\n    height = 0;\n    scrollHeight = 0;\n    scrollWidth = 0;\n    // These are instanciated in the constructor as they need information from the options\n    debouncedResize;\n    wrapperResizeObserver;\n    contentResizeObserver;\n    destroy() {\n      this.wrapperResizeObserver?.disconnect();\n      this.contentResizeObserver?.disconnect();\n      if (this.wrapper === window && this.debouncedResize) {\n        window.removeEventListener(\"resize\", this.debouncedResize, false);\n      }\n    }\n    resize = () => {\n      this.onWrapperResize();\n      this.onContentResize();\n    };\n    onWrapperResize = () => {\n      if (this.wrapper instanceof Window) {\n        this.width = window.innerWidth;\n        this.height = window.innerHeight;\n      } else {\n        this.width = this.wrapper.clientWidth;\n        this.height = this.wrapper.clientHeight;\n      }\n    };\n    onContentResize = () => {\n      if (this.wrapper instanceof Window) {\n        this.scrollHeight = this.content.scrollHeight;\n        this.scrollWidth = this.content.scrollWidth;\n      } else {\n        this.scrollHeight = this.wrapper.scrollHeight;\n        this.scrollWidth = this.wrapper.scrollWidth;\n      }\n    };\n    get limit() {\n      return {\n        x: this.scrollWidth - this.width,\n        y: this.scrollHeight - this.height\n      };\n    }\n  };\n\n  // packages/core/src/emitter.ts\n  var Emitter = class {\n    events = {};\n    /**\n     * Emit an event with the given data\n     * @param event Event name\n     * @param args Data to pass to the event handlers\n     */\n    emit(event, ...args) {\n      let callbacks = this.events[event] || [];\n      for (let i = 0, length = callbacks.length; i < length; i++) {\n        callbacks[i]?.(...args);\n      }\n    }\n    /**\n     * Add a callback to the event\n     * @param event Event name\n     * @param cb Callback function\n     * @returns Unsubscribe function\n     */\n    on(event, cb) {\n      this.events[event]?.push(cb) || (this.events[event] = [cb]);\n      return () => {\n        this.events[event] = this.events[event]?.filter((i) => cb !== i);\n      };\n    }\n    /**\n     * Remove a callback from the event\n     * @param event Event name\n     * @param callback Callback function\n     */\n    off(event, callback) {\n      this.events[event] = this.events[event]?.filter((i) => callback !== i);\n    }\n    /**\n     * Remove all event listeners and clean up\n     */\n    destroy() {\n      this.events = {};\n    }\n  };\n\n  // packages/core/src/virtual-scroll.ts\n  var LINE_HEIGHT = 100 / 6;\n  var listenerOptions = { passive: false };\n  var VirtualScroll = class {\n    constructor(element, options = { wheelMultiplier: 1, touchMultiplier: 1 }) {\n      this.element = element;\n      this.options = options;\n      window.addEventListener(\"resize\", this.onWindowResize, false);\n      this.onWindowResize();\n      this.element.addEventListener(\"wheel\", this.onWheel, listenerOptions);\n      this.element.addEventListener(\n        \"touchstart\",\n        this.onTouchStart,\n        listenerOptions\n      );\n      this.element.addEventListener(\n        \"touchmove\",\n        this.onTouchMove,\n        listenerOptions\n      );\n      this.element.addEventListener(\"touchend\", this.onTouchEnd, listenerOptions);\n    }\n    touchStart = {\n      x: 0,\n      y: 0\n    };\n    lastDelta = {\n      x: 0,\n      y: 0\n    };\n    window = {\n      width: 0,\n      height: 0\n    };\n    emitter = new Emitter();\n    /**\n     * Add an event listener for the given event and callback\n     *\n     * @param event Event name\n     * @param callback Callback function\n     */\n    on(event, callback) {\n      return this.emitter.on(event, callback);\n    }\n    /** Remove all event listeners and clean up */\n    destroy() {\n      this.emitter.destroy();\n      window.removeEventListener(\"resize\", this.onWindowResize, false);\n      this.element.removeEventListener(\"wheel\", this.onWheel, listenerOptions);\n      this.element.removeEventListener(\n        \"touchstart\",\n        this.onTouchStart,\n        listenerOptions\n      );\n      this.element.removeEventListener(\n        \"touchmove\",\n        this.onTouchMove,\n        listenerOptions\n      );\n      this.element.removeEventListener(\n        \"touchend\",\n        this.onTouchEnd,\n        listenerOptions\n      );\n    }\n    /**\n     * Event handler for 'touchstart' event\n     *\n     * @param event Touch event\n     */\n    onTouchStart = (event) => {\n      const { clientX, clientY } = event.targetTouches ? event.targetTouches[0] : event;\n      this.touchStart.x = clientX;\n      this.touchStart.y = clientY;\n      this.lastDelta = {\n        x: 0,\n        y: 0\n      };\n      this.emitter.emit(\"scroll\", {\n        deltaX: 0,\n        deltaY: 0,\n        event\n      });\n    };\n    /** Event handler for 'touchmove' event */\n    onTouchMove = (event) => {\n      const { clientX, clientY } = event.targetTouches ? event.targetTouches[0] : event;\n      const deltaX = -(clientX - this.touchStart.x) * this.options.touchMultiplier;\n      const deltaY = -(clientY - this.touchStart.y) * this.options.touchMultiplier;\n      this.touchStart.x = clientX;\n      this.touchStart.y = clientY;\n      this.lastDelta = {\n        x: deltaX,\n        y: deltaY\n      };\n      this.emitter.emit(\"scroll\", {\n        deltaX,\n        deltaY,\n        event\n      });\n    };\n    onTouchEnd = (event) => {\n      this.emitter.emit(\"scroll\", {\n        deltaX: this.lastDelta.x,\n        deltaY: this.lastDelta.y,\n        event\n      });\n    };\n    /** Event handler for 'wheel' event */\n    onWheel = (event) => {\n      let { deltaX, deltaY, deltaMode } = event;\n      const multiplierX = deltaMode === 1 ? LINE_HEIGHT : deltaMode === 2 ? this.window.width : 1;\n      const multiplierY = deltaMode === 1 ? LINE_HEIGHT : deltaMode === 2 ? this.window.height : 1;\n      deltaX *= multiplierX;\n      deltaY *= multiplierY;\n      deltaX *= this.options.wheelMultiplier;\n      deltaY *= this.options.wheelMultiplier;\n      this.emitter.emit(\"scroll\", { deltaX, deltaY, event });\n    };\n    onWindowResize = () => {\n      this.window = {\n        width: window.innerWidth,\n        height: window.innerHeight\n      };\n    };\n  };\n\n  // packages/core/src/lenis.ts\n  var defaultEasing = (t) => Math.min(1, 1.001 - Math.pow(2, -10 * t));\n  var Lenis = class {\n    _isScrolling = false;\n    // true when scroll is animating\n    _isStopped = false;\n    // true if user should not be able to scroll - enable/disable programmatically\n    _isLocked = false;\n    // same as isStopped but enabled/disabled when scroll reaches target\n    _preventNextNativeScrollEvent = false;\n    _resetVelocityTimeout = null;\n    _rafId = null;\n    /**\n     * Whether or not the user is touching the screen\n     */\n    isTouching;\n    /**\n     * The time in ms since the lenis instance was created\n     */\n    time = 0;\n    /**\n     * User data that will be forwarded through the scroll event\n     *\n     * @example\n     * lenis.scrollTo(100, {\n     *   userData: {\n     *     foo: 'bar'\n     *   }\n     * })\n     */\n    userData = {};\n    /**\n     * The last velocity of the scroll\n     */\n    lastVelocity = 0;\n    /**\n     * The current velocity of the scroll\n     */\n    velocity = 0;\n    /**\n     * The direction of the scroll\n     */\n    direction = 0;\n    /**\n     * The options passed to the lenis instance\n     */\n    options;\n    /**\n     * The target scroll value\n     */\n    targetScroll;\n    /**\n     * The animated scroll value\n     */\n    animatedScroll;\n    // These are instanciated here as they don't need information from the options\n    animate = new Animate();\n    emitter = new Emitter();\n    // These are instanciated in the constructor as they need information from the options\n    dimensions;\n    // This is not private because it's used in the Snap class\n    virtualScroll;\n    constructor({\n      wrapper = window,\n      content = document.documentElement,\n      eventsTarget = wrapper,\n      smoothWheel = true,\n      syncTouch = false,\n      syncTouchLerp = 0.075,\n      touchInertiaExponent = 1.7,\n      duration,\n      // in seconds\n      easing,\n      lerp: lerp2 = 0.1,\n      infinite = false,\n      orientation = \"vertical\",\n      // vertical, horizontal\n      gestureOrientation = orientation === \"horizontal\" ? \"both\" : \"vertical\",\n      // vertical, horizontal, both\n      touchMultiplier = 1,\n      wheelMultiplier = 1,\n      autoResize = true,\n      prevent,\n      virtualScroll,\n      overscroll = true,\n      autoRaf = false,\n      anchors = false,\n      autoToggle = false,\n      // https://caniuse.com/?search=transition-behavior\n      allowNestedScroll = false,\n      // @ts-ignore: this will be deprecated in the future\n      __experimental__naiveDimensions = false,\n      naiveDimensions = __experimental__naiveDimensions,\n      stopInertiaOnNavigate = false\n    } = {}) {\n      window.lenisVersion = version;\n      if (!wrapper || wrapper === document.documentElement) {\n        wrapper = window;\n      }\n      if (typeof duration === \"number\" && typeof easing !== \"function\") {\n        easing = defaultEasing;\n      } else if (typeof easing === \"function\" && typeof duration !== \"number\") {\n        duration = 1;\n      }\n      this.options = {\n        wrapper,\n        content,\n        eventsTarget,\n        smoothWheel,\n        syncTouch,\n        syncTouchLerp,\n        touchInertiaExponent,\n        duration,\n        easing,\n        lerp: lerp2,\n        infinite,\n        gestureOrientation,\n        orientation,\n        touchMultiplier,\n        wheelMultiplier,\n        autoResize,\n        prevent,\n        virtualScroll,\n        overscroll,\n        autoRaf,\n        anchors,\n        autoToggle,\n        allowNestedScroll,\n        naiveDimensions,\n        stopInertiaOnNavigate\n      };\n      this.dimensions = new Dimensions(wrapper, content, { autoResize });\n      this.updateClassName();\n      this.targetScroll = this.animatedScroll = this.actualScroll;\n      this.options.wrapper.addEventListener(\"scroll\", this.onNativeScroll, false);\n      this.options.wrapper.addEventListener(\"scrollend\", this.onScrollEnd, {\n        capture: true\n      });\n      if (this.options.anchors || this.options.stopInertiaOnNavigate) {\n        this.options.wrapper.addEventListener(\n          \"click\",\n          this.onClick,\n          false\n        );\n      }\n      this.options.wrapper.addEventListener(\n        \"pointerdown\",\n        this.onPointerDown,\n        false\n      );\n      this.virtualScroll = new VirtualScroll(eventsTarget, {\n        touchMultiplier,\n        wheelMultiplier\n      });\n      this.virtualScroll.on(\"scroll\", this.onVirtualScroll);\n      if (this.options.autoToggle) {\n        this.checkOverflow();\n        this.rootElement.addEventListener(\"transitionend\", this.onTransitionEnd, {\n          passive: true\n        });\n      }\n      if (this.options.autoRaf) {\n        this._rafId = requestAnimationFrame(this.raf);\n      }\n    }\n    /**\n     * Destroy the lenis instance, remove all event listeners and clean up the class name\n     */\n    destroy() {\n      this.emitter.destroy();\n      this.options.wrapper.removeEventListener(\n        \"scroll\",\n        this.onNativeScroll,\n        false\n      );\n      this.options.wrapper.removeEventListener(\"scrollend\", this.onScrollEnd, {\n        capture: true\n      });\n      this.options.wrapper.removeEventListener(\n        \"pointerdown\",\n        this.onPointerDown,\n        false\n      );\n      if (this.options.anchors || this.options.stopInertiaOnNavigate) {\n        this.options.wrapper.removeEventListener(\n          \"click\",\n          this.onClick,\n          false\n        );\n      }\n      this.virtualScroll.destroy();\n      this.dimensions.destroy();\n      this.cleanUpClassName();\n      if (this._rafId) {\n        cancelAnimationFrame(this._rafId);\n      }\n    }\n    on(event, callback) {\n      return this.emitter.on(event, callback);\n    }\n    off(event, callback) {\n      return this.emitter.off(event, callback);\n    }\n    onScrollEnd = (e) => {\n      if (!(e instanceof CustomEvent)) {\n        if (this.isScrolling === \"smooth\" || this.isScrolling === false) {\n          e.stopPropagation();\n        }\n      }\n    };\n    dispatchScrollendEvent = () => {\n      this.options.wrapper.dispatchEvent(\n        new CustomEvent(\"scrollend\", {\n          bubbles: this.options.wrapper === window,\n          // cancelable: false,\n          detail: {\n            lenisScrollEnd: true\n          }\n        })\n      );\n    };\n    get overflow() {\n      const property = this.isHorizontal ? \"overflow-x\" : \"overflow-y\";\n      return getComputedStyle(this.rootElement)[property];\n    }\n    checkOverflow() {\n      if ([\"hidden\", \"clip\"].includes(this.overflow)) {\n        this.internalStop();\n      } else {\n        this.internalStart();\n      }\n    }\n    onTransitionEnd = (event) => {\n      if (event.propertyName.includes(\"overflow\")) {\n        this.checkOverflow();\n      }\n    };\n    setScroll(scroll) {\n      if (this.isHorizontal) {\n        this.options.wrapper.scrollTo({ left: scroll, behavior: \"instant\" });\n      } else {\n        this.options.wrapper.scrollTo({ top: scroll, behavior: \"instant\" });\n      }\n    }\n    onClick = (event) => {\n      const path = event.composedPath();\n      const anchorElements = path.filter(\n        (node) => node instanceof HTMLAnchorElement && node.getAttribute(\"href\")\n      );\n      if (this.options.anchors) {\n        const anchor = anchorElements.find(\n          (node) => node.getAttribute(\"href\")?.includes(\"#\")\n        );\n        if (anchor) {\n          const href = anchor.getAttribute(\"href\");\n          if (href) {\n            const options = typeof this.options.anchors === \"object\" && this.options.anchors ? this.options.anchors : void 0;\n            const target = `#${href.split(\"#\")[1]}`;\n            this.scrollTo(target, options);\n          }\n        }\n      }\n      if (this.options.stopInertiaOnNavigate) {\n        const internalLink = anchorElements.find(\n          (node) => node.host === window.location.host\n        );\n        if (internalLink) {\n          this.reset();\n        }\n      }\n    };\n    onPointerDown = (event) => {\n      if (event.button === 1) {\n        this.reset();\n      }\n    };\n    onVirtualScroll = (data) => {\n      if (typeof this.options.virtualScroll === \"function\" && this.options.virtualScroll(data) === false)\n        return;\n      const { deltaX, deltaY, event } = data;\n      this.emitter.emit(\"virtual-scroll\", { deltaX, deltaY, event });\n      if (event.ctrlKey) return;\n      if (event.lenisStopPropagation) return;\n      const isTouch = event.type.includes(\"touch\");\n      const isWheel = event.type.includes(\"wheel\");\n      this.isTouching = event.type === \"touchstart\" || event.type === \"touchmove\";\n      const isClickOrTap = deltaX === 0 && deltaY === 0;\n      const isTapToStop = this.options.syncTouch && isTouch && event.type === \"touchstart\" && isClickOrTap && !this.isStopped && !this.isLocked;\n      if (isTapToStop) {\n        this.reset();\n        return;\n      }\n      const isUnknownGesture = this.options.gestureOrientation === \"vertical\" && deltaY === 0 || this.options.gestureOrientation === \"horizontal\" && deltaX === 0;\n      if (isClickOrTap || isUnknownGesture) {\n        return;\n      }\n      let composedPath = event.composedPath();\n      composedPath = composedPath.slice(0, composedPath.indexOf(this.rootElement));\n      const prevent = this.options.prevent;\n      if (!!composedPath.find(\n        (node) => node instanceof HTMLElement && (typeof prevent === \"function\" && prevent?.(node) || node.hasAttribute?.(\"data-lenis-prevent\") || isTouch && node.hasAttribute?.(\"data-lenis-prevent-touch\") || isWheel && node.hasAttribute?.(\"data-lenis-prevent-wheel\") || this.options.allowNestedScroll && this.checkNestedScroll(node, { deltaX, deltaY }))\n      ))\n        return;\n      if (this.isStopped || this.isLocked) {\n        if (event.cancelable) {\n          event.preventDefault();\n        }\n        return;\n      }\n      const isSmooth = this.options.syncTouch && isTouch || this.options.smoothWheel && isWheel;\n      if (!isSmooth) {\n        this.isScrolling = \"native\";\n        this.animate.stop();\n        event.lenisStopPropagation = true;\n        return;\n      }\n      let delta = deltaY;\n      if (this.options.gestureOrientation === \"both\") {\n        delta = Math.abs(deltaY) > Math.abs(deltaX) ? deltaY : deltaX;\n      } else if (this.options.gestureOrientation === \"horizontal\") {\n        delta = deltaX;\n      }\n      if (!this.options.overscroll || this.options.infinite || this.options.wrapper !== window && this.limit > 0 && (this.animatedScroll > 0 && this.animatedScroll < this.limit || this.animatedScroll === 0 && deltaY > 0 || this.animatedScroll === this.limit && deltaY < 0)) {\n        event.lenisStopPropagation = true;\n      }\n      if (event.cancelable) {\n        event.preventDefault();\n      }\n      const isSyncTouch = isTouch && this.options.syncTouch;\n      const isTouchEnd = isTouch && event.type === \"touchend\";\n      const hasTouchInertia = isTouchEnd;\n      if (hasTouchInertia) {\n        delta = Math.sign(this.velocity) * Math.pow(Math.abs(this.velocity), this.options.touchInertiaExponent);\n      }\n      this.scrollTo(this.targetScroll + delta, {\n        programmatic: false,\n        ...isSyncTouch ? {\n          lerp: hasTouchInertia ? this.options.syncTouchLerp : 1\n        } : {\n          lerp: this.options.lerp,\n          duration: this.options.duration,\n          easing: this.options.easing\n        }\n      });\n    };\n    /**\n     * Force lenis to recalculate the dimensions\n     */\n    resize() {\n      this.dimensions.resize();\n      this.animatedScroll = this.targetScroll = this.actualScroll;\n      this.emit();\n    }\n    emit() {\n      this.emitter.emit(\"scroll\", this);\n    }\n    onNativeScroll = () => {\n      if (this._resetVelocityTimeout !== null) {\n        clearTimeout(this._resetVelocityTimeout);\n        this._resetVelocityTimeout = null;\n      }\n      if (this._preventNextNativeScrollEvent) {\n        this._preventNextNativeScrollEvent = false;\n        return;\n      }\n      if (this.isScrolling === false || this.isScrolling === \"native\") {\n        const lastScroll = this.animatedScroll;\n        this.animatedScroll = this.targetScroll = this.actualScroll;\n        this.lastVelocity = this.velocity;\n        this.velocity = this.animatedScroll - lastScroll;\n        this.direction = Math.sign(\n          this.animatedScroll - lastScroll\n        );\n        if (!this.isStopped) {\n          this.isScrolling = \"native\";\n        }\n        this.emit();\n        if (this.velocity !== 0) {\n          this._resetVelocityTimeout = setTimeout(() => {\n            this.lastVelocity = this.velocity;\n            this.velocity = 0;\n            this.isScrolling = false;\n            this.emit();\n          }, 400);\n        }\n      }\n    };\n    reset() {\n      this.isLocked = false;\n      this.isScrolling = false;\n      this.animatedScroll = this.targetScroll = this.actualScroll;\n      this.lastVelocity = this.velocity = 0;\n      this.animate.stop();\n    }\n    /**\n     * Start lenis scroll after it has been stopped\n     */\n    start() {\n      if (!this.isStopped) return;\n      if (this.options.autoToggle) {\n        this.rootElement.style.removeProperty(\"overflow\");\n        return;\n      }\n      this.internalStart();\n    }\n    internalStart() {\n      if (!this.isStopped) return;\n      this.reset();\n      this.isStopped = false;\n      this.emit();\n    }\n    /**\n     * Stop lenis scroll\n     */\n    stop() {\n      if (this.isStopped) return;\n      if (this.options.autoToggle) {\n        this.rootElement.style.setProperty(\"overflow\", \"clip\");\n        return;\n      }\n      this.internalStop();\n    }\n    internalStop() {\n      if (this.isStopped) return;\n      this.reset();\n      this.isStopped = true;\n      this.emit();\n    }\n    /**\n     * RequestAnimationFrame for lenis\n     *\n     * @param time The time in ms from an external clock like `requestAnimationFrame` or Tempus\n     */\n    raf = (time) => {\n      const deltaTime = time - (this.time || time);\n      this.time = time;\n      this.animate.advance(deltaTime * 1e-3);\n      if (this.options.autoRaf) {\n        this._rafId = requestAnimationFrame(this.raf);\n      }\n    };\n    /**\n     * Scroll to a target value\n     *\n     * @param target The target value to scroll to\n     * @param options The options for the scroll\n     *\n     * @example\n     * lenis.scrollTo(100, {\n     *   offset: 100,\n     *   duration: 1,\n     *   easing: (t) => 1 - Math.cos((t * Math.PI) / 2),\n     *   lerp: 0.1,\n     *   onStart: () => {\n     *     console.log('onStart')\n     *   },\n     *   onComplete: () => {\n     *     console.log('onComplete')\n     *   },\n     * })\n     */\n    scrollTo(target, {\n      offset = 0,\n      immediate = false,\n      lock = false,\n      programmatic = true,\n      // called from outside of the class\n      lerp: lerp2 = programmatic ? this.options.lerp : void 0,\n      duration = programmatic ? this.options.duration : void 0,\n      easing = programmatic ? this.options.easing : void 0,\n      onStart,\n      onComplete,\n      force = false,\n      // scroll even if stopped\n      userData\n    } = {}) {\n      if ((this.isStopped || this.isLocked) && !force) return;\n      if (typeof target === \"string\" && [\"top\", \"left\", \"start\", \"#\"].includes(target)) {\n        target = 0;\n      } else if (typeof target === \"string\" && [\"bottom\", \"right\", \"end\"].includes(target)) {\n        target = this.limit;\n      } else {\n        let node;\n        if (typeof target === \"string\") {\n          node = document.querySelector(target);\n          if (!node) {\n            if (target === \"#top\") {\n              target = 0;\n            } else {\n              console.warn(\"Lenis: Target not found\", target);\n            }\n          }\n        } else if (target instanceof HTMLElement && target?.nodeType) {\n          node = target;\n        }\n        if (node) {\n          if (this.options.wrapper !== window) {\n            const wrapperRect = this.rootElement.getBoundingClientRect();\n            offset -= this.isHorizontal ? wrapperRect.left : wrapperRect.top;\n          }\n          const rect = node.getBoundingClientRect();\n          target = (this.isHorizontal ? rect.left : rect.top) + this.animatedScroll;\n        }\n      }\n      if (typeof target !== \"number\") return;\n      target += offset;\n      target = Math.round(target);\n      if (this.options.infinite) {\n        if (programmatic) {\n          this.targetScroll = this.animatedScroll = this.scroll;\n          const distance = target - this.animatedScroll;\n          if (distance > this.limit / 2) {\n            target = target - this.limit;\n          } else if (distance < -this.limit / 2) {\n            target = target + this.limit;\n          }\n        }\n      } else {\n        target = clamp$1(0, target, this.limit);\n      }\n      if (target === this.targetScroll) {\n        onStart?.(this);\n        onComplete?.(this);\n        return;\n      }\n      this.userData = userData ?? {};\n      if (immediate) {\n        this.animatedScroll = this.targetScroll = target;\n        this.setScroll(this.scroll);\n        this.reset();\n        this.preventNextNativeScrollEvent();\n        this.emit();\n        onComplete?.(this);\n        this.userData = {};\n        requestAnimationFrame(() => {\n          this.dispatchScrollendEvent();\n        });\n        return;\n      }\n      if (!programmatic) {\n        this.targetScroll = target;\n      }\n      if (typeof duration === \"number\" && typeof easing !== \"function\") {\n        easing = defaultEasing;\n      } else if (typeof easing === \"function\" && typeof duration !== \"number\") {\n        duration = 1;\n      }\n      this.animate.fromTo(this.animatedScroll, target, {\n        duration,\n        easing,\n        lerp: lerp2,\n        onStart: () => {\n          if (lock) this.isLocked = true;\n          this.isScrolling = \"smooth\";\n          onStart?.(this);\n        },\n        onUpdate: (value, completed) => {\n          this.isScrolling = \"smooth\";\n          this.lastVelocity = this.velocity;\n          this.velocity = value - this.animatedScroll;\n          this.direction = Math.sign(this.velocity);\n          this.animatedScroll = value;\n          this.setScroll(this.scroll);\n          if (programmatic) {\n            this.targetScroll = value;\n          }\n          if (!completed) this.emit();\n          if (completed) {\n            this.reset();\n            this.emit();\n            onComplete?.(this);\n            this.userData = {};\n            requestAnimationFrame(() => {\n              this.dispatchScrollendEvent();\n            });\n            this.preventNextNativeScrollEvent();\n          }\n        }\n      });\n    }\n    preventNextNativeScrollEvent() {\n      this._preventNextNativeScrollEvent = true;\n      requestAnimationFrame(() => {\n        this._preventNextNativeScrollEvent = false;\n      });\n    }\n    checkNestedScroll(node, { deltaX, deltaY }) {\n      const time = Date.now();\n      const cache = node._lenis ??= {};\n      let hasOverflowX, hasOverflowY, isScrollableX, isScrollableY, scrollWidth, scrollHeight, clientWidth, clientHeight;\n      const gestureOrientation = this.options.gestureOrientation;\n      if (time - (cache.time ?? 0) > 2e3) {\n        cache.time = Date.now();\n        const computedStyle = window.getComputedStyle(node);\n        cache.computedStyle = computedStyle;\n        const overflowXString = computedStyle.overflowX;\n        const overflowYString = computedStyle.overflowY;\n        hasOverflowX = [\"auto\", \"overlay\", \"scroll\"].includes(overflowXString);\n        hasOverflowY = [\"auto\", \"overlay\", \"scroll\"].includes(overflowYString);\n        cache.hasOverflowX = hasOverflowX;\n        cache.hasOverflowY = hasOverflowY;\n        if (!hasOverflowX && !hasOverflowY) return false;\n        if (gestureOrientation === \"vertical\" && !hasOverflowY) return false;\n        if (gestureOrientation === \"horizontal\" && !hasOverflowX) return false;\n        scrollWidth = node.scrollWidth;\n        scrollHeight = node.scrollHeight;\n        clientWidth = node.clientWidth;\n        clientHeight = node.clientHeight;\n        isScrollableX = scrollWidth > clientWidth;\n        isScrollableY = scrollHeight > clientHeight;\n        cache.isScrollableX = isScrollableX;\n        cache.isScrollableY = isScrollableY;\n        cache.scrollWidth = scrollWidth;\n        cache.scrollHeight = scrollHeight;\n        cache.clientWidth = clientWidth;\n        cache.clientHeight = clientHeight;\n      } else {\n        isScrollableX = cache.isScrollableX;\n        isScrollableY = cache.isScrollableY;\n        hasOverflowX = cache.hasOverflowX;\n        hasOverflowY = cache.hasOverflowY;\n        scrollWidth = cache.scrollWidth;\n        scrollHeight = cache.scrollHeight;\n        clientWidth = cache.clientWidth;\n        clientHeight = cache.clientHeight;\n      }\n      if (!hasOverflowX && !hasOverflowY || !isScrollableX && !isScrollableY) {\n        return false;\n      }\n      if (gestureOrientation === \"vertical\" && (!hasOverflowY || !isScrollableY))\n        return false;\n      if (gestureOrientation === \"horizontal\" && (!hasOverflowX || !isScrollableX))\n        return false;\n      let orientation;\n      if (gestureOrientation === \"horizontal\") {\n        orientation = \"x\";\n      } else if (gestureOrientation === \"vertical\") {\n        orientation = \"y\";\n      } else {\n        const isScrollingX = deltaX !== 0;\n        const isScrollingY = deltaY !== 0;\n        if (isScrollingX && hasOverflowX && isScrollableX) {\n          orientation = \"x\";\n        }\n        if (isScrollingY && hasOverflowY && isScrollableY) {\n          orientation = \"y\";\n        }\n      }\n      if (!orientation) return false;\n      let scroll, maxScroll, delta, hasOverflow, isScrollable;\n      if (orientation === \"x\") {\n        scroll = node.scrollLeft;\n        maxScroll = scrollWidth - clientWidth;\n        delta = deltaX;\n        hasOverflow = hasOverflowX;\n        isScrollable = isScrollableX;\n      } else if (orientation === \"y\") {\n        scroll = node.scrollTop;\n        maxScroll = scrollHeight - clientHeight;\n        delta = deltaY;\n        hasOverflow = hasOverflowY;\n        isScrollable = isScrollableY;\n      } else {\n        return false;\n      }\n      const willScroll = delta > 0 ? scroll < maxScroll : scroll > 0;\n      return willScroll && hasOverflow && isScrollable;\n    }\n    /**\n     * The root element on which lenis is instanced\n     */\n    get rootElement() {\n      return this.options.wrapper === window ? document.documentElement : this.options.wrapper;\n    }\n    /**\n     * The limit which is the maximum scroll value\n     */\n    get limit() {\n      if (this.options.naiveDimensions) {\n        if (this.isHorizontal) {\n          return this.rootElement.scrollWidth - this.rootElement.clientWidth;\n        } else {\n          return this.rootElement.scrollHeight - this.rootElement.clientHeight;\n        }\n      } else {\n        return this.dimensions.limit[this.isHorizontal ? \"x\" : \"y\"];\n      }\n    }\n    /**\n     * Whether or not the scroll is horizontal\n     */\n    get isHorizontal() {\n      return this.options.orientation === \"horizontal\";\n    }\n    /**\n     * The actual scroll value\n     */\n    get actualScroll() {\n      const wrapper = this.options.wrapper;\n      return this.isHorizontal ? wrapper.scrollX ?? wrapper.scrollLeft : wrapper.scrollY ?? wrapper.scrollTop;\n    }\n    /**\n     * The current scroll value\n     */\n    get scroll() {\n      return this.options.infinite ? modulo(this.animatedScroll, this.limit) : this.animatedScroll;\n    }\n    /**\n     * The progress of the scroll relative to the limit\n     */\n    get progress() {\n      return this.limit === 0 ? 1 : this.scroll / this.limit;\n    }\n    /**\n     * Current scroll state\n     */\n    get isScrolling() {\n      return this._isScrolling;\n    }\n    set isScrolling(value) {\n      if (this._isScrolling !== value) {\n        this._isScrolling = value;\n        this.updateClassName();\n      }\n    }\n    /**\n     * Check if lenis is stopped\n     */\n    get isStopped() {\n      return this._isStopped;\n    }\n    set isStopped(value) {\n      if (this._isStopped !== value) {\n        this._isStopped = value;\n        this.updateClassName();\n      }\n    }\n    /**\n     * Check if lenis is locked\n     */\n    get isLocked() {\n      return this._isLocked;\n    }\n    set isLocked(value) {\n      if (this._isLocked !== value) {\n        this._isLocked = value;\n        this.updateClassName();\n      }\n    }\n    /**\n     * Check if lenis is smooth scrolling\n     */\n    get isSmooth() {\n      return this.isScrolling === \"smooth\";\n    }\n    /**\n     * The class name applied to the wrapper element\n     */\n    get className() {\n      let className = \"lenis\";\n      if (this.options.autoToggle) className += \" lenis-autoToggle\";\n      if (this.isStopped) className += \" lenis-stopped\";\n      if (this.isLocked) className += \" lenis-locked\";\n      if (this.isScrolling) className += \" lenis-scrolling\";\n      if (this.isScrolling === \"smooth\") className += \" lenis-smooth\";\n      return className;\n    }\n    updateClassName() {\n      this.cleanUpClassName();\n      this.rootElement.className = `${this.rootElement.className} ${this.className}`.trim();\n    }\n    cleanUpClassName() {\n      this.rootElement.className = this.rootElement.className.replace(/lenis(-\\w+)?/g, \"\").trim();\n    }\n  };\n\n  /**\n   * Intersection Observer\n   *\n   * Detecting visibility of an element in the viewport.\n   *\n   * Features functions to:\n   *\n   * - Trigger inview/outOfView callbacks\n   * - If the element has a requestAnimationFrame dependency, set interactivy status for the ScrollElement Class\n   *\n   * References:\n   *\n   * - {@link https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API}\n   */\n  var IO = /*#__PURE__*/function () {\n    function IO(_ref) {\n      var scrollElements = _ref.scrollElements,\n        _ref$rootMargin = _ref.rootMargin,\n        rootMargin = _ref$rootMargin === void 0 ? '-1px -1px -1px -1px' : _ref$rootMargin,\n        _ref$root = _ref.root,\n        root = _ref$root === void 0 ? null : _ref$root,\n        IORaf = _ref.IORaf;\n      this.scrollElements = void 0;\n      this.rootMargin = void 0;\n      this.root = void 0;\n      this.IORaf = void 0;\n      this.observer = void 0;\n      // Parameters\n      this.scrollElements = scrollElements;\n      this.rootMargin = rootMargin;\n      this.root = root;\n      this.IORaf = IORaf;\n      // Init\n      this._init();\n    }\n    /**\n     * Lifecyle - Initialize Intersection Observer.\n     *\n     * @private\n     */\n    var _proto = IO.prototype;\n    _proto._init = function _init() {\n      var _this = this;\n      // Options\n      var observerOptions = {\n        root: this.root,\n        rootMargin: this.rootMargin\n      };\n      // Callback\n      var onIntersect = function onIntersect(entries) {\n        entries.forEach(function (entry) {\n          var $targetItem = _this.scrollElements.find(function (item) {\n            return item.$el === entry.target;\n          });\n          if (entry.isIntersecting) {\n            $targetItem && ($targetItem.isAlreadyIntersected = true);\n            _this._setInview(entry);\n          } else if ($targetItem && $targetItem.isAlreadyIntersected) {\n            _this._setOutOfView(entry);\n          }\n        });\n      };\n      // Instance\n      this.observer = new IntersectionObserver(onIntersect, observerOptions);\n      // Observe each default elements\n      for (var _iterator = _createForOfIteratorHelperLoose(this.scrollElements), _step; !(_step = _iterator()).done;) {\n        var scrollElement = _step.value;\n        var $scrollElement = scrollElement.$el;\n        this.observe($scrollElement);\n      }\n    }\n    /**\n     * Lifecyle - Destroy Intersection Observer.\n     */;\n    _proto.destroy = function destroy() {\n      this.observer.disconnect();\n    }\n    /**\n     * Subscribe element to the Intersection Observer.\n     *\n     * @param {HTMLElement} $scrollElement - DOM Element to observe.\n     */;\n    _proto.observe = function observe($scrollElement) {\n      if (!$scrollElement) {\n        return;\n      }\n      this.observer.observe($scrollElement);\n    }\n    /**\n     * Unsubscribe element to the Intersection Observer.\n     *\n     * @param {HTMLElement} $scrollElement - DOM Element to unobserve.\n     */;\n    _proto.unobserve = function unobserve($scrollElement) {\n      if (!$scrollElement) {\n        return;\n      }\n      this.observer.unobserve($scrollElement);\n    }\n    /**\n     * Find ScrollElementReference instance and trigger inview callbacks.\n     *\n     * @private\n     *\n     * @param {IntersectionObserverEntry} entry - DOM Element to observe.\n     */;\n    _proto._setInview = function _setInview(entry) {\n      var scrollElement = this.scrollElements.find(function (scrollElement) {\n        return scrollElement.$el === entry.target;\n      });\n      this.IORaf && (scrollElement == null ? void 0 : scrollElement.setInteractivityOn());\n      !this.IORaf && (scrollElement == null ? void 0 : scrollElement.setInview());\n    }\n    /**\n     * Find ScrollElementReference instance and trigger out of view callbacks.\n     *\n     * @private\n     *\n     * @param {IntersectionObserverEntry} entry - DOM Element to observe.\n     */;\n    _proto._setOutOfView = function _setOutOfView(entry) {\n      var scrollElement = this.scrollElements.find(function (scrollElement) {\n        return scrollElement.$el === entry.target;\n      });\n      this.IORaf && (scrollElement == null ? void 0 : scrollElement.setInteractivityOff());\n      !this.IORaf && (scrollElement == null ? void 0 : scrollElement.setOutOfView());\n      // Unobserve if element doesn't have repeat attribute\n      if (!(scrollElement != null && scrollElement.attributes.scrollRepeat) && !this.IORaf) {\n        this.unobserve(entry.target);\n      }\n    };\n    return IO;\n  }();\n\n  // https://greensock.com/docs/v3/GSAP/gsap.utils\n  /**\n   * Clamp a value to fit within a specific range (ex: clamp(0, 100, -12) --> 0).\n   *\n   * @param {number} min   - Minimum value expected.\n   * @param {number} max   - Maximum value expected.\n   * @param {number} value - Current value.\n   *\n   * @returns {number} - Clamped value.\n   */\n  function clamp(min, max, value) {\n    return value < min ? min : value > max ? max : value;\n  }\n  /**\n   * Map one range to another (ex: mapRange(-10, 10, 0, 100, 5) --> 75).\n   *\n   * @param {number} inMin  - Current minimum value.\n   * @param {number} inMax  - Current maximum value.\n   * @param {number} outMin - Maximum value expected.\n   * @param {number} outMax - Maximum value expected.\n   * @param {number} value  - Current value.\n   *\n   * @returns {number} - New value that should be between minimum value expected and maximum value.\n   */\n  function mapRange(inMin, inMax, outMin, outMax, value) {\n    var inRange = inMax - inMin;\n    var outRange = outMax - outMin;\n    return outMin + ((value - inMin) / inRange * outRange || 0);\n  }\n  /**\n   * Map a number within a range to a progress between 0 to 1 (ex: normalize(100, 200, 150) --> 0.5).\n   *\n   * @param {number} min   - Current minimum value.\n   * @param {number} max   - Current maximum value.\n   * @param {number} value - Current value.\n   *\n   * @returns {number} - New value that should be between 0 and 1.\n   */\n  function normalize(min, max, value) {\n    return mapRange(min, max, 0, 1, value);\n  }\n  /**\n   * Get closest number from an array.\n   *\n   * @param {number[]} array  - Numbers array.\n   * @param {number}   target - Reference value.\n   *\n   * @returns {number} - Closest number.\n   */\n  function closestNumber(array, target) {\n    return array.reduce(function (prev, curr) {\n      return Math.abs(curr - target) < Math.abs(prev - target) ? curr : prev;\n    });\n  }\n\n  /**\n   * Scroll Element\n   *\n   * Give tools to compute element progress in the viewport and triggers callbacks to animate it.\n   *\n   * Features functions to:\n   *\n   * - scrollClass - Add a custom class when the element is intersected by the offset\n   * - scrollOffset - Determine offsets to intersect the element\n   * - scrollPosition - Determine the element positions to consider an element as intersected.\n   * - scrollCssProgress - Add a specific css variable (PROGRESS_CSS_VAR) that store the scroll progress\n   * - scrollEventProgress - Send scroll progress to custom event listeners.\n   * - scrollSpeed - Add a scroll multiplicator to create a parallax effect\n   * - scrollRepeat - Repeat the option to trigger animation each time the element is intersected\n   * - scrollCall - Call a custom event when the element is intersected\n   */\n  /** Constants */\n  var INVIEW_CLASS = 'is-inview';\n  var PROGRESS_CSS_VAR = '--progress';\n  var ScrollElement = /*#__PURE__*/function () {\n    function ScrollElement(_ref) {\n      var _this$$el$dataset$scr,\n        _this$$el$dataset$scr2,\n        _this$$el$dataset$scr3,\n        _this$$el$dataset$scr4,\n        _this$$el$dataset$scr5,\n        _this = this;\n      var $el = _ref.$el,\n        id = _ref.id,\n        subscribeElementUpdateFn = _ref.subscribeElementUpdateFn,\n        unsubscribeElementUpdateFn = _ref.unsubscribeElementUpdateFn,\n        needRaf = _ref.needRaf,\n        scrollOrientation = _ref.scrollOrientation,\n        lenisInstance = _ref.lenisInstance;\n      this.$el = void 0;\n      this.id = void 0;\n      this.needRaf = void 0;\n      this.attributes = void 0;\n      this.scrollOrientation = void 0;\n      this.isAlreadyIntersected = void 0;\n      this.intersection = void 0;\n      this.metrics = void 0;\n      this.currentScroll = void 0;\n      this.translateValue = void 0;\n      this.progress = void 0;\n      this.lastProgress = void 0;\n      this.isInview = void 0;\n      this.isInteractive = void 0;\n      this.isInFold = void 0;\n      this.isFirstResize = void 0;\n      this.subscribeElementUpdateFn = void 0;\n      this.unsubscribeElementUpdateFn = void 0;\n      this.lenisInstance = void 0;\n      // Cached functions to avoid orientation checks every frame\n      this.getWindowSize = void 0;\n      this.getMetricsStart = void 0;\n      this.getMetricsSize = void 0;\n      // Position handlers for intersection.start (includes wSize)\n      this.startPositionHandlers = {\n        'start': function start(offsetStart, wSize, viewport) {\n          return offsetStart - wSize + viewport;\n        },\n        'middle': function middle(offsetStart, wSize, viewport, size) {\n          return offsetStart - wSize + viewport + size * 0.5;\n        },\n        'end': function end(offsetStart, wSize, viewport, size) {\n          return offsetStart - wSize + viewport + size;\n        },\n        'fold': function fold() {\n          return 0;\n        }\n      };\n      // Position handlers for intersection.end (DOES NOT include wSize - critical difference)\n      this.endPositionHandlers = {\n        'start': function start(offsetStart, viewport) {\n          return offsetStart - viewport;\n        },\n        'middle': function middle(offsetStart, viewport, size) {\n          return offsetStart - viewport + size * 0.5;\n        },\n        'end': function end(offsetStart, viewport, size) {\n          return offsetStart - viewport + size;\n        }\n      };\n      // Scroll DOM element\n      this.$el = $el;\n      // Unique ID\n      this.id = id;\n      // RAF option\n      this.needRaf = needRaf;\n      // Scroll Direction\n      this.scrollOrientation = scrollOrientation;\n      // Lenis instance\n      this.lenisInstance = lenisInstance;\n      // Parent's callbacks\n      this.subscribeElementUpdateFn = subscribeElementUpdateFn;\n      this.unsubscribeElementUpdateFn = unsubscribeElementUpdateFn;\n      // Attributes\n      this.attributes = {\n        scrollClass: (_this$$el$dataset$scr = this.$el.dataset['scrollClass']) != null ? _this$$el$dataset$scr : INVIEW_CLASS,\n        scrollOffset: (_this$$el$dataset$scr2 = this.$el.dataset['scrollOffset']) != null ? _this$$el$dataset$scr2 : '0,0',\n        scrollPosition: (_this$$el$dataset$scr3 = this.$el.dataset['scrollPosition']) != null ? _this$$el$dataset$scr3 : 'start,end',\n        scrollCssProgress: this.$el.dataset['scrollCssProgress'] !== undefined,\n        scrollEventProgress: (_this$$el$dataset$scr4 = this.$el.dataset['scrollEventProgress']) != null ? _this$$el$dataset$scr4 : null,\n        scrollSpeed: this.$el.dataset['scrollSpeed'] !== undefined ? parseFloat(this.$el.dataset['scrollSpeed']) : null,\n        scrollRepeat: this.$el.dataset['scrollRepeat'] !== undefined,\n        scrollCall: (_this$$el$dataset$scr5 = this.$el.dataset['scrollCall']) != null ? _this$$el$dataset$scr5 : null,\n        scrollIgnoreFold: this.$el.dataset['scrollIgnoreFold'] !== undefined,\n        scrollEnableTouchSpeed: this.$el.dataset['scrollEnableTouchSpeed'] !== undefined\n      };\n      // Limits\n      this.intersection = {\n        start: 0,\n        end: 0\n      };\n      // Metrics\n      this.metrics = {\n        offsetStart: 0,\n        offsetEnd: 0,\n        bcr: {}\n      };\n      // Scroll Values\n      this.currentScroll = this.lenisInstance.scroll;\n      // Parallax\n      this.translateValue = 0;\n      // Progress\n      this.progress = 0;\n      this.lastProgress = null;\n      // Inview\n      this.isInview = false;\n      this.isInteractive = false;\n      this.isAlreadyIntersected = false;\n      this.isInFold = false;\n      this.isFirstResize = true;\n      // Cache orientation-dependent functions to avoid repeated conditionals\n      this.getWindowSize = this.scrollOrientation === 'vertical' ? function () {\n        return _this.lenisInstance.dimensions.height;\n      } : function () {\n        return _this.lenisInstance.dimensions.width;\n      };\n      this.getMetricsStart = this.scrollOrientation === 'vertical' ? function (bcr) {\n        return bcr.top;\n      } : function (bcr) {\n        return bcr.left;\n      };\n      this.getMetricsSize = this.scrollOrientation === 'vertical' ? function (bcr) {\n        return bcr.height;\n      } : function (bcr) {\n        return bcr.width;\n      };\n      // Init\n      this._init();\n    }\n    /**\n     * Lifecyle - Initialize progress tracking.\n     *\n     * @private\n     */\n    var _proto = ScrollElement.prototype;\n    _proto._init = function _init() {\n      if (!this.needRaf) {\n        return;\n      }\n      // First resize to compute all values\n      this._resize();\n    }\n    /**\n     * Callback - Resize callback\n     */;\n    _proto.onResize = function onResize(_ref2) {\n      var currentScroll = _ref2.currentScroll;\n      this.currentScroll = currentScroll;\n      this._resize();\n    }\n    /**\n     * Callback - RAF callback\n     */;\n    _proto.onRender = function onRender(_ref3) {\n      var currentScroll = _ref3.currentScroll,\n        smooth = _ref3.smooth;\n      var wSize = this.getWindowSize();\n      this.currentScroll = currentScroll;\n      this._computeProgress();\n      // Parallax\n      if (this.attributes.scrollSpeed && !isNaN(this.attributes.scrollSpeed)) {\n        // if touch detected or smooth disabled\n        if (!this.attributes.scrollEnableTouchSpeed && !smooth) {\n          if (this.translateValue) {\n            this.$el.style.transform = \"translate3d(0, 0, 0)\";\n          }\n          this.translateValue = 0;\n          // if mousewheel or smooth enabled\n        } else {\n          // Check fold condition\n          if (this.isInFold) {\n            var progress = Math.max(0, this.progress);\n            this.translateValue = progress * wSize * this.attributes.scrollSpeed * -1;\n          } else {\n            var _progress = mapRange(0, 1, -1, 1, this.progress);\n            this.translateValue = _progress * wSize * this.attributes.scrollSpeed * -1;\n          }\n          this.$el.style.transform = this.scrollOrientation === 'vertical' ? \"translate3d(0, \" + this.translateValue + \"px, 0)\" : \"translate3d(\" + this.translateValue + \"px, 0, 0)\";\n        }\n      }\n    }\n    /**\n     * Inview callback\n     */;\n    _proto.setInview = function setInview() {\n      if (this.isInview) {\n        return;\n      }\n      this.isInview = true;\n      this.$el.classList.add(this.attributes.scrollClass);\n      var way = 'enter';\n      var from = this._getScrollCallFrom();\n      this.attributes.scrollCall && this._dispatchCall(way, from);\n    }\n    /**\n     * Out of view callback\n     */;\n    _proto.setOutOfView = function setOutOfView() {\n      if (!(this.isInview && this.attributes.scrollRepeat)) {\n        return;\n      }\n      this.isInview = false;\n      this.$el.classList.remove(this.attributes.scrollClass);\n      var way = 'leave';\n      var from = this._getScrollCallFrom();\n      this.attributes.scrollCall && this._dispatchCall(way, from);\n    }\n    /**\n     * Switch interactivity on to subscribe the instance to the RAF\n     * and start calculations.\n     */;\n    _proto.setInteractivityOn = function setInteractivityOn() {\n      if (this.isInteractive) {\n        return;\n      }\n      this.isInteractive = true;\n      this.subscribeElementUpdateFn(this);\n    }\n    /**\n     * Switch interactivity off to unsubscribe the instance to the RAF\n     * and stop calculations.\n     */;\n    _proto.setInteractivityOff = function setInteractivityOff() {\n      if (!this.isInteractive) {\n        return;\n      }\n      this.isInteractive = false;\n      this.unsubscribeElementUpdateFn(this);\n      // Force progress to progress limit when the element is out\n      this.lastProgress !== null && this._computeProgress(closestNumber([0, 1], this.lastProgress));\n    }\n    /**\n     * Resize method that compute the element's values.\n     *\n     * @private\n     */;\n    _proto._resize = function _resize() {\n      this.metrics.bcr = this.$el.getBoundingClientRect();\n      this._computeMetrics();\n      this._computeIntersection();\n      // First resize logic\n      if (this.isFirstResize) {\n        this.isFirstResize = false;\n        // Dispatch default call if the element is in fold.\n        if (this.isInFold) {\n          this.setInview();\n        }\n      }\n    }\n    /**\n     * Compute element's offsets and determine if the element is in fold.\n     *\n     * @private\n     */;\n    _proto._computeMetrics = function _computeMetrics() {\n      var wSize = this.getWindowSize();\n      var metricsStart = this.getMetricsStart(this.metrics.bcr);\n      var metricsSize = this.getMetricsSize(this.metrics.bcr);\n      this.metrics.offsetStart = this.currentScroll + metricsStart - this.translateValue;\n      this.metrics.offsetEnd = this.metrics.offsetStart + metricsSize;\n      if (this.metrics.offsetStart < wSize && !this.attributes.scrollIgnoreFold) {\n        this.isInFold = true;\n      } else {\n        this.isInFold = false;\n      }\n    }\n    /**\n     * Compute intersection values depending on the context.\n     * Uses handler-based approach for cleaner, more maintainable code.\n     *\n     * @private\n     */;\n    _proto._computeIntersection = function _computeIntersection() {\n      var _offset$0$trim, _offset$, _offset$1$trim, _offset$2, _scrollPosition$0$tri, _scrollPosition$, _scrollPosition$1$tri, _scrollPosition$2;\n      var wSize = this.getWindowSize();\n      var metricsSize = this.getMetricsSize(this.metrics.bcr);\n      // Parse offset\n      var offset = this.attributes.scrollOffset.split(',');\n      var offsetStart = (_offset$0$trim = (_offset$ = offset[0]) == null ? void 0 : _offset$.trim()) != null ? _offset$0$trim : '0';\n      var offsetEnd = (_offset$1$trim = (_offset$2 = offset[1]) == null ? void 0 : _offset$2.trim()) != null ? _offset$1$trim : '0';\n      // Parse positions\n      var scrollPosition = this.attributes.scrollPosition.split(',');\n      var scrollPositionStart = (_scrollPosition$0$tri = (_scrollPosition$ = scrollPosition[0]) == null ? void 0 : _scrollPosition$.trim()) != null ? _scrollPosition$0$tri : 'start';\n      var scrollPositionEnd = (_scrollPosition$1$tri = (_scrollPosition$2 = scrollPosition[1]) == null ? void 0 : _scrollPosition$2.trim()) != null ? _scrollPosition$1$tri : 'end';\n      // Calculate viewport offsets\n      var viewportStart = offsetStart.includes('%') ? wSize * parseInt(offsetStart.replace('%', '').trim()) * 0.01 : parseInt(offsetStart);\n      var viewportEnd = offsetEnd.includes('%') ? wSize * parseInt(offsetEnd.replace('%', '').trim()) * 0.01 : parseInt(offsetEnd);\n      // Fold exception\n      if (this.isInFold) {\n        scrollPositionStart = 'fold';\n      }\n      // Calculate intersection.start using handlers\n      var startHandler = this.startPositionHandlers[scrollPositionStart];\n      this.intersection.start = startHandler ? startHandler(this.metrics.offsetStart, wSize, viewportStart, metricsSize) : this.metrics.offsetStart - wSize + viewportStart; // default fallback\n      // Calculate intersection.end using handlers\n      var endHandler = this.endPositionHandlers[scrollPositionEnd];\n      this.intersection.end = endHandler ? endHandler(this.metrics.offsetStart, viewportEnd, metricsSize) : this.metrics.offsetStart - viewportEnd + metricsSize; // default fallback\n      // Ensure end > start\n      if (this.intersection.end <= this.intersection.start) {\n        switch (scrollPositionEnd) {\n          case 'start':\n            this.intersection.end = this.intersection.start + 1;\n            break;\n          case 'middle':\n            this.intersection.end = this.intersection.start + metricsSize * 0.5;\n            break;\n          case 'end':\n            this.intersection.end = this.intersection.start + metricsSize;\n            break;\n          default:\n            this.intersection.end = this.intersection.start + 1;\n            break;\n        }\n      }\n    }\n    /**\n     * Compute the scroll progress of the element depending\n     * on its intersection values.\n     *\n     * @private\n     *\n     * @param {number} [forcedProgress] - Value to force progress.\n     */;\n    _proto._computeProgress = function _computeProgress(forcedProgress) {\n      // Progress\n      var progress = forcedProgress != null ? forcedProgress : clamp(0, 1, normalize(this.intersection.start, this.intersection.end, this.currentScroll));\n      this.progress = progress;\n      if (progress !== this.lastProgress) {\n        this.lastProgress = progress;\n        // Set the element's progress to the css variable\n        this.attributes.scrollCssProgress && this._setCssProgress(progress);\n        // Set the element's progress to the custom event listeners\n        this.attributes.scrollEventProgress && this._setCustomEventProgress(progress);\n        // Logic to trigger the inview/out of view callbacks\n        progress > 0 && progress < 1 && this.setInview();\n        progress === 0 && this.setOutOfView();\n        progress === 1 && this.setOutOfView();\n      }\n    }\n    /**\n     * Set the element's progress to a specific css variable.\n     *\n     * @private\n     *\n     * @param {number} [currentProgress] - Progress value.\n     */;\n    _proto._setCssProgress = function _setCssProgress(currentProgress) {\n      if (currentProgress === void 0) {\n        currentProgress = 0;\n      }\n      this.$el.style.setProperty(PROGRESS_CSS_VAR, currentProgress.toString());\n    }\n    /**\n     * Set the element's progress to the custom event listeners.\n     *\n     * @private\n     *\n     * @param {number} [currentProgress] - Progress value.\n     */;\n    _proto._setCustomEventProgress = function _setCustomEventProgress(currentProgress) {\n      if (currentProgress === void 0) {\n        currentProgress = 0;\n      }\n      var customEventName = this.attributes.scrollEventProgress;\n      if (!customEventName) return;\n      var customEvent = new CustomEvent(customEventName, {\n        detail: {\n          target: this.$el,\n          progress: currentProgress\n        }\n      });\n      window.dispatchEvent(customEvent);\n    }\n    /**\n     * Function to get scroll call from.\n     *\n     * @private\n     */;\n    _proto._getScrollCallFrom = function _getScrollCallFrom() {\n      var closestIntersectionValue = closestNumber([this.intersection.start, this.intersection.end], this.currentScroll);\n      return this.intersection.start === closestIntersectionValue ? 'start' : 'end';\n    }\n    /**\n     * Lifecyle - Destroy and cleanup the scroll element.\n     *\n     * Removes all CSS modifications and clears references to prevent memory leaks.\n     */;\n    _proto.destroy = function destroy() {\n      // Remove CSS variables\n      if (this.attributes.scrollCssProgress) {\n        this.$el.style.removeProperty(PROGRESS_CSS_VAR);\n      }\n      // Remove transform if parallax was applied\n      if (this.attributes.scrollSpeed) {\n        this.$el.style.removeProperty('transform');\n      }\n      // Remove class if added\n      if (this.isInview && this.attributes.scrollClass) {\n        this.$el.classList.remove(this.attributes.scrollClass);\n      }\n    }\n    /**\n     * Function to dispatch a custom event.\n     *\n     * @private\n     *\n     * @param {string} way - Enter or leave.\n     * @param {string} from - Start or end.\n     */;\n    _proto._dispatchCall = function _dispatchCall(way, from) {\n      var customEventName = this.attributes.scrollCall;\n      if (!customEventName) return;\n      // Using CustomEvent API (https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent)\n      var customEvent = new CustomEvent(customEventName, {\n        detail: {\n          target: this.$el,\n          way: way,\n          from: from\n        }\n      });\n      window.dispatchEvent(customEvent);\n    };\n    return ScrollElement;\n  }();\n\n  /** Defined attributes that need a requestAnimationFrame */\n  var ATTRIBUTES_THAT_NEED_RAF = ['scrollOffset', 'scrollPosition', 'scrollCssProgress', 'scrollEventProgress', 'scrollSpeed'];\n  /** Default root margins */\n  var TRIGGER_ROOT_MARGIN = '-1px -1px -1px -1px';\n  var RAF_ROOT_MARGIN = '100% 100% 100% 100%'; // Add 100vh top/bottom && 100vw left/right to use a biggest value with data-scroll-speed\n  /** Default scroll attribute values */\n  var DEFAULT_SCROLL_OFFSET = '0,0';\n  var DEFAULT_SCROLL_POSITION = 'top,bottom';\n  var Core = /*#__PURE__*/function () {\n    function Core(_ref) {\n      var $el = _ref.$el,\n        triggerRootMargin = _ref.triggerRootMargin,\n        rafRootMargin = _ref.rafRootMargin,\n        scrollOrientation = _ref.scrollOrientation,\n        lenisInstance = _ref.lenisInstance;\n      this.$scrollContainer = void 0;\n      this.triggerRootMargin = void 0;\n      this.rafRootMargin = void 0;\n      this.scrollElements = void 0;\n      this.triggeredScrollElements = void 0;\n      this.RAFScrollElements = void 0;\n      this.scrollElementsToUpdate = void 0;\n      this.IOTriggerInstance = void 0;\n      this.IORafInstance = void 0;\n      this.scrollOrientation = void 0;\n      this.lenisInstance = void 0;\n      if (!$el) {\n        console.error('Please provide a DOM Element as scrollContainer');\n        return;\n      }\n      // Scroll container\n      this.$scrollContainer = $el;\n      // Lenis instance\n      this.lenisInstance = lenisInstance;\n      // Scroll Direction\n      this.scrollOrientation = scrollOrientation;\n      // IO Margins\n      this.triggerRootMargin = triggerRootMargin != null ? triggerRootMargin : TRIGGER_ROOT_MARGIN;\n      this.rafRootMargin = rafRootMargin != null ? rafRootMargin : RAF_ROOT_MARGIN;\n      // ScrollElements arrays\n      this.scrollElements = [];\n      this.triggeredScrollElements = [];\n      this.RAFScrollElements = [];\n      this.scrollElementsToUpdate = [];\n      // Init\n      this._init();\n    }\n    /**\n     * Lifecyle - Initialize the core.\n     *\n     * @private\n     */\n    var _proto = Core.prototype;\n    _proto._init = function _init() {\n      var $scrollElements = this.$scrollContainer.querySelectorAll('[data-scroll]');\n      var $scrollElementsArr = this.toElementArray($scrollElements);\n      this._subscribeScrollElements($scrollElementsArr);\n      // Determine IO root (null for window, wrapper element for custom container)\n      var ioRoot = this.lenisInstance.options.wrapper === window ? null : this.lenisInstance.options.wrapper;\n      // Trigger IO\n      this.IOTriggerInstance = new IO({\n        scrollElements: [].concat(this.triggeredScrollElements),\n        root: ioRoot,\n        rootMargin: this.triggerRootMargin,\n        IORaf: false\n      });\n      // Raf IO\n      this.IORafInstance = new IO({\n        scrollElements: [].concat(this.RAFScrollElements),\n        root: ioRoot,\n        rootMargin: this.rafRootMargin,\n        IORaf: true\n      });\n    }\n    /**\n     * Lifecyle - Destroy core.\n     */;\n    _proto.destroy = function destroy() {\n      this.IOTriggerInstance.destroy();\n      this.IORafInstance.destroy();\n      this._unsubscribeAllScrollElements();\n    }\n    /**\n     * Callback - Resize callback.\n     */;\n    _proto.onResize = function onResize(_ref2) {\n      var currentScroll = _ref2.currentScroll;\n      for (var _iterator = _createForOfIteratorHelperLoose(this.RAFScrollElements), _step; !(_step = _iterator()).done;) {\n        var scrollElement = _step.value;\n        scrollElement.onResize({\n          currentScroll: currentScroll\n        });\n      }\n    }\n    /**\n     * Callback - RAF callback.\n     */;\n    _proto.onRender = function onRender(_ref3) {\n      var currentScroll = _ref3.currentScroll,\n        smooth = _ref3.smooth;\n      for (var _iterator2 = _createForOfIteratorHelperLoose(this.scrollElementsToUpdate), _step2; !(_step2 = _iterator2()).done;) {\n        var scrollElement = _step2.value;\n        scrollElement.onRender({\n          currentScroll: currentScroll,\n          smooth: smooth\n        });\n      }\n    }\n    /**\n     * Remove items from lists of scroll elements and compute all new values.\n     *\n     * @param {HTMLElement} $oldContainer - HTMLElement that contains data-scroll elements to unsubscribe\n     */;\n    _proto.removeScrollElements = function removeScrollElements($oldContainer) {\n      var _this = this;\n      var $scrollElementsToRemove = $oldContainer.querySelectorAll('[data-scroll]');\n      if (!$scrollElementsToRemove.length) return;\n      var $scrollElementsToRemoveSet = new Set(Array.from($scrollElementsToRemove));\n      // 1. Remove from IO\n      for (var index = 0; index < this.triggeredScrollElements.length; index++) {\n        var scrollElement = this.triggeredScrollElements[index];\n        if ($scrollElementsToRemoveSet.has(scrollElement.$el)) {\n          this.IOTriggerInstance.unobserve(scrollElement.$el);\n          this.triggeredScrollElements.splice(index, 1);\n        }\n      }\n      for (var _index = 0; _index < this.RAFScrollElements.length; _index++) {\n        var _scrollElement = this.RAFScrollElements[_index];\n        if ($scrollElementsToRemoveSet.has(_scrollElement.$el)) {\n          this.IORafInstance.unobserve(_scrollElement.$el);\n          this.RAFScrollElements.splice(_index, 1);\n        }\n      }\n      // 2. Remove from scrollElementsToUpdate[] and scrollElements[]\n      $scrollElementsToRemove.forEach(function ($scrollElement) {\n        var targetScrollElementToUpdate = _this.scrollElementsToUpdate.find(function (scrollElement) {\n          return scrollElement.$el === $scrollElement;\n        });\n        var targetScrollElement = _this.scrollElements.find(function (scrollElement) {\n          return scrollElement.$el === $scrollElement;\n        });\n        if (targetScrollElementToUpdate) {\n          _this._unsubscribeElementUpdate(targetScrollElementToUpdate);\n        }\n        if (targetScrollElement) {\n          _this.scrollElements = _this.scrollElements.filter(function (scrollElementItem) {\n            return scrollElementItem.id != targetScrollElement.id;\n          });\n        }\n      });\n    }\n    /**\n     * Add items to lists of scroll elements and compute all new values.\n     *\n     * @param {HTMLElement} $newContainer - HTMLElement that contains data-scroll elements to subscribe\n     */;\n    _proto.addScrollElements = function addScrollElements($newContainer) {\n      // 3. Rebuild ScrollElements\n      var $scrollElements = $newContainer.querySelectorAll('[data-scroll]');\n      // 4. Get max scrollElement.id\n      var ids = [];\n      this.scrollElements.forEach(function (scrollElement) {\n        ids.push(scrollElement.id);\n      });\n      var maxID = Math.max.apply(Math, ids.concat([0]));\n      var fromIndex = maxID + 1;\n      var $scrollElementsArr = this.toElementArray($scrollElements);\n      this._subscribeScrollElements($scrollElementsArr, fromIndex, true);\n    }\n    /**\n     * Create a ScrollElement instance for each elements with\n     * `data-scroll` attribute.\n     *\n     * @private\n     *\n     * @param {HTMLElement[]} $scrollElements - List of elements that need\n     *     to be regarded.\n     */;\n    _proto._subscribeScrollElements = function _subscribeScrollElements($scrollElements, fromIndex, toObserve) {\n      if (fromIndex === void 0) {\n        fromIndex = 0;\n      }\n      if (toObserve === void 0) {\n        toObserve = false;\n      }\n      // For each scroll element create a ScrollElement instance\n      for (var index = 0; index < $scrollElements.length; index++) {\n        var $scrollElement = $scrollElements[index];\n        var needRaf = this._checkRafNeeded($scrollElement);\n        var scrollElementInstance = new ScrollElement({\n          $el: $scrollElement,\n          id: fromIndex + index,\n          scrollOrientation: this.scrollOrientation,\n          lenisInstance: this.lenisInstance,\n          subscribeElementUpdateFn: this._subscribeElementUpdate.bind(this),\n          unsubscribeElementUpdateFn: this._unsubscribeElementUpdate.bind(this),\n          needRaf: needRaf\n        });\n        // Push to common array\n        this.scrollElements.push(scrollElementInstance);\n        // Push to specific array\n        if (needRaf) {\n          this.RAFScrollElements.push(scrollElementInstance);\n          // Dynamic observe item\n          if (toObserve) {\n            this.IORafInstance.scrollElements.push(scrollElementInstance);\n            this.IORafInstance.observe(scrollElementInstance.$el);\n          }\n        } else {\n          this.triggeredScrollElements.push(scrollElementInstance);\n          // Dynamic observe item\n          if (toObserve) {\n            this.IOTriggerInstance.scrollElements.push(scrollElementInstance);\n            this.IOTriggerInstance.observe(scrollElementInstance.$el);\n          }\n        }\n      }\n    }\n    /**\n     * Clear all ScrollElement arrays.\n     *\n     * @private\n     */;\n    _proto._unsubscribeAllScrollElements = function _unsubscribeAllScrollElements() {\n      // Destroy all scroll elements to clean up CSS and references\n      for (var _iterator3 = _createForOfIteratorHelperLoose(this.scrollElements), _step3; !(_step3 = _iterator3()).done;) {\n        var scrollElement = _step3.value;\n        scrollElement.destroy();\n      }\n      this.scrollElements = [];\n      this.RAFScrollElements = [];\n      this.triggeredScrollElements = [];\n      this.scrollElementsToUpdate = [];\n    }\n    /**\n     * Subscribe ScrollElement instance that needs to be updated.\n     *\n     * @private\n     *\n     * @param {ScrollElement} scrollElement - ScrollElement instance inview\n     *     that needs to be updated.\n     */;\n    _proto._subscribeElementUpdate = function _subscribeElementUpdate(scrollElement) {\n      this.scrollElementsToUpdate.push(scrollElement);\n    }\n    /**\n     * Unscribe ScrollElement instance that doesn't need to be updated.\n     *\n     * @private\n     *\n     * @param {ScrollElement} scrollElement - The updated ScrollElement instance\n     *     out of view now.\n     */;\n    _proto._unsubscribeElementUpdate = function _unsubscribeElementUpdate(scrollElement) {\n      this.scrollElementsToUpdate = this.scrollElementsToUpdate.filter(function (scrollElementToUpdate) {\n        return scrollElementToUpdate.id != scrollElement.id;\n      });\n    }\n    /**\n     * Convert NodeListOf<Element> to HTMLElement array.\n     *\n     * @private\n     *\n     * @param {NodeListOf<Element>} elements - The NodeList to convert.\n     *\n     * @returns {HTMLElement[]}\n     */;\n    _proto.toElementArray = function toElementArray(elements) {\n      return Array.from(elements);\n    }\n    /**\n     * Check if a DOM Element need a requestAnimationFrame to be used.\n     *\n     * @private\n     *\n     * @param {HTMLElement} $scrollElement - The element that needs to be checked.\n     *\n     * @returns {boolean}\n     */;\n    _proto._checkRafNeeded = function _checkRafNeeded($scrollElement) {\n      var attributesThatNeedRaf = [].concat(ATTRIBUTES_THAT_NEED_RAF);\n      // Remove utils\n      var removeAttribute = function removeAttribute(attributeToRemove) {\n        attributesThatNeedRaf = attributesThatNeedRaf.filter(function (attribute) {\n          return attribute !== attributeToRemove;\n        });\n      };\n      // 1. Check scroll offset values\n      if ($scrollElement.dataset.scrollOffset) {\n        var value = $scrollElement.dataset.scrollOffset.split(',').map(function (test) {\n          return test.replace('%', '').trim();\n        }).join(',');\n        if (value !== DEFAULT_SCROLL_OFFSET) {\n          return true;\n        } else {\n          removeAttribute('scrollOffset');\n        }\n      } else {\n        removeAttribute('scrollOffset');\n      }\n      // 2. Check scroll position values\n      if ($scrollElement.dataset.scrollPosition) {\n        var _value = $scrollElement.dataset.scrollPosition.trim();\n        if (_value !== DEFAULT_SCROLL_POSITION) {\n          return true;\n        } else {\n          removeAttribute('scrollPosition');\n        }\n      } else {\n        removeAttribute('scrollPosition');\n      }\n      // 3. Check scroll speed values\n      if ($scrollElement.dataset.scrollSpeed && !isNaN(parseFloat($scrollElement.dataset.scrollSpeed))) {\n        return true;\n      } else {\n        removeAttribute('scrollSpeed');\n      }\n      // 4. Check others attributes\n      for (var _iterator4 = _createForOfIteratorHelperLoose(attributesThatNeedRaf), _step4; !(_step4 = _iterator4()).done;) {\n        var attribute = _step4.value;\n        if (attribute in $scrollElement.dataset) {\n          return true;\n        }\n      }\n      return false;\n    };\n    return Core;\n  }();\n\n  /**\n   * Locomotive Scroll\n   *\n   * Detection of elements in viewport & smooth scrolling with parallax.\n   *\n   * Inspired by\n   * {@link https://github.com/locomotivemtl/locomotive-scroll locomotive-scroll.js}\n   * and built around\n   * {@link https://github.com/darkroomengineering/lenis lenis.js}.\n   */\n  var LocomotiveScroll = /*#__PURE__*/function () {\n    function LocomotiveScroll(_temp) {\n      var _ref = _temp === void 0 ? {} : _temp,\n        _ref$lenisOptions = _ref.lenisOptions,\n        lenisOptions = _ref$lenisOptions === void 0 ? {} : _ref$lenisOptions,\n        triggerRootMargin = _ref.triggerRootMargin,\n        rafRootMargin = _ref.rafRootMargin,\n        _ref$autoStart = _ref.autoStart,\n        autoStart = _ref$autoStart === void 0 ? true : _ref$autoStart,\n        _ref$scrollCallback = _ref.scrollCallback,\n        scrollCallback = _ref$scrollCallback === void 0 ? function () {} : _ref$scrollCallback,\n        initCustomTicker = _ref.initCustomTicker,\n        destroyCustomTicker = _ref.destroyCustomTicker;\n      this.rafPlaying = void 0;\n      this.lenisInstance = null;\n      this.coreInstance = null;\n      this.lenisOptions = void 0;\n      this.triggerRootMargin = void 0;\n      this.rafRootMargin = void 0;\n      this.rafInstance = void 0;\n      this.autoStart = void 0;\n      this.isTouchDevice = void 0;\n      this.initCustomTicker = void 0;\n      this.destroyCustomTicker = void 0;\n      this._onRenderBind = void 0;\n      this._onResizeBind = void 0;\n      this._onScrollToBind = void 0;\n      this._originalOnContentResize = void 0;\n      this._originalOnWrapperResize = void 0;\n      // Set version\n      window.locomotiveScrollVersion = version$1;\n      // Get arguments\n      Object.assign(this, {\n        lenisOptions: lenisOptions,\n        triggerRootMargin: triggerRootMargin,\n        rafRootMargin: rafRootMargin,\n        autoStart: autoStart,\n        scrollCallback: scrollCallback,\n        initCustomTicker: initCustomTicker,\n        destroyCustomTicker: destroyCustomTicker\n      });\n      // Binding\n      this._onRenderBind = this._onRender.bind(this);\n      this._onScrollToBind = this._onScrollTo.bind(this);\n      this._onResizeBind = this._onResize.bind(this);\n      // Data\n      this.rafPlaying = false;\n      // Detect if device has touch capability\n      this.isTouchDevice = 'ontouchstart' in window || navigator.maxTouchPoints > 0;\n      // Init\n      this._init();\n    }\n    /**\n     * Lifecyle - Initialize instance.\n     *\n     * @private\n     */\n    var _proto = LocomotiveScroll.prototype;\n    _proto._init = function _init() {\n      var _this = this;\n      // Create Lenis instance\n      this.lenisInstance = new Lenis(_extends({}, this.lenisOptions));\n      // Subscribe to scroll callback if provided\n      if (this.scrollCallback) {\n        this.lenisInstance.on('scroll', this.scrollCallback);\n      }\n      // Add scroll direction attribute on body\n      document.documentElement.setAttribute('data-scroll-orientation', this.lenisInstance.options.orientation);\n      requestAnimationFrame(function () {\n        // Create Core Instance\n        // lenisInstance is guaranteed to exist at this point (created above)\n        _this.coreInstance = new Core({\n          $el: _this.lenisInstance.rootElement,\n          triggerRootMargin: _this.triggerRootMargin,\n          rafRootMargin: _this.rafRootMargin,\n          scrollOrientation: _this.lenisInstance.options.orientation,\n          lenisInstance: _this.lenisInstance\n        });\n        // Bind Events\n        _this._bindEvents();\n        // RAF warning\n        if (_this.initCustomTicker && !_this.destroyCustomTicker) {\n          console.warn('initCustomTicker callback is declared, but destroyCustomTicker is not. Please pay attention. It could cause trouble.');\n        } else if (!_this.initCustomTicker && _this.destroyCustomTicker) {\n          console.warn('destroyCustomTicker callback is declared, but initCustomTicker is not. Please pay attention. It could cause trouble.');\n        }\n        // Start RAF\n        _this.autoStart && _this.start();\n      });\n    }\n    /**\n     * Lifecyle - Destroy instance.\n     */;\n    _proto.destroy = function destroy() {\n      var _this$lenisInstance,\n        _this2 = this;\n      // Stop raf\n      this.stop();\n      // Unbind Events\n      this._unbindEvents();\n      // Destroy Lenis\n      (_this$lenisInstance = this.lenisInstance) == null || _this$lenisInstance.destroy();\n      // Destroy Core after RAF to ensure any pending Intersection Observer callbacks complete\n      // This prevents race conditions when destroy() is called while IO callbacks are queued\n      requestAnimationFrame(function () {\n        var _this2$coreInstance;\n        (_this2$coreInstance = _this2.coreInstance) == null || _this2$coreInstance.destroy();\n      });\n    }\n    /**\n     * Events - Subscribe events to listen.\n     */;\n    _proto._bindEvents = function _bindEvents() {\n      var _this3 = this;\n      this._bindScrollToEvents();\n      // Hook into Lenis dimensions resize callbacks\n      // onContentResize: called when content size changes (images load, dynamic content)\n      // onWrapperResize: called when wrapper size changes (window resize, layout changes)\n      if (this.lenisInstance) {\n        this._originalOnContentResize = this.lenisInstance.dimensions.onContentResize.bind(this.lenisInstance.dimensions);\n        this._originalOnWrapperResize = this.lenisInstance.dimensions.onWrapperResize.bind(this.lenisInstance.dimensions);\n        this.lenisInstance.dimensions.onContentResize = function () {\n          _this3._originalOnContentResize == null || _this3._originalOnContentResize();\n          _this3._onResizeBind();\n        };\n        this.lenisInstance.dimensions.onWrapperResize = function () {\n          _this3._originalOnWrapperResize == null || _this3._originalOnWrapperResize();\n          _this3._onResizeBind();\n        };\n      }\n    }\n    /**\n     * Events - Unsubscribe listened events.\n     */;\n    _proto._unbindEvents = function _unbindEvents() {\n      this._unbindScrollToEvents();\n      // Restore original Lenis dimensions resize callbacks\n      if (this.lenisInstance) {\n        if (this._originalOnContentResize) {\n          this.lenisInstance.dimensions.onContentResize = this._originalOnContentResize;\n        }\n        if (this._originalOnWrapperResize) {\n          this.lenisInstance.dimensions.onWrapperResize = this._originalOnWrapperResize;\n        }\n      }\n    }\n    /**\n     * Events - Subscribe scrollTo events to listen.\n     */;\n    _proto._bindScrollToEvents = function _bindScrollToEvents($container) {\n      var _this$lenisInstance2,\n        _this4 = this;\n      var $rootContainer = $container ? $container : (_this$lenisInstance2 = this.lenisInstance) == null ? void 0 : _this$lenisInstance2.rootElement;\n      var $scrollToElements = $rootContainer == null ? void 0 : $rootContainer.querySelectorAll('[data-scroll-to]');\n      ($scrollToElements == null ? void 0 : $scrollToElements.length) && $scrollToElements.forEach(function ($el) {\n        $el.addEventListener('click', _this4._onScrollToBind, false);\n      });\n    }\n    /**\n     * Events - Unsubscribe scrollTo listened events.\n     */;\n    _proto._unbindScrollToEvents = function _unbindScrollToEvents($container) {\n      var _this$lenisInstance3,\n        _this5 = this;\n      var $rootContainer = $container ? $container : (_this$lenisInstance3 = this.lenisInstance) == null ? void 0 : _this$lenisInstance3.rootElement;\n      var $scrollToElements = $rootContainer == null ? void 0 : $rootContainer.querySelectorAll('[data-scroll-to]');\n      ($scrollToElements == null ? void 0 : $scrollToElements.length) && $scrollToElements.forEach(function ($el) {\n        $el.removeEventListener('click', _this5._onScrollToBind, false);\n      });\n    }\n    /**\n     * Callback - Resize callback.\n     *\n     * Called synchronously after Lenis updates its dimensions via onContentResize/onWrapperResize.\n     * All dimension values are already up-to-date when this executes.\n     */;\n    _proto._onResize = function _onResize() {\n      var _this$coreInstance, _this$lenisInstance$s, _this$lenisInstance4;\n      (_this$coreInstance = this.coreInstance) == null || _this$coreInstance.onResize({\n        currentScroll: (_this$lenisInstance$s = (_this$lenisInstance4 = this.lenisInstance) == null ? void 0 : _this$lenisInstance4.scroll) != null ? _this$lenisInstance$s : 0,\n        smooth: !this.isTouchDevice\n      });\n    }\n    /**\n     * Callback - Render callback.\n     */;\n    _proto._onRender = function _onRender() {\n      var _this$lenisInstance5, _this$coreInstance2, _this$lenisInstance$s2, _this$lenisInstance6;\n      (_this$lenisInstance5 = this.lenisInstance) == null || _this$lenisInstance5.raf(Date.now());\n      (_this$coreInstance2 = this.coreInstance) == null || _this$coreInstance2.onRender({\n        currentScroll: (_this$lenisInstance$s2 = (_this$lenisInstance6 = this.lenisInstance) == null ? void 0 : _this$lenisInstance6.scroll) != null ? _this$lenisInstance$s2 : 0,\n        smooth: !this.isTouchDevice\n      });\n    }\n    /**\n     * Callback - Scroll To callback.\n     */;\n    _proto._onScrollTo = function _onScrollTo(event) {\n      var _event$currentTarget, _this$lenisInstance7;\n      event.preventDefault();\n      var $target = (_event$currentTarget = event.currentTarget) != null ? _event$currentTarget : null;\n      if (!$target) return;\n      var target = $target.getAttribute('data-scroll-to-href') || $target.getAttribute('href');\n      var offset = $target.getAttribute('data-scroll-to-offset') || 0;\n      var duration = $target.getAttribute('data-scroll-to-duration') || ((_this$lenisInstance7 = this.lenisInstance) == null ? void 0 : _this$lenisInstance7.options.duration);\n      target && this.scrollTo(target, {\n        offset: typeof offset === 'string' ? parseInt(offset) : offset,\n        duration: typeof duration === 'string' ? parseInt(duration) : duration\n      });\n    }\n    /**\n     * Start RequestAnimationFrame that active Lenis smooth and scroll progress.\n     */;\n    _proto.start = function start() {\n      var _this$lenisInstance8;\n      if (this.rafPlaying) {\n        return;\n      }\n      // Call lenis start method\n      (_this$lenisInstance8 = this.lenisInstance) == null || _this$lenisInstance8.start();\n      this.rafPlaying = true;\n      this.initCustomTicker ? this.initCustomTicker(this._onRenderBind) : this._raf();\n    }\n    /**\n     * Stop RequestAnimationFrame that active Lenis smooth and scroll progress.\n     */;\n    _proto.stop = function stop() {\n      var _this$lenisInstance9;\n      if (!this.rafPlaying) {\n        return;\n      }\n      // Call lenis stop method\n      (_this$lenisInstance9 = this.lenisInstance) == null || _this$lenisInstance9.stop();\n      this.rafPlaying = false;\n      this.destroyCustomTicker ? this.destroyCustomTicker(this._onRenderBind) : this.rafInstance && cancelAnimationFrame(this.rafInstance);\n    }\n    /**\n     * Remove old scroll elements items and rebuild ScrollElements instances.\n     */;\n    _proto.removeScrollElements = function removeScrollElements($oldContainer) {\n      var _this$coreInstance3;\n      if (!$oldContainer) {\n        console.error('Please provide a DOM Element as $oldContainer');\n        return;\n      }\n      this._unbindScrollToEvents($oldContainer);\n      (_this$coreInstance3 = this.coreInstance) == null || _this$coreInstance3.removeScrollElements($oldContainer);\n    }\n    /**\n     * Add new scroll elements items and rebuild ScrollElements instances.\n     */;\n    _proto.addScrollElements = function addScrollElements($newContainer) {\n      var _this$coreInstance4,\n        _this6 = this;\n      if (!$newContainer) {\n        console.error('Please provide a DOM Element as $newContainer');\n        return;\n      }\n      (_this$coreInstance4 = this.coreInstance) == null || _this$coreInstance4.addScrollElements($newContainer);\n      requestAnimationFrame(function () {\n        _this6._bindScrollToEvents($newContainer);\n      });\n    }\n    /**\n     * Trigger resize callback.\n     */;\n    _proto.resize = function resize() {\n      this._onResizeBind();\n    }\n    /**\n     * Trigger scroll to callback.\n     */;\n    _proto.scrollTo = function scrollTo(target, options) {\n      var _this$lenisInstance0;\n      (_this$lenisInstance0 = this.lenisInstance) == null || _this$lenisInstance0.scrollTo(target, {\n        offset: options == null ? void 0 : options.offset,\n        lerp: options == null ? void 0 : options.lerp,\n        duration: options == null ? void 0 : options.duration,\n        immediate: options == null ? void 0 : options.immediate,\n        lock: options == null ? void 0 : options.lock,\n        force: options == null ? void 0 : options.force,\n        easing: options == null ? void 0 : options.easing,\n        onComplete: options == null ? void 0 : options.onComplete\n      });\n    }\n    /**\n     * RequestAnimationFrame that active Lenis smooth and scroll progress.\n     *\n     * @private\n     *\n     */;\n    _proto._raf = function _raf() {\n      var _this7 = this;\n      this._onRenderBind();\n      this.rafInstance = requestAnimationFrame(function () {\n        return _this7._raf();\n      });\n    };\n    return LocomotiveScroll;\n  }();\n\n  return LocomotiveScroll;\n\n}));\n"
  },
  {
    "path": "packages/lib/core/Core.ts",
    "content": "/**\n * Integrates Lenis with Locomotive's built-in animation system\n */\n\nimport type {\n    CoreOptions,\n    IScrollElementCallbacksValues,\n    scrollOrientation,\n} from '../types';\nimport IO from './IO';\nimport ScrollElement from './ScrollElement';\n\n/** Defined attributes that need a requestAnimationFrame */\nconst ATTRIBUTES_THAT_NEED_RAF = [\n    'scrollOffset',\n    'scrollPosition',\n    'scrollCssProgress',\n    'scrollEventProgress',\n    'scrollSpeed',\n];\n\n/** Default root margins */\nconst TRIGGER_ROOT_MARGIN = '-1px -1px -1px -1px';\nconst RAF_ROOT_MARGIN = '100% 100% 100% 100%'; // Add 100vh top/bottom && 100vw left/right to use a biggest value with data-scroll-speed\n\n/** Default scroll attribute values */\nconst DEFAULT_SCROLL_OFFSET = '0,0';\nconst DEFAULT_SCROLL_POSITION = 'top,bottom';\n\nexport default class Core {\n    private $scrollContainer!: HTMLElement;\n    private triggerRootMargin!: string;\n    private rafRootMargin!: string;\n    private scrollElements!: ScrollElement[];\n    private triggeredScrollElements!: ScrollElement[];\n    private RAFScrollElements!: ScrollElement[];\n    private scrollElementsToUpdate!: ScrollElement[];\n    private IOTriggerInstance!: IO;\n    private IORafInstance!: IO;\n    private scrollOrientation!: scrollOrientation;\n    private lenisInstance: any;\n\n    constructor({\n        $el,\n        triggerRootMargin,\n        rafRootMargin,\n        scrollOrientation,\n        lenisInstance,\n    }: CoreOptions) {\n        if (!$el) {\n            console.error('Please provide a DOM Element as scrollContainer');\n            return;\n        }\n\n        // Scroll container\n        this.$scrollContainer = $el;\n\n        // Lenis instance\n        this.lenisInstance = lenisInstance;\n\n        // Scroll Direction\n        this.scrollOrientation = scrollOrientation;\n\n        // IO Margins\n        this.triggerRootMargin = triggerRootMargin ?? TRIGGER_ROOT_MARGIN;\n        this.rafRootMargin = rafRootMargin ?? RAF_ROOT_MARGIN;\n\n        // ScrollElements arrays\n        this.scrollElements = [];\n        this.triggeredScrollElements = [];\n        this.RAFScrollElements = [];\n        this.scrollElementsToUpdate = [];\n\n\n        // Init\n        this._init();\n    }\n\n    /**\n     * Lifecyle - Initialize the core.\n     *\n     * @private\n     */\n    private _init() {\n        const $scrollElements =\n            this.$scrollContainer.querySelectorAll('[data-scroll]');\n\n        const $scrollElementsArr = this.toElementArray($scrollElements);\n        this._subscribeScrollElements($scrollElementsArr);\n\n        // Determine IO root (null for window, wrapper element for custom container)\n        const ioRoot = this.lenisInstance.options.wrapper === window\n            ? null\n            : this.lenisInstance.options.wrapper as HTMLElement;\n\n        // Trigger IO\n        this.IOTriggerInstance = new IO({\n            scrollElements: [...this.triggeredScrollElements],\n            root: ioRoot,\n            rootMargin: this.triggerRootMargin,\n            IORaf: false,\n        });\n\n        // Raf IO\n        this.IORafInstance = new IO({\n            scrollElements: [...this.RAFScrollElements],\n            root: ioRoot,\n            rootMargin: this.rafRootMargin,\n            IORaf: true,\n        });\n    }\n\n    /**\n     * Lifecyle - Destroy core.\n     */\n    public destroy() {\n        this.IOTriggerInstance.destroy();\n        this.IORafInstance.destroy();\n        this._unsubscribeAllScrollElements();\n    }\n\n    /**\n     * Callback - Resize callback.\n     */\n    onResize({ currentScroll }: IScrollElementCallbacksValues) {\n        for (const scrollElement of this.RAFScrollElements) {\n            scrollElement.onResize({\n                currentScroll,\n            } as IScrollElementCallbacksValues);\n        }\n    }\n\n    /**\n     * Callback - RAF callback.\n     */\n    onRender({ currentScroll, smooth }: IScrollElementCallbacksValues) {\n        for (const scrollElement of this.scrollElementsToUpdate) {\n            scrollElement.onRender({\n                currentScroll,\n                smooth,\n            } as IScrollElementCallbacksValues);\n        }\n    }\n\n    /**\n     * Remove items from lists of scroll elements and compute all new values.\n     *\n     * @param {HTMLElement} $oldContainer - HTMLElement that contains data-scroll elements to unsubscribe\n     */\n    removeScrollElements($oldContainer: HTMLElement) {\n        const $scrollElementsToRemove =\n            $oldContainer.querySelectorAll('[data-scroll]');\n\n        if (!$scrollElementsToRemove.length) return;\n\n        const $scrollElementsToRemoveSet = new Set(Array.from($scrollElementsToRemove));\n\n        // 1. Remove from IO\n        for (let index = 0; index < this.triggeredScrollElements.length; index++) {\n            const scrollElement = this.triggeredScrollElements[index];\n            if ($scrollElementsToRemoveSet.has(scrollElement.$el)) {\n                this.IOTriggerInstance.unobserve(scrollElement.$el);\n                this.triggeredScrollElements.splice(index, 1);\n            }\n        }\n\n        for (let index = 0; index < this.RAFScrollElements.length; index++) {\n            const scrollElement = this.RAFScrollElements[index];\n            if ($scrollElementsToRemoveSet.has(scrollElement.$el)) {\n                this.IORafInstance.unobserve(scrollElement.$el);\n                this.RAFScrollElements.splice(index, 1);\n            }\n        }\n\n        // 2. Remove from scrollElementsToUpdate[] and scrollElements[]\n        $scrollElementsToRemove.forEach(($scrollElement) => {\n            const targetScrollElementToUpdate =\n                this.scrollElementsToUpdate.find(\n                    (scrollElement) => scrollElement.$el === $scrollElement\n                );\n            const targetScrollElement = this.scrollElements.find(\n                (scrollElement) => scrollElement.$el === $scrollElement\n            );\n\n            if (targetScrollElementToUpdate) {\n                this._unsubscribeElementUpdate(targetScrollElementToUpdate);\n            }\n            if (targetScrollElement) {\n                this.scrollElements = this.scrollElements.filter(\n                    (scrollElementItem) =>\n                        scrollElementItem.id != targetScrollElement.id\n                );\n            }\n        });\n    }\n\n    /**\n     * Add items to lists of scroll elements and compute all new values.\n     *\n     * @param {HTMLElement} $newContainer - HTMLElement that contains data-scroll elements to subscribe\n     */\n    addScrollElements($newContainer: HTMLElement) {\n        // 3. Rebuild ScrollElements\n        const $scrollElements = $newContainer.querySelectorAll('[data-scroll]');\n\n        // 4. Get max scrollElement.id\n        const ids: number[] = [];\n        this.scrollElements.forEach((scrollElement) => {\n            ids.push(scrollElement.id);\n        });\n        const maxID = Math.max(...ids, 0);\n        const fromIndex = maxID + 1;\n        const $scrollElementsArr = this.toElementArray($scrollElements);\n        this._subscribeScrollElements(\n            $scrollElementsArr,\n            fromIndex,\n            true\n        );\n    }\n\n    /**\n     * Create a ScrollElement instance for each elements with\n     * `data-scroll` attribute.\n     *\n     * @private\n     *\n     * @param {HTMLElement[]} $scrollElements - List of elements that need\n     *     to be regarded.\n     */\n    _subscribeScrollElements(\n        $scrollElements: HTMLElement[],\n        fromIndex = 0,\n        toObserve = false\n    ) {\n        // For each scroll element create a ScrollElement instance\n        for (let index = 0; index < $scrollElements.length; index++) {\n            const $scrollElement = $scrollElements[index];\n            const needRaf = this._checkRafNeeded($scrollElement);\n\n            const scrollElementInstance = new ScrollElement({\n                $el: $scrollElement,\n                id: fromIndex + index,\n                scrollOrientation: this.scrollOrientation,\n                lenisInstance: this.lenisInstance,\n                subscribeElementUpdateFn:\n                    this._subscribeElementUpdate.bind(this),\n                unsubscribeElementUpdateFn:\n                    this._unsubscribeElementUpdate.bind(this),\n                needRaf,\n            });\n\n            // Push to common array\n            this.scrollElements.push(scrollElementInstance);\n\n            // Push to specific array\n            if (needRaf) {\n                this.RAFScrollElements.push(scrollElementInstance);\n\n                // Dynamic observe item\n                if (toObserve) {\n                    this.IORafInstance.scrollElements.push(\n                        scrollElementInstance\n                    );\n                    this.IORafInstance.observe(scrollElementInstance.$el);\n                }\n            } else {\n                this.triggeredScrollElements.push(scrollElementInstance);\n\n                // Dynamic observe item\n                if (toObserve) {\n                    this.IOTriggerInstance.scrollElements.push(\n                        scrollElementInstance\n                    );\n                    this.IOTriggerInstance.observe(scrollElementInstance.$el);\n                }\n            }\n        }\n    }\n\n    /**\n     * Clear all ScrollElement arrays.\n     *\n     * @private\n     */\n    _unsubscribeAllScrollElements() {\n        // Destroy all scroll elements to clean up CSS and references\n        for (const scrollElement of this.scrollElements) {\n            scrollElement.destroy();\n        }\n\n        this.scrollElements = [];\n        this.RAFScrollElements = [];\n        this.triggeredScrollElements = [];\n        this.scrollElementsToUpdate = [];\n    }\n\n    /**\n     * Subscribe ScrollElement instance that needs to be updated.\n     *\n     * @private\n     *\n     * @param {ScrollElement} scrollElement - ScrollElement instance inview\n     *     that needs to be updated.\n     */\n    _subscribeElementUpdate(scrollElement: ScrollElement) {\n        this.scrollElementsToUpdate.push(scrollElement);\n    }\n\n    /**\n     * Unscribe ScrollElement instance that doesn't need to be updated.\n     *\n     * @private\n     *\n     * @param {ScrollElement} scrollElement - The updated ScrollElement instance\n     *     out of view now.\n     */\n    _unsubscribeElementUpdate(scrollElement: ScrollElement) {\n        this.scrollElementsToUpdate = this.scrollElementsToUpdate.filter(\n            (scrollElementToUpdate) =>\n                scrollElementToUpdate.id != scrollElement.id\n        );\n    }\n\n    /**\n     * Convert NodeListOf<Element> to HTMLElement array.\n     *\n     * @private\n     *\n     * @param {NodeListOf<Element>} elements - The NodeList to convert.\n     *\n     * @returns {HTMLElement[]}\n     */\n    private toElementArray(elements: NodeListOf<Element>): HTMLElement[] {\n        return Array.from(elements) as HTMLElement[];\n    }\n\n    /**\n     * Check if a DOM Element need a requestAnimationFrame to be used.\n     *\n     * @private\n     *\n     * @param {HTMLElement} $scrollElement - The element that needs to be checked.\n     *\n     * @returns {boolean}\n     */\n    _checkRafNeeded($scrollElement: HTMLElement) {\n        let attributesThatNeedRaf = [...ATTRIBUTES_THAT_NEED_RAF];\n\n        // Remove utils\n        const removeAttribute = (attributeToRemove: string) => {\n            attributesThatNeedRaf = attributesThatNeedRaf.filter(\n                (attribute) => attribute !== attributeToRemove\n            );\n        };\n\n        // 1. Check scroll offset values\n        if ($scrollElement.dataset.scrollOffset) {\n            const value = $scrollElement.dataset.scrollOffset\n                .split(',')\n                .map((test) => test.replace('%', '').trim())\n                .join(',');\n            if (value !== DEFAULT_SCROLL_OFFSET) {\n                return true;\n            } else {\n                removeAttribute('scrollOffset');\n            }\n        } else {\n            removeAttribute('scrollOffset');\n        }\n\n        // 2. Check scroll position values\n        if ($scrollElement.dataset.scrollPosition) {\n            const value = $scrollElement.dataset.scrollPosition.trim();\n            if (value !== DEFAULT_SCROLL_POSITION) {\n                return true;\n            } else {\n                removeAttribute('scrollPosition');\n            }\n        } else {\n            removeAttribute('scrollPosition');\n        }\n\n        // 3. Check scroll speed values\n        if (\n            $scrollElement.dataset.scrollSpeed &&\n            !isNaN(parseFloat($scrollElement.dataset.scrollSpeed))\n        ) {\n            return true;\n        } else {\n            removeAttribute('scrollSpeed');\n        }\n\n        // 4. Check others attributes\n        for (const attribute of attributesThatNeedRaf) {\n            if (attribute in $scrollElement.dataset) {\n                return true;\n            }\n        }\n\n        return false;\n    }\n}\n"
  },
  {
    "path": "packages/lib/core/IO.ts",
    "content": "/**\n * Intersection Observer\n *\n * Detecting visibility of an element in the viewport.\n *\n * Features functions to:\n *\n * - Trigger inview/outOfView callbacks\n * - If the element has a requestAnimationFrame dependency, set interactivy status for the ScrollElement Class\n *\n * References:\n *\n * - {@link https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API}\n */\n\nimport type { IIOOptions } from '../types';\nimport ScrollElement from './ScrollElement';\n\nexport default class IO {\n    public scrollElements: ScrollElement[];\n    private rootMargin: string;\n    private root: HTMLElement | null;\n    private IORaf: boolean;\n    private observer!: IntersectionObserver;\n\n    constructor({\n        scrollElements,\n        rootMargin = '-1px -1px -1px -1px',\n        root = null,\n        IORaf,\n    }: IIOOptions) {\n        // Parameters\n        this.scrollElements = scrollElements;\n        this.rootMargin = rootMargin;\n        this.root = root;\n        this.IORaf = IORaf;\n\n        // Init\n        this._init();\n    }\n\n    /**\n     * Lifecyle - Initialize Intersection Observer.\n     *\n     * @private\n     */\n    private _init() {\n        // Options\n        const observerOptions = {\n            root: this.root,\n            rootMargin: this.rootMargin,\n        };\n\n        // Callback\n        const onIntersect = (entries: IntersectionObserverEntry[]) => {\n            entries.forEach((entry) => {\n                const $targetItem: ScrollElement | undefined =\n                    this.scrollElements.find(\n                        (item) => item.$el === entry.target\n                    );\n\n                if (entry.isIntersecting) {\n                    $targetItem && ($targetItem.isAlreadyIntersected = true);\n                    this._setInview(entry);\n                } else if ($targetItem && $targetItem.isAlreadyIntersected) {\n                    this._setOutOfView(entry);\n                }\n            });\n        };\n\n        // Instance\n        this.observer = new IntersectionObserver(onIntersect, observerOptions);\n\n        // Observe each default elements\n        for (const scrollElement of this.scrollElements) {\n            const $scrollElement = scrollElement.$el;\n            this.observe($scrollElement);\n        }\n    }\n\n    /**\n     * Lifecyle - Destroy Intersection Observer.\n     */\n    public destroy() {\n        this.observer.disconnect();\n    }\n\n    /**\n     * Subscribe element to the Intersection Observer.\n     *\n     * @param {HTMLElement} $scrollElement - DOM Element to observe.\n     */\n    public observe($scrollElement: HTMLElement) {\n        if (!$scrollElement) {\n            return;\n        }\n\n        this.observer.observe($scrollElement);\n    }\n\n    /**\n     * Unsubscribe element to the Intersection Observer.\n     *\n     * @param {HTMLElement} $scrollElement - DOM Element to unobserve.\n     */\n    public unobserve($scrollElement: HTMLElement) {\n        if (!$scrollElement) {\n            return;\n        }\n\n        this.observer.unobserve($scrollElement);\n    }\n\n    /**\n     * Find ScrollElementReference instance and trigger inview callbacks.\n     *\n     * @private\n     *\n     * @param {IntersectionObserverEntry} entry - DOM Element to observe.\n     */\n    private _setInview(entry: IntersectionObserverEntry) {\n        const scrollElement = this.scrollElements.find(\n            (scrollElement) => scrollElement.$el === entry.target\n        );\n\n        this.IORaf && scrollElement?.setInteractivityOn();\n        !this.IORaf && scrollElement?.setInview();\n    }\n\n    /**\n     * Find ScrollElementReference instance and trigger out of view callbacks.\n     *\n     * @private\n     *\n     * @param {IntersectionObserverEntry} entry - DOM Element to observe.\n     */\n    private _setOutOfView(entry: IntersectionObserverEntry) {\n        const scrollElement = this.scrollElements.find(\n            (scrollElement) => scrollElement.$el === entry.target\n        );\n\n        this.IORaf && scrollElement?.setInteractivityOff();\n        !this.IORaf && scrollElement?.setOutOfView();\n\n        // Unobserve if element doesn't have repeat attribute\n        if (!scrollElement?.attributes.scrollRepeat && !this.IORaf) {\n            this.unobserve(entry.target as HTMLElement);\n        }\n    }\n}\n"
  },
  {
    "path": "packages/lib/core/ScrollElement.ts",
    "content": "/**\n * Scroll Element\n *\n * Give tools to compute element progress in the viewport and triggers callbacks to animate it.\n *\n * Features functions to:\n *\n * - scrollClass - Add a custom class when the element is intersected by the offset\n * - scrollOffset - Determine offsets to intersect the element\n * - scrollPosition - Determine the element positions to consider an element as intersected.\n * - scrollCssProgress - Add a specific css variable (PROGRESS_CSS_VAR) that store the scroll progress\n * - scrollEventProgress - Send scroll progress to custom event listeners.\n * - scrollSpeed - Add a scroll multiplicator to create a parallax effect\n * - scrollRepeat - Repeat the option to trigger animation each time the element is intersected\n * - scrollCall - Call a custom event when the element is intersected\n */\n\nimport type {\n    IScrollElementOptions,\n    IScrollElementAttributes,\n    IScrollElementIntersection,\n    IScrollElementMetrics,\n    IScrollElementCallbacksValues,\n    scrollOrientation,\n} from '../types';\nimport { clamp, closestNumber, normalize, mapRange } from '../utils/maths';\n\n/** Constants */\nconst INVIEW_CLASS = 'is-inview';\nconst PROGRESS_CSS_VAR = '--progress';\n\nexport default class ScrollElement {\n    public $el: HTMLElement;\n    public id: number;\n    public needRaf: boolean;\n    public attributes: IScrollElementAttributes;\n    public scrollOrientation: scrollOrientation;\n    public isAlreadyIntersected: boolean;\n\n    private intersection: IScrollElementIntersection;\n    private metrics: IScrollElementMetrics;\n    private currentScroll: number;\n    private translateValue: number;\n    private progress: number;\n    private lastProgress: number | null;\n    private isInview: boolean;\n    private isInteractive: boolean;\n    private isInFold: boolean;\n    private isFirstResize: boolean;\n\n    private subscribeElementUpdateFn: (scrollElement: ScrollElement) => void;\n    private unsubscribeElementUpdateFn: (scrollElement: ScrollElement) => void;\n    private lenisInstance: any;\n\n    // Cached functions to avoid orientation checks every frame\n    private getWindowSize: () => number;\n    private getMetricsStart: (bcr: DOMRect) => number;\n    private getMetricsSize: (bcr: DOMRect) => number;\n\n    // Position handlers for intersection.start (includes wSize)\n    private readonly startPositionHandlers: Record<string, (offsetStart: number, wSize: number, viewport: number, size: number) => number> = {\n        'start': (offsetStart, wSize, viewport) => offsetStart - wSize + viewport,\n        'middle': (offsetStart, wSize, viewport, size) => offsetStart - wSize + viewport + size * 0.5,\n        'end': (offsetStart, wSize, viewport, size) => offsetStart - wSize + viewport + size,\n        'fold': () => 0,\n    };\n\n    // Position handlers for intersection.end (DOES NOT include wSize - critical difference)\n    private readonly endPositionHandlers: Record<string, (offsetStart: number, viewport: number, size: number) => number> = {\n        'start': (offsetStart, viewport) => offsetStart - viewport,\n        'middle': (offsetStart, viewport, size) => offsetStart - viewport + size * 0.5,\n        'end': (offsetStart, viewport, size) => offsetStart - viewport + size,\n    };\n\n    constructor({\n        $el,\n        id,\n        subscribeElementUpdateFn,\n        unsubscribeElementUpdateFn,\n        needRaf,\n        scrollOrientation,\n        lenisInstance,\n    }: IScrollElementOptions) {\n        // Scroll DOM element\n        this.$el = $el;\n        // Unique ID\n        this.id = id;\n        // RAF option\n        this.needRaf = needRaf;\n        // Scroll Direction\n        this.scrollOrientation = scrollOrientation;\n        // Lenis instance\n        this.lenisInstance = lenisInstance;\n        // Parent's callbacks\n        this.subscribeElementUpdateFn = subscribeElementUpdateFn;\n        this.unsubscribeElementUpdateFn = unsubscribeElementUpdateFn;\n\n        // Attributes\n        this.attributes = {\n            scrollClass: this.$el.dataset['scrollClass'] ?? INVIEW_CLASS,\n            scrollOffset: this.$el.dataset['scrollOffset'] ?? '0,0',\n            scrollPosition: this.$el.dataset['scrollPosition'] ?? 'start,end',\n            scrollCssProgress: this.$el.dataset['scrollCssProgress'] !== undefined,\n            scrollEventProgress:\n                this.$el.dataset['scrollEventProgress'] ?? null,\n            scrollSpeed:\n                this.$el.dataset['scrollSpeed'] !== undefined\n                    ? parseFloat(this.$el.dataset['scrollSpeed'])\n                    : null,\n            scrollRepeat: this.$el.dataset['scrollRepeat'] !== undefined,\n            scrollCall: this.$el.dataset['scrollCall'] ?? null,\n            scrollIgnoreFold: this.$el.dataset['scrollIgnoreFold'] !== undefined,\n            scrollEnableTouchSpeed:\n                this.$el.dataset['scrollEnableTouchSpeed'] !== undefined,\n        };\n\n        // Limits\n        this.intersection = {\n            start: 0,\n            end: 0,\n        };\n\n        // Metrics\n        this.metrics = {\n            offsetStart: 0,\n            offsetEnd: 0,\n            bcr: {} as DOMRect,\n        };\n\n        // Scroll Values\n        this.currentScroll = this.lenisInstance.scroll;\n\n        // Parallax\n        this.translateValue = 0;\n\n        // Progress\n        this.progress = 0;\n        this.lastProgress = null;\n\n        // Inview\n        this.isInview = false;\n        this.isInteractive = false;\n        this.isAlreadyIntersected = false;\n        this.isInFold = false;\n        this.isFirstResize = true;\n\n        // Cache orientation-dependent functions to avoid repeated conditionals\n        this.getWindowSize = this.scrollOrientation === 'vertical'\n            ? () => this.lenisInstance.dimensions.height\n            : () => this.lenisInstance.dimensions.width;\n\n        this.getMetricsStart = this.scrollOrientation === 'vertical'\n            ? (bcr: DOMRect) => bcr.top\n            : (bcr: DOMRect) => bcr.left;\n\n        this.getMetricsSize = this.scrollOrientation === 'vertical'\n            ? (bcr: DOMRect) => bcr.height\n            : (bcr: DOMRect) => bcr.width;\n\n        // Init\n        this._init();\n    }\n\n    /**\n     * Lifecyle - Initialize progress tracking.\n     *\n     * @private\n     */\n    private _init() {\n        if (!this.needRaf) {\n            return;\n        }\n\n        // First resize to compute all values\n        this._resize();\n    }\n\n    /**\n     * Callback - Resize callback\n     */\n    public onResize({ currentScroll }: IScrollElementCallbacksValues) {\n        this.currentScroll = currentScroll;\n        this._resize();\n    }\n\n    /**\n     * Callback - RAF callback\n     */\n    public onRender({ currentScroll, smooth }: IScrollElementCallbacksValues) {\n        const wSize = this.getWindowSize();\n        this.currentScroll = currentScroll;\n        this._computeProgress();\n\n        // Parallax\n        if (\n            this.attributes.scrollSpeed &&\n            !isNaN(this.attributes.scrollSpeed)\n        ) {\n            // if touch detected or smooth disabled\n            if (!this.attributes.scrollEnableTouchSpeed && !smooth) {\n                if (this.translateValue) {\n                    this.$el.style.transform = `translate3d(0, 0, 0)`;\n                }\n                this.translateValue = 0;\n\n            // if mousewheel or smooth enabled\n            } else {\n                // Check fold condition\n                if (this.isInFold) {\n                    const progress = Math.max(0, this.progress);\n                    this.translateValue =\n                        progress * wSize * this.attributes.scrollSpeed * -1;\n                } else {\n                    const progress = mapRange(0, 1, -1, 1, this.progress);\n                    this.translateValue =\n                        progress * wSize * this.attributes.scrollSpeed * -1;\n                }\n\n                this.$el.style.transform =\n                    this.scrollOrientation === 'vertical'\n                        ? `translate3d(0, ${this.translateValue}px, 0)`\n                        : `translate3d(${this.translateValue}px, 0, 0)`;\n            }\n        }\n    }\n\n    /**\n     * Inview callback\n     */\n    public setInview() {\n        if (this.isInview) {\n            return;\n        }\n\n        this.isInview = true;\n        this.$el.classList.add(this.attributes.scrollClass);\n\n        const way = 'enter';\n        const from = this._getScrollCallFrom();\n        this.attributes.scrollCall && this._dispatchCall(way, from);\n    }\n\n    /**\n     * Out of view callback\n     */\n    public setOutOfView() {\n        if (!(this.isInview && this.attributes.scrollRepeat)) {\n            return;\n        }\n\n        this.isInview = false;\n        this.$el.classList.remove(this.attributes.scrollClass);\n\n        const way = 'leave';\n        const from = this._getScrollCallFrom();\n        this.attributes.scrollCall && this._dispatchCall(way, from);\n    }\n\n    /**\n     * Switch interactivity on to subscribe the instance to the RAF\n     * and start calculations.\n     */\n    public setInteractivityOn() {\n        if (this.isInteractive) {\n            return;\n        }\n\n        this.isInteractive = true;\n        this.subscribeElementUpdateFn(this);\n    }\n\n    /**\n     * Switch interactivity off to unsubscribe the instance to the RAF\n     * and stop calculations.\n     */\n    public setInteractivityOff() {\n        if (!this.isInteractive) {\n            return;\n        }\n\n        this.isInteractive = false;\n        this.unsubscribeElementUpdateFn(this);\n\n        // Force progress to progress limit when the element is out\n        this.lastProgress !== null &&\n            this._computeProgress(closestNumber([0, 1], this.lastProgress));\n    }\n\n    /**\n     * Resize method that compute the element's values.\n     *\n     * @private\n     */\n    private _resize() {\n        this.metrics.bcr = this.$el.getBoundingClientRect();\n        this._computeMetrics();\n        this._computeIntersection();\n\n        // First resize logic\n        if (this.isFirstResize) {\n            this.isFirstResize = false;\n            // Dispatch default call if the element is in fold.\n            if (this.isInFold) {\n                this.setInview();\n            }\n        }\n    }\n\n    /**\n     * Compute element's offsets and determine if the element is in fold.\n     *\n     * @private\n     */\n    private _computeMetrics() {\n        const wSize = this.getWindowSize();\n        const metricsStart = this.getMetricsStart(this.metrics.bcr);\n        const metricsSize = this.getMetricsSize(this.metrics.bcr);\n\n        this.metrics.offsetStart =\n            this.currentScroll + metricsStart - this.translateValue;\n        this.metrics.offsetEnd = this.metrics.offsetStart + metricsSize;\n\n        if (\n            this.metrics.offsetStart < wSize &&\n            !this.attributes.scrollIgnoreFold\n        ) {\n            this.isInFold = true;\n        } else {\n            this.isInFold = false;\n        }\n    }\n\n    /**\n     * Compute intersection values depending on the context.\n     * Uses handler-based approach for cleaner, more maintainable code.\n     *\n     * @private\n     */\n    private _computeIntersection() {\n        const wSize = this.getWindowSize();\n        const metricsSize = this.getMetricsSize(this.metrics.bcr);\n\n        // Parse offset\n        const offset = this.attributes.scrollOffset.split(',');\n        const offsetStart = offset[0]?.trim() ?? '0';\n        const offsetEnd = offset[1]?.trim() ?? '0';\n\n        // Parse positions\n        const scrollPosition = this.attributes.scrollPosition.split(',');\n        let scrollPositionStart = scrollPosition[0]?.trim() ?? 'start';\n        const scrollPositionEnd = scrollPosition[1]?.trim() ?? 'end';\n\n        // Calculate viewport offsets\n        const viewportStart = offsetStart.includes('%')\n            ? wSize * parseInt(offsetStart.replace('%', '').trim()) * 0.01\n            : parseInt(offsetStart);\n        const viewportEnd = offsetEnd.includes('%')\n            ? wSize * parseInt(offsetEnd.replace('%', '').trim()) * 0.01\n            : parseInt(offsetEnd);\n\n        // Fold exception\n        if (this.isInFold) {\n            scrollPositionStart = 'fold';\n        }\n\n        // Calculate intersection.start using handlers\n        const startHandler = this.startPositionHandlers[scrollPositionStart];\n        this.intersection.start = startHandler\n            ? startHandler(this.metrics.offsetStart, wSize, viewportStart, metricsSize)\n            : this.metrics.offsetStart - wSize + viewportStart; // default fallback\n\n        // Calculate intersection.end using handlers\n        const endHandler = this.endPositionHandlers[scrollPositionEnd];\n        this.intersection.end = endHandler\n            ? endHandler(this.metrics.offsetStart, viewportEnd, metricsSize)\n            : this.metrics.offsetStart - viewportEnd + metricsSize; // default fallback\n\n        // Ensure end > start\n        if (this.intersection.end <= this.intersection.start) {\n            switch (scrollPositionEnd) {\n                case 'start':\n                    this.intersection.end = this.intersection.start + 1;\n                    break;\n                case 'middle':\n                    this.intersection.end = this.intersection.start + metricsSize * 0.5;\n                    break;\n                case 'end':\n                    this.intersection.end = this.intersection.start + metricsSize;\n                    break;\n                default:\n                    this.intersection.end = this.intersection.start + 1;\n                    break;\n            }\n        }\n    }\n\n    /**\n     * Compute the scroll progress of the element depending\n     * on its intersection values.\n     *\n     * @private\n     *\n     * @param {number} [forcedProgress] - Value to force progress.\n     */\n    private _computeProgress(forcedProgress?: number) {\n        // Progress\n        const progress =\n            forcedProgress ??\n            clamp(\n                0,\n                1,\n                normalize(\n                    this.intersection.start,\n                    this.intersection.end,\n                    this.currentScroll\n                )\n            );\n\n        this.progress = progress;\n\n        if (progress !== this.lastProgress) {\n            this.lastProgress = progress;\n\n            // Set the element's progress to the css variable\n            this.attributes.scrollCssProgress && this._setCssProgress(progress);\n\n            // Set the element's progress to the custom event listeners\n            this.attributes.scrollEventProgress &&\n                this._setCustomEventProgress(progress);\n\n            // Logic to trigger the inview/out of view callbacks\n            progress > 0 && progress < 1 && this.setInview();\n            progress === 0 && this.setOutOfView();\n            progress === 1 && this.setOutOfView();\n        }\n    }\n\n    /**\n     * Set the element's progress to a specific css variable.\n     *\n     * @private\n     *\n     * @param {number} [currentProgress] - Progress value.\n     */\n    _setCssProgress(currentProgress = 0) {\n        this.$el.style.setProperty(\n            PROGRESS_CSS_VAR,\n            currentProgress.toString()\n        );\n    }\n\n    /**\n     * Set the element's progress to the custom event listeners.\n     *\n     * @private\n     *\n     * @param {number} [currentProgress] - Progress value.\n     */\n    _setCustomEventProgress(currentProgress = 0) {\n        const customEventName = this.attributes.scrollEventProgress;\n\n        if (!customEventName) return;\n\n        const customEvent = new CustomEvent(customEventName, {\n            detail: {\n                target: this.$el,\n                progress: currentProgress,\n            },\n        });\n        window.dispatchEvent(customEvent);\n    }\n\n    /**\n     * Function to get scroll call from.\n     *\n     * @private\n     */\n    _getScrollCallFrom() {\n        const closestIntersectionValue = closestNumber(\n            [this.intersection.start, this.intersection.end],\n            this.currentScroll\n        );\n        return this.intersection.start === closestIntersectionValue\n            ? 'start'\n            : 'end';\n    }\n\n    /**\n     * Lifecyle - Destroy and cleanup the scroll element.\n     *\n     * Removes all CSS modifications and clears references to prevent memory leaks.\n     */\n    public destroy(): void {\n        // Remove CSS variables\n        if (this.attributes.scrollCssProgress) {\n            this.$el.style.removeProperty(PROGRESS_CSS_VAR);\n        }\n\n        // Remove transform if parallax was applied\n        if (this.attributes.scrollSpeed) {\n            this.$el.style.removeProperty('transform');\n        }\n\n        // Remove class if added\n        if (this.isInview && this.attributes.scrollClass) {\n            this.$el.classList.remove(this.attributes.scrollClass);\n        }\n    }\n\n    /**\n     * Function to dispatch a custom event.\n     *\n     * @private\n     *\n     * @param {string} way - Enter or leave.\n     * @param {string} from - Start or end.\n     */\n    _dispatchCall(way: string, from: string) {\n        const customEventName = this.attributes.scrollCall;\n\n        if (!customEventName) return;\n\n        // Using CustomEvent API (https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent)\n        const customEvent = new CustomEvent(customEventName, {\n            detail: {\n                target: this.$el,\n                way,\n                from,\n            },\n        });\n        window.dispatchEvent(customEvent);\n    }\n}\n"
  },
  {
    "path": "packages/lib/dist/locomotive-scroll.cjs",
    "content": "function t(t){return t&&\"object\"==typeof t&&\"default\"in t?t:{default:t}}var e=/*#__PURE__*/t(require(\"lenis\"));function s(t,e){(null==e||e>t.length)&&(e=t.length);for(var s=0,i=Array(e);s<e;s++)i[s]=t[s];return i}function i(t,e){var i=\"undefined\"!=typeof Symbol&&t[Symbol.iterator]||t[\"@@iterator\"];if(i)return(i=i.call(t)).next.bind(i);if(Array.isArray(t)||(i=function(t,e){if(t){if(\"string\"==typeof t)return s(t,e);var i={}.toString.call(t).slice(8,-1);return\"Object\"===i&&t.constructor&&(i=t.constructor.name),\"Map\"===i||\"Set\"===i?Array.from(t):\"Arguments\"===i||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(i)?s(t,e):void 0}}(t))||e&&t&&\"number\"==typeof t.length){i&&(t=i);var n=0;return function(){return n>=t.length?{done:!0}:{done:!1,value:t[n++]}}}throw new TypeError(\"Invalid attempt to iterate non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.\")}function n(){return n=Object.assign?Object.assign.bind():function(t){for(var e=1;e<arguments.length;e++){var s=arguments[e];for(var i in s)({}).hasOwnProperty.call(s,i)&&(t[i]=s[i])}return t},n.apply(null,arguments)}var r=/*#__PURE__*/function(){function t(t){var e=t.scrollElements,s=t.rootMargin,i=void 0===s?\"-1px -1px -1px -1px\":s,n=t.root,r=void 0===n?null:n,o=t.IORaf;this.scrollElements=void 0,this.rootMargin=void 0,this.root=void 0,this.IORaf=void 0,this.observer=void 0,this.scrollElements=e,this.rootMargin=i,this.root=r,this.IORaf=o,this._init()}var e=t.prototype;return e._init=function(){var t=this;this.observer=new IntersectionObserver(function(e){e.forEach(function(e){var s=t.scrollElements.find(function(t){return t.$el===e.target});e.isIntersecting?(s&&(s.isAlreadyIntersected=!0),t._setInview(e)):s&&s.isAlreadyIntersected&&t._setOutOfView(e)})},{root:this.root,rootMargin:this.rootMargin});for(var e,s=i(this.scrollElements);!(e=s()).done;)this.observe(e.value.$el)},e.destroy=function(){this.observer.disconnect()},e.observe=function(t){t&&this.observer.observe(t)},e.unobserve=function(t){t&&this.observer.unobserve(t)},e._setInview=function(t){var e=this.scrollElements.find(function(e){return e.$el===t.target});this.IORaf&&(null==e||e.setInteractivityOn()),!this.IORaf&&(null==e||e.setInview())},e._setOutOfView=function(t){var e=this.scrollElements.find(function(e){return e.$el===t.target});this.IORaf&&(null==e||e.setInteractivityOff()),!this.IORaf&&(null==e||e.setOutOfView()),null!=e&&e.attributes.scrollRepeat||this.IORaf||this.unobserve(t.target)},t}();function o(t,e,s,i,n){return s+((n-t)/(e-t)*(i-s)||0)}function l(t,e){return t.reduce(function(t,s){return Math.abs(s-e)<Math.abs(t-e)?s:t})}var a=\"--progress\",c=/*#__PURE__*/function(){function t(t){var e,s,i,n,r,o=this,l=t.$el,a=t.id,c=t.subscribeElementUpdateFn,h=t.unsubscribeElementUpdateFn,u=t.needRaf,d=t.scrollOrientation,f=t.lenisInstance;this.$el=void 0,this.id=void 0,this.needRaf=void 0,this.attributes=void 0,this.scrollOrientation=void 0,this.isAlreadyIntersected=void 0,this.intersection=void 0,this.metrics=void 0,this.currentScroll=void 0,this.translateValue=void 0,this.progress=void 0,this.lastProgress=void 0,this.isInview=void 0,this.isInteractive=void 0,this.isInFold=void 0,this.isFirstResize=void 0,this.subscribeElementUpdateFn=void 0,this.unsubscribeElementUpdateFn=void 0,this.lenisInstance=void 0,this.getWindowSize=void 0,this.getMetricsStart=void 0,this.getMetricsSize=void 0,this.startPositionHandlers={start:function(t,e,s){return t-e+s},middle:function(t,e,s,i){return t-e+s+.5*i},end:function(t,e,s,i){return t-e+s+i},fold:function(){return 0}},this.endPositionHandlers={start:function(t,e){return t-e},middle:function(t,e,s){return t-e+.5*s},end:function(t,e,s){return t-e+s}},this.$el=l,this.id=a,this.needRaf=u,this.scrollOrientation=d,this.lenisInstance=f,this.subscribeElementUpdateFn=c,this.unsubscribeElementUpdateFn=h,this.attributes={scrollClass:null!=(e=this.$el.dataset.scrollClass)?e:\"is-inview\",scrollOffset:null!=(s=this.$el.dataset.scrollOffset)?s:\"0,0\",scrollPosition:null!=(i=this.$el.dataset.scrollPosition)?i:\"start,end\",scrollCssProgress:void 0!==this.$el.dataset.scrollCssProgress,scrollEventProgress:null!=(n=this.$el.dataset.scrollEventProgress)?n:null,scrollSpeed:void 0!==this.$el.dataset.scrollSpeed?parseFloat(this.$el.dataset.scrollSpeed):null,scrollRepeat:void 0!==this.$el.dataset.scrollRepeat,scrollCall:null!=(r=this.$el.dataset.scrollCall)?r:null,scrollIgnoreFold:void 0!==this.$el.dataset.scrollIgnoreFold,scrollEnableTouchSpeed:void 0!==this.$el.dataset.scrollEnableTouchSpeed},this.intersection={start:0,end:0},this.metrics={offsetStart:0,offsetEnd:0,bcr:{}},this.currentScroll=this.lenisInstance.scroll,this.translateValue=0,this.progress=0,this.lastProgress=null,this.isInview=!1,this.isInteractive=!1,this.isAlreadyIntersected=!1,this.isInFold=!1,this.isFirstResize=!0,this.getWindowSize=\"vertical\"===this.scrollOrientation?function(){return o.lenisInstance.dimensions.height}:function(){return o.lenisInstance.dimensions.width},this.getMetricsStart=\"vertical\"===this.scrollOrientation?function(t){return t.top}:function(t){return t.left},this.getMetricsSize=\"vertical\"===this.scrollOrientation?function(t){return t.height}:function(t){return t.width},this._init()}var e=t.prototype;return e._init=function(){this.needRaf&&this._resize()},e.onResize=function(t){this.currentScroll=t.currentScroll,this._resize()},e.onRender=function(t){var e=t.currentScroll,s=t.smooth,i=this.getWindowSize();if(this.currentScroll=e,this._computeProgress(),this.attributes.scrollSpeed&&!isNaN(this.attributes.scrollSpeed))if(this.attributes.scrollEnableTouchSpeed||s){if(this.isInFold){var n=Math.max(0,this.progress);this.translateValue=n*i*this.attributes.scrollSpeed*-1}else{var r=o(0,1,-1,1,this.progress);this.translateValue=r*i*this.attributes.scrollSpeed*-1}this.$el.style.transform=\"vertical\"===this.scrollOrientation?\"translate3d(0, \"+this.translateValue+\"px, 0)\":\"translate3d(\"+this.translateValue+\"px, 0, 0)\"}else this.translateValue&&(this.$el.style.transform=\"translate3d(0, 0, 0)\"),this.translateValue=0},e.setInview=function(){if(!this.isInview){this.isInview=!0,this.$el.classList.add(this.attributes.scrollClass);var t=this._getScrollCallFrom();this.attributes.scrollCall&&this._dispatchCall(\"enter\",t)}},e.setOutOfView=function(){if(this.isInview&&this.attributes.scrollRepeat){this.isInview=!1,this.$el.classList.remove(this.attributes.scrollClass);var t=this._getScrollCallFrom();this.attributes.scrollCall&&this._dispatchCall(\"leave\",t)}},e.setInteractivityOn=function(){this.isInteractive||(this.isInteractive=!0,this.subscribeElementUpdateFn(this))},e.setInteractivityOff=function(){this.isInteractive&&(this.isInteractive=!1,this.unsubscribeElementUpdateFn(this),null!==this.lastProgress&&this._computeProgress(l([0,1],this.lastProgress)))},e._resize=function(){this.metrics.bcr=this.$el.getBoundingClientRect(),this._computeMetrics(),this._computeIntersection(),this.isFirstResize&&(this.isFirstResize=!1,this.isInFold&&this.setInview())},e._computeMetrics=function(){var t=this.getWindowSize(),e=this.getMetricsStart(this.metrics.bcr),s=this.getMetricsSize(this.metrics.bcr);this.metrics.offsetStart=this.currentScroll+e-this.translateValue,this.metrics.offsetEnd=this.metrics.offsetStart+s,this.isInFold=this.metrics.offsetStart<t&&!this.attributes.scrollIgnoreFold},e._computeIntersection=function(){var t,e,s,i,n,r,o,l,a=this.getWindowSize(),c=this.getMetricsSize(this.metrics.bcr),h=this.attributes.scrollOffset.split(\",\"),u=null!=(t=null==(e=h[0])?void 0:e.trim())?t:\"0\",d=null!=(s=null==(i=h[1])?void 0:i.trim())?s:\"0\",f=this.attributes.scrollPosition.split(\",\"),v=null!=(n=null==(r=f[0])?void 0:r.trim())?n:\"start\",m=null!=(o=null==(l=f[1])?void 0:l.trim())?o:\"end\",g=u.includes(\"%\")?a*parseInt(u.replace(\"%\",\"\").trim())*.01:parseInt(u),p=d.includes(\"%\")?a*parseInt(d.replace(\"%\",\"\").trim())*.01:parseInt(d);this.isInFold&&(v=\"fold\");var b=this.startPositionHandlers[v];this.intersection.start=b?b(this.metrics.offsetStart,a,g,c):this.metrics.offsetStart-a+g;var I=this.endPositionHandlers[m];if(this.intersection.end=I?I(this.metrics.offsetStart,p,c):this.metrics.offsetStart-p+c,this.intersection.end<=this.intersection.start)switch(m){case\"start\":default:this.intersection.end=this.intersection.start+1;break;case\"middle\":this.intersection.end=this.intersection.start+.5*c;break;case\"end\":this.intersection.end=this.intersection.start+c}},e._computeProgress=function(t){var e,s=null!=t?t:(e=o(this.intersection.start,this.intersection.end,0,1,this.currentScroll))<0?0:e>1?1:e;this.progress=s,s!==this.lastProgress&&(this.lastProgress=s,this.attributes.scrollCssProgress&&this._setCssProgress(s),this.attributes.scrollEventProgress&&this._setCustomEventProgress(s),s>0&&s<1&&this.setInview(),0===s&&this.setOutOfView(),1===s&&this.setOutOfView())},e._setCssProgress=function(t){void 0===t&&(t=0),this.$el.style.setProperty(a,t.toString())},e._setCustomEventProgress=function(t){void 0===t&&(t=0);var e=this.attributes.scrollEventProgress;if(e){var s=new CustomEvent(e,{detail:{target:this.$el,progress:t}});window.dispatchEvent(s)}},e._getScrollCallFrom=function(){var t=l([this.intersection.start,this.intersection.end],this.currentScroll);return this.intersection.start===t?\"start\":\"end\"},e.destroy=function(){this.attributes.scrollCssProgress&&this.$el.style.removeProperty(a),this.attributes.scrollSpeed&&this.$el.style.removeProperty(\"transform\"),this.isInview&&this.attributes.scrollClass&&this.$el.classList.remove(this.attributes.scrollClass)},e._dispatchCall=function(t,e){var s=this.attributes.scrollCall;if(s){var i=new CustomEvent(s,{detail:{target:this.$el,way:t,from:e}});window.dispatchEvent(i)}},t}(),h=[\"scrollOffset\",\"scrollPosition\",\"scrollCssProgress\",\"scrollEventProgress\",\"scrollSpeed\"],u=/*#__PURE__*/function(){function t(t){var e=t.$el,s=t.triggerRootMargin,i=t.rafRootMargin,n=t.scrollOrientation,r=t.lenisInstance;this.$scrollContainer=void 0,this.triggerRootMargin=void 0,this.rafRootMargin=void 0,this.scrollElements=void 0,this.triggeredScrollElements=void 0,this.RAFScrollElements=void 0,this.scrollElementsToUpdate=void 0,this.IOTriggerInstance=void 0,this.IORafInstance=void 0,this.scrollOrientation=void 0,this.lenisInstance=void 0,e?(this.$scrollContainer=e,this.lenisInstance=r,this.scrollOrientation=n,this.triggerRootMargin=null!=s?s:\"-1px -1px -1px -1px\",this.rafRootMargin=null!=i?i:\"100% 100% 100% 100%\",this.scrollElements=[],this.triggeredScrollElements=[],this.RAFScrollElements=[],this.scrollElementsToUpdate=[],this._init()):console.error(\"Please provide a DOM Element as scrollContainer\")}var e=t.prototype;return e._init=function(){var t=this.$scrollContainer.querySelectorAll(\"[data-scroll]\"),e=this.toElementArray(t);this._subscribeScrollElements(e);var s=this.lenisInstance.options.wrapper===window?null:this.lenisInstance.options.wrapper;this.IOTriggerInstance=new r({scrollElements:[].concat(this.triggeredScrollElements),root:s,rootMargin:this.triggerRootMargin,IORaf:!1}),this.IORafInstance=new r({scrollElements:[].concat(this.RAFScrollElements),root:s,rootMargin:this.rafRootMargin,IORaf:!0})},e.destroy=function(){this.IOTriggerInstance.destroy(),this.IORafInstance.destroy(),this._unsubscribeAllScrollElements()},e.onResize=function(t){for(var e,s=t.currentScroll,n=i(this.RAFScrollElements);!(e=n()).done;)e.value.onResize({currentScroll:s})},e.onRender=function(t){for(var e,s=t.currentScroll,n=t.smooth,r=i(this.scrollElementsToUpdate);!(e=r()).done;)e.value.onRender({currentScroll:s,smooth:n})},e.removeScrollElements=function(t){var e=this,s=t.querySelectorAll(\"[data-scroll]\");if(s.length){for(var i=new Set(Array.from(s)),n=0;n<this.triggeredScrollElements.length;n++){var r=this.triggeredScrollElements[n];i.has(r.$el)&&(this.IOTriggerInstance.unobserve(r.$el),this.triggeredScrollElements.splice(n,1))}for(var o=0;o<this.RAFScrollElements.length;o++){var l=this.RAFScrollElements[o];i.has(l.$el)&&(this.IORafInstance.unobserve(l.$el),this.RAFScrollElements.splice(o,1))}s.forEach(function(t){var s=e.scrollElementsToUpdate.find(function(e){return e.$el===t}),i=e.scrollElements.find(function(e){return e.$el===t});s&&e._unsubscribeElementUpdate(s),i&&(e.scrollElements=e.scrollElements.filter(function(t){return t.id!=i.id}))})}},e.addScrollElements=function(t){var e=t.querySelectorAll(\"[data-scroll]\"),s=[];this.scrollElements.forEach(function(t){s.push(t.id)});var i=Math.max.apply(Math,s.concat([0]))+1,n=this.toElementArray(e);this._subscribeScrollElements(n,i,!0)},e._subscribeScrollElements=function(t,e,s){void 0===e&&(e=0),void 0===s&&(s=!1);for(var i=0;i<t.length;i++){var n=t[i],r=this._checkRafNeeded(n),o=new c({$el:n,id:e+i,scrollOrientation:this.scrollOrientation,lenisInstance:this.lenisInstance,subscribeElementUpdateFn:this._subscribeElementUpdate.bind(this),unsubscribeElementUpdateFn:this._unsubscribeElementUpdate.bind(this),needRaf:r});this.scrollElements.push(o),r?(this.RAFScrollElements.push(o),s&&(this.IORafInstance.scrollElements.push(o),this.IORafInstance.observe(o.$el))):(this.triggeredScrollElements.push(o),s&&(this.IOTriggerInstance.scrollElements.push(o),this.IOTriggerInstance.observe(o.$el)))}},e._unsubscribeAllScrollElements=function(){for(var t,e=i(this.scrollElements);!(t=e()).done;)t.value.destroy();this.scrollElements=[],this.RAFScrollElements=[],this.triggeredScrollElements=[],this.scrollElementsToUpdate=[]},e._subscribeElementUpdate=function(t){this.scrollElementsToUpdate.push(t)},e._unsubscribeElementUpdate=function(t){this.scrollElementsToUpdate=this.scrollElementsToUpdate.filter(function(e){return e.id!=t.id})},e.toElementArray=function(t){return Array.from(t)},e._checkRafNeeded=function(t){var e=[].concat(h),s=function(t){e=e.filter(function(e){return e!==t})};if(t.dataset.scrollOffset){if(\"0,0\"!==t.dataset.scrollOffset.split(\",\").map(function(t){return t.replace(\"%\",\"\").trim()}).join(\",\"))return!0;s(\"scrollOffset\")}else s(\"scrollOffset\");if(t.dataset.scrollPosition){if(\"top,bottom\"!==t.dataset.scrollPosition.trim())return!0;s(\"scrollPosition\")}else s(\"scrollPosition\");if(t.dataset.scrollSpeed&&!isNaN(parseFloat(t.dataset.scrollSpeed)))return!0;s(\"scrollSpeed\");for(var n,r=i(e);!(n=r()).done;)if(n.value in t.dataset)return!0;return!1},t}();module.exports=/*#__PURE__*/function(){function t(t){var e=void 0===t?{}:t,s=e.lenisOptions,i=void 0===s?{}:s,n=e.triggerRootMargin,r=e.rafRootMargin,o=e.autoStart,l=void 0===o||o,a=e.scrollCallback,c=void 0===a?function(){}:a,h=e.initCustomTicker,u=e.destroyCustomTicker;this.rafPlaying=void 0,this.lenisInstance=null,this.coreInstance=null,this.lenisOptions=void 0,this.triggerRootMargin=void 0,this.rafRootMargin=void 0,this.rafInstance=void 0,this.autoStart=void 0,this.isTouchDevice=void 0,this.initCustomTicker=void 0,this.destroyCustomTicker=void 0,this._onRenderBind=void 0,this._onResizeBind=void 0,this._onScrollToBind=void 0,this._originalOnContentResize=void 0,this._originalOnWrapperResize=void 0,window.locomotiveScrollVersion=\"5.0.0\",Object.assign(this,{lenisOptions:i,triggerRootMargin:n,rafRootMargin:r,autoStart:l,scrollCallback:c,initCustomTicker:h,destroyCustomTicker:u}),this._onRenderBind=this._onRender.bind(this),this._onScrollToBind=this._onScrollTo.bind(this),this._onResizeBind=this._onResize.bind(this),this.rafPlaying=!1,this.isTouchDevice=\"ontouchstart\"in window||navigator.maxTouchPoints>0,this._init()}var s=t.prototype;return s._init=function(){var t=this;this.lenisInstance=new e.default(n({},this.lenisOptions)),this.scrollCallback&&this.lenisInstance.on(\"scroll\",this.scrollCallback),document.documentElement.setAttribute(\"data-scroll-orientation\",this.lenisInstance.options.orientation),requestAnimationFrame(function(){t.coreInstance=new u({$el:t.lenisInstance.rootElement,triggerRootMargin:t.triggerRootMargin,rafRootMargin:t.rafRootMargin,scrollOrientation:t.lenisInstance.options.orientation,lenisInstance:t.lenisInstance}),t._bindEvents(),t.initCustomTicker&&!t.destroyCustomTicker?console.warn(\"initCustomTicker callback is declared, but destroyCustomTicker is not. Please pay attention. It could cause trouble.\"):!t.initCustomTicker&&t.destroyCustomTicker&&console.warn(\"destroyCustomTicker callback is declared, but initCustomTicker is not. Please pay attention. It could cause trouble.\"),t.autoStart&&t.start()})},s.destroy=function(){var t,e=this;this.stop(),this._unbindEvents(),null==(t=this.lenisInstance)||t.destroy(),requestAnimationFrame(function(){var t;null==(t=e.coreInstance)||t.destroy()})},s._bindEvents=function(){var t=this;this._bindScrollToEvents(),this.lenisInstance&&(this._originalOnContentResize=this.lenisInstance.dimensions.onContentResize.bind(this.lenisInstance.dimensions),this._originalOnWrapperResize=this.lenisInstance.dimensions.onWrapperResize.bind(this.lenisInstance.dimensions),this.lenisInstance.dimensions.onContentResize=function(){null==t._originalOnContentResize||t._originalOnContentResize(),t._onResizeBind()},this.lenisInstance.dimensions.onWrapperResize=function(){null==t._originalOnWrapperResize||t._originalOnWrapperResize(),t._onResizeBind()})},s._unbindEvents=function(){this._unbindScrollToEvents(),this.lenisInstance&&(this._originalOnContentResize&&(this.lenisInstance.dimensions.onContentResize=this._originalOnContentResize),this._originalOnWrapperResize&&(this.lenisInstance.dimensions.onWrapperResize=this._originalOnWrapperResize))},s._bindScrollToEvents=function(t){var e,s=this,i=t||(null==(e=this.lenisInstance)?void 0:e.rootElement),n=null==i?void 0:i.querySelectorAll(\"[data-scroll-to]\");(null==n?void 0:n.length)&&n.forEach(function(t){t.addEventListener(\"click\",s._onScrollToBind,!1)})},s._unbindScrollToEvents=function(t){var e,s=this,i=t||(null==(e=this.lenisInstance)?void 0:e.rootElement),n=null==i?void 0:i.querySelectorAll(\"[data-scroll-to]\");(null==n?void 0:n.length)&&n.forEach(function(t){t.removeEventListener(\"click\",s._onScrollToBind,!1)})},s._onResize=function(){var t,e,s;null==(t=this.coreInstance)||t.onResize({currentScroll:null!=(e=null==(s=this.lenisInstance)?void 0:s.scroll)?e:0,smooth:!this.isTouchDevice})},s._onRender=function(){var t,e,s,i;null==(t=this.lenisInstance)||t.raf(Date.now()),null==(e=this.coreInstance)||e.onRender({currentScroll:null!=(s=null==(i=this.lenisInstance)?void 0:i.scroll)?s:0,smooth:!this.isTouchDevice})},s._onScrollTo=function(t){var e,s;t.preventDefault();var i=null!=(e=t.currentTarget)?e:null;if(i){var n=i.getAttribute(\"data-scroll-to-href\")||i.getAttribute(\"href\"),r=i.getAttribute(\"data-scroll-to-offset\")||0,o=i.getAttribute(\"data-scroll-to-duration\")||(null==(s=this.lenisInstance)?void 0:s.options.duration);n&&this.scrollTo(n,{offset:\"string\"==typeof r?parseInt(r):r,duration:\"string\"==typeof o?parseInt(o):o})}},s.start=function(){var t;this.rafPlaying||(null==(t=this.lenisInstance)||t.start(),this.rafPlaying=!0,this.initCustomTicker?this.initCustomTicker(this._onRenderBind):this._raf())},s.stop=function(){var t;this.rafPlaying&&(null==(t=this.lenisInstance)||t.stop(),this.rafPlaying=!1,this.destroyCustomTicker?this.destroyCustomTicker(this._onRenderBind):this.rafInstance&&cancelAnimationFrame(this.rafInstance))},s.removeScrollElements=function(t){var e;t?(this._unbindScrollToEvents(t),null==(e=this.coreInstance)||e.removeScrollElements(t)):console.error(\"Please provide a DOM Element as $oldContainer\")},s.addScrollElements=function(t){var e,s=this;t?(null==(e=this.coreInstance)||e.addScrollElements(t),requestAnimationFrame(function(){s._bindScrollToEvents(t)})):console.error(\"Please provide a DOM Element as $newContainer\")},s.resize=function(){this._onResizeBind()},s.scrollTo=function(t,e){var s;null==(s=this.lenisInstance)||s.scrollTo(t,{offset:null==e?void 0:e.offset,lerp:null==e?void 0:e.lerp,duration:null==e?void 0:e.duration,immediate:null==e?void 0:e.immediate,lock:null==e?void 0:e.lock,force:null==e?void 0:e.force,easing:null==e?void 0:e.easing,onComplete:null==e?void 0:e.onComplete})},s._raf=function(){var t=this;this._onRenderBind(),this.rafInstance=requestAnimationFrame(function(){return t._raf()})},t}();\n//# sourceMappingURL=locomotive-scroll.cjs.map\n"
  },
  {
    "path": "packages/lib/dist/locomotive-scroll.css",
    "content": "html.lenis,html.lenis body{height:auto}.lenis:not(.lenis-autoToggle).lenis-stopped{overflow:clip}.lenis [data-lenis-prevent-touch],.lenis [data-lenis-prevent-wheel],.lenis [data-lenis-prevent]{overscroll-behavior:contain}.lenis.lenis-smooth iframe{pointer-events:none}.lenis.lenis-autoToggle{transition-behavior:allow-discrete;transition-duration:1ms;transition-property:overflow}"
  },
  {
    "path": "packages/lib/dist/locomotive-scroll.mjs",
    "content": "import t from\"lenis\";function e(t,e){(null==e||e>t.length)&&(e=t.length);for(var s=0,i=Array(e);s<e;s++)i[s]=t[s];return i}function s(t,s){var i=\"undefined\"!=typeof Symbol&&t[Symbol.iterator]||t[\"@@iterator\"];if(i)return(i=i.call(t)).next.bind(i);if(Array.isArray(t)||(i=function(t,s){if(t){if(\"string\"==typeof t)return e(t,s);var i={}.toString.call(t).slice(8,-1);return\"Object\"===i&&t.constructor&&(i=t.constructor.name),\"Map\"===i||\"Set\"===i?Array.from(t):\"Arguments\"===i||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(i)?e(t,s):void 0}}(t))||s&&t&&\"number\"==typeof t.length){i&&(t=i);var n=0;return function(){return n>=t.length?{done:!0}:{done:!1,value:t[n++]}}}throw new TypeError(\"Invalid attempt to iterate non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.\")}function i(){return i=Object.assign?Object.assign.bind():function(t){for(var e=1;e<arguments.length;e++){var s=arguments[e];for(var i in s)({}).hasOwnProperty.call(s,i)&&(t[i]=s[i])}return t},i.apply(null,arguments)}var n=/*#__PURE__*/function(){function t(t){var e=t.scrollElements,s=t.rootMargin,i=void 0===s?\"-1px -1px -1px -1px\":s,n=t.root,r=void 0===n?null:n,o=t.IORaf;this.scrollElements=void 0,this.rootMargin=void 0,this.root=void 0,this.IORaf=void 0,this.observer=void 0,this.scrollElements=e,this.rootMargin=i,this.root=r,this.IORaf=o,this._init()}var e=t.prototype;return e._init=function(){var t=this;this.observer=new IntersectionObserver(function(e){e.forEach(function(e){var s=t.scrollElements.find(function(t){return t.$el===e.target});e.isIntersecting?(s&&(s.isAlreadyIntersected=!0),t._setInview(e)):s&&s.isAlreadyIntersected&&t._setOutOfView(e)})},{root:this.root,rootMargin:this.rootMargin});for(var e,i=s(this.scrollElements);!(e=i()).done;)this.observe(e.value.$el)},e.destroy=function(){this.observer.disconnect()},e.observe=function(t){t&&this.observer.observe(t)},e.unobserve=function(t){t&&this.observer.unobserve(t)},e._setInview=function(t){var e=this.scrollElements.find(function(e){return e.$el===t.target});this.IORaf&&(null==e||e.setInteractivityOn()),!this.IORaf&&(null==e||e.setInview())},e._setOutOfView=function(t){var e=this.scrollElements.find(function(e){return e.$el===t.target});this.IORaf&&(null==e||e.setInteractivityOff()),!this.IORaf&&(null==e||e.setOutOfView()),null!=e&&e.attributes.scrollRepeat||this.IORaf||this.unobserve(t.target)},t}();function r(t,e,s,i,n){return s+((n-t)/(e-t)*(i-s)||0)}function o(t,e){return t.reduce(function(t,s){return Math.abs(s-e)<Math.abs(t-e)?s:t})}var l=\"--progress\",a=/*#__PURE__*/function(){function t(t){var e,s,i,n,r,o=this,l=t.$el,a=t.id,c=t.subscribeElementUpdateFn,h=t.unsubscribeElementUpdateFn,u=t.needRaf,d=t.scrollOrientation,f=t.lenisInstance;this.$el=void 0,this.id=void 0,this.needRaf=void 0,this.attributes=void 0,this.scrollOrientation=void 0,this.isAlreadyIntersected=void 0,this.intersection=void 0,this.metrics=void 0,this.currentScroll=void 0,this.translateValue=void 0,this.progress=void 0,this.lastProgress=void 0,this.isInview=void 0,this.isInteractive=void 0,this.isInFold=void 0,this.isFirstResize=void 0,this.subscribeElementUpdateFn=void 0,this.unsubscribeElementUpdateFn=void 0,this.lenisInstance=void 0,this.getWindowSize=void 0,this.getMetricsStart=void 0,this.getMetricsSize=void 0,this.startPositionHandlers={start:function(t,e,s){return t-e+s},middle:function(t,e,s,i){return t-e+s+.5*i},end:function(t,e,s,i){return t-e+s+i},fold:function(){return 0}},this.endPositionHandlers={start:function(t,e){return t-e},middle:function(t,e,s){return t-e+.5*s},end:function(t,e,s){return t-e+s}},this.$el=l,this.id=a,this.needRaf=u,this.scrollOrientation=d,this.lenisInstance=f,this.subscribeElementUpdateFn=c,this.unsubscribeElementUpdateFn=h,this.attributes={scrollClass:null!=(e=this.$el.dataset.scrollClass)?e:\"is-inview\",scrollOffset:null!=(s=this.$el.dataset.scrollOffset)?s:\"0,0\",scrollPosition:null!=(i=this.$el.dataset.scrollPosition)?i:\"start,end\",scrollCssProgress:void 0!==this.$el.dataset.scrollCssProgress,scrollEventProgress:null!=(n=this.$el.dataset.scrollEventProgress)?n:null,scrollSpeed:void 0!==this.$el.dataset.scrollSpeed?parseFloat(this.$el.dataset.scrollSpeed):null,scrollRepeat:void 0!==this.$el.dataset.scrollRepeat,scrollCall:null!=(r=this.$el.dataset.scrollCall)?r:null,scrollIgnoreFold:void 0!==this.$el.dataset.scrollIgnoreFold,scrollEnableTouchSpeed:void 0!==this.$el.dataset.scrollEnableTouchSpeed},this.intersection={start:0,end:0},this.metrics={offsetStart:0,offsetEnd:0,bcr:{}},this.currentScroll=this.lenisInstance.scroll,this.translateValue=0,this.progress=0,this.lastProgress=null,this.isInview=!1,this.isInteractive=!1,this.isAlreadyIntersected=!1,this.isInFold=!1,this.isFirstResize=!0,this.getWindowSize=\"vertical\"===this.scrollOrientation?function(){return o.lenisInstance.dimensions.height}:function(){return o.lenisInstance.dimensions.width},this.getMetricsStart=\"vertical\"===this.scrollOrientation?function(t){return t.top}:function(t){return t.left},this.getMetricsSize=\"vertical\"===this.scrollOrientation?function(t){return t.height}:function(t){return t.width},this._init()}var e=t.prototype;return e._init=function(){this.needRaf&&this._resize()},e.onResize=function(t){this.currentScroll=t.currentScroll,this._resize()},e.onRender=function(t){var e=t.currentScroll,s=t.smooth,i=this.getWindowSize();if(this.currentScroll=e,this._computeProgress(),this.attributes.scrollSpeed&&!isNaN(this.attributes.scrollSpeed))if(this.attributes.scrollEnableTouchSpeed||s){if(this.isInFold){var n=Math.max(0,this.progress);this.translateValue=n*i*this.attributes.scrollSpeed*-1}else{var o=r(0,1,-1,1,this.progress);this.translateValue=o*i*this.attributes.scrollSpeed*-1}this.$el.style.transform=\"vertical\"===this.scrollOrientation?\"translate3d(0, \"+this.translateValue+\"px, 0)\":\"translate3d(\"+this.translateValue+\"px, 0, 0)\"}else this.translateValue&&(this.$el.style.transform=\"translate3d(0, 0, 0)\"),this.translateValue=0},e.setInview=function(){if(!this.isInview){this.isInview=!0,this.$el.classList.add(this.attributes.scrollClass);var t=this._getScrollCallFrom();this.attributes.scrollCall&&this._dispatchCall(\"enter\",t)}},e.setOutOfView=function(){if(this.isInview&&this.attributes.scrollRepeat){this.isInview=!1,this.$el.classList.remove(this.attributes.scrollClass);var t=this._getScrollCallFrom();this.attributes.scrollCall&&this._dispatchCall(\"leave\",t)}},e.setInteractivityOn=function(){this.isInteractive||(this.isInteractive=!0,this.subscribeElementUpdateFn(this))},e.setInteractivityOff=function(){this.isInteractive&&(this.isInteractive=!1,this.unsubscribeElementUpdateFn(this),null!==this.lastProgress&&this._computeProgress(o([0,1],this.lastProgress)))},e._resize=function(){this.metrics.bcr=this.$el.getBoundingClientRect(),this._computeMetrics(),this._computeIntersection(),this.isFirstResize&&(this.isFirstResize=!1,this.isInFold&&this.setInview())},e._computeMetrics=function(){var t=this.getWindowSize(),e=this.getMetricsStart(this.metrics.bcr),s=this.getMetricsSize(this.metrics.bcr);this.metrics.offsetStart=this.currentScroll+e-this.translateValue,this.metrics.offsetEnd=this.metrics.offsetStart+s,this.isInFold=this.metrics.offsetStart<t&&!this.attributes.scrollIgnoreFold},e._computeIntersection=function(){var t,e,s,i,n,r,o,l,a=this.getWindowSize(),c=this.getMetricsSize(this.metrics.bcr),h=this.attributes.scrollOffset.split(\",\"),u=null!=(t=null==(e=h[0])?void 0:e.trim())?t:\"0\",d=null!=(s=null==(i=h[1])?void 0:i.trim())?s:\"0\",f=this.attributes.scrollPosition.split(\",\"),v=null!=(n=null==(r=f[0])?void 0:r.trim())?n:\"start\",m=null!=(o=null==(l=f[1])?void 0:l.trim())?o:\"end\",g=u.includes(\"%\")?a*parseInt(u.replace(\"%\",\"\").trim())*.01:parseInt(u),p=d.includes(\"%\")?a*parseInt(d.replace(\"%\",\"\").trim())*.01:parseInt(d);this.isInFold&&(v=\"fold\");var b=this.startPositionHandlers[v];this.intersection.start=b?b(this.metrics.offsetStart,a,g,c):this.metrics.offsetStart-a+g;var I=this.endPositionHandlers[m];if(this.intersection.end=I?I(this.metrics.offsetStart,p,c):this.metrics.offsetStart-p+c,this.intersection.end<=this.intersection.start)switch(m){case\"start\":default:this.intersection.end=this.intersection.start+1;break;case\"middle\":this.intersection.end=this.intersection.start+.5*c;break;case\"end\":this.intersection.end=this.intersection.start+c}},e._computeProgress=function(t){var e,s=null!=t?t:(e=r(this.intersection.start,this.intersection.end,0,1,this.currentScroll))<0?0:e>1?1:e;this.progress=s,s!==this.lastProgress&&(this.lastProgress=s,this.attributes.scrollCssProgress&&this._setCssProgress(s),this.attributes.scrollEventProgress&&this._setCustomEventProgress(s),s>0&&s<1&&this.setInview(),0===s&&this.setOutOfView(),1===s&&this.setOutOfView())},e._setCssProgress=function(t){void 0===t&&(t=0),this.$el.style.setProperty(l,t.toString())},e._setCustomEventProgress=function(t){void 0===t&&(t=0);var e=this.attributes.scrollEventProgress;if(e){var s=new CustomEvent(e,{detail:{target:this.$el,progress:t}});window.dispatchEvent(s)}},e._getScrollCallFrom=function(){var t=o([this.intersection.start,this.intersection.end],this.currentScroll);return this.intersection.start===t?\"start\":\"end\"},e.destroy=function(){this.attributes.scrollCssProgress&&this.$el.style.removeProperty(l),this.attributes.scrollSpeed&&this.$el.style.removeProperty(\"transform\"),this.isInview&&this.attributes.scrollClass&&this.$el.classList.remove(this.attributes.scrollClass)},e._dispatchCall=function(t,e){var s=this.attributes.scrollCall;if(s){var i=new CustomEvent(s,{detail:{target:this.$el,way:t,from:e}});window.dispatchEvent(i)}},t}(),c=[\"scrollOffset\",\"scrollPosition\",\"scrollCssProgress\",\"scrollEventProgress\",\"scrollSpeed\"],h=/*#__PURE__*/function(){function t(t){var e=t.$el,s=t.triggerRootMargin,i=t.rafRootMargin,n=t.scrollOrientation,r=t.lenisInstance;this.$scrollContainer=void 0,this.triggerRootMargin=void 0,this.rafRootMargin=void 0,this.scrollElements=void 0,this.triggeredScrollElements=void 0,this.RAFScrollElements=void 0,this.scrollElementsToUpdate=void 0,this.IOTriggerInstance=void 0,this.IORafInstance=void 0,this.scrollOrientation=void 0,this.lenisInstance=void 0,e?(this.$scrollContainer=e,this.lenisInstance=r,this.scrollOrientation=n,this.triggerRootMargin=null!=s?s:\"-1px -1px -1px -1px\",this.rafRootMargin=null!=i?i:\"100% 100% 100% 100%\",this.scrollElements=[],this.triggeredScrollElements=[],this.RAFScrollElements=[],this.scrollElementsToUpdate=[],this._init()):console.error(\"Please provide a DOM Element as scrollContainer\")}var e=t.prototype;return e._init=function(){var t=this.$scrollContainer.querySelectorAll(\"[data-scroll]\"),e=this.toElementArray(t);this._subscribeScrollElements(e);var s=this.lenisInstance.options.wrapper===window?null:this.lenisInstance.options.wrapper;this.IOTriggerInstance=new n({scrollElements:[].concat(this.triggeredScrollElements),root:s,rootMargin:this.triggerRootMargin,IORaf:!1}),this.IORafInstance=new n({scrollElements:[].concat(this.RAFScrollElements),root:s,rootMargin:this.rafRootMargin,IORaf:!0})},e.destroy=function(){this.IOTriggerInstance.destroy(),this.IORafInstance.destroy(),this._unsubscribeAllScrollElements()},e.onResize=function(t){for(var e,i=t.currentScroll,n=s(this.RAFScrollElements);!(e=n()).done;)e.value.onResize({currentScroll:i})},e.onRender=function(t){for(var e,i=t.currentScroll,n=t.smooth,r=s(this.scrollElementsToUpdate);!(e=r()).done;)e.value.onRender({currentScroll:i,smooth:n})},e.removeScrollElements=function(t){var e=this,s=t.querySelectorAll(\"[data-scroll]\");if(s.length){for(var i=new Set(Array.from(s)),n=0;n<this.triggeredScrollElements.length;n++){var r=this.triggeredScrollElements[n];i.has(r.$el)&&(this.IOTriggerInstance.unobserve(r.$el),this.triggeredScrollElements.splice(n,1))}for(var o=0;o<this.RAFScrollElements.length;o++){var l=this.RAFScrollElements[o];i.has(l.$el)&&(this.IORafInstance.unobserve(l.$el),this.RAFScrollElements.splice(o,1))}s.forEach(function(t){var s=e.scrollElementsToUpdate.find(function(e){return e.$el===t}),i=e.scrollElements.find(function(e){return e.$el===t});s&&e._unsubscribeElementUpdate(s),i&&(e.scrollElements=e.scrollElements.filter(function(t){return t.id!=i.id}))})}},e.addScrollElements=function(t){var e=t.querySelectorAll(\"[data-scroll]\"),s=[];this.scrollElements.forEach(function(t){s.push(t.id)});var i=Math.max.apply(Math,s.concat([0]))+1,n=this.toElementArray(e);this._subscribeScrollElements(n,i,!0)},e._subscribeScrollElements=function(t,e,s){void 0===e&&(e=0),void 0===s&&(s=!1);for(var i=0;i<t.length;i++){var n=t[i],r=this._checkRafNeeded(n),o=new a({$el:n,id:e+i,scrollOrientation:this.scrollOrientation,lenisInstance:this.lenisInstance,subscribeElementUpdateFn:this._subscribeElementUpdate.bind(this),unsubscribeElementUpdateFn:this._unsubscribeElementUpdate.bind(this),needRaf:r});this.scrollElements.push(o),r?(this.RAFScrollElements.push(o),s&&(this.IORafInstance.scrollElements.push(o),this.IORafInstance.observe(o.$el))):(this.triggeredScrollElements.push(o),s&&(this.IOTriggerInstance.scrollElements.push(o),this.IOTriggerInstance.observe(o.$el)))}},e._unsubscribeAllScrollElements=function(){for(var t,e=s(this.scrollElements);!(t=e()).done;)t.value.destroy();this.scrollElements=[],this.RAFScrollElements=[],this.triggeredScrollElements=[],this.scrollElementsToUpdate=[]},e._subscribeElementUpdate=function(t){this.scrollElementsToUpdate.push(t)},e._unsubscribeElementUpdate=function(t){this.scrollElementsToUpdate=this.scrollElementsToUpdate.filter(function(e){return e.id!=t.id})},e.toElementArray=function(t){return Array.from(t)},e._checkRafNeeded=function(t){var e=[].concat(c),i=function(t){e=e.filter(function(e){return e!==t})};if(t.dataset.scrollOffset){if(\"0,0\"!==t.dataset.scrollOffset.split(\",\").map(function(t){return t.replace(\"%\",\"\").trim()}).join(\",\"))return!0;i(\"scrollOffset\")}else i(\"scrollOffset\");if(t.dataset.scrollPosition){if(\"top,bottom\"!==t.dataset.scrollPosition.trim())return!0;i(\"scrollPosition\")}else i(\"scrollPosition\");if(t.dataset.scrollSpeed&&!isNaN(parseFloat(t.dataset.scrollSpeed)))return!0;i(\"scrollSpeed\");for(var n,r=s(e);!(n=r()).done;)if(n.value in t.dataset)return!0;return!1},t}(),u=/*#__PURE__*/function(){function e(t){var e=void 0===t?{}:t,s=e.lenisOptions,i=void 0===s?{}:s,n=e.triggerRootMargin,r=e.rafRootMargin,o=e.autoStart,l=void 0===o||o,a=e.scrollCallback,c=void 0===a?function(){}:a,h=e.initCustomTicker,u=e.destroyCustomTicker;this.rafPlaying=void 0,this.lenisInstance=null,this.coreInstance=null,this.lenisOptions=void 0,this.triggerRootMargin=void 0,this.rafRootMargin=void 0,this.rafInstance=void 0,this.autoStart=void 0,this.isTouchDevice=void 0,this.initCustomTicker=void 0,this.destroyCustomTicker=void 0,this._onRenderBind=void 0,this._onResizeBind=void 0,this._onScrollToBind=void 0,this._originalOnContentResize=void 0,this._originalOnWrapperResize=void 0,window.locomotiveScrollVersion=\"5.0.0\",Object.assign(this,{lenisOptions:i,triggerRootMargin:n,rafRootMargin:r,autoStart:l,scrollCallback:c,initCustomTicker:h,destroyCustomTicker:u}),this._onRenderBind=this._onRender.bind(this),this._onScrollToBind=this._onScrollTo.bind(this),this._onResizeBind=this._onResize.bind(this),this.rafPlaying=!1,this.isTouchDevice=\"ontouchstart\"in window||navigator.maxTouchPoints>0,this._init()}var s=e.prototype;return s._init=function(){var e=this;this.lenisInstance=new t(i({},this.lenisOptions)),this.scrollCallback&&this.lenisInstance.on(\"scroll\",this.scrollCallback),document.documentElement.setAttribute(\"data-scroll-orientation\",this.lenisInstance.options.orientation),requestAnimationFrame(function(){e.coreInstance=new h({$el:e.lenisInstance.rootElement,triggerRootMargin:e.triggerRootMargin,rafRootMargin:e.rafRootMargin,scrollOrientation:e.lenisInstance.options.orientation,lenisInstance:e.lenisInstance}),e._bindEvents(),e.initCustomTicker&&!e.destroyCustomTicker?console.warn(\"initCustomTicker callback is declared, but destroyCustomTicker is not. Please pay attention. It could cause trouble.\"):!e.initCustomTicker&&e.destroyCustomTicker&&console.warn(\"destroyCustomTicker callback is declared, but initCustomTicker is not. Please pay attention. It could cause trouble.\"),e.autoStart&&e.start()})},s.destroy=function(){var t,e=this;this.stop(),this._unbindEvents(),null==(t=this.lenisInstance)||t.destroy(),requestAnimationFrame(function(){var t;null==(t=e.coreInstance)||t.destroy()})},s._bindEvents=function(){var t=this;this._bindScrollToEvents(),this.lenisInstance&&(this._originalOnContentResize=this.lenisInstance.dimensions.onContentResize.bind(this.lenisInstance.dimensions),this._originalOnWrapperResize=this.lenisInstance.dimensions.onWrapperResize.bind(this.lenisInstance.dimensions),this.lenisInstance.dimensions.onContentResize=function(){null==t._originalOnContentResize||t._originalOnContentResize(),t._onResizeBind()},this.lenisInstance.dimensions.onWrapperResize=function(){null==t._originalOnWrapperResize||t._originalOnWrapperResize(),t._onResizeBind()})},s._unbindEvents=function(){this._unbindScrollToEvents(),this.lenisInstance&&(this._originalOnContentResize&&(this.lenisInstance.dimensions.onContentResize=this._originalOnContentResize),this._originalOnWrapperResize&&(this.lenisInstance.dimensions.onWrapperResize=this._originalOnWrapperResize))},s._bindScrollToEvents=function(t){var e,s=this,i=t||(null==(e=this.lenisInstance)?void 0:e.rootElement),n=null==i?void 0:i.querySelectorAll(\"[data-scroll-to]\");(null==n?void 0:n.length)&&n.forEach(function(t){t.addEventListener(\"click\",s._onScrollToBind,!1)})},s._unbindScrollToEvents=function(t){var e,s=this,i=t||(null==(e=this.lenisInstance)?void 0:e.rootElement),n=null==i?void 0:i.querySelectorAll(\"[data-scroll-to]\");(null==n?void 0:n.length)&&n.forEach(function(t){t.removeEventListener(\"click\",s._onScrollToBind,!1)})},s._onResize=function(){var t,e,s;null==(t=this.coreInstance)||t.onResize({currentScroll:null!=(e=null==(s=this.lenisInstance)?void 0:s.scroll)?e:0,smooth:!this.isTouchDevice})},s._onRender=function(){var t,e,s,i;null==(t=this.lenisInstance)||t.raf(Date.now()),null==(e=this.coreInstance)||e.onRender({currentScroll:null!=(s=null==(i=this.lenisInstance)?void 0:i.scroll)?s:0,smooth:!this.isTouchDevice})},s._onScrollTo=function(t){var e,s;t.preventDefault();var i=null!=(e=t.currentTarget)?e:null;if(i){var n=i.getAttribute(\"data-scroll-to-href\")||i.getAttribute(\"href\"),r=i.getAttribute(\"data-scroll-to-offset\")||0,o=i.getAttribute(\"data-scroll-to-duration\")||(null==(s=this.lenisInstance)?void 0:s.options.duration);n&&this.scrollTo(n,{offset:\"string\"==typeof r?parseInt(r):r,duration:\"string\"==typeof o?parseInt(o):o})}},s.start=function(){var t;this.rafPlaying||(null==(t=this.lenisInstance)||t.start(),this.rafPlaying=!0,this.initCustomTicker?this.initCustomTicker(this._onRenderBind):this._raf())},s.stop=function(){var t;this.rafPlaying&&(null==(t=this.lenisInstance)||t.stop(),this.rafPlaying=!1,this.destroyCustomTicker?this.destroyCustomTicker(this._onRenderBind):this.rafInstance&&cancelAnimationFrame(this.rafInstance))},s.removeScrollElements=function(t){var e;t?(this._unbindScrollToEvents(t),null==(e=this.coreInstance)||e.removeScrollElements(t)):console.error(\"Please provide a DOM Element as $oldContainer\")},s.addScrollElements=function(t){var e,s=this;t?(null==(e=this.coreInstance)||e.addScrollElements(t),requestAnimationFrame(function(){s._bindScrollToEvents(t)})):console.error(\"Please provide a DOM Element as $newContainer\")},s.resize=function(){this._onResizeBind()},s.scrollTo=function(t,e){var s;null==(s=this.lenisInstance)||s.scrollTo(t,{offset:null==e?void 0:e.offset,lerp:null==e?void 0:e.lerp,duration:null==e?void 0:e.duration,immediate:null==e?void 0:e.immediate,lock:null==e?void 0:e.lock,force:null==e?void 0:e.force,easing:null==e?void 0:e.easing,onComplete:null==e?void 0:e.onComplete})},s._raf=function(){var t=this;this._onRenderBind(),this.rafInstance=requestAnimationFrame(function(){return t._raf()})},e}();export{u as default};\n//# sourceMappingURL=locomotive-scroll.mjs.map\n"
  },
  {
    "path": "packages/lib/dist/locomotive-scroll.modern.mjs",
    "content": "import t from\"lenis\";function s(){return s=Object.assign?Object.assign.bind():function(t){for(var s=1;s<arguments.length;s++){var e=arguments[s];for(var i in e)({}).hasOwnProperty.call(e,i)&&(t[i]=e[i])}return t},s.apply(null,arguments)}class e{constructor({scrollElements:t,rootMargin:s=\"-1px -1px -1px -1px\",root:e=null,IORaf:i}){this.scrollElements=void 0,this.rootMargin=void 0,this.root=void 0,this.IORaf=void 0,this.observer=void 0,this.scrollElements=t,this.rootMargin=s,this.root=e,this.IORaf=i,this._init()}_init(){this.observer=new IntersectionObserver(t=>{t.forEach(t=>{const s=this.scrollElements.find(s=>s.$el===t.target);t.isIntersecting?(s&&(s.isAlreadyIntersected=!0),this._setInview(t)):s&&s.isAlreadyIntersected&&this._setOutOfView(t)})},{root:this.root,rootMargin:this.rootMargin});for(const t of this.scrollElements)this.observe(t.$el)}destroy(){this.observer.disconnect()}observe(t){t&&this.observer.observe(t)}unobserve(t){t&&this.observer.unobserve(t)}_setInview(t){const s=this.scrollElements.find(s=>s.$el===t.target);this.IORaf&&(null==s||s.setInteractivityOn()),!this.IORaf&&(null==s||s.setInview())}_setOutOfView(t){const s=this.scrollElements.find(s=>s.$el===t.target);this.IORaf&&(null==s||s.setInteractivityOff()),!this.IORaf&&(null==s||s.setOutOfView()),null!=s&&s.attributes.scrollRepeat||this.IORaf||this.unobserve(t.target)}}function i(t,s,e,i,n){return e+((n-t)/(s-t)*(i-e)||0)}function n(t,s){return t.reduce((t,e)=>Math.abs(e-s)<Math.abs(t-s)?e:t)}const r=\"--progress\";class l{constructor({$el:t,id:s,subscribeElementUpdateFn:e,unsubscribeElementUpdateFn:i,needRaf:n,scrollOrientation:r,lenisInstance:l}){var o,a,c,h,d;this.$el=void 0,this.id=void 0,this.needRaf=void 0,this.attributes=void 0,this.scrollOrientation=void 0,this.isAlreadyIntersected=void 0,this.intersection=void 0,this.metrics=void 0,this.currentScroll=void 0,this.translateValue=void 0,this.progress=void 0,this.lastProgress=void 0,this.isInview=void 0,this.isInteractive=void 0,this.isInFold=void 0,this.isFirstResize=void 0,this.subscribeElementUpdateFn=void 0,this.unsubscribeElementUpdateFn=void 0,this.lenisInstance=void 0,this.getWindowSize=void 0,this.getMetricsStart=void 0,this.getMetricsSize=void 0,this.startPositionHandlers={start:(t,s,e)=>t-s+e,middle:(t,s,e,i)=>t-s+e+.5*i,end:(t,s,e,i)=>t-s+e+i,fold:()=>0},this.endPositionHandlers={start:(t,s)=>t-s,middle:(t,s,e)=>t-s+.5*e,end:(t,s,e)=>t-s+e},this.$el=t,this.id=s,this.needRaf=n,this.scrollOrientation=r,this.lenisInstance=l,this.subscribeElementUpdateFn=e,this.unsubscribeElementUpdateFn=i,this.attributes={scrollClass:null!=(o=this.$el.dataset.scrollClass)?o:\"is-inview\",scrollOffset:null!=(a=this.$el.dataset.scrollOffset)?a:\"0,0\",scrollPosition:null!=(c=this.$el.dataset.scrollPosition)?c:\"start,end\",scrollCssProgress:void 0!==this.$el.dataset.scrollCssProgress,scrollEventProgress:null!=(h=this.$el.dataset.scrollEventProgress)?h:null,scrollSpeed:void 0!==this.$el.dataset.scrollSpeed?parseFloat(this.$el.dataset.scrollSpeed):null,scrollRepeat:void 0!==this.$el.dataset.scrollRepeat,scrollCall:null!=(d=this.$el.dataset.scrollCall)?d:null,scrollIgnoreFold:void 0!==this.$el.dataset.scrollIgnoreFold,scrollEnableTouchSpeed:void 0!==this.$el.dataset.scrollEnableTouchSpeed},this.intersection={start:0,end:0},this.metrics={offsetStart:0,offsetEnd:0,bcr:{}},this.currentScroll=this.lenisInstance.scroll,this.translateValue=0,this.progress=0,this.lastProgress=null,this.isInview=!1,this.isInteractive=!1,this.isAlreadyIntersected=!1,this.isInFold=!1,this.isFirstResize=!0,this.getWindowSize=\"vertical\"===this.scrollOrientation?()=>this.lenisInstance.dimensions.height:()=>this.lenisInstance.dimensions.width,this.getMetricsStart=\"vertical\"===this.scrollOrientation?t=>t.top:t=>t.left,this.getMetricsSize=\"vertical\"===this.scrollOrientation?t=>t.height:t=>t.width,this._init()}_init(){this.needRaf&&this._resize()}onResize({currentScroll:t}){this.currentScroll=t,this._resize()}onRender({currentScroll:t,smooth:s}){const e=this.getWindowSize();if(this.currentScroll=t,this._computeProgress(),this.attributes.scrollSpeed&&!isNaN(this.attributes.scrollSpeed))if(this.attributes.scrollEnableTouchSpeed||s){if(this.isInFold){const t=Math.max(0,this.progress);this.translateValue=t*e*this.attributes.scrollSpeed*-1}else{const t=i(0,1,-1,1,this.progress);this.translateValue=t*e*this.attributes.scrollSpeed*-1}this.$el.style.transform=\"vertical\"===this.scrollOrientation?`translate3d(0, ${this.translateValue}px, 0)`:`translate3d(${this.translateValue}px, 0, 0)`}else this.translateValue&&(this.$el.style.transform=\"translate3d(0, 0, 0)\"),this.translateValue=0}setInview(){if(this.isInview)return;this.isInview=!0,this.$el.classList.add(this.attributes.scrollClass);const t=this._getScrollCallFrom();this.attributes.scrollCall&&this._dispatchCall(\"enter\",t)}setOutOfView(){if(!this.isInview||!this.attributes.scrollRepeat)return;this.isInview=!1,this.$el.classList.remove(this.attributes.scrollClass);const t=this._getScrollCallFrom();this.attributes.scrollCall&&this._dispatchCall(\"leave\",t)}setInteractivityOn(){this.isInteractive||(this.isInteractive=!0,this.subscribeElementUpdateFn(this))}setInteractivityOff(){this.isInteractive&&(this.isInteractive=!1,this.unsubscribeElementUpdateFn(this),null!==this.lastProgress&&this._computeProgress(n([0,1],this.lastProgress)))}_resize(){this.metrics.bcr=this.$el.getBoundingClientRect(),this._computeMetrics(),this._computeIntersection(),this.isFirstResize&&(this.isFirstResize=!1,this.isInFold&&this.setInview())}_computeMetrics(){const t=this.getWindowSize(),s=this.getMetricsStart(this.metrics.bcr),e=this.getMetricsSize(this.metrics.bcr);this.metrics.offsetStart=this.currentScroll+s-this.translateValue,this.metrics.offsetEnd=this.metrics.offsetStart+e,this.isInFold=this.metrics.offsetStart<t&&!this.attributes.scrollIgnoreFold}_computeIntersection(){var t,s,e,i,n,r,l,o;const a=this.getWindowSize(),c=this.getMetricsSize(this.metrics.bcr),h=this.attributes.scrollOffset.split(\",\"),d=null!=(t=null==(s=h[0])?void 0:s.trim())?t:\"0\",u=null!=(e=null==(i=h[1])?void 0:i.trim())?e:\"0\",m=this.attributes.scrollPosition.split(\",\");let v=null!=(n=null==(r=m[0])?void 0:r.trim())?n:\"start\";const f=null!=(l=null==(o=m[1])?void 0:o.trim())?l:\"end\",g=d.includes(\"%\")?a*parseInt(d.replace(\"%\",\"\").trim())*.01:parseInt(d),p=u.includes(\"%\")?a*parseInt(u.replace(\"%\",\"\").trim())*.01:parseInt(u);this.isInFold&&(v=\"fold\");const I=this.startPositionHandlers[v];this.intersection.start=I?I(this.metrics.offsetStart,a,g,c):this.metrics.offsetStart-a+g;const b=this.endPositionHandlers[f];if(this.intersection.end=b?b(this.metrics.offsetStart,p,c):this.metrics.offsetStart-p+c,this.intersection.end<=this.intersection.start)switch(f){case\"start\":default:this.intersection.end=this.intersection.start+1;break;case\"middle\":this.intersection.end=this.intersection.start+.5*c;break;case\"end\":this.intersection.end=this.intersection.start+c}}_computeProgress(t){const s=null!=t?t:(e=i(this.intersection.start,this.intersection.end,0,1,this.currentScroll))<0?0:e>1?1:e;var e;this.progress=s,s!==this.lastProgress&&(this.lastProgress=s,this.attributes.scrollCssProgress&&this._setCssProgress(s),this.attributes.scrollEventProgress&&this._setCustomEventProgress(s),s>0&&s<1&&this.setInview(),0===s&&this.setOutOfView(),1===s&&this.setOutOfView())}_setCssProgress(t=0){this.$el.style.setProperty(r,t.toString())}_setCustomEventProgress(t=0){const s=this.attributes.scrollEventProgress;if(!s)return;const e=new CustomEvent(s,{detail:{target:this.$el,progress:t}});window.dispatchEvent(e)}_getScrollCallFrom(){const t=n([this.intersection.start,this.intersection.end],this.currentScroll);return this.intersection.start===t?\"start\":\"end\"}destroy(){this.attributes.scrollCssProgress&&this.$el.style.removeProperty(r),this.attributes.scrollSpeed&&this.$el.style.removeProperty(\"transform\"),this.isInview&&this.attributes.scrollClass&&this.$el.classList.remove(this.attributes.scrollClass)}_dispatchCall(t,s){const e=this.attributes.scrollCall;if(!e)return;const i=new CustomEvent(e,{detail:{target:this.$el,way:t,from:s}});window.dispatchEvent(i)}}const o=[\"scrollOffset\",\"scrollPosition\",\"scrollCssProgress\",\"scrollEventProgress\",\"scrollSpeed\"];class a{constructor({$el:t,triggerRootMargin:s,rafRootMargin:e,scrollOrientation:i,lenisInstance:n}){this.$scrollContainer=void 0,this.triggerRootMargin=void 0,this.rafRootMargin=void 0,this.scrollElements=void 0,this.triggeredScrollElements=void 0,this.RAFScrollElements=void 0,this.scrollElementsToUpdate=void 0,this.IOTriggerInstance=void 0,this.IORafInstance=void 0,this.scrollOrientation=void 0,this.lenisInstance=void 0,t?(this.$scrollContainer=t,this.lenisInstance=n,this.scrollOrientation=i,this.triggerRootMargin=null!=s?s:\"-1px -1px -1px -1px\",this.rafRootMargin=null!=e?e:\"100% 100% 100% 100%\",this.scrollElements=[],this.triggeredScrollElements=[],this.RAFScrollElements=[],this.scrollElementsToUpdate=[],this._init()):console.error(\"Please provide a DOM Element as scrollContainer\")}_init(){const t=this.$scrollContainer.querySelectorAll(\"[data-scroll]\"),s=this.toElementArray(t);this._subscribeScrollElements(s);const i=this.lenisInstance.options.wrapper===window?null:this.lenisInstance.options.wrapper;this.IOTriggerInstance=new e({scrollElements:[...this.triggeredScrollElements],root:i,rootMargin:this.triggerRootMargin,IORaf:!1}),this.IORafInstance=new e({scrollElements:[...this.RAFScrollElements],root:i,rootMargin:this.rafRootMargin,IORaf:!0})}destroy(){this.IOTriggerInstance.destroy(),this.IORafInstance.destroy(),this._unsubscribeAllScrollElements()}onResize({currentScroll:t}){for(const s of this.RAFScrollElements)s.onResize({currentScroll:t})}onRender({currentScroll:t,smooth:s}){for(const e of this.scrollElementsToUpdate)e.onRender({currentScroll:t,smooth:s})}removeScrollElements(t){const s=t.querySelectorAll(\"[data-scroll]\");if(!s.length)return;const e=new Set(Array.from(s));for(let t=0;t<this.triggeredScrollElements.length;t++){const s=this.triggeredScrollElements[t];e.has(s.$el)&&(this.IOTriggerInstance.unobserve(s.$el),this.triggeredScrollElements.splice(t,1))}for(let t=0;t<this.RAFScrollElements.length;t++){const s=this.RAFScrollElements[t];e.has(s.$el)&&(this.IORafInstance.unobserve(s.$el),this.RAFScrollElements.splice(t,1))}s.forEach(t=>{const s=this.scrollElementsToUpdate.find(s=>s.$el===t),e=this.scrollElements.find(s=>s.$el===t);s&&this._unsubscribeElementUpdate(s),e&&(this.scrollElements=this.scrollElements.filter(t=>t.id!=e.id))})}addScrollElements(t){const s=t.querySelectorAll(\"[data-scroll]\"),e=[];this.scrollElements.forEach(t=>{e.push(t.id)});const i=Math.max(...e,0)+1,n=this.toElementArray(s);this._subscribeScrollElements(n,i,!0)}_subscribeScrollElements(t,s=0,e=!1){for(let i=0;i<t.length;i++){const n=t[i],r=this._checkRafNeeded(n),o=new l({$el:n,id:s+i,scrollOrientation:this.scrollOrientation,lenisInstance:this.lenisInstance,subscribeElementUpdateFn:this._subscribeElementUpdate.bind(this),unsubscribeElementUpdateFn:this._unsubscribeElementUpdate.bind(this),needRaf:r});this.scrollElements.push(o),r?(this.RAFScrollElements.push(o),e&&(this.IORafInstance.scrollElements.push(o),this.IORafInstance.observe(o.$el))):(this.triggeredScrollElements.push(o),e&&(this.IOTriggerInstance.scrollElements.push(o),this.IOTriggerInstance.observe(o.$el)))}}_unsubscribeAllScrollElements(){for(const t of this.scrollElements)t.destroy();this.scrollElements=[],this.RAFScrollElements=[],this.triggeredScrollElements=[],this.scrollElementsToUpdate=[]}_subscribeElementUpdate(t){this.scrollElementsToUpdate.push(t)}_unsubscribeElementUpdate(t){this.scrollElementsToUpdate=this.scrollElementsToUpdate.filter(s=>s.id!=t.id)}toElementArray(t){return Array.from(t)}_checkRafNeeded(t){let s=[...o];const e=t=>{s=s.filter(s=>s!==t)};if(t.dataset.scrollOffset){if(\"0,0\"!==t.dataset.scrollOffset.split(\",\").map(t=>t.replace(\"%\",\"\").trim()).join(\",\"))return!0;e(\"scrollOffset\")}else e(\"scrollOffset\");if(t.dataset.scrollPosition){if(\"top,bottom\"!==t.dataset.scrollPosition.trim())return!0;e(\"scrollPosition\")}else e(\"scrollPosition\");if(t.dataset.scrollSpeed&&!isNaN(parseFloat(t.dataset.scrollSpeed)))return!0;e(\"scrollSpeed\");for(const e of s)if(e in t.dataset)return!0;return!1}}class c{constructor({lenisOptions:t={},triggerRootMargin:s,rafRootMargin:e,autoStart:i=!0,scrollCallback:n=()=>{},initCustomTicker:r,destroyCustomTicker:l}={}){this.rafPlaying=void 0,this.lenisInstance=null,this.coreInstance=null,this.lenisOptions=void 0,this.triggerRootMargin=void 0,this.rafRootMargin=void 0,this.rafInstance=void 0,this.autoStart=void 0,this.isTouchDevice=void 0,this.initCustomTicker=void 0,this.destroyCustomTicker=void 0,this._onRenderBind=void 0,this._onResizeBind=void 0,this._onScrollToBind=void 0,this._originalOnContentResize=void 0,this._originalOnWrapperResize=void 0,window.locomotiveScrollVersion=\"5.0.0\",Object.assign(this,{lenisOptions:t,triggerRootMargin:s,rafRootMargin:e,autoStart:i,scrollCallback:n,initCustomTicker:r,destroyCustomTicker:l}),this._onRenderBind=this._onRender.bind(this),this._onScrollToBind=this._onScrollTo.bind(this),this._onResizeBind=this._onResize.bind(this),this.rafPlaying=!1,this.isTouchDevice=\"ontouchstart\"in window||navigator.maxTouchPoints>0,this._init()}_init(){this.lenisInstance=new t(s({},this.lenisOptions)),this.scrollCallback&&this.lenisInstance.on(\"scroll\",this.scrollCallback),document.documentElement.setAttribute(\"data-scroll-orientation\",this.lenisInstance.options.orientation),requestAnimationFrame(()=>{this.coreInstance=new a({$el:this.lenisInstance.rootElement,triggerRootMargin:this.triggerRootMargin,rafRootMargin:this.rafRootMargin,scrollOrientation:this.lenisInstance.options.orientation,lenisInstance:this.lenisInstance}),this._bindEvents(),this.initCustomTicker&&!this.destroyCustomTicker?console.warn(\"initCustomTicker callback is declared, but destroyCustomTicker is not. Please pay attention. It could cause trouble.\"):!this.initCustomTicker&&this.destroyCustomTicker&&console.warn(\"destroyCustomTicker callback is declared, but initCustomTicker is not. Please pay attention. It could cause trouble.\"),this.autoStart&&this.start()})}destroy(){var t;this.stop(),this._unbindEvents(),null==(t=this.lenisInstance)||t.destroy(),requestAnimationFrame(()=>{var t;null==(t=this.coreInstance)||t.destroy()})}_bindEvents(){this._bindScrollToEvents(),this.lenisInstance&&(this._originalOnContentResize=this.lenisInstance.dimensions.onContentResize.bind(this.lenisInstance.dimensions),this._originalOnWrapperResize=this.lenisInstance.dimensions.onWrapperResize.bind(this.lenisInstance.dimensions),this.lenisInstance.dimensions.onContentResize=()=>{var t;null==(t=this._originalOnContentResize)||t.call(this),this._onResizeBind()},this.lenisInstance.dimensions.onWrapperResize=()=>{var t;null==(t=this._originalOnWrapperResize)||t.call(this),this._onResizeBind()})}_unbindEvents(){this._unbindScrollToEvents(),this.lenisInstance&&(this._originalOnContentResize&&(this.lenisInstance.dimensions.onContentResize=this._originalOnContentResize),this._originalOnWrapperResize&&(this.lenisInstance.dimensions.onWrapperResize=this._originalOnWrapperResize))}_bindScrollToEvents(t){var s;const e=t||(null==(s=this.lenisInstance)?void 0:s.rootElement),i=null==e?void 0:e.querySelectorAll(\"[data-scroll-to]\");(null==i?void 0:i.length)&&i.forEach(t=>{t.addEventListener(\"click\",this._onScrollToBind,!1)})}_unbindScrollToEvents(t){var s;const e=t||(null==(s=this.lenisInstance)?void 0:s.rootElement),i=null==e?void 0:e.querySelectorAll(\"[data-scroll-to]\");(null==i?void 0:i.length)&&i.forEach(t=>{t.removeEventListener(\"click\",this._onScrollToBind,!1)})}_onResize(){var t,s,e;null==(t=this.coreInstance)||t.onResize({currentScroll:null!=(s=null==(e=this.lenisInstance)?void 0:e.scroll)?s:0,smooth:!this.isTouchDevice})}_onRender(){var t,s,e,i;null==(t=this.lenisInstance)||t.raf(Date.now()),null==(s=this.coreInstance)||s.onRender({currentScroll:null!=(e=null==(i=this.lenisInstance)?void 0:i.scroll)?e:0,smooth:!this.isTouchDevice})}_onScrollTo(t){var s,e;t.preventDefault();const i=null!=(s=t.currentTarget)?s:null;if(!i)return;const n=i.getAttribute(\"data-scroll-to-href\")||i.getAttribute(\"href\"),r=i.getAttribute(\"data-scroll-to-offset\")||0,l=i.getAttribute(\"data-scroll-to-duration\")||(null==(e=this.lenisInstance)?void 0:e.options.duration);n&&this.scrollTo(n,{offset:\"string\"==typeof r?parseInt(r):r,duration:\"string\"==typeof l?parseInt(l):l})}start(){var t;this.rafPlaying||(null==(t=this.lenisInstance)||t.start(),this.rafPlaying=!0,this.initCustomTicker?this.initCustomTicker(this._onRenderBind):this._raf())}stop(){var t;this.rafPlaying&&(null==(t=this.lenisInstance)||t.stop(),this.rafPlaying=!1,this.destroyCustomTicker?this.destroyCustomTicker(this._onRenderBind):this.rafInstance&&cancelAnimationFrame(this.rafInstance))}removeScrollElements(t){var s;t?(this._unbindScrollToEvents(t),null==(s=this.coreInstance)||s.removeScrollElements(t)):console.error(\"Please provide a DOM Element as $oldContainer\")}addScrollElements(t){var s;t?(null==(s=this.coreInstance)||s.addScrollElements(t),requestAnimationFrame(()=>{this._bindScrollToEvents(t)})):console.error(\"Please provide a DOM Element as $newContainer\")}resize(){this._onResizeBind()}scrollTo(t,s){var e;null==(e=this.lenisInstance)||e.scrollTo(t,{offset:null==s?void 0:s.offset,lerp:null==s?void 0:s.lerp,duration:null==s?void 0:s.duration,immediate:null==s?void 0:s.immediate,lock:null==s?void 0:s.lock,force:null==s?void 0:s.force,easing:null==s?void 0:s.easing,onComplete:null==s?void 0:s.onComplete})}_raf(){this._onRenderBind(),this.rafInstance=requestAnimationFrame(()=>this._raf())}}export{c as default};\n//# sourceMappingURL=locomotive-scroll.modern.mjs.map\n"
  },
  {
    "path": "packages/lib/dist/locomotive-scroll.umd.js",
    "content": "!function(t,e){\"object\"==typeof exports&&\"undefined\"!=typeof module?module.exports=e(require(\"lenis\")):\"function\"==typeof define&&define.amd?define([\"lenis\"],e):(t||self).locomotiveScroll=e(t.lenis)}(this,function(t){function e(t){return t&&\"object\"==typeof t&&\"default\"in t?t:{default:t}}var s=/*#__PURE__*/e(t);function i(t,e){(null==e||e>t.length)&&(e=t.length);for(var s=0,i=Array(e);s<e;s++)i[s]=t[s];return i}function n(t,e){var s=\"undefined\"!=typeof Symbol&&t[Symbol.iterator]||t[\"@@iterator\"];if(s)return(s=s.call(t)).next.bind(s);if(Array.isArray(t)||(s=function(t,e){if(t){if(\"string\"==typeof t)return i(t,e);var s={}.toString.call(t).slice(8,-1);return\"Object\"===s&&t.constructor&&(s=t.constructor.name),\"Map\"===s||\"Set\"===s?Array.from(t):\"Arguments\"===s||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(s)?i(t,e):void 0}}(t))||e&&t&&\"number\"==typeof t.length){s&&(t=s);var n=0;return function(){return n>=t.length?{done:!0}:{done:!1,value:t[n++]}}}throw new TypeError(\"Invalid attempt to iterate non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.\")}function r(){return r=Object.assign?Object.assign.bind():function(t){for(var e=1;e<arguments.length;e++){var s=arguments[e];for(var i in s)({}).hasOwnProperty.call(s,i)&&(t[i]=s[i])}return t},r.apply(null,arguments)}var o=/*#__PURE__*/function(){function t(t){var e=t.scrollElements,s=t.rootMargin,i=void 0===s?\"-1px -1px -1px -1px\":s,n=t.root,r=void 0===n?null:n,o=t.IORaf;this.scrollElements=void 0,this.rootMargin=void 0,this.root=void 0,this.IORaf=void 0,this.observer=void 0,this.scrollElements=e,this.rootMargin=i,this.root=r,this.IORaf=o,this._init()}var e=t.prototype;return e._init=function(){var t=this;this.observer=new IntersectionObserver(function(e){e.forEach(function(e){var s=t.scrollElements.find(function(t){return t.$el===e.target});e.isIntersecting?(s&&(s.isAlreadyIntersected=!0),t._setInview(e)):s&&s.isAlreadyIntersected&&t._setOutOfView(e)})},{root:this.root,rootMargin:this.rootMargin});for(var e,s=n(this.scrollElements);!(e=s()).done;)this.observe(e.value.$el)},e.destroy=function(){this.observer.disconnect()},e.observe=function(t){t&&this.observer.observe(t)},e.unobserve=function(t){t&&this.observer.unobserve(t)},e._setInview=function(t){var e=this.scrollElements.find(function(e){return e.$el===t.target});this.IORaf&&(null==e||e.setInteractivityOn()),!this.IORaf&&(null==e||e.setInview())},e._setOutOfView=function(t){var e=this.scrollElements.find(function(e){return e.$el===t.target});this.IORaf&&(null==e||e.setInteractivityOff()),!this.IORaf&&(null==e||e.setOutOfView()),null!=e&&e.attributes.scrollRepeat||this.IORaf||this.unobserve(t.target)},t}();function l(t,e,s,i,n){return s+((n-t)/(e-t)*(i-s)||0)}function a(t,e){return t.reduce(function(t,s){return Math.abs(s-e)<Math.abs(t-e)?s:t})}var c=\"--progress\",h=/*#__PURE__*/function(){function t(t){var e,s,i,n,r,o=this,l=t.$el,a=t.id,c=t.subscribeElementUpdateFn,h=t.unsubscribeElementUpdateFn,u=t.needRaf,d=t.scrollOrientation,f=t.lenisInstance;this.$el=void 0,this.id=void 0,this.needRaf=void 0,this.attributes=void 0,this.scrollOrientation=void 0,this.isAlreadyIntersected=void 0,this.intersection=void 0,this.metrics=void 0,this.currentScroll=void 0,this.translateValue=void 0,this.progress=void 0,this.lastProgress=void 0,this.isInview=void 0,this.isInteractive=void 0,this.isInFold=void 0,this.isFirstResize=void 0,this.subscribeElementUpdateFn=void 0,this.unsubscribeElementUpdateFn=void 0,this.lenisInstance=void 0,this.getWindowSize=void 0,this.getMetricsStart=void 0,this.getMetricsSize=void 0,this.startPositionHandlers={start:function(t,e,s){return t-e+s},middle:function(t,e,s,i){return t-e+s+.5*i},end:function(t,e,s,i){return t-e+s+i},fold:function(){return 0}},this.endPositionHandlers={start:function(t,e){return t-e},middle:function(t,e,s){return t-e+.5*s},end:function(t,e,s){return t-e+s}},this.$el=l,this.id=a,this.needRaf=u,this.scrollOrientation=d,this.lenisInstance=f,this.subscribeElementUpdateFn=c,this.unsubscribeElementUpdateFn=h,this.attributes={scrollClass:null!=(e=this.$el.dataset.scrollClass)?e:\"is-inview\",scrollOffset:null!=(s=this.$el.dataset.scrollOffset)?s:\"0,0\",scrollPosition:null!=(i=this.$el.dataset.scrollPosition)?i:\"start,end\",scrollCssProgress:void 0!==this.$el.dataset.scrollCssProgress,scrollEventProgress:null!=(n=this.$el.dataset.scrollEventProgress)?n:null,scrollSpeed:void 0!==this.$el.dataset.scrollSpeed?parseFloat(this.$el.dataset.scrollSpeed):null,scrollRepeat:void 0!==this.$el.dataset.scrollRepeat,scrollCall:null!=(r=this.$el.dataset.scrollCall)?r:null,scrollIgnoreFold:void 0!==this.$el.dataset.scrollIgnoreFold,scrollEnableTouchSpeed:void 0!==this.$el.dataset.scrollEnableTouchSpeed},this.intersection={start:0,end:0},this.metrics={offsetStart:0,offsetEnd:0,bcr:{}},this.currentScroll=this.lenisInstance.scroll,this.translateValue=0,this.progress=0,this.lastProgress=null,this.isInview=!1,this.isInteractive=!1,this.isAlreadyIntersected=!1,this.isInFold=!1,this.isFirstResize=!0,this.getWindowSize=\"vertical\"===this.scrollOrientation?function(){return o.lenisInstance.dimensions.height}:function(){return o.lenisInstance.dimensions.width},this.getMetricsStart=\"vertical\"===this.scrollOrientation?function(t){return t.top}:function(t){return t.left},this.getMetricsSize=\"vertical\"===this.scrollOrientation?function(t){return t.height}:function(t){return t.width},this._init()}var e=t.prototype;return e._init=function(){this.needRaf&&this._resize()},e.onResize=function(t){this.currentScroll=t.currentScroll,this._resize()},e.onRender=function(t){var e=t.currentScroll,s=t.smooth,i=this.getWindowSize();if(this.currentScroll=e,this._computeProgress(),this.attributes.scrollSpeed&&!isNaN(this.attributes.scrollSpeed))if(this.attributes.scrollEnableTouchSpeed||s){if(this.isInFold){var n=Math.max(0,this.progress);this.translateValue=n*i*this.attributes.scrollSpeed*-1}else{var r=l(0,1,-1,1,this.progress);this.translateValue=r*i*this.attributes.scrollSpeed*-1}this.$el.style.transform=\"vertical\"===this.scrollOrientation?\"translate3d(0, \"+this.translateValue+\"px, 0)\":\"translate3d(\"+this.translateValue+\"px, 0, 0)\"}else this.translateValue&&(this.$el.style.transform=\"translate3d(0, 0, 0)\"),this.translateValue=0},e.setInview=function(){if(!this.isInview){this.isInview=!0,this.$el.classList.add(this.attributes.scrollClass);var t=this._getScrollCallFrom();this.attributes.scrollCall&&this._dispatchCall(\"enter\",t)}},e.setOutOfView=function(){if(this.isInview&&this.attributes.scrollRepeat){this.isInview=!1,this.$el.classList.remove(this.attributes.scrollClass);var t=this._getScrollCallFrom();this.attributes.scrollCall&&this._dispatchCall(\"leave\",t)}},e.setInteractivityOn=function(){this.isInteractive||(this.isInteractive=!0,this.subscribeElementUpdateFn(this))},e.setInteractivityOff=function(){this.isInteractive&&(this.isInteractive=!1,this.unsubscribeElementUpdateFn(this),null!==this.lastProgress&&this._computeProgress(a([0,1],this.lastProgress)))},e._resize=function(){this.metrics.bcr=this.$el.getBoundingClientRect(),this._computeMetrics(),this._computeIntersection(),this.isFirstResize&&(this.isFirstResize=!1,this.isInFold&&this.setInview())},e._computeMetrics=function(){var t=this.getWindowSize(),e=this.getMetricsStart(this.metrics.bcr),s=this.getMetricsSize(this.metrics.bcr);this.metrics.offsetStart=this.currentScroll+e-this.translateValue,this.metrics.offsetEnd=this.metrics.offsetStart+s,this.isInFold=this.metrics.offsetStart<t&&!this.attributes.scrollIgnoreFold},e._computeIntersection=function(){var t,e,s,i,n,r,o,l,a=this.getWindowSize(),c=this.getMetricsSize(this.metrics.bcr),h=this.attributes.scrollOffset.split(\",\"),u=null!=(t=null==(e=h[0])?void 0:e.trim())?t:\"0\",d=null!=(s=null==(i=h[1])?void 0:i.trim())?s:\"0\",f=this.attributes.scrollPosition.split(\",\"),v=null!=(n=null==(r=f[0])?void 0:r.trim())?n:\"start\",m=null!=(o=null==(l=f[1])?void 0:l.trim())?o:\"end\",g=u.includes(\"%\")?a*parseInt(u.replace(\"%\",\"\").trim())*.01:parseInt(u),p=d.includes(\"%\")?a*parseInt(d.replace(\"%\",\"\").trim())*.01:parseInt(d);this.isInFold&&(v=\"fold\");var b=this.startPositionHandlers[v];this.intersection.start=b?b(this.metrics.offsetStart,a,g,c):this.metrics.offsetStart-a+g;var I=this.endPositionHandlers[m];if(this.intersection.end=I?I(this.metrics.offsetStart,p,c):this.metrics.offsetStart-p+c,this.intersection.end<=this.intersection.start)switch(m){case\"start\":default:this.intersection.end=this.intersection.start+1;break;case\"middle\":this.intersection.end=this.intersection.start+.5*c;break;case\"end\":this.intersection.end=this.intersection.start+c}},e._computeProgress=function(t){var e,s=null!=t?t:(e=l(this.intersection.start,this.intersection.end,0,1,this.currentScroll))<0?0:e>1?1:e;this.progress=s,s!==this.lastProgress&&(this.lastProgress=s,this.attributes.scrollCssProgress&&this._setCssProgress(s),this.attributes.scrollEventProgress&&this._setCustomEventProgress(s),s>0&&s<1&&this.setInview(),0===s&&this.setOutOfView(),1===s&&this.setOutOfView())},e._setCssProgress=function(t){void 0===t&&(t=0),this.$el.style.setProperty(c,t.toString())},e._setCustomEventProgress=function(t){void 0===t&&(t=0);var e=this.attributes.scrollEventProgress;if(e){var s=new CustomEvent(e,{detail:{target:this.$el,progress:t}});window.dispatchEvent(s)}},e._getScrollCallFrom=function(){var t=a([this.intersection.start,this.intersection.end],this.currentScroll);return this.intersection.start===t?\"start\":\"end\"},e.destroy=function(){this.attributes.scrollCssProgress&&this.$el.style.removeProperty(c),this.attributes.scrollSpeed&&this.$el.style.removeProperty(\"transform\"),this.isInview&&this.attributes.scrollClass&&this.$el.classList.remove(this.attributes.scrollClass)},e._dispatchCall=function(t,e){var s=this.attributes.scrollCall;if(s){var i=new CustomEvent(s,{detail:{target:this.$el,way:t,from:e}});window.dispatchEvent(i)}},t}(),u=[\"scrollOffset\",\"scrollPosition\",\"scrollCssProgress\",\"scrollEventProgress\",\"scrollSpeed\"],d=/*#__PURE__*/function(){function t(t){var e=t.$el,s=t.triggerRootMargin,i=t.rafRootMargin,n=t.scrollOrientation,r=t.lenisInstance;this.$scrollContainer=void 0,this.triggerRootMargin=void 0,this.rafRootMargin=void 0,this.scrollElements=void 0,this.triggeredScrollElements=void 0,this.RAFScrollElements=void 0,this.scrollElementsToUpdate=void 0,this.IOTriggerInstance=void 0,this.IORafInstance=void 0,this.scrollOrientation=void 0,this.lenisInstance=void 0,e?(this.$scrollContainer=e,this.lenisInstance=r,this.scrollOrientation=n,this.triggerRootMargin=null!=s?s:\"-1px -1px -1px -1px\",this.rafRootMargin=null!=i?i:\"100% 100% 100% 100%\",this.scrollElements=[],this.triggeredScrollElements=[],this.RAFScrollElements=[],this.scrollElementsToUpdate=[],this._init()):console.error(\"Please provide a DOM Element as scrollContainer\")}var e=t.prototype;return e._init=function(){var t=this.$scrollContainer.querySelectorAll(\"[data-scroll]\"),e=this.toElementArray(t);this._subscribeScrollElements(e);var s=this.lenisInstance.options.wrapper===window?null:this.lenisInstance.options.wrapper;this.IOTriggerInstance=new o({scrollElements:[].concat(this.triggeredScrollElements),root:s,rootMargin:this.triggerRootMargin,IORaf:!1}),this.IORafInstance=new o({scrollElements:[].concat(this.RAFScrollElements),root:s,rootMargin:this.rafRootMargin,IORaf:!0})},e.destroy=function(){this.IOTriggerInstance.destroy(),this.IORafInstance.destroy(),this._unsubscribeAllScrollElements()},e.onResize=function(t){for(var e,s=t.currentScroll,i=n(this.RAFScrollElements);!(e=i()).done;)e.value.onResize({currentScroll:s})},e.onRender=function(t){for(var e,s=t.currentScroll,i=t.smooth,r=n(this.scrollElementsToUpdate);!(e=r()).done;)e.value.onRender({currentScroll:s,smooth:i})},e.removeScrollElements=function(t){var e=this,s=t.querySelectorAll(\"[data-scroll]\");if(s.length){for(var i=new Set(Array.from(s)),n=0;n<this.triggeredScrollElements.length;n++){var r=this.triggeredScrollElements[n];i.has(r.$el)&&(this.IOTriggerInstance.unobserve(r.$el),this.triggeredScrollElements.splice(n,1))}for(var o=0;o<this.RAFScrollElements.length;o++){var l=this.RAFScrollElements[o];i.has(l.$el)&&(this.IORafInstance.unobserve(l.$el),this.RAFScrollElements.splice(o,1))}s.forEach(function(t){var s=e.scrollElementsToUpdate.find(function(e){return e.$el===t}),i=e.scrollElements.find(function(e){return e.$el===t});s&&e._unsubscribeElementUpdate(s),i&&(e.scrollElements=e.scrollElements.filter(function(t){return t.id!=i.id}))})}},e.addScrollElements=function(t){var e=t.querySelectorAll(\"[data-scroll]\"),s=[];this.scrollElements.forEach(function(t){s.push(t.id)});var i=Math.max.apply(Math,s.concat([0]))+1,n=this.toElementArray(e);this._subscribeScrollElements(n,i,!0)},e._subscribeScrollElements=function(t,e,s){void 0===e&&(e=0),void 0===s&&(s=!1);for(var i=0;i<t.length;i++){var n=t[i],r=this._checkRafNeeded(n),o=new h({$el:n,id:e+i,scrollOrientation:this.scrollOrientation,lenisInstance:this.lenisInstance,subscribeElementUpdateFn:this._subscribeElementUpdate.bind(this),unsubscribeElementUpdateFn:this._unsubscribeElementUpdate.bind(this),needRaf:r});this.scrollElements.push(o),r?(this.RAFScrollElements.push(o),s&&(this.IORafInstance.scrollElements.push(o),this.IORafInstance.observe(o.$el))):(this.triggeredScrollElements.push(o),s&&(this.IOTriggerInstance.scrollElements.push(o),this.IOTriggerInstance.observe(o.$el)))}},e._unsubscribeAllScrollElements=function(){for(var t,e=n(this.scrollElements);!(t=e()).done;)t.value.destroy();this.scrollElements=[],this.RAFScrollElements=[],this.triggeredScrollElements=[],this.scrollElementsToUpdate=[]},e._subscribeElementUpdate=function(t){this.scrollElementsToUpdate.push(t)},e._unsubscribeElementUpdate=function(t){this.scrollElementsToUpdate=this.scrollElementsToUpdate.filter(function(e){return e.id!=t.id})},e.toElementArray=function(t){return Array.from(t)},e._checkRafNeeded=function(t){var e=[].concat(u),s=function(t){e=e.filter(function(e){return e!==t})};if(t.dataset.scrollOffset){if(\"0,0\"!==t.dataset.scrollOffset.split(\",\").map(function(t){return t.replace(\"%\",\"\").trim()}).join(\",\"))return!0;s(\"scrollOffset\")}else s(\"scrollOffset\");if(t.dataset.scrollPosition){if(\"top,bottom\"!==t.dataset.scrollPosition.trim())return!0;s(\"scrollPosition\")}else s(\"scrollPosition\");if(t.dataset.scrollSpeed&&!isNaN(parseFloat(t.dataset.scrollSpeed)))return!0;s(\"scrollSpeed\");for(var i,r=n(e);!(i=r()).done;)if(i.value in t.dataset)return!0;return!1},t}();/*#__PURE__*/\nreturn function(){function t(t){var e=void 0===t?{}:t,s=e.lenisOptions,i=void 0===s?{}:s,n=e.triggerRootMargin,r=e.rafRootMargin,o=e.autoStart,l=void 0===o||o,a=e.scrollCallback,c=void 0===a?function(){}:a,h=e.initCustomTicker,u=e.destroyCustomTicker;this.rafPlaying=void 0,this.lenisInstance=null,this.coreInstance=null,this.lenisOptions=void 0,this.triggerRootMargin=void 0,this.rafRootMargin=void 0,this.rafInstance=void 0,this.autoStart=void 0,this.isTouchDevice=void 0,this.initCustomTicker=void 0,this.destroyCustomTicker=void 0,this._onRenderBind=void 0,this._onResizeBind=void 0,this._onScrollToBind=void 0,this._originalOnContentResize=void 0,this._originalOnWrapperResize=void 0,window.locomotiveScrollVersion=\"5.0.0\",Object.assign(this,{lenisOptions:i,triggerRootMargin:n,rafRootMargin:r,autoStart:l,scrollCallback:c,initCustomTicker:h,destroyCustomTicker:u}),this._onRenderBind=this._onRender.bind(this),this._onScrollToBind=this._onScrollTo.bind(this),this._onResizeBind=this._onResize.bind(this),this.rafPlaying=!1,this.isTouchDevice=\"ontouchstart\"in window||navigator.maxTouchPoints>0,this._init()}var e=t.prototype;return e._init=function(){var t=this;this.lenisInstance=new s.default(r({},this.lenisOptions)),this.scrollCallback&&this.lenisInstance.on(\"scroll\",this.scrollCallback),document.documentElement.setAttribute(\"data-scroll-orientation\",this.lenisInstance.options.orientation),requestAnimationFrame(function(){t.coreInstance=new d({$el:t.lenisInstance.rootElement,triggerRootMargin:t.triggerRootMargin,rafRootMargin:t.rafRootMargin,scrollOrientation:t.lenisInstance.options.orientation,lenisInstance:t.lenisInstance}),t._bindEvents(),t.initCustomTicker&&!t.destroyCustomTicker?console.warn(\"initCustomTicker callback is declared, but destroyCustomTicker is not. Please pay attention. It could cause trouble.\"):!t.initCustomTicker&&t.destroyCustomTicker&&console.warn(\"destroyCustomTicker callback is declared, but initCustomTicker is not. Please pay attention. It could cause trouble.\"),t.autoStart&&t.start()})},e.destroy=function(){var t,e=this;this.stop(),this._unbindEvents(),null==(t=this.lenisInstance)||t.destroy(),requestAnimationFrame(function(){var t;null==(t=e.coreInstance)||t.destroy()})},e._bindEvents=function(){var t=this;this._bindScrollToEvents(),this.lenisInstance&&(this._originalOnContentResize=this.lenisInstance.dimensions.onContentResize.bind(this.lenisInstance.dimensions),this._originalOnWrapperResize=this.lenisInstance.dimensions.onWrapperResize.bind(this.lenisInstance.dimensions),this.lenisInstance.dimensions.onContentResize=function(){null==t._originalOnContentResize||t._originalOnContentResize(),t._onResizeBind()},this.lenisInstance.dimensions.onWrapperResize=function(){null==t._originalOnWrapperResize||t._originalOnWrapperResize(),t._onResizeBind()})},e._unbindEvents=function(){this._unbindScrollToEvents(),this.lenisInstance&&(this._originalOnContentResize&&(this.lenisInstance.dimensions.onContentResize=this._originalOnContentResize),this._originalOnWrapperResize&&(this.lenisInstance.dimensions.onWrapperResize=this._originalOnWrapperResize))},e._bindScrollToEvents=function(t){var e,s=this,i=t||(null==(e=this.lenisInstance)?void 0:e.rootElement),n=null==i?void 0:i.querySelectorAll(\"[data-scroll-to]\");(null==n?void 0:n.length)&&n.forEach(function(t){t.addEventListener(\"click\",s._onScrollToBind,!1)})},e._unbindScrollToEvents=function(t){var e,s=this,i=t||(null==(e=this.lenisInstance)?void 0:e.rootElement),n=null==i?void 0:i.querySelectorAll(\"[data-scroll-to]\");(null==n?void 0:n.length)&&n.forEach(function(t){t.removeEventListener(\"click\",s._onScrollToBind,!1)})},e._onResize=function(){var t,e,s;null==(t=this.coreInstance)||t.onResize({currentScroll:null!=(e=null==(s=this.lenisInstance)?void 0:s.scroll)?e:0,smooth:!this.isTouchDevice})},e._onRender=function(){var t,e,s,i;null==(t=this.lenisInstance)||t.raf(Date.now()),null==(e=this.coreInstance)||e.onRender({currentScroll:null!=(s=null==(i=this.lenisInstance)?void 0:i.scroll)?s:0,smooth:!this.isTouchDevice})},e._onScrollTo=function(t){var e,s;t.preventDefault();var i=null!=(e=t.currentTarget)?e:null;if(i){var n=i.getAttribute(\"data-scroll-to-href\")||i.getAttribute(\"href\"),r=i.getAttribute(\"data-scroll-to-offset\")||0,o=i.getAttribute(\"data-scroll-to-duration\")||(null==(s=this.lenisInstance)?void 0:s.options.duration);n&&this.scrollTo(n,{offset:\"string\"==typeof r?parseInt(r):r,duration:\"string\"==typeof o?parseInt(o):o})}},e.start=function(){var t;this.rafPlaying||(null==(t=this.lenisInstance)||t.start(),this.rafPlaying=!0,this.initCustomTicker?this.initCustomTicker(this._onRenderBind):this._raf())},e.stop=function(){var t;this.rafPlaying&&(null==(t=this.lenisInstance)||t.stop(),this.rafPlaying=!1,this.destroyCustomTicker?this.destroyCustomTicker(this._onRenderBind):this.rafInstance&&cancelAnimationFrame(this.rafInstance))},e.removeScrollElements=function(t){var e;t?(this._unbindScrollToEvents(t),null==(e=this.coreInstance)||e.removeScrollElements(t)):console.error(\"Please provide a DOM Element as $oldContainer\")},e.addScrollElements=function(t){var e,s=this;t?(null==(e=this.coreInstance)||e.addScrollElements(t),requestAnimationFrame(function(){s._bindScrollToEvents(t)})):console.error(\"Please provide a DOM Element as $newContainer\")},e.resize=function(){this._onResizeBind()},e.scrollTo=function(t,e){var s;null==(s=this.lenisInstance)||s.scrollTo(t,{offset:null==e?void 0:e.offset,lerp:null==e?void 0:e.lerp,duration:null==e?void 0:e.duration,immediate:null==e?void 0:e.immediate,lock:null==e?void 0:e.lock,force:null==e?void 0:e.force,easing:null==e?void 0:e.easing,onComplete:null==e?void 0:e.onComplete})},e._raf=function(){var t=this;this._onRenderBind(),this.rafInstance=requestAnimationFrame(function(){return t._raf()})},t}()});\n//# sourceMappingURL=locomotive-scroll.umd.js.map\n"
  },
  {
    "path": "packages/lib/dist/types/core/Core.d.ts",
    "content": "/**\n * Integrates Lenis with Locomotive's built-in animation system\n */\nimport type { CoreOptions, IScrollElementCallbacksValues } from '../types';\nimport ScrollElement from './ScrollElement';\nexport default class Core {\n    private $scrollContainer;\n    private triggerRootMargin;\n    private rafRootMargin;\n    private scrollElements;\n    private triggeredScrollElements;\n    private RAFScrollElements;\n    private scrollElementsToUpdate;\n    private IOTriggerInstance;\n    private IORafInstance;\n    private scrollOrientation;\n    private lenisInstance;\n    constructor({ $el, triggerRootMargin, rafRootMargin, scrollOrientation, lenisInstance, }: CoreOptions);\n    /**\n     * Lifecyle - Initialize the core.\n     *\n     * @private\n     */\n    private _init;\n    /**\n     * Lifecyle - Destroy core.\n     */\n    destroy(): void;\n    /**\n     * Callback - Resize callback.\n     */\n    onResize({ currentScroll }: IScrollElementCallbacksValues): void;\n    /**\n     * Callback - RAF callback.\n     */\n    onRender({ currentScroll, smooth }: IScrollElementCallbacksValues): void;\n    /**\n     * Remove items from lists of scroll elements and compute all new values.\n     *\n     * @param {HTMLElement} $oldContainer - HTMLElement that contains data-scroll elements to unsubscribe\n     */\n    removeScrollElements($oldContainer: HTMLElement): void;\n    /**\n     * Add items to lists of scroll elements and compute all new values.\n     *\n     * @param {HTMLElement} $newContainer - HTMLElement that contains data-scroll elements to subscribe\n     */\n    addScrollElements($newContainer: HTMLElement): void;\n    /**\n     * Create a ScrollElement instance for each elements with\n     * `data-scroll` attribute.\n     *\n     * @private\n     *\n     * @param {HTMLElement[]} $scrollElements - List of elements that need\n     *     to be regarded.\n     */\n    _subscribeScrollElements($scrollElements: HTMLElement[], fromIndex?: number, toObserve?: boolean): void;\n    /**\n     * Clear all ScrollElement arrays.\n     *\n     * @private\n     */\n    _unsubscribeAllScrollElements(): void;\n    /**\n     * Subscribe ScrollElement instance that needs to be updated.\n     *\n     * @private\n     *\n     * @param {ScrollElement} scrollElement - ScrollElement instance inview\n     *     that needs to be updated.\n     */\n    _subscribeElementUpdate(scrollElement: ScrollElement): void;\n    /**\n     * Unscribe ScrollElement instance that doesn't need to be updated.\n     *\n     * @private\n     *\n     * @param {ScrollElement} scrollElement - The updated ScrollElement instance\n     *     out of view now.\n     */\n    _unsubscribeElementUpdate(scrollElement: ScrollElement): void;\n    /**\n     * Convert NodeListOf<Element> to HTMLElement array.\n     *\n     * @private\n     *\n     * @param {NodeListOf<Element>} elements - The NodeList to convert.\n     *\n     * @returns {HTMLElement[]}\n     */\n    private toElementArray;\n    /**\n     * Check if a DOM Element need a requestAnimationFrame to be used.\n     *\n     * @private\n     *\n     * @param {HTMLElement} $scrollElement - The element that needs to be checked.\n     *\n     * @returns {boolean}\n     */\n    _checkRafNeeded($scrollElement: HTMLElement): boolean;\n}\n//# sourceMappingURL=Core.d.ts.map"
  },
  {
    "path": "packages/lib/dist/types/core/IO.d.ts",
    "content": "/**\n * Intersection Observer\n *\n * Detecting visibility of an element in the viewport.\n *\n * Features functions to:\n *\n * - Trigger inview/outOfView callbacks\n * - If the element has a requestAnimationFrame dependency, set interactivy status for the ScrollElement Class\n *\n * References:\n *\n * - {@link https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API}\n */\nimport type { IIOOptions } from '../types';\nimport ScrollElement from './ScrollElement';\nexport default class IO {\n    scrollElements: ScrollElement[];\n    private rootMargin;\n    private root;\n    private IORaf;\n    private observer;\n    constructor({ scrollElements, rootMargin, root, IORaf, }: IIOOptions);\n    /**\n     * Lifecyle - Initialize Intersection Observer.\n     *\n     * @private\n     */\n    private _init;\n    /**\n     * Lifecyle - Destroy Intersection Observer.\n     */\n    destroy(): void;\n    /**\n     * Subscribe element to the Intersection Observer.\n     *\n     * @param {HTMLElement} $scrollElement - DOM Element to observe.\n     */\n    observe($scrollElement: HTMLElement): void;\n    /**\n     * Unsubscribe element to the Intersection Observer.\n     *\n     * @param {HTMLElement} $scrollElement - DOM Element to unobserve.\n     */\n    unobserve($scrollElement: HTMLElement): void;\n    /**\n     * Find ScrollElementReference instance and trigger inview callbacks.\n     *\n     * @private\n     *\n     * @param {IntersectionObserverEntry} entry - DOM Element to observe.\n     */\n    private _setInview;\n    /**\n     * Find ScrollElementReference instance and trigger out of view callbacks.\n     *\n     * @private\n     *\n     * @param {IntersectionObserverEntry} entry - DOM Element to observe.\n     */\n    private _setOutOfView;\n}\n//# sourceMappingURL=IO.d.ts.map"
  },
  {
    "path": "packages/lib/dist/types/core/ScrollElement.d.ts",
    "content": "/**\n * Scroll Element\n *\n * Give tools to compute element progress in the viewport and triggers callbacks to animate it.\n *\n * Features functions to:\n *\n * - scrollClass - Add a custom class when the element is intersected by the offset\n * - scrollOffset - Determine offsets to intersect the element\n * - scrollPosition - Determine the element positions to consider an element as intersected.\n * - scrollCssProgress - Add a specific css variable (PROGRESS_CSS_VAR) that store the scroll progress\n * - scrollEventProgress - Send scroll progress to custom event listeners.\n * - scrollSpeed - Add a scroll multiplicator to create a parallax effect\n * - scrollRepeat - Repeat the option to trigger animation each time the element is intersected\n * - scrollCall - Call a custom event when the element is intersected\n */\nimport type { IScrollElementOptions, IScrollElementAttributes, IScrollElementCallbacksValues, scrollOrientation } from '../types';\nexport default class ScrollElement {\n    $el: HTMLElement;\n    id: number;\n    needRaf: boolean;\n    attributes: IScrollElementAttributes;\n    scrollOrientation: scrollOrientation;\n    isAlreadyIntersected: boolean;\n    private intersection;\n    private metrics;\n    private currentScroll;\n    private translateValue;\n    private progress;\n    private lastProgress;\n    private isInview;\n    private isInteractive;\n    private isInFold;\n    private isFirstResize;\n    private subscribeElementUpdateFn;\n    private unsubscribeElementUpdateFn;\n    private lenisInstance;\n    private getWindowSize;\n    private getMetricsStart;\n    private getMetricsSize;\n    private readonly startPositionHandlers;\n    private readonly endPositionHandlers;\n    constructor({ $el, id, subscribeElementUpdateFn, unsubscribeElementUpdateFn, needRaf, scrollOrientation, lenisInstance, }: IScrollElementOptions);\n    /**\n     * Lifecyle - Initialize progress tracking.\n     *\n     * @private\n     */\n    private _init;\n    /**\n     * Callback - Resize callback\n     */\n    onResize({ currentScroll }: IScrollElementCallbacksValues): void;\n    /**\n     * Callback - RAF callback\n     */\n    onRender({ currentScroll, smooth }: IScrollElementCallbacksValues): void;\n    /**\n     * Inview callback\n     */\n    setInview(): void;\n    /**\n     * Out of view callback\n     */\n    setOutOfView(): void;\n    /**\n     * Switch interactivity on to subscribe the instance to the RAF\n     * and start calculations.\n     */\n    setInteractivityOn(): void;\n    /**\n     * Switch interactivity off to unsubscribe the instance to the RAF\n     * and stop calculations.\n     */\n    setInteractivityOff(): void;\n    /**\n     * Resize method that compute the element's values.\n     *\n     * @private\n     */\n    private _resize;\n    /**\n     * Compute element's offsets and determine if the element is in fold.\n     *\n     * @private\n     */\n    private _computeMetrics;\n    /**\n     * Compute intersection values depending on the context.\n     * Uses handler-based approach for cleaner, more maintainable code.\n     *\n     * @private\n     */\n    private _computeIntersection;\n    /**\n     * Compute the scroll progress of the element depending\n     * on its intersection values.\n     *\n     * @private\n     *\n     * @param {number} [forcedProgress] - Value to force progress.\n     */\n    private _computeProgress;\n    /**\n     * Set the element's progress to a specific css variable.\n     *\n     * @private\n     *\n     * @param {number} [currentProgress] - Progress value.\n     */\n    _setCssProgress(currentProgress?: number): void;\n    /**\n     * Set the element's progress to the custom event listeners.\n     *\n     * @private\n     *\n     * @param {number} [currentProgress] - Progress value.\n     */\n    _setCustomEventProgress(currentProgress?: number): void;\n    /**\n     * Function to get scroll call from.\n     *\n     * @private\n     */\n    _getScrollCallFrom(): \"start\" | \"end\";\n    /**\n     * Lifecyle - Destroy and cleanup the scroll element.\n     *\n     * Removes all CSS modifications and clears references to prevent memory leaks.\n     */\n    destroy(): void;\n    /**\n     * Function to dispatch a custom event.\n     *\n     * @private\n     *\n     * @param {string} way - Enter or leave.\n     * @param {string} from - Start or end.\n     */\n    _dispatchCall(way: string, from: string): void;\n}\n//# sourceMappingURL=ScrollElement.d.ts.map"
  },
  {
    "path": "packages/lib/dist/types/index.d.ts",
    "content": "import Lenis from 'lenis';\nimport type { ILenisScrollToOptions, ILocomotiveScrollOptions, lenisTargetScrollTo } from './types';\n/**\n * Locomotive Scroll\n *\n * Detection of elements in viewport & smooth scrolling with parallax.\n *\n * Inspired by\n * {@link https://github.com/locomotivemtl/locomotive-scroll locomotive-scroll.js}\n * and built around\n * {@link https://github.com/darkroomengineering/lenis lenis.js}.\n */\nexport default class LocomotiveScroll {\n    rafPlaying: boolean;\n    lenisInstance: Lenis | null;\n    private coreInstance;\n    private lenisOptions?;\n    private triggerRootMargin?;\n    private rafRootMargin?;\n    private rafInstance?;\n    private autoStart?;\n    private isTouchDevice;\n    private scrollCallback;\n    private initCustomTicker?;\n    private destroyCustomTicker?;\n    private _onRenderBind;\n    private _onResizeBind;\n    private _onScrollToBind;\n    private _originalOnContentResize?;\n    private _originalOnWrapperResize?;\n    constructor({ lenisOptions, triggerRootMargin, rafRootMargin, autoStart, scrollCallback, initCustomTicker, destroyCustomTicker, }?: ILocomotiveScrollOptions);\n    /**\n     * Lifecyle - Initialize instance.\n     *\n     * @private\n     */\n    private _init;\n    /**\n     * Lifecyle - Destroy instance.\n     */\n    destroy(): void;\n    /**\n     * Events - Subscribe events to listen.\n     */\n    private _bindEvents;\n    /**\n     * Events - Unsubscribe listened events.\n     */\n    private _unbindEvents;\n    /**\n     * Events - Subscribe scrollTo events to listen.\n     */\n    private _bindScrollToEvents;\n    /**\n     * Events - Unsubscribe scrollTo listened events.\n     */\n    private _unbindScrollToEvents;\n    /**\n     * Callback - Resize callback.\n     *\n     * Called synchronously after Lenis updates its dimensions via onContentResize/onWrapperResize.\n     * All dimension values are already up-to-date when this executes.\n     */\n    private _onResize;\n    /**\n     * Callback - Render callback.\n     */\n    private _onRender;\n    /**\n     * Callback - Scroll To callback.\n     */\n    private _onScrollTo;\n    /**\n     * Start RequestAnimationFrame that active Lenis smooth and scroll progress.\n     */\n    start(): void;\n    /**\n     * Stop RequestAnimationFrame that active Lenis smooth and scroll progress.\n     */\n    stop(): void;\n    /**\n     * Remove old scroll elements items and rebuild ScrollElements instances.\n     */\n    removeScrollElements($oldContainer: HTMLElement): void;\n    /**\n     * Add new scroll elements items and rebuild ScrollElements instances.\n     */\n    addScrollElements($newContainer: HTMLElement): void;\n    /**\n     * Trigger resize callback.\n     */\n    resize(): void;\n    /**\n     * Trigger scroll to callback.\n     */\n    scrollTo(target: lenisTargetScrollTo, options?: ILenisScrollToOptions): void;\n    /**\n     * RequestAnimationFrame that active Lenis smooth and scroll progress.\n     *\n     * @private\n     *\n     */\n    private _raf;\n}\nexport * from './types';\n//# sourceMappingURL=index.d.ts.map"
  },
  {
    "path": "packages/lib/dist/types/types.d.ts",
    "content": "import ScrollElement from './core/ScrollElement';\nimport type { LenisOptions } from 'lenis';\nimport type Lenis from 'lenis';\n/**\n * @typedef {Object} ILenisScrollValues\n *\n * @property {number} scroll\n * @property {number} limit\n * @property {number} velocity\n * @property {number} direction\n * @property {number} progress\n */\nexport interface ILenisScrollValues {\n    scroll: number;\n    limit: number;\n    velocity: number;\n    direction: number;\n    progress: number;\n}\n/**\n * @typedef {(number|HTMLElement|string)} LenisTargetScrollTo\n */\nexport type lenisTargetScrollTo = number | HTMLElement | string;\n/**\n *\n * @typedef {Object} ILenisScrollTo\n *\n * @property {LenisTargetScrollTo} target      - Target that can be number, NodeElement or string (CSS selector).\n * @property {ILenisScrollToOptions} [options] - Scroll to options.\n */\nexport interface ILenisScrollTo {\n    target: number | HTMLElement | string;\n    options?: ILenisScrollToOptions;\n}\n/**\n * @typedef {Object} ILenisScrollToOptions\n *\n * @property {number} [offset]       - Number equivalent to scroll-padding-top.\n * @property {number} [lerp]         - Animation lerp intensity.\n * @property {number} [duration]     - Number scroll duration in seconds.\n * @property {boolean} [immediate]   - Ignore duration and easing.\n * @property {boolean} [lock]        - Whether or not to prevent the user from scrolling until the target is reached.\n * @property {boolean} [force]       - Reach target even if instance is stopped.\n * @property {function} [easing]     - Smooth scroll easing function.\n * @property {function} [onComplete] - Called when the target is reached.\n */\nexport interface ILenisScrollToOptions {\n    offset?: number;\n    lerp?: number;\n    duration?: number;\n    immediate?: boolean;\n    lock?: boolean;\n    force?: boolean;\n    easing?(t: number): number;\n    onComplete?(): void;\n}\n/**\n * @typedef {Object} ILocomotiveScrollOptions\n *\n * @property {LenisOptions}  [lenisOptions]      - Object to override default Lenis options.\n * @property {string}        [triggerRootMargin] - Root margin for trigger Intersection Observer.\n * @property {string}        [rafRootMargin]     - Root margin for RAF Intersection Observer.\n * @property {boolean}       [autoStart]         - Enable/Disable RAF auto start.\n * @property {function}      [scrollCallback]    - Scroll callback binded on the Lenis scroll event.\n */\nexport interface ILocomotiveScrollOptions {\n    lenisOptions?: LenisOptions;\n    triggerRootMargin?: string;\n    rafRootMargin?: string;\n    autoStart?: boolean;\n    scrollCallback?(scrollValues: ILenisScrollValues): void;\n    initCustomTicker?(render: () => void): void;\n    destroyCustomTicker?(render: () => void): void;\n}\n/**\n * @typedef {Object} IScrollElementOptions\n *\n * @property {HTMLElement} $el                        - DOM Element with data-scroll attribute.\n * @property {number}      id                         - Instance UID.\n * @property {boolean}     needRaf                    - RequestAnimationFrame status.\n * @property {Lenis}       lenisInstance              - Lenis instance for scroll data.\n * @property {function}    subscribeElementUpdateFn   - Callback to subscribe instance to the main RAF.\n * @property {function}    unsubscribeElementUpdateFn - Callback to unsubscribe instance to the main RAF.\n * @property {function}    [scrollCallback]           - Scroll callback binded on the Lenis scroll event.\n */\nexport interface IScrollElementOptions {\n    $el: HTMLElement;\n    id: number;\n    needRaf: boolean;\n    scrollOrientation: scrollOrientation;\n    lenisInstance: Lenis;\n    subscribeElementUpdateFn(scrollElement: ScrollElement): void;\n    unsubscribeElementUpdateFn(scrollElement: ScrollElement): void;\n    scrollCallback?(scrollValues: ILenisScrollValues): void;\n}\n/**\n * @typedef {Object} IScrollElementAttributes\n *\n *  @property {string}  scrollClass             - Add a custom class when the element is intersected by the offset.\n *  @property {string}  scrollOffset            - Determine offsets to intersect the element.\n *  @property {string}  scrollPosition          - Determine the element positions to consider an element as intersected..\n *  @property {boolean} scrollCssProgress       - Add a specific css variable (PROGRESS_CSS_VAR) that store the scroll progress.\n *  @property {?string} scrollEventProgress     - Send scroll progress to custom event listeners.\n *  @property {?number} scrollSpeed             - Add a scroll multiplicator to create a parallax effect.\n *  @property {boolean} scrollRepeat            - Repeat the option to trigger animation each time the element is intersected.\n *  @property {?string} scrollCall              - Call a custom event when the element is intersected.\n *  @property {boolean} scrollIgnoreFold        - Ignore fold progress remapping.\n *  @property {boolean} scrollEnableTouchSpeed  - Enable parallax on touch devices.\n */\nexport interface IScrollElementAttributes {\n    scrollClass: string;\n    scrollOffset: string;\n    scrollPosition: string;\n    scrollCssProgress: boolean;\n    scrollEventProgress: string | null;\n    scrollSpeed: number | null;\n    scrollRepeat: boolean;\n    scrollCall: string | null;\n    scrollIgnoreFold: boolean;\n    scrollEnableTouchSpeed: boolean;\n}\n/**\n * @typedef {Object} IScrollElementIntersection\n *\n *  @property {number} start\n *  @property {number} end\n */\nexport interface IScrollElementIntersection {\n    start: number;\n    end: number;\n}\n/**\n * @typedef {Object} IScrollElementMetrics\n *\n *  @property {number}  offsetTop\n *  @property {number}  offsetBottom\n *  @property {DOMRect} bcr\n */\nexport interface IScrollElementMetrics {\n    offsetStart: number;\n    offsetEnd: number;\n    bcr: DOMRect;\n}\n/**\n * @typedef {Object} IScrollElementCallbacksValues\n *\n *  @property {number}  currentScroll - Scroll value returned by Lenis.\n *  @property {boolean} smooth        - Whether parallax should be enabled (false on touch devices).\n */\nexport interface IScrollElementCallbacksValues {\n    currentScroll: number;\n    smooth: boolean;\n}\n/**\n * @typedef {Object} IIOOptions\n *\n *  @property {ScrollElement[]} scrollElements - A list of objects with property values to match.\n *  @property {boolean}         IORaf          - Defined if it concern elements which need a RAF.\n *  @property {string}          [rootMargin]   - Margin around the root.\n *  @property {HTMLElement}     [root]         - The Element that is used as the viewport for checking visibility (null for window).\n */\nexport interface IIOOptions {\n    scrollElements: ScrollElement[];\n    IORaf: boolean;\n    rootMargin?: string;\n    root?: HTMLElement | null;\n}\n/**\n * @typedef {Object} CoreOptions\n *\n * @property {HTMLElement} $el                                     - DOM Element used as scroll container.\n * @property {string}      [triggerRootMargin=TRIGGER_ROOT_MARGIN] - Root margin for trigger Intersection Observer.\n * @property {string}      [rafRootMargin=RAF_ROOT_MARGIN]         - Root margin for raf Intersection Observer.\n * @property {Lenis}       lenisInstance                          - Lenis instance for scroll data.\n */\nexport interface CoreOptions {\n    $el: HTMLElement;\n    triggerRootMargin?: string;\n    rafRootMargin?: string;\n    scrollOrientation: scrollOrientation;\n    lenisInstance: Lenis;\n}\nexport type scrollOrientation = 'vertical' | 'horizontal';\nexport type gestureOrientation = 'vertical' | 'horizontal' | 'both';\ndeclare global {\n    interface Window {\n        locomotiveScrollVersion: string;\n    }\n}\n//# sourceMappingURL=types.d.ts.map"
  },
  {
    "path": "packages/lib/dist/types/utils/maths.d.ts",
    "content": "/**\n * Clamp a value to fit within a specific range (ex: clamp(0, 100, -12) --> 0).\n *\n * @param {number} min   - Minimum value expected.\n * @param {number} max   - Maximum value expected.\n * @param {number} value - Current value.\n *\n * @returns {number} - Clamped value.\n */\nexport declare function clamp(min: number, max: number, value: number): number;\n/**\n * Map one range to another (ex: mapRange(-10, 10, 0, 100, 5) --> 75).\n *\n * @param {number} inMin  - Current minimum value.\n * @param {number} inMax  - Current maximum value.\n * @param {number} outMin - Maximum value expected.\n * @param {number} outMax - Maximum value expected.\n * @param {number} value  - Current value.\n *\n * @returns {number} - New value that should be between minimum value expected and maximum value.\n */\nexport declare function mapRange(inMin: number, inMax: number, outMin: number, outMax: number, value: number): number;\n/**\n * Map a number within a range to a progress between 0 to 1 (ex: normalize(100, 200, 150) --> 0.5).\n *\n * @param {number} min   - Current minimum value.\n * @param {number} max   - Current maximum value.\n * @param {number} value - Current value.\n *\n * @returns {number} - New value that should be between 0 and 1.\n */\nexport declare function normalize(min: number, max: number, value: number): number;\n/**\n * Get closest number from an array.\n *\n * @param {number[]} array  - Numbers array.\n * @param {number}   target - Reference value.\n *\n * @returns {number} - Closest number.\n */\nexport declare function closestNumber(array: number[], target: number): number;\n//# sourceMappingURL=maths.d.ts.map"
  },
  {
    "path": "packages/lib/index.ts",
    "content": "import { version } from './package.json'\nimport Lenis from 'lenis';\nimport Core from './core/Core';\nimport type {\n    ILenisScrollToOptions,\n    ILenisScrollValues,\n    ILocomotiveScrollOptions,\n    lenisTargetScrollTo,\n} from './types';\nimport type { LenisOptions } from 'lenis';\n\n/**\n * Locomotive Scroll\n *\n * Detection of elements in viewport & smooth scrolling with parallax.\n *\n * Inspired by\n * {@link https://github.com/locomotivemtl/locomotive-scroll locomotive-scroll.js}\n * and built around\n * {@link https://github.com/darkroomengineering/lenis lenis.js}.\n */\n\nexport default class LocomotiveScroll {\n    public rafPlaying: boolean;\n    public lenisInstance: Lenis | null = null;\n\n    private coreInstance: Core | null = null;\n\n    private lenisOptions?: LenisOptions;\n    private triggerRootMargin?: string;\n    private rafRootMargin?: string;\n    private rafInstance?: number;\n    private autoStart?: boolean;\n    private isTouchDevice: boolean;\n    private scrollCallback?(scrollValues: ILenisScrollValues): void;\n    private initCustomTicker?: (render: () => void) => void;\n    private destroyCustomTicker?: (render: () => void) => void;\n    private _onRenderBind: () => void;\n    private _onResizeBind: () => void;\n    private _onScrollToBind: (event: MouseEvent) => void;\n    private _originalOnContentResize?: () => void;\n    private _originalOnWrapperResize?: () => void;\n\n    constructor({\n        lenisOptions = {},\n        triggerRootMargin,\n        rafRootMargin,\n        autoStart = true,\n        scrollCallback = () => {},\n        initCustomTicker,\n        destroyCustomTicker,\n    }: ILocomotiveScrollOptions = {}) {\n\n        // Set version\n        window.locomotiveScrollVersion = version;\n\n        // Get arguments\n        Object.assign(this, {\n            lenisOptions,\n            triggerRootMargin,\n            rafRootMargin,\n            autoStart,\n            scrollCallback,\n            initCustomTicker,\n            destroyCustomTicker,\n        });\n\n\n        // Binding\n        this._onRenderBind = this._onRender.bind(this);\n        this._onScrollToBind = this._onScrollTo.bind(this);\n        this._onResizeBind = this._onResize.bind(this);\n\n        // Data\n        this.rafPlaying = false;\n\n        // Detect if device has touch capability\n        this.isTouchDevice = 'ontouchstart' in window || navigator.maxTouchPoints > 0;\n\n        // Init\n        this._init();\n    }\n\n    /**\n     * Lifecyle - Initialize instance.\n     *\n     * @private\n     */\n    private _init(): void {\n        \n        // Create Lenis instance\n        this.lenisInstance = new Lenis({\n            ...this.lenisOptions\n        });\n\n        // Subscribe to scroll callback if provided\n        if (this.scrollCallback) {\n            this.lenisInstance.on('scroll', this.scrollCallback);\n        }\n\n        // Add scroll direction attribute on body\n        document.documentElement.setAttribute(\n            'data-scroll-orientation',\n            this.lenisInstance.options.orientation\n        );\n\n        requestAnimationFrame(() => {\n            // Create Core Instance\n            // lenisInstance is guaranteed to exist at this point (created above)\n            this.coreInstance = new Core({\n                $el: this.lenisInstance!.rootElement,\n                triggerRootMargin: this.triggerRootMargin,\n                rafRootMargin: this.rafRootMargin,\n                scrollOrientation: this.lenisInstance!.options.orientation,\n                lenisInstance: this.lenisInstance!,\n            });\n\n            // Bind Events\n            this._bindEvents();\n\n            // RAF warning\n            if (this.initCustomTicker && !this.destroyCustomTicker) {\n                console.warn(\n                    'initCustomTicker callback is declared, but destroyCustomTicker is not. Please pay attention. It could cause trouble.'\n                );\n            } else if (!this.initCustomTicker && this.destroyCustomTicker) {\n                console.warn(\n                    'destroyCustomTicker callback is declared, but initCustomTicker is not. Please pay attention. It could cause trouble.'\n                );\n            }\n\n            // Start RAF\n            this.autoStart && this.start();\n        });\n    }\n\n    /**\n     * Lifecyle - Destroy instance.\n     */\n    public destroy(): void {\n        // Stop raf\n        this.stop();\n        // Unbind Events\n        this._unbindEvents();\n        // Destroy Lenis\n        this.lenisInstance?.destroy();\n\n        // Destroy Core after RAF to ensure any pending Intersection Observer callbacks complete\n        // This prevents race conditions when destroy() is called while IO callbacks are queued\n        requestAnimationFrame(() => {\n            this.coreInstance?.destroy();\n        });\n    }\n\n    /**\n     * Events - Subscribe events to listen.\n     */\n    private _bindEvents() {\n        this._bindScrollToEvents();\n\n        // Hook into Lenis dimensions resize callbacks\n        // onContentResize: called when content size changes (images load, dynamic content)\n        // onWrapperResize: called when wrapper size changes (window resize, layout changes)\n        if (this.lenisInstance) {\n            this._originalOnContentResize = this.lenisInstance.dimensions.onContentResize.bind(\n                this.lenisInstance.dimensions\n            );\n            this._originalOnWrapperResize = this.lenisInstance.dimensions.onWrapperResize.bind(\n                this.lenisInstance.dimensions\n            );\n\n            this.lenisInstance.dimensions.onContentResize = () => {\n                this._originalOnContentResize?.();\n                this._onResizeBind();\n            };\n\n            this.lenisInstance.dimensions.onWrapperResize = () => {\n                this._originalOnWrapperResize?.();\n                this._onResizeBind();\n            };\n        }\n    }\n\n    /**\n     * Events - Unsubscribe listened events.\n     */\n    private _unbindEvents() {\n        this._unbindScrollToEvents();\n\n        // Restore original Lenis dimensions resize callbacks\n        if (this.lenisInstance) {\n            if (this._originalOnContentResize) {\n                this.lenisInstance.dimensions.onContentResize = this._originalOnContentResize;\n            }\n            if (this._originalOnWrapperResize) {\n                this.lenisInstance.dimensions.onWrapperResize = this._originalOnWrapperResize;\n            }\n        }\n    }\n\n    /**\n     * Events - Subscribe scrollTo events to listen.\n     */\n    private _bindScrollToEvents($container?: HTMLElement) {\n        const $rootContainer = $container\n            ? $container\n            : this.lenisInstance?.rootElement;\n        const $scrollToElements =\n            $rootContainer?.querySelectorAll('[data-scroll-to]');\n\n        $scrollToElements?.length &&\n            $scrollToElements.forEach(($el): void => {\n                ($el as HTMLElement).addEventListener('click', this._onScrollToBind, false);\n            });\n    }\n\n    /**\n     * Events - Unsubscribe scrollTo listened events.\n     */\n    private _unbindScrollToEvents($container?: HTMLElement) {\n        const $rootContainer = $container\n            ? $container\n            : this.lenisInstance?.rootElement;\n        const $scrollToElements =\n            $rootContainer?.querySelectorAll('[data-scroll-to]');\n        $scrollToElements?.length &&\n            $scrollToElements.forEach(($el) => {\n                ($el as HTMLElement).removeEventListener('click', this._onScrollToBind, false);\n            });\n    }\n\n    /**\n     * Callback - Resize callback.\n     *\n     * Called synchronously after Lenis updates its dimensions via onContentResize/onWrapperResize.\n     * All dimension values are already up-to-date when this executes.\n     */\n    private _onResize() {\n        this.coreInstance?.onResize({\n            currentScroll: this.lenisInstance?.scroll ?? 0,\n            smooth: !this.isTouchDevice,\n        });\n    }\n\n    /**\n     * Callback - Render callback.\n     */\n    private _onRender() {\n        this.lenisInstance?.raf(Date.now());\n\n        this.coreInstance?.onRender({\n            currentScroll: this.lenisInstance?.scroll ?? 0,\n            smooth: !this.isTouchDevice,\n        });\n    }\n\n    /**\n     * Callback - Scroll To callback.\n     */\n    private _onScrollTo(event: MouseEvent) {\n        event.preventDefault();\n        const $target = (event.currentTarget as HTMLElement) ?? null;\n        if (!$target) return;\n        const target =\n            $target.getAttribute('data-scroll-to-href') ||\n            $target.getAttribute('href');\n        const offset = $target.getAttribute('data-scroll-to-offset') || 0;\n        const duration =\n            $target.getAttribute('data-scroll-to-duration') ||\n            this.lenisInstance?.options.duration\n        target &&\n            this.scrollTo(target, {\n                offset: typeof offset === 'string' ? parseInt(offset) : offset,\n                duration:\n                    typeof duration === 'string'\n                        ? parseInt(duration)\n                        : duration,\n            });\n    }\n\n    /**\n     * Start RequestAnimationFrame that active Lenis smooth and scroll progress.\n     */\n    public start(): void {\n        if (this.rafPlaying) {\n            return;\n        }\n\n        // Call lenis start method\n        this.lenisInstance?.start();\n\n        this.rafPlaying = true;\n        this.initCustomTicker\n            ? this.initCustomTicker(this._onRenderBind)\n            : this._raf();\n    }\n\n    /**\n     * Stop RequestAnimationFrame that active Lenis smooth and scroll progress.\n     */\n    public stop(): void {\n        if (!this.rafPlaying) {\n            return;\n        }\n\n        // Call lenis stop method\n        this.lenisInstance?.stop();\n\n        this.rafPlaying = false;\n        this.destroyCustomTicker\n            ? this.destroyCustomTicker(this._onRenderBind)\n            : this.rafInstance && cancelAnimationFrame(this.rafInstance);\n    }\n\n    /**\n     * Remove old scroll elements items and rebuild ScrollElements instances.\n     */\n    public removeScrollElements($oldContainer: HTMLElement): void {\n        if (!$oldContainer) {\n            console.error('Please provide a DOM Element as $oldContainer');\n            return;\n        }\n\n        this._unbindScrollToEvents($oldContainer);\n        this.coreInstance?.removeScrollElements($oldContainer);\n    }\n\n    /**\n     * Add new scroll elements items and rebuild ScrollElements instances.\n     */\n    public addScrollElements($newContainer: HTMLElement): void {\n        if (!$newContainer) {\n            console.error('Please provide a DOM Element as $newContainer');\n            return;\n        }\n\n        this.coreInstance?.addScrollElements($newContainer);\n        requestAnimationFrame(() => {\n            this._bindScrollToEvents($newContainer);\n        });\n    }\n\n    /**\n     * Trigger resize callback.\n     */\n    public resize(): void {\n        this._onResizeBind();\n    }\n\n    /**\n     * Trigger scroll to callback.\n     */\n    public scrollTo(\n        target: lenisTargetScrollTo,\n        options?: ILenisScrollToOptions\n    ): void {\n        this.lenisInstance?.scrollTo(target, {\n            offset: options?.offset,\n            lerp: options?.lerp,\n            duration: options?.duration,\n            immediate: options?.immediate,\n            lock: options?.lock,\n            force: options?.force,\n            easing: options?.easing,\n            onComplete: options?.onComplete,\n        });\n    }\n\n    /**\n     * RequestAnimationFrame that active Lenis smooth and scroll progress.\n     *\n     * @private\n     *\n     */\n    private _raf() {\n        this._onRenderBind();\n        this.rafInstance = requestAnimationFrame(() => this._raf());\n    }\n}\n\nexport * from './types';\n"
  },
  {
    "path": "packages/lib/package.json",
    "content": "{\n    \"name\": \"locomotive-scroll\",\n    \"version\": \"5.0.1\",\n    \"description\": \"Detection of elements in viewport & smooth scrolling with parallax effects.\",\n    \"license\": \"MIT\",\n    \"homepage\": \"https://github.com/locomotivemtl/locomotive-scroll\",\n    \"repository\": {\n        \"type\": \"git\",\n        \"url\": \"https://github.com/locomotivemtl/locomotive-scroll.git\"\n    },\n    \"author\": {\n        \"name\": \"Locomotive\",\n        \"email\": \"info@locomotive.ca\",\n        \"homepage\": \"https://locomotive.ca\"\n    },\n    \"keywords\": [\n        \"front-end\",\n        \"javascript\",\n        \"smooth-scrolling\",\n        \"parallax\",\n        \"scroll\"\n    ],\n    \"engines\": {\n        \"node\": \">=20\"\n    },\n    \"type\": \"module\",\n    \"source\": \"src/index.ts\",\n    \"main\": \"dist/locomotive-scroll.js\",\n    \"umd:main\": \"dist/locomotive-scroll.umd.js\",\n    \"module\": \"dist/locomotive-scroll.mjs\",\n    \"types\": \"dist/types/index.d.ts\",\n    \"exports\": {\n        \".\": {\n            \"types\": \"./dist/types/index.d.ts\",\n            \"require\": \"./dist/locomotive-scroll.js\",\n            \"default\": \"./dist/locomotive-scroll.modern.mjs\"\n        },\n        \"./locomotive-scroll.css\": \"./dist/locomotive-scroll.css\",\n        \"./dist/*\": \"./dist/*\"\n    },\n    \"scripts\": {\n        \"clean\": \"rimraf dist bundled\",\n        \"build\": \"npm run clean && npm-run-all --parallel build:dist build:css build:bundle build:types\",\n        \"build:types\": \"tsc --allowJs -d --emitDeclarationOnly --declarationDir ./dist/types --removeComments --skipLibCheck --resolveJsonModule ./index.ts\",\n        \"build:dist\": \"microbundle build -i index.ts --o ./dist\",\n        \"build:bundle\": \"npm-run-all build:bundle-full build:bundle-min build:bundle-css\",\n        \"build:bundle-full\": \"microbundle build -i index.ts --o ./bundled/locomotive-scroll.js --no-sourcemap --no-pkg-main --external none --name LocomotiveScroll --format umd --no-compress\",\n        \"build:bundle-min\": \"microbundle build -i index.ts --o ./bundled/locomotive-scroll.min.js --no-sourcemap --no-pkg-main --external none --name LocomotiveScroll --format umd\",\n        \"build:css\": \"postcss styles/main.css --o ./dist/locomotive-scroll.css --no-map\",\n        \"build:bundle-css\": \"postcss styles/main.css --o ./bundled/locomotive-scroll.css --no-map\",\n        \"watch\": \"microbundle watch -i index.ts --o ./dist --no-compress\",\n        \"publish\": \"npm publish\",\n        \"publish:next\": \"npm publish --tag next\"\n    },\n    \"files\": [\n        \"dist\",\n        \"bundled\"\n    ],\n    \"dependencies\": {\n        \"lenis\": \"1.3.17\"\n    },\n    \"devDependencies\": {\n        \"cssnano\": \"^6.0.1\",\n        \"microbundle\": \"^0.15.1\",\n        \"npm-run-all\": \"^4.1.5\",\n        \"postcss\": \"^8.4.23\",\n        \"postcss-cli\": \"^10.1.0\",\n        \"postcss-import\": \"^15.1.0\",\n        \"rimraf\": \"^5.0.0\",\n        \"typescript\": \"^5.5.4\"\n    }\n}\n"
  },
  {
    "path": "packages/lib/styles/locomotive-scroll.css",
    "content": ""
  },
  {
    "path": "packages/lib/styles/main.css",
    "content": "@import \"locomotive-scroll.css\";\n@import \"../../../node_modules/lenis/dist/lenis.css\";\n"
  },
  {
    "path": "packages/lib/tsconfig.json",
    "content": "{\n    \"compilerOptions\": {\n        \"target\": \"ES2020\",\n        \"module\": \"ESNext\",\n        \"lib\": [\"ES2020\", \"DOM\", \"DOM.Iterable\"],\n        \"moduleResolution\": \"bundler\",\n        \"strict\": true,\n        \"esModuleInterop\": true,\n        \"skipLibCheck\": true,\n        \"forceConsistentCasingInFileNames\": true,\n        \"resolveJsonModule\": true,\n        \"declaration\": true,\n        \"declarationMap\": true,\n        \"sourceMap\": true,\n        \"noEmit\": true,\n        \"noUnusedLocals\": false,\n        \"noUnusedParameters\": false,\n        \"noImplicitReturns\": true,\n        \"noFallthroughCasesInSwitch\": true,\n        \"allowSyntheticDefaultImports\": true\n    },\n    \"include\": [\"**/*.ts\"],\n    \"exclude\": [\"node_modules\", \"dist\", \"bundled\"]\n}\n"
  },
  {
    "path": "packages/lib/types.ts",
    "content": "import ScrollElement from './core/ScrollElement';\nimport type { LenisOptions } from 'lenis';\nimport type Lenis from 'lenis';\n\n/**\n * @typedef {Object} ILenisScrollValues\n *\n * @property {number} scroll\n * @property {number} limit\n * @property {number} velocity\n * @property {number} direction\n * @property {number} progress\n */\nexport interface ILenisScrollValues {\n    scroll: number;\n    limit: number;\n    velocity: number;\n    direction: number;\n    progress: number;\n}\n\n/**\n * @typedef {(number|HTMLElement|string)} LenisTargetScrollTo\n */\nexport type lenisTargetScrollTo = number | HTMLElement | string;\n\n/**\n *\n * @typedef {Object} ILenisScrollTo\n *\n * @property {LenisTargetScrollTo} target      - Target that can be number, NodeElement or string (CSS selector).\n * @property {ILenisScrollToOptions} [options] - Scroll to options.\n */\nexport interface ILenisScrollTo {\n    target: number | HTMLElement | string;\n    options?: ILenisScrollToOptions;\n}\n\n/**\n * @typedef {Object} ILenisScrollToOptions\n *\n * @property {number} [offset]       - Number equivalent to scroll-padding-top.\n * @property {number} [lerp]         - Animation lerp intensity.\n * @property {number} [duration]     - Number scroll duration in seconds.\n * @property {boolean} [immediate]   - Ignore duration and easing.\n * @property {boolean} [lock]        - Whether or not to prevent the user from scrolling until the target is reached.\n * @property {boolean} [force]       - Reach target even if instance is stopped.\n * @property {function} [easing]     - Smooth scroll easing function.\n * @property {function} [onComplete] - Called when the target is reached.\n */\nexport interface ILenisScrollToOptions {\n    offset?: number;\n    lerp?: number;\n    duration?: number;\n    immediate?: boolean;\n    lock?: boolean;\n    force?: boolean;\n    easing?(t: number): number;\n    onComplete?(): void;\n}\n\n/**\n * @typedef {Object} ILocomotiveScrollOptions\n *\n * @property {LenisOptions}  [lenisOptions]      - Object to override default Lenis options.\n * @property {string}        [triggerRootMargin] - Root margin for trigger Intersection Observer.\n * @property {string}        [rafRootMargin]     - Root margin for RAF Intersection Observer.\n * @property {boolean}       [autoStart]         - Enable/Disable RAF auto start.\n * @property {function}      [scrollCallback]    - Scroll callback binded on the Lenis scroll event.\n */\nexport interface ILocomotiveScrollOptions {\n    lenisOptions?: LenisOptions;\n    triggerRootMargin?: string;\n    rafRootMargin?: string;\n    autoStart?: boolean;\n    scrollCallback?(scrollValues: ILenisScrollValues): void;\n    initCustomTicker?(render: () => void): void;\n    destroyCustomTicker?(render: () => void): void;\n}\n\n/**\n * @typedef {Object} IScrollElementOptions\n *\n * @property {HTMLElement} $el                        - DOM Element with data-scroll attribute.\n * @property {number}      id                         - Instance UID.\n * @property {boolean}     needRaf                    - RequestAnimationFrame status.\n * @property {Lenis}       lenisInstance              - Lenis instance for scroll data.\n * @property {function}    subscribeElementUpdateFn   - Callback to subscribe instance to the main RAF.\n * @property {function}    unsubscribeElementUpdateFn - Callback to unsubscribe instance to the main RAF.\n * @property {function}    [scrollCallback]           - Scroll callback binded on the Lenis scroll event.\n */\nexport interface IScrollElementOptions {\n    $el: HTMLElement;\n    id: number;\n    needRaf: boolean;\n    scrollOrientation: scrollOrientation;\n    lenisInstance: Lenis;\n    subscribeElementUpdateFn(scrollElement: ScrollElement): void;\n    unsubscribeElementUpdateFn(scrollElement: ScrollElement): void;\n    scrollCallback?(scrollValues: ILenisScrollValues): void;\n}\n\n/**\n * @typedef {Object} IScrollElementAttributes\n *\n *  @property {string}  scrollClass             - Add a custom class when the element is intersected by the offset.\n *  @property {string}  scrollOffset            - Determine offsets to intersect the element.\n *  @property {string}  scrollPosition          - Determine the element positions to consider an element as intersected..\n *  @property {boolean} scrollCssProgress       - Add a specific css variable (PROGRESS_CSS_VAR) that store the scroll progress.\n *  @property {?string} scrollEventProgress     - Send scroll progress to custom event listeners.\n *  @property {?number} scrollSpeed             - Add a scroll multiplicator to create a parallax effect.\n *  @property {boolean} scrollRepeat            - Repeat the option to trigger animation each time the element is intersected.\n *  @property {?string} scrollCall              - Call a custom event when the element is intersected.\n *  @property {boolean} scrollIgnoreFold        - Ignore fold progress remapping.\n *  @property {boolean} scrollEnableTouchSpeed  - Enable parallax on touch devices.\n */\nexport interface IScrollElementAttributes {\n    scrollClass: string;\n    scrollOffset: string;\n    scrollPosition: string;\n    scrollCssProgress: boolean;\n    scrollEventProgress: string | null;\n    scrollSpeed: number | null;\n    scrollRepeat: boolean;\n    scrollCall: string | null;\n    scrollIgnoreFold: boolean;\n    scrollEnableTouchSpeed: boolean;\n}\n\n/**\n * @typedef {Object} IScrollElementIntersection\n *\n *  @property {number} start\n *  @property {number} end\n */\nexport interface IScrollElementIntersection {\n    start: number;\n    end: number;\n}\n\n/**\n * @typedef {Object} IScrollElementMetrics\n *\n *  @property {number}  offsetTop\n *  @property {number}  offsetBottom\n *  @property {DOMRect} bcr\n */\nexport interface IScrollElementMetrics {\n    offsetStart: number;\n    offsetEnd: number;\n    bcr: DOMRect;\n}\n\n/**\n * @typedef {Object} IScrollElementCallbacksValues\n *\n *  @property {number}  currentScroll - Scroll value returned by Lenis.\n *  @property {boolean} smooth        - Whether parallax should be enabled (false on touch devices).\n */\nexport interface IScrollElementCallbacksValues {\n    currentScroll: number;\n    smooth: boolean;\n}\n\n/**\n * @typedef {Object} IIOOptions\n *\n *  @property {ScrollElement[]} scrollElements - A list of objects with property values to match.\n *  @property {boolean}         IORaf          - Defined if it concern elements which need a RAF.\n *  @property {string}          [rootMargin]   - Margin around the root.\n *  @property {HTMLElement}     [root]         - The Element that is used as the viewport for checking visibility (null for window).\n */\nexport interface IIOOptions {\n    scrollElements: ScrollElement[];\n    IORaf: boolean;\n    rootMargin?: string;\n    root?: HTMLElement | null;\n}\n\n/**\n * @typedef {Object} CoreOptions\n *\n * @property {HTMLElement} $el                                     - DOM Element used as scroll container.\n * @property {string}      [triggerRootMargin=TRIGGER_ROOT_MARGIN] - Root margin for trigger Intersection Observer.\n * @property {string}      [rafRootMargin=RAF_ROOT_MARGIN]         - Root margin for raf Intersection Observer.\n * @property {Lenis}       lenisInstance                          - Lenis instance for scroll data.\n */\nexport interface CoreOptions {\n    $el: HTMLElement;\n    triggerRootMargin?: string;\n    rafRootMargin?: string;\n    scrollOrientation: scrollOrientation;\n    lenisInstance: Lenis;\n}\n\nexport type scrollOrientation = 'vertical' | 'horizontal';\n\nexport type gestureOrientation = 'vertical' | 'horizontal' | 'both';\n\ndeclare global {\n    interface Window {\n        locomotiveScrollVersion: string;\n    }\n}"
  },
  {
    "path": "packages/lib/utils/maths.ts",
    "content": "// https://greensock.com/docs/v3/GSAP/gsap.utils\n\n/**\n * Clamp a value to fit within a specific range (ex: clamp(0, 100, -12) --> 0).\n *\n * @param {number} min   - Minimum value expected.\n * @param {number} max   - Maximum value expected.\n * @param {number} value - Current value.\n *\n * @returns {number} - Clamped value.\n */\nexport function clamp(min: number, max: number, value: number): number {\n    return value < min ? min : value > max ? max : value;\n}\n\n/**\n * Map one range to another (ex: mapRange(-10, 10, 0, 100, 5) --> 75).\n *\n * @param {number} inMin  - Current minimum value.\n * @param {number} inMax  - Current maximum value.\n * @param {number} outMin - Maximum value expected.\n * @param {number} outMax - Maximum value expected.\n * @param {number} value  - Current value.\n *\n * @returns {number} - New value that should be between minimum value expected and maximum value.\n */\nexport function mapRange(\n    inMin: number,\n    inMax: number,\n    outMin: number,\n    outMax: number,\n    value: number\n): number {\n    const inRange = inMax - inMin;\n    const outRange = outMax - outMin;\n    return outMin + (((value - inMin) / inRange) * outRange || 0);\n}\n\n/**\n * Map a number within a range to a progress between 0 to 1 (ex: normalize(100, 200, 150) --> 0.5).\n *\n * @param {number} min   - Current minimum value.\n * @param {number} max   - Current maximum value.\n * @param {number} value - Current value.\n *\n * @returns {number} - New value that should be between 0 and 1.\n */\nexport function normalize(min: number, max: number, value: number): number {\n    return mapRange(min, max, 0, 1, value);\n}\n\n/**\n * Get closest number from an array.\n *\n * @param {number[]} array  - Numbers array.\n * @param {number}   target - Reference value.\n *\n * @returns {number} - Closest number.\n */\nexport function closestNumber(array: number[], target: number): number {\n    return array.reduce((prev, curr) => {\n        return Math.abs(curr - target) < Math.abs(prev - target) ? curr : prev;\n    });\n}\n"
  },
  {
    "path": "postcss.config.cjs",
    "content": "module.exports = {\n    plugins: [\n        require('cssnano')({\n            preset: 'default',\n        }),\n        require('postcss-import'),\n    ],\n};\n"
  },
  {
    "path": "scripts/ignore-build-step.js",
    "content": "#!/usr/bin/env node\n\n/**\n * Vercel Ignore Build Step Script\n *\n * This script determines whether Vercel should skip the build process.\n * Returns exit code 0 to skip build, exit code 1 to proceed with build.\n *\n * Build is skipped ONLY when:\n * - Only non-code files changed (README, .github, IDE config)\n * - Changes are only in landing package (deployed separately via committed builds)\n *\n * Build proceeds for ANY changes in:\n * - packages/lib, packages/demo, packages/docs (including all files)\n * - Config files (vercel.json, turbo.json, package.json, etc.)\n *\n * Note: Turbo handles caching - we only skip truly irrelevant changes.\n * Turbo will cache unchanged packages automatically.\n */\n\nconst { execSync } = require('child_process');\n\nconst SKIP_BUILD_EXIT_CODE = 0;\nconst PROCEED_BUILD_EXIT_CODE = 1;\n\nfunction log(message) {\n  console.log(`[Ignore Build] ${message}`);\n}\n\nfunction getChangedFiles() {\n  try {\n    // Get the commit SHA to compare against\n    const beforeCommit = process.env.VERCEL_GIT_PREVIOUS_SHA || 'HEAD~1';\n    const command = `git diff --name-only ${beforeCommit} HEAD`;\n\n    log(`Running: ${command}`);\n    const output = execSync(command, { encoding: 'utf-8' });\n    const files = output.split('\\n').filter(Boolean);\n\n    log(`Changed files (${files.length}):`);\n    files.forEach(file => log(`  - ${file}`));\n\n    return files;\n  } catch (error) {\n    log(`Error getting changed files: ${error.message}`);\n    log('Proceeding with build to be safe');\n    return null;\n  }\n}\n\nfunction shouldSkipBuild(changedFiles) {\n  // If we can't determine changed files, proceed with build\n  if (!changedFiles || changedFiles.length === 0) {\n    log('No changed files detected or error occurred');\n    return false;\n  }\n\n  // Patterns that are safe to skip (truly non-critical files)\n  // Everything else will trigger a build\n  const skipPatterns = [\n    /^README\\.md$/i,              // Root README only\n    /^LICENSE$/i,                 // License file\n    /^\\.github\\//,                // GitHub workflows/actions\n    /^\\.vscode\\//,                // VSCode settings\n    /^\\.idea\\//,                  // JetBrains IDE settings\n    /^\\.editorconfig$/,           // Editor config\n    /^\\.gitignore$/,              // Git ignore\n    /^\\.gitattributes$/,          // Git attributes\n  ];\n\n  // Check if ALL changed files match skip patterns\n  const allFilesCanBeSkipped = changedFiles.every(file =>\n    skipPatterns.some(pattern => pattern.test(file))\n  );\n\n  if (allFilesCanBeSkipped) {\n    log('Build can be skipped: Only non-critical files changed');\n    log('Changed files are: ' + changedFiles.join(', '));\n    return true;\n  }\n\n  // If any file doesn't match skip patterns, we need to build\n  const criticalFiles = changedFiles.filter(file =>\n    !skipPatterns.some(pattern => pattern.test(file))\n  );\n\n  log('Build required: Critical files changed');\n  log('Critical files: ' + criticalFiles.join(', '));\n  return false;\n}\n\nfunction main() {\n  log('Starting Vercel ignore build check...');\n\n  // Check environment variables\n  const branch = process.env.VERCEL_GIT_COMMIT_REF;\n  const isProduction = process.env.VERCEL_ENV === 'production';\n\n  log(`Branch: ${branch}`);\n  log(`Environment: ${process.env.VERCEL_ENV}`);\n  log(`Previous SHA: ${process.env.VERCEL_GIT_PREVIOUS_SHA || 'not available'}`);\n\n  // Always build on production/master branch to be safe\n  if (isProduction || branch === 'master' || branch === 'main') {\n    log('Production branch detected - proceeding with build');\n    process.exit(PROCEED_BUILD_EXIT_CODE);\n  }\n\n  // Get changed files and determine if we should skip\n  const changedFiles = getChangedFiles();\n  const shouldSkip = shouldSkipBuild(changedFiles);\n\n  if (shouldSkip) {\n    log('✓ Skipping build - no relevant changes detected');\n    process.exit(SKIP_BUILD_EXIT_CODE);\n  } else {\n    log('✓ Proceeding with build - relevant changes detected');\n    process.exit(PROCEED_BUILD_EXIT_CODE);\n  }\n}\n\nmain();\n"
  },
  {
    "path": "turbo.json",
    "content": "{\n  \"$schema\": \"https://turbo.build/schema.json\",\n  \"tasks\": {\n    \"build\": {\n      \"dependsOn\": [\"^build\"],\n      \"outputs\": [\n        \"dist/**\",\n        \"bundled/**\",\n        \".next/**\",\n        \"!.next/cache/**\",\n        \".docusaurus/**\",\n        \"build/**\",\n        \"../../www/demo/**\",\n        \"../../www/docs/**\"\n      ],\n      \"cache\": true\n    },\n    \"dev\": {\n      \"cache\": false,\n      \"persistent\": true\n    },\n    \"clean\": {\n      \"cache\": false\n    }\n  },\n  \"globalDependencies\": [\n    \"tsconfig.json\"\n  ]\n}\n"
  },
  {
    "path": "vercel.json",
    "content": "{\n    \"buildCommand\": \"npm run build:vercel\",\n    \"ignoreCommand\": \"node scripts/ignore-build-step.js\",\n    \"outputDirectory\": \"www\",\n    \"rewrites\": [\n        {\n            \"source\": \"/\",\n            \"destination\": \"/landing\"\n        },\n        {\n            \"source\": \"/assets/:path*\",\n            \"destination\": \"/landing/assets/:path*\"\n        }\n    ],\n    \"cleanUrls\": true\n}\n"
  },
  {
    "path": "www/landing/assets/images/favicons/browserconfig.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<browserconfig>\n    <msapplication>\n        <tile>\n            <square150x150logo src=\"assets/images/favicons/mstile-150x150.png\"/>\n            <TileColor>#ffffff</TileColor>\n        </tile>\n    </msapplication>\n</browserconfig>\n"
  },
  {
    "path": "www/landing/assets/scripts/app.js",
    "content": "(()=>{var fc=Object.create;var Rn=Object.defineProperty;var dc=Object.getOwnPropertyDescriptor;var pc=Object.getOwnPropertyNames,Pn=Object.getOwnPropertySymbols,_c=Object.getPrototypeOf,zs=Object.prototype.hasOwnProperty,ma=Object.prototype.propertyIsEnumerable;var Bs=(n,t,e)=>t in n?Rn(n,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):n[t]=e,Mn=(n,t)=>{for(var e in t||(t={}))zs.call(t,e)&&Bs(n,e,t[e]);if(Pn)for(var e of Pn(t))ma.call(t,e)&&Bs(n,e,t[e]);return n};var Ns=(n,t)=>{var e={};for(var i in n)zs.call(n,i)&&t.indexOf(i)<0&&(e[i]=n[i]);if(n!=null&&Pn)for(var i of Pn(n))t.indexOf(i)<0&&ma.call(n,i)&&(e[i]=n[i]);return e};var mc=(n,t)=>()=>(n&&(t=n(n=0)),t);var gc=(n,t)=>()=>(t||n((t={exports:{}}).exports,t),t.exports),ga=(n,t)=>{for(var e in t)Rn(n,e,{get:t[e],enumerable:!0})},Dc=(n,t,e,i)=>{if(t&&typeof t==\"object\"||typeof t==\"function\")for(let r of pc(t))!zs.call(n,r)&&r!==e&&Rn(n,r,{get:()=>t[r],enumerable:!(i=dc(t,r))||i.enumerable});return n};var vc=(n,t,e)=>(e=n!=null?fc(_c(n)):{},Dc(t||!n||!n.__esModule?Rn(e,\"default\",{value:n,enumerable:!0}):e,n));var I=(n,t,e)=>(Bs(n,typeof t!=\"symbol\"?t+\"\":t,e),e);var Hi=(n,t,e)=>new Promise((i,r)=>{var s=l=>{try{a(e.next(l))}catch(u){r(u)}},o=l=>{try{a(e.throw(l))}catch(u){r(u)}},a=l=>l.done?i(l.value):Promise.resolve(l.value).then(s,o);a((e=e.apply(n,t)).next())});var ec=gc((tc,Ms)=>{(function(n,t){typeof define==\"function\"&&define.amd?define([],function(){return n.svg4everybody=t()}):typeof Ms==\"object\"&&Ms.exports?Ms.exports=t():n.svg4everybody=t()})(tc,function(){function n(r,s,o){if(o){var a=document.createDocumentFragment(),l=!s.hasAttribute(\"viewBox\")&&o.getAttribute(\"viewBox\");l&&s.setAttribute(\"viewBox\",l);for(var u=o.cloneNode(!0);u.childNodes.length;)a.appendChild(u.firstChild);r.appendChild(a)}}function t(r){r.onreadystatechange=function(){if(r.readyState===4){var s=r._cachedDocument;s||(s=r._cachedDocument=document.implementation.createHTMLDocument(\"\"),s.body.innerHTML=r.responseText,r._cachedTarget={}),r._embeds.splice(0).map(function(o){var a=r._cachedTarget[o.id];a||(a=r._cachedTarget[o.id]=s.getElementById(o.id)),n(o.parent,o.svg,a)})}},r.onreadystatechange()}function e(r){function s(){for(var E=0;E<p.length;){var y=p[E],S=y.parentNode,D=i(S),v=y.getAttribute(\"xlink:href\")||y.getAttribute(\"href\");if(!v&&a.attributeName&&(v=y.getAttribute(a.attributeName)),D&&v){if(o)if(!a.validate||a.validate(v,D,y)){S.removeChild(y);var T=v.split(\"#\"),b=T.shift(),x=T.join(\"#\");if(b.length){var w=h[b];w||(w=h[b]=new XMLHttpRequest,w.open(\"GET\",b),w.send(),w._embeds=[]),w._embeds.push({parent:S,svg:D,id:x}),t(w)}else n(S,D,document.getElementById(x))}else++E,++g}else++E}(!p.length||p.length-g>0)&&_(s,67)}var o,a=Object(r),l=/\\bTrident\\/[567]\\b|\\bMSIE (?:9|10)\\.0\\b/,u=/\\bAppleWebKit\\/(\\d+)\\b/,c=/\\bEdge\\/12\\.(\\d+)\\b/,f=/\\bEdge\\/.(\\d+)\\b/,d=window.top!==window.self;o=\"polyfill\"in a?a.polyfill:l.test(navigator.userAgent)||(navigator.userAgent.match(c)||[])[1]<10547||(navigator.userAgent.match(u)||[])[1]<537||f.test(navigator.userAgent)&&d;var h={},_=window.requestAnimationFrame||setTimeout,p=document.getElementsByTagName(\"use\"),g=0;o&&s()}function i(r){for(var s=r;s.nodeName.toLowerCase()!==\"svg\"&&(s=s.parentNode););return s}return e})});var rc={};ga(rc,{gridHelper:()=>vd});function vd({gutterCssVar:n=md,marginCssVar:t=gd,rgbaColor:e=Dd}={}){let i=document.createElement(\"div\");document.body.append(i),ic(i,e),yd(i,n,t),bd(i,e)}function yd(n,t,e){let i=n.style;i.zIndex=\"10000\",i.position=\"fixed\",i.top=\"0\",i.left=\"0\",i.display=\"flex\",i.width=\"100%\",i.height=\"100%\",i.columnGap=`var(${t}, 0)`,i.paddingLeft=`var(${e}, 0)`,i.paddingRight=`var(${e}, 0)`,i.pointerEvents=\"none\",i.visibility=\"hidden\"}function ic(n,t){n.innerHTML=\"\";let e=Number(window.getComputedStyle(n).getPropertyValue(\"--grid-columns\")),i;for(var r=0;r<e;r++)i=document.createElement(\"div\"),i.style.flex=\"1 1 0\",i.style.backgroundColor=t,n.appendChild(i)}function bd(n,t){window.addEventListener(\"resize\",ic(n,t));let e=!1,i=!1;document.addEventListener(\"keydown\",r=>{r.key==\"Control\"?e=!0:e&&r.key==\"g\"&&(i?n.style.visibility=\"hidden\":n.style.visibility=\"visible\",i=!i)}),document.addEventListener(\"keyup\",r=>{r.key==\"Control\"&&(e=!1)})}var md,gd,Dd,nc=mc(()=>{md=\"--grid-gutter\",gd=\"--grid-margin\",Dd=\"rgba(255, 0, 0, .1)\"});function Ln(n){\"@babel/helpers - typeof\";return typeof Symbol==\"function\"&&typeof Symbol.iterator==\"symbol\"?Ln=function(t){return typeof t}:Ln=function(t){return t&&typeof Symbol==\"function\"&&t.constructor===Symbol&&t!==Symbol.prototype?\"symbol\":typeof t},Ln(n)}function ya(n,t){if(!(n instanceof t))throw new TypeError(\"Cannot call a class as a function\")}function Da(n,t){for(var e=0;e<t.length;e++){var i=t[e];i.enumerable=i.enumerable||!1,i.configurable=!0,\"value\"in i&&(i.writable=!0),Object.defineProperty(n,i.key,i)}}function ba(n,t,e){return t&&Da(n.prototype,t),e&&Da(n,e),n}function va(n,t,e){return t in n?Object.defineProperty(n,t,{value:e,enumerable:!0,configurable:!0,writable:!0}):n[t]=e,n}function In(n,t){return Ec(n)||Cc(n,t)||Ea(n,t)||Tc()}function yc(n){return bc(n)||wc(n)||Ea(n)||Sc()}function bc(n){if(Array.isArray(n))return Hs(n)}function Ec(n){if(Array.isArray(n))return n}function wc(n){if(typeof Symbol!=\"undefined\"&&Symbol.iterator in Object(n))return Array.from(n)}function Cc(n,t){if(!(typeof Symbol==\"undefined\"||!(Symbol.iterator in Object(n)))){var e=[],i=!0,r=!1,s=void 0;try{for(var o=n[Symbol.iterator](),a;!(i=(a=o.next()).done)&&(e.push(a.value),!(t&&e.length===t));i=!0);}catch(l){r=!0,s=l}finally{try{!i&&o.return!=null&&o.return()}finally{if(r)throw s}}return e}}function Ea(n,t){if(n){if(typeof n==\"string\")return Hs(n,t);var e=Object.prototype.toString.call(n).slice(8,-1);if(e===\"Object\"&&n.constructor&&(e=n.constructor.name),e===\"Map\"||e===\"Set\")return Array.from(n);if(e===\"Arguments\"||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(e))return Hs(n,t)}}function Hs(n,t){(t==null||t>n.length)&&(t=n.length);for(var e=0,i=new Array(t);e<t;e++)i[e]=n[e];return i}function Sc(){throw new TypeError(`Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.`)}function Tc(){throw new TypeError(`Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.`)}var de=function(){function n(t){ya(this,n),this.mAttr=\"data-\"+t.dataName,this.mCaptureEvents=[\"mouseenter\",\"mouseleave\"],this.el=t.el}return ba(n,[{key:\"mInit\",value:function(e){var i=this;this.modules=e,this.mCheckEventTarget=this.mCheckEventTarget.bind(this),this.events&&Object.keys(this.events).forEach(function(r){return i.mAddEvent(r)})}},{key:\"mUpdate\",value:function(e){this.modules=e}},{key:\"mDestroy\",value:function(){var e=this;this.events&&Object.keys(this.events).forEach(function(i){return e.mRemoveEvent(i)})}},{key:\"mAddEvent\",value:function(e){var i=!!this.mCaptureEvents.includes(e);this.el.addEventListener(e,this.mCheckEventTarget,i)}},{key:\"mRemoveEvent\",value:function(e){var i=!!this.mCaptureEvents.includes(e);this.el.removeEventListener(e,this.mCheckEventTarget,i)}},{key:\"mCheckEventTarget\",value:function(e){var i=this.events[e.type];if(typeof i==\"string\")this[i](e);else{var r=\"[\"+this.mAttr+\"]\",s=e.target;if(this.mCaptureEvents.includes(e.type))s.matches(r)&&this.mCallEventMethod(e,i,s);else for(;s&&s!==document&&!(s.matches(r)&&this.mCallEventMethod(e,i,s)!=\"undefined\");)s=s.parentNode}}},{key:\"mCallEventMethod\",value:function(e,i,r){var s=r.getAttribute(this.mAttr);if(i.hasOwnProperty(s)){var o=i[s];e.hasOwnProperty(\"currentTarget\")||Object.defineProperty(e,\"currentTarget\",{value:r}),e.hasOwnProperty(\"curTarget\")||Object.defineProperty(e,\"curTarget\",{value:r}),this[o](e)}}},{key:\"$\",value:function(e,i){var r=e.indexOf(\".\"),s=e.indexOf(\"#\"),o=e.indexOf(\"[\"),a=[r,s,o].filter(function(d){return d!=-1}),l=!1,u=e,c=\"\",f=this.el;return a.length&&(l=Math.min.apply(Math,yc(a)),u=e.slice(0,l),c=e.slice(l)),Ln(i)==\"object\"&&(f=i),f.querySelectorAll(\"[\"+this.mAttr+\"=\"+u+\"]\"+c)}},{key:\"parent\",value:function(e,i){for(var r=\"[\"+this.mAttr+\"=\"+e+\"]\",s=i.parentNode;s&&s!==document;){if(s.matches(r))return s;s=s.parentNode}}},{key:\"getData\",value:function(e,i){var r=i||this.el;return r.getAttribute(this.mAttr+\"-\"+e)}},{key:\"setData\",value:function(e,i,r){var s=r||this.el;return s.setAttribute(this.mAttr+\"-\"+e,i)}},{key:\"call\",value:function(e,i,r,s){var o=this;i&&!r&&(r=i,i=!1),this.modules[r]&&(s?this.modules[r][s]&&this.modules[r][s][e](i):Object.keys(this.modules[r]).forEach(function(a){o.modules[r][a][e](i)}))}},{key:\"on\",value:function(e,i,r,s){var o=this;this.modules[i]&&(s?this.modules[i][s].el.addEventListener(e,function(a){return r(a)}):Object.keys(this.modules[i]).forEach(function(a){o.modules[i][a].el.addEventListener(e,function(l){return r(l)})}))}},{key:\"init\",value:function(){}},{key:\"destroy\",value:function(){}}]),n}(),xc=function(){function n(t){ya(this,n),this.app,this.modules=t.modules,this.currentModules={},this.activeModules={},this.newModules={},this.moduleId=0}return ba(n,[{key:\"init\",value:function(e,i){var r=this,s=i||document,o=s.querySelectorAll(\"*\");e&&!this.app&&(this.app=e),this.activeModules.app={app:this.app},o.forEach(function(a){Array.from(a.attributes).forEach(function(l){if(l.name.startsWith(\"data-module\")){var u=!1,c=l.name.split(\"-\").splice(2),f=r.toCamel(c);if(r.modules[f]?u=!0:r.modules[r.toUpper(f)]&&(f=r.toUpper(f),u=!0),u){var d={el:a,name:f,dataName:c.join(\"-\")},h=new r.modules[f](d),_=l.value;_||(r.moduleId++,_=\"m\"+r.moduleId,a.setAttribute(l.name,_)),r.addActiveModule(f,_,h);var p=f+\"-\"+_;i?r.newModules[p]=h:r.currentModules[p]=h}}})}),Object.entries(this.currentModules).forEach(function(a){var l=In(a,2),u=l[0],c=l[1];if(i){var f=u.split(\"-\"),d=f.shift(),h=f.pop();r.addActiveModule(d,h,c)}else r.initModule(c)})}},{key:\"initModule\",value:function(e){e.mInit(this.activeModules),e.init()}},{key:\"addActiveModule\",value:function(e,i,r){this.activeModules[e]?Object.assign(this.activeModules[e],va({},i,r)):this.activeModules[e]=va({},i,r)}},{key:\"update\",value:function(e){var i=this;this.init(this.app,e),Object.entries(this.currentModules).forEach(function(r){var s=In(r,2),o=s[0],a=s[1];a.mUpdate(i.activeModules)}),Object.entries(this.newModules).forEach(function(r){var s=In(r,2),o=s[0],a=s[1];i.initModule(a)}),Object.assign(this.currentModules,this.newModules)}},{key:\"destroy\",value:function(e){e?this.destroyScope(e):this.destroyModules()}},{key:\"destroyScope\",value:function(e){var i=this,r=e.querySelectorAll(\"*\");r.forEach(function(s){Array.from(s.attributes).forEach(function(o){if(o.name.startsWith(\"data-module\")){var a=o.value,l=o.name.split(\"-\").splice(2),u=i.toCamel(l)+\"-\"+a,c=!1;i.currentModules[u]?c=!0:i.currentModules[i.toUpper(u)]&&(u=i.toUpper(u),c=!0),c&&(i.destroyModule(i.currentModules[u]),delete i.currentModules[u])}})}),this.activeModules={},this.newModules={}}},{key:\"destroyModules\",value:function(){var e=this;Object.entries(this.currentModules).forEach(function(i){var r=In(i,2),s=r[0],o=r[1];e.destroyModule(o)}),this.currentModules=[]}},{key:\"destroyModule\",value:function(e){e.mDestroy(),e.destroy()}},{key:\"toCamel\",value:function(e){var i=this;return e.reduce(function(r,s){return r+i.toUpper(s)})}},{key:\"toUpper\",value:function(e){return e.charAt(0).toUpperCase()+e.slice(1)}}]),n}(),wa=xc;var fa={};ga(fa,{FadeInText:()=>Ps,HoverShuffle:()=>Rs,Load:()=>Bn,MaskLines:()=>ks,Rail:()=>rs,Randomize:()=>an,Scroll:()=>sn});function Fc(n,t){if(!(n instanceof t))throw new TypeError(\"Cannot call a class as a function\")}function Ca(n,t){for(var e=0;e<t.length;e++){var i=t[e];i.enumerable=i.enumerable||!1,i.configurable=!0,\"value\"in i&&(i.writable=!0),Object.defineProperty(n,i.key,i)}}function Ac(n,t,e){return t&&Ca(n.prototype,t),e&&Ca(n,e),n}function Oc(n,t){return kc(n)||Pc(n,t)||Rc(n,t)||Mc()}function kc(n){if(Array.isArray(n))return n}function Pc(n,t){var e=n==null?null:typeof Symbol!=\"undefined\"&&n[Symbol.iterator]||n[\"@@iterator\"];if(e!=null){var i=[],r=!0,s=!1,o,a;try{for(e=e.call(n);!(r=(o=e.next()).done)&&(i.push(o.value),!(t&&i.length===t));r=!0);}catch(l){s=!0,a=l}finally{try{!r&&e.return!=null&&e.return()}finally{if(s)throw a}}return i}}function Rc(n,t){if(n){if(typeof n==\"string\")return Sa(n,t);var e=Object.prototype.toString.call(n).slice(8,-1);if(e===\"Object\"&&n.constructor&&(e=n.constructor.name),e===\"Map\"||e===\"Set\")return Array.from(n);if(e===\"Arguments\"||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(e))return Sa(n,t)}}function Sa(n,t){(t==null||t>n.length)&&(t=n.length);for(var e=0,i=new Array(t);e<t;e++)i[e]=n[e];return i}function Mc(){throw new TypeError(`Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.`)}var Ic=function(){function n(t){Fc(this,n),this.defaults={name:\"load\",loadingClass:\"is-loading\",loadedClass:\"is-loaded\",readyClass:\"is-ready\",transitionsPrefix:\"is-\",transitionsHistory:!0,enterDelay:0,exitDelay:0,loadedDelay:0,isLoaded:!1,isEntered:!1,isUrl:!1,transitionContainer:null,popstateIgnore:!1},Object.assign(this,this.defaults,t),this.options=t,this.namespace=\"modular\",this.html=document.documentElement,this.href=window.location.href,this.container=\"data-\"+this.name+\"-container\",this.subContainer=!1,this.prevTransition=null,this.loadAttributes=[\"src\",\"srcset\",\"style\",\"href\"],this.isInserted=!1,this.isLoading=!1,this.enterTimeout=!1,this.controller=new AbortController,this.classContainer=this.html,this.isChrome=navigator.userAgent.indexOf(\"Chrome\")!=-1,this.init()}return Ac(n,[{key:\"init\",value:function(){var e=this;window.addEventListener(\"popstate\",function(i){return e.checkState(i)},!1),this.html.addEventListener(\"click\",function(i){return e.checkClick(i)},!1),this.loadEls(document)}},{key:\"checkClick\",value:function(e){if(!e.ctrlKey&&!e.metaKey)for(var i=e.target;i&&i!==document;){if(i.matches(\"a\")&&i.getAttribute(\"download\")==null){var r=i.getAttribute(\"href\");!r.startsWith(\"#\")&&!r.startsWith(\"mailto:\")&&!r.startsWith(\"tel:\")&&(e.preventDefault(),this.reset(),this.getClickOptions(i));break}i=i.parentNode}}},{key:\"checkState\",value:function(){typeof this.popstateIgnore==\"string\"&&window.location.href.indexOf(this.popstateIgnore)>-1||(this.reset(),this.getStateOptions())}},{key:\"reset\",value:function(){this.isLoading&&(this.controller.abort(),this.isLoading=!1,this.controller=new AbortController),window.clearTimeout(this.enterTimeout),this.isInserted&&this.removeContainer(),this.classContainer=this.html,Object.assign(this,this.defaults,this.options)}},{key:\"getClickOptions\",value:function(e){this.transition=e.getAttribute(\"data-\"+this.name),this.isUrl=e.getAttribute(\"data-\"+this.name+\"-url\");var i=e.getAttribute(\"href\"),r=e.getAttribute(\"target\");if(r==\"_blank\"){window.open(i,\"_blank\");return}if(this.transition==\"false\"){window.location=i;return}this.setOptions(i,!0)}},{key:\"getStateOptions\",value:function(){this.transitionsHistory?this.transition=history.state:this.transition=!1;var e=window.location.href;this.setOptions(e)}},{key:\"goTo\",value:function(e,i,r){this.reset(),this.transition=i,this.isUrl=r,this.setOptions(e,!0)}},{key:\"setOptions\",value:function(e,i){var r=\"[\"+this.container+\"]\",s;this.transition&&this.transition!=\"true\"&&(this.transitionContainer=\"[\"+this.container+'=\"'+this.transition+'\"]',this.loadingClass=this.transitions[this.transition].loadingClass||this.loadingClass,this.loadedClass=this.transitions[this.transition].loadedClass||this.loadedClass,this.readyClass=this.transitions[this.transition].readyClass||this.readyClass,this.transitionsPrefix=this.transitions[this.transition].transitionsPrefix||this.transitionsPrefix,this.enterDelay=this.transitions[this.transition].enterDelay||this.enterDelay,this.exitDelay=this.transitions[this.transition].exitDelay||this.exitDelay,this.loadedDelay=this.transitions[this.transition].loadedDelay||this.loadedDelay,s=document.querySelector(this.transitionContainer)),s?(r=this.transitionContainer,this.oldContainer=s,this.classContainer=this.oldContainer.parentNode,this.subContainer||history.replaceState(this.transition,null,this.href),this.subContainer=!0):(this.oldContainer=document.querySelector(r),this.subContainer&&history.replaceState(this.prevTransition,null,this.href),this.subContainer=!1),this.href=e,this.parentContainer=this.oldContainer.parentNode,this.isUrl===\"\"||this.isUrl!=null&&this.isUrl!=\"false\"&&this.isUrl!=!1?history.pushState(this.transition,null,e):(this.oldContainer.classList.add(\"is-old\"),this.setLoading(),this.startEnterDelay(),this.loadHref(e,r,i))}},{key:\"setLoading\",value:function(){this.classContainer.classList.remove(this.loadedClass,this.readyClass),this.classContainer.classList.add(this.loadingClass),this.classContainer.classList.remove(this.transitionsPrefix+this.prevTransition),this.transition&&this.classContainer.classList.add(this.transitionsPrefix+this.transition),this.subContainer||(this.prevTransition=this.transition);var e=new Event(this.namespace+\"loading\");window.dispatchEvent(e)}},{key:\"startEnterDelay\",value:function(){var e=this;this.enterTimeout=window.setTimeout(function(){e.isEntered=!0,e.isLoaded&&e.transitionContainers()},this.enterDelay)}},{key:\"loadHref\",value:function(e,i,r){var s=this;this.isLoading=!0;var o=this.controller.signal;fetch(e,{signal:o}).then(function(a){return a.text()}).then(function(a){r&&history.pushState(s.transition,null,e);var l=new DOMParser;s.data=l.parseFromString(a,\"text/html\"),s.newContainer=s.data.querySelector(i),s.newContainer.classList.add(\"is-new\"),s.parentNewContainer=s.newContainer.parentNode,s.hideContainer(),s.parentContainer.insertBefore(s.newContainer,s.oldContainer),s.isInserted=!0,s.setSvgs(),s.isLoaded=!0,s.isEntered&&s.transitionContainers(),s.loadEls(s.newContainer),s.isLoading=!1}).catch(function(a){window.location=e})}},{key:\"transitionContainers\",value:function(){var e=this;this.setAttributes(),this.showContainer(),this.setLoaded(),setTimeout(function(){e.removeContainer(),e.setReady()},this.exitDelay)}},{key:\"setSvgs\",value:function(){if(this.isChrome){var e=this.newContainer.querySelectorAll(\"use\");e.length&&e.forEach(function(i){var r=i.getAttribute(\"xlink:href\");if(r)i.parentNode.innerHTML='<use xlink:href=\"'+r+'\"></use>';else{var s=i.getAttribute(\"href\");s&&(i.parentNode.innerHTML='<use href=\"'+s+'\"></use>')}})}}},{key:\"setAttributes\",value:function(){var e=this,i=this.data.getElementsByTagName(\"title\")[0],r=this.data.head.querySelector('meta[name=\"description\"]'),s=document.head.querySelector('meta[name=\"description\"]'),o,a;this.subContainer?(a=this.parentNewContainer,o=document.querySelector(this.transitionContainer).parentNode):(a=this.data.querySelector(\"html\"),o=document.querySelector(\"html\"));var l=Object.assign({},a.dataset);i&&(document.title=i.innerText),s&&r&&s.setAttribute(\"content\",r.getAttribute(\"content\")),l&&Object.entries(l).forEach(function(u){var c=Oc(u,2),f=c[0],d=c[1];o.setAttribute(\"data-\"+e.toDash(f),d)})}},{key:\"toDash\",value:function(e){return e.split(/(?=[A-Z])/).join(\"-\").toLowerCase()}},{key:\"hideContainer\",value:function(){this.newContainer.style.visibility=\"hidden\",this.newContainer.style.height=0,this.newContainer.style.overflow=\"hidden\"}},{key:\"showContainer\",value:function(){this.newContainer.style.visibility=\"\",this.newContainer.style.height=\"\",this.newContainer.style.overflow=\"\"}},{key:\"loadEls\",value:function(e){var i=this,r=[];this.loadAttributes.forEach(function(s){var o=\"data-\"+i.name+\"-\"+s,a=e.querySelectorAll(\"[\"+o+\"]\");a.length&&a.forEach(function(l){var u=l.getAttribute(o);if(l.setAttribute(s,u),s==\"src\"||s==\"srcset\"){var c=new Promise(function(f){l.onload=function(){return f(l)}});r.push(c)}})}),Promise.all(r).then(function(s){var o=new Event(i.namespace+\"images\");window.dispatchEvent(o)})}},{key:\"setLoaded\",value:function(){var e=this;this.classContainer.classList.remove(this.loadingClass),setTimeout(function(){e.classContainer.classList.add(e.loadedClass)},this.loadedDelay);var i=new Event(this.namespace+\"loaded\");window.dispatchEvent(i)}},{key:\"removeContainer\",value:function(){this.parentContainer.removeChild(this.oldContainer),this.newContainer.classList.remove(\"is-new\"),this.isInserted=!1}},{key:\"setReady\",value:function(){this.classContainer.classList.add(this.readyClass);var e=new Event(this.namespace+\"ready\");window.dispatchEvent(e)}},{key:\"on\",value:function(e,i){var r=this;window.addEventListener(this.namespace+e,function(){switch(e){case\"loading\":return i(r.transition,r.oldContainer);case\"loaded\":return i(r.transition,r.oldContainer,r.newContainer);case\"ready\":return i(r.transition,r.newContainer);default:return i()}},!1)}}]),n}(),Ta=Ic;var Bn=class extends de{constructor(n){super(n)}init(){new Ta({enterDelay:0,transitions:{customTransition:{}}}).on(\"loaded\",(t,e,i)=>{this.call(\"destroy\",e,\"app\"),this.call(\"update\",i,\"app\")})}};var Fa=\"fonts\"in document;function Lc(n,t){for(let[e,i]of Object.entries(t))switch(e){case\"family\":{if(zn(n[e])!==i)return!1;break}case\"weight\":{if(n[e]!=i)return!1;break}default:{if(n[e]!==i)return!1;break}}return!0}function Bc(n,t){let e=zn(n.family);return zn(e)===t||t.endsWith(zn(e))&&(t.match(n.weight)||t.match(n.style)),!0}function zc(n){let t=[];for(let e of document.fonts)Lc(e,n)&&t.push(e);return t}function Nc(n){let t=[];for(let e of document.fonts)Bc(e,n)&&t.push(e);return t}function Aa(n){Array.isArray(n)||(n=[n]);let t=new Set;return n.forEach(e=>{if(e)switch(typeof e){case\"string\":t.add(...Nc(e));return;case\"object\":t.add(...zc(e));return}throw new TypeError(\"Expected font query to be font shorthand or font reference\")}),[...t]}function Oa(n,t=!1){return Hi(this,null,function*(){var e;if(((e=n.size)!=null?e:n.length)===0)throw new TypeError(\"Expected at least one font\");return yield Hc([...n],t)})}function xa(n){return Hi(this,null,function*(){return yield(n.status===\"unloaded\"?n.load():n.loaded).then(t=>t,t=>n)})}function Hc(n,t=!1){return Hi(this,null,function*(){t&&console.group(\"[loadFonts:API]\",n.length,\"/\",document.fonts.size);let e=[];for(let i of n)i instanceof FontFace?(document.fonts.has(i)||document.fonts.add(i),e.push(xa(i))):e.push(...Aa(i).map(r=>xa(r)));return t&&console.groupEnd(),yield Promise.all(e)})}function zn(n){return n.replace(/['\"]+/g,\"\")}function Nn(n){return Hi(this,null,function*(){let t=Aa(n);return yield Promise.all(t.map(e=>e.loaded.then(i=>i,i=>(console.warn(`Font failed to load: ${e.family} ${e.style} ${e.weight}`,i),e))))})}function oi(n){if(n===void 0)throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\");return n}function Na(n,t){n.prototype=Object.create(t.prototype),n.prototype.constructor=n,n.__proto__=t}var ge={autoSleep:120,force3D:\"auto\",nullTargetWarn:1,units:{lineHeight:\"\"}},dr={duration:.5,overwrite:!1,delay:0},no,Wt,ct,Pe=1e8,at=1/Pe,qs=Math.PI*2,Wc=qs/4,Vc=0,Ha=Math.sqrt,Uc=Math.cos,Yc=Math.sin,kt=function(t){return typeof t==\"string\"},Dt=function(t){return typeof t==\"function\"},li=function(t){return typeof t==\"number\"},Gn=function(t){return typeof t==\"undefined\"},Qe=function(t){return typeof t==\"object\"},me=function(t){return t!==!1},so=function(){return typeof window!=\"undefined\"},Hn=function(t){return Dt(t)||kt(t)},Wa=typeof ArrayBuffer==\"function\"&&ArrayBuffer.isView||function(){},Gt=Array.isArray,$c=/random\\([^)]+\\)/g,jc=/,\\s*/g,ka=/(?:-?\\.?\\d|\\.)+/gi,oo=/[-+=.]*\\d+[.e\\-+]*\\d*[e\\-+]*\\d*/g,Yi=/[-+=.]*\\d+[.e-]*\\d*[a-z%]*/g,Ws=/[-+=.]*\\d+\\.?\\d*(?:e-|e\\+)?\\d*/gi,ao=/[+-]=-?[.\\d]+/,Xc=/[^,'\"\\[\\]\\s]+/gi,qc=/^[+\\-=e\\s\\d]*\\d+[.\\d]*([a-z]*|%)\\s*$/i,dt,Ge,Gs,lo,we={},Yn={},Va,Ua=function(t){return(Yn=pr(t,we))&&Kt},Kn=function(t,e){return console.warn(\"Invalid property\",t,\"set to\",e,\"Missing plugin? gsap.registerPlugin()\")},jr=function(t,e){return!e&&console.warn(t)},Ya=function(t,e){return t&&(we[t]=e)&&Yn&&(Yn[t]=e)||we},Xr=function(){return 0},Gc={suppressEvents:!0,isStart:!0,kill:!1},Wn={suppressEvents:!0,kill:!1},Kc={suppressEvents:!0},uo={},wi=[],Ks={},$a,pe={},Vs={},Pa=30,Vn=[],co=\"\",ho=function(t){var e=t[0],i,r;if(Qe(e)||Dt(e)||(t=[t]),!(i=(e._gsap||{}).harness)){for(r=Vn.length;r--&&!Vn[r].targetTest(e););i=Vn[r]}for(r=t.length;r--;)t[r]&&(t[r]._gsap||(t[r]._gsap=new mo(t[r],i)))||t.splice(r,1);return t},Ci=function(t){return t._gsap||ho(Re(t))[0]._gsap},fo=function(t,e,i){return(i=t[e])&&Dt(i)?t[e]():Gn(i)&&t.getAttribute&&t.getAttribute(e)||i},ne=function(t,e){return(t=t.split(\",\")).forEach(e)||t},vt=function(t){return Math.round(t*1e5)/1e5||0},ft=function(t){return Math.round(t*1e7)/1e7||0},$i=function(t,e){var i=e.charAt(0),r=parseFloat(e.substr(2));return t=parseFloat(t),i===\"+\"?t+r:i===\"-\"?t-r:i===\"*\"?t*r:t/r},Qc=function(t,e){for(var i=e.length,r=0;t.indexOf(e[r])<0&&++r<i;);return r<i},$n=function(){var t=wi.length,e=wi.slice(0),i,r;for(Ks={},wi.length=0,i=0;i<t;i++)r=e[i],r&&r._lazy&&(r.render(r._lazy[0],r._lazy[1],!0)._lazy=0)},po=function(t){return!!(t._initted||t._startAt||t.add)},ja=function(t,e,i,r){wi.length&&!Wt&&$n(),t.render(e,i,r||!!(Wt&&e<0&&po(t))),wi.length&&!Wt&&$n()},Xa=function(t){var e=parseFloat(t);return(e||e===0)&&(t+\"\").match(Xc).length<2?e:kt(t)?t.trim():t},qa=function(t){return t},Ce=function(t,e){for(var i in e)i in t||(t[i]=e[i]);return t},Zc=function(t){return function(e,i){for(var r in i)r in e||r===\"duration\"&&t||r===\"ease\"||(e[r]=i[r])}},pr=function(t,e){for(var i in e)t[i]=e[i];return t},Ra=function n(t,e){for(var i in e)i!==\"__proto__\"&&i!==\"constructor\"&&i!==\"prototype\"&&(t[i]=Qe(e[i])?n(t[i]||(t[i]={}),e[i]):e[i]);return t},jn=function(t,e){var i={},r;for(r in t)r in e||(i[r]=t[r]);return i},Ur=function(t){var e=t.parent||dt,i=t.keyframes?Zc(Gt(t.keyframes)):Ce;if(me(t.inherit))for(;e;)i(t,e.vars.defaults),e=e.parent||e._dp;return t},Jc=function(t,e){for(var i=t.length,r=i===e.length;r&&i--&&t[i]===e[i];);return i<0},Ga=function(t,e,i,r,s){i===void 0&&(i=\"_first\"),r===void 0&&(r=\"_last\");var o=t[r],a;if(s)for(a=e[s];o&&o[s]>a;)o=o._prev;return o?(e._next=o._next,o._next=e):(e._next=t[i],t[i]=e),e._next?e._next._prev=e:t[r]=e,e._prev=o,e.parent=e._dp=t,e},Qn=function(t,e,i,r){i===void 0&&(i=\"_first\"),r===void 0&&(r=\"_last\");var s=e._prev,o=e._next;s?s._next=o:t[i]===e&&(t[i]=o),o?o._prev=s:t[r]===e&&(t[r]=s),e._next=e._prev=e.parent=null},Si=function(t,e){t.parent&&(!e||t.parent.autoRemoveChildren)&&t.parent.remove&&t.parent.remove(t),t._act=0},Wi=function(t,e){if(t&&(!e||e._end>t._dur||e._start<0))for(var i=t;i;)i._dirty=1,i=i.parent;return t},th=function(t){for(var e=t.parent;e&&e.parent;)e._dirty=1,e.totalDuration(),e=e.parent;return t},Qs=function(t,e,i,r){return t._startAt&&(Wt?t._startAt.revert(Wn):t.vars.immediateRender&&!t.vars.autoRevert||t._startAt.render(e,!0,r))},eh=function n(t){return!t||t._ts&&n(t.parent)},Ma=function(t){return t._repeat?_r(t._tTime,t=t.duration()+t._rDelay)*t:0},_r=function(t,e){var i=Math.floor(t=ft(t/e));return t&&i===t?i-1:i},Xn=function(t,e){return(t-e._start)*e._ts+(e._ts>=0?0:e._dirty?e.totalDuration():e._tDur)},Zn=function(t){return t._end=ft(t._start+(t._tDur/Math.abs(t._ts||t._rts||at)||0))},Jn=function(t,e){var i=t._dp;return i&&i.smoothChildTiming&&t._ts&&(t._start=ft(i._time-(t._ts>0?e/t._ts:((t._dirty?t.totalDuration():t._tDur)-e)/-t._ts)),Zn(t),i._dirty||Wi(i,t)),t},Ka=function(t,e){var i;if((e._time||!e._dur&&e._initted||e._start<t._time&&(e._dur||!e.add))&&(i=Xn(t.rawTime(),e),(!e._dur||Kr(0,e.totalDuration(),i)-e._tTime>at)&&e.render(i,!0)),Wi(t,e)._dp&&t._initted&&t._time>=t._dur&&t._ts){if(t._dur<t.duration())for(i=t;i._dp;)i.rawTime()>=0&&i.totalTime(i._tTime),i=i._dp;t._zTime=-at}},Ke=function(t,e,i,r){return e.parent&&Si(e),e._start=ft((li(i)?i:i||t!==dt?ke(t,i,e):t._time)+e._delay),e._end=ft(e._start+(e.totalDuration()/Math.abs(e.timeScale())||0)),Ga(t,e,\"_first\",\"_last\",t._sort?\"_start\":0),Zs(e)||(t._recent=e),r||Ka(t,e),t._ts<0&&Jn(t,t._tTime),t},Qa=function(t,e){return(we.ScrollTrigger||Kn(\"scrollTrigger\",e))&&we.ScrollTrigger.create(e,t)},Za=function(t,e,i,r,s){if(vo(t,e,s),!t._initted)return 1;if(!i&&t._pt&&!Wt&&(t._dur&&t.vars.lazy!==!1||!t._dur&&t.vars.lazy)&&$a!==_e.frame)return wi.push(t),t._lazy=[s,r],1},ih=function n(t){var e=t.parent;return e&&e._ts&&e._initted&&!e._lock&&(e.rawTime()<0||n(e))},Zs=function(t){var e=t.data;return e===\"isFromStart\"||e===\"isStart\"},rh=function(t,e,i,r){var s=t.ratio,o=e<0||!e&&(!t._start&&ih(t)&&!(!t._initted&&Zs(t))||(t._ts<0||t._dp._ts<0)&&!Zs(t))?0:1,a=t._rDelay,l=0,u,c,f;if(a&&t._repeat&&(l=Kr(0,t._tDur,e),c=_r(l,a),t._yoyo&&c&1&&(o=1-o),c!==_r(t._tTime,a)&&(s=1-o,t.vars.repeatRefresh&&t._initted&&t.invalidate())),o!==s||Wt||r||t._zTime===at||!e&&t._zTime){if(!t._initted&&Za(t,e,r,i,l))return;for(f=t._zTime,t._zTime=e||(i?at:0),i||(i=e&&!f),t.ratio=o,t._from&&(o=1-o),t._time=0,t._tTime=l,u=t._pt;u;)u.r(o,u.d),u=u._next;e<0&&Qs(t,e,i,!0),t._onUpdate&&!i&&Ee(t,\"onUpdate\"),l&&t._repeat&&!i&&t.parent&&Ee(t,\"onRepeat\"),(e>=t._tDur||e<0)&&t.ratio===o&&(o&&Si(t,1),!i&&!Wt&&(Ee(t,o?\"onComplete\":\"onReverseComplete\",!0),t._prom&&t._prom()))}else t._zTime||(t._zTime=e)},nh=function(t,e,i){var r;if(i>e)for(r=t._first;r&&r._start<=i;){if(r.data===\"isPause\"&&r._start>e)return r;r=r._next}else for(r=t._last;r&&r._start>=i;){if(r.data===\"isPause\"&&r._start<e)return r;r=r._prev}},mr=function(t,e,i,r){var s=t._repeat,o=ft(e)||0,a=t._tTime/t._tDur;return a&&!r&&(t._time*=o/t._dur),t._dur=o,t._tDur=s?s<0?1e10:ft(o*(s+1)+t._rDelay*s):o,a>0&&!r&&Jn(t,t._tTime=t._tDur*a),t.parent&&Zn(t),i||Wi(t.parent,t),t},Ia=function(t){return t instanceof Ht?Wi(t):mr(t,t._dur)},sh={_start:0,endTime:Xr,totalDuration:Xr},ke=function n(t,e,i){var r=t.labels,s=t._recent||sh,o=t.duration()>=Pe?s.endTime(!1):t._dur,a,l,u;return kt(e)&&(isNaN(e)||e in r)?(l=e.charAt(0),u=e.substr(-1)===\"%\",a=e.indexOf(\"=\"),l===\"<\"||l===\">\"?(a>=0&&(e=e.replace(/=/,\"\")),(l===\"<\"?s._start:s.endTime(s._repeat>=0))+(parseFloat(e.substr(1))||0)*(u?(a<0?s:i).totalDuration()/100:1)):a<0?(e in r||(r[e]=o),r[e]):(l=parseFloat(e.charAt(a-1)+e.substr(a+1)),u&&i&&(l=l/100*(Gt(i)?i[0]:i).totalDuration()),a>1?n(t,e.substr(0,a-1),i)+l:o+l)):e==null?o:+e},Yr=function(t,e,i){var r=li(e[1]),s=(r?2:1)+(t<2?0:1),o=e[s],a,l;if(r&&(o.duration=e[1]),o.parent=i,t){for(a=o,l=i;l&&!(\"immediateRender\"in a);)a=l.vars.defaults||{},l=me(l.vars.inherit)&&l.parent;o.immediateRender=me(a.immediateRender),t<2?o.runBackwards=1:o.startAt=e[s-1]}return new Ct(e[0],o,e[s+1])},Ti=function(t,e){return t||t===0?e(t):e},Kr=function(t,e,i){return i<t?t:i>e?e:i},Vt=function(t,e){return!kt(t)||!(e=qc.exec(t))?\"\":e[1]},oh=function(t,e,i){return Ti(i,function(r){return Kr(t,e,r)})},Js=[].slice,Ja=function(t,e){return t&&Qe(t)&&\"length\"in t&&(!e&&!t.length||t.length-1 in t&&Qe(t[0]))&&!t.nodeType&&t!==Ge},ah=function(t,e,i){return i===void 0&&(i=[]),t.forEach(function(r){var s;return kt(r)&&!e||Ja(r,1)?(s=i).push.apply(s,Re(r)):i.push(r)})||i},Re=function(t,e,i){return ct&&!e&&ct.selector?ct.selector(t):kt(t)&&!i&&(Gs||!gr())?Js.call((e||lo).querySelectorAll(t),0):Gt(t)?ah(t,i):Ja(t)?Js.call(t,0):t?[t]:[]},to=function(t){return t=Re(t)[0]||jr(\"Invalid scope\")||{},function(e){var i=t.current||t.nativeElement||t;return Re(e,i.querySelectorAll?i:i===t?jr(\"Invalid scope\")||lo.createElement(\"div\"):t)}},tl=function(t){return t.sort(function(){return .5-Math.random()})},el=function(t){if(Dt(t))return t;var e=Qe(t)?t:{each:t},i=Vi(e.ease),r=e.from||0,s=parseFloat(e.base)||0,o={},a=r>0&&r<1,l=isNaN(r)||a,u=e.axis,c=r,f=r;return kt(r)?c=f={center:.5,edges:.5,end:1}[r]||0:!a&&l&&(c=r[0],f=r[1]),function(d,h,_){var p=(_||e).length,g=o[p],E,y,S,D,v,T,b,x,w;if(!g){if(w=e.grid===\"auto\"?0:(e.grid||[1,Pe])[1],!w){for(b=-Pe;b<(b=_[w++].getBoundingClientRect().left)&&w<p;);w<p&&w--}for(g=o[p]=[],E=l?Math.min(w,p)*c-.5:r%w,y=w===Pe?0:l?p*f/w-.5:r/w|0,b=0,x=Pe,T=0;T<p;T++)S=T%w-E,D=y-(T/w|0),g[T]=v=u?Math.abs(u===\"y\"?D:S):Ha(S*S+D*D),v>b&&(b=v),v<x&&(x=v);r===\"random\"&&tl(g),g.max=b-x,g.min=x,g.v=p=(parseFloat(e.amount)||parseFloat(e.each)*(w>p?p-1:u?u===\"y\"?p/w:w:Math.max(w,p/w))||0)*(r===\"edges\"?-1:1),g.b=p<0?s-p:s,g.u=Vt(e.amount||e.each)||0,i=i&&p<0?cl(i):i}return p=(g[d]-g.min)/g.max||0,ft(g.b+(i?i(p):p)*g.v)+g.u}},eo=function(t){var e=Math.pow(10,((t+\"\").split(\".\")[1]||\"\").length);return function(i){var r=ft(Math.round(parseFloat(i)/t)*t*e);return(r-r%1)/e+(li(i)?0:Vt(i))}},il=function(t,e){var i=Gt(t),r,s;return!i&&Qe(t)&&(r=i=t.radius||Pe,t.values?(t=Re(t.values),(s=!li(t[0]))&&(r*=r)):t=eo(t.increment)),Ti(e,i?Dt(t)?function(o){return s=t(o),Math.abs(s-o)<=r?s:o}:function(o){for(var a=parseFloat(s?o.x:o),l=parseFloat(s?o.y:0),u=Pe,c=0,f=t.length,d,h;f--;)s?(d=t[f].x-a,h=t[f].y-l,d=d*d+h*h):d=Math.abs(t[f]-a),d<u&&(u=d,c=f);return c=!r||u<=r?t[c]:o,s||c===o||li(o)?c:c+Vt(o)}:eo(t))},rl=function(t,e,i,r){return Ti(Gt(t)?!e:i===!0?!!(i=0):!r,function(){return Gt(t)?t[~~(Math.random()*t.length)]:(i=i||1e-5)&&(r=i<1?Math.pow(10,(i+\"\").length-2):1)&&Math.floor(Math.round((t-i/2+Math.random()*(e-t+i*.99))/i)*i*r)/r})},lh=function(){for(var t=arguments.length,e=new Array(t),i=0;i<t;i++)e[i]=arguments[i];return function(r){return e.reduce(function(s,o){return o(s)},r)}},uh=function(t,e){return function(i){return t(parseFloat(i))+(e||Vt(i))}},ch=function(t,e,i){return sl(t,e,0,1,i)},nl=function(t,e,i){return Ti(i,function(r){return t[~~e(r)]})},hh=function n(t,e,i){var r=e-t;return Gt(t)?nl(t,n(0,t.length),e):Ti(i,function(s){return(r+(s-t)%r)%r+t})},fh=function n(t,e,i){var r=e-t,s=r*2;return Gt(t)?nl(t,n(0,t.length-1),e):Ti(i,function(o){return o=(s+(o-t)%s)%s||0,t+(o>r?s-o:o)})},Dr=function(t){return t.replace($c,function(e){var i=e.indexOf(\"[\")+1,r=e.substring(i||7,i?e.indexOf(\"]\"):e.length-1).split(jc);return rl(i?r:+r[0],i?0:+r[1],+r[2]||1e-5)})},sl=function(t,e,i,r,s){var o=e-t,a=r-i;return Ti(s,function(l){return i+((l-t)/o*a||0)})},dh=function n(t,e,i,r){var s=isNaN(t+e)?0:function(h){return(1-h)*t+h*e};if(!s){var o=kt(t),a={},l,u,c,f,d;if(i===!0&&(r=1)&&(i=null),o)t={p:t},e={p:e};else if(Gt(t)&&!Gt(e)){for(c=[],f=t.length,d=f-2,u=1;u<f;u++)c.push(n(t[u-1],t[u]));f--,s=function(_){_*=f;var p=Math.min(d,~~_);return c[p](_-p)},i=e}else r||(t=pr(Gt(t)?[]:{},t));if(!c){for(l in e)go.call(a,t,l,\"get\",e[l]);s=function(_){return Eo(_,a)||(o?t.p:t)}}}return Ti(i,s)},La=function(t,e,i){var r=t.labels,s=Pe,o,a,l;for(o in r)a=r[o]-e,a<0==!!i&&a&&s>(a=Math.abs(a))&&(l=o,s=a);return l},Ee=function(t,e,i){var r=t.vars,s=r[e],o=ct,a=t._ctx,l,u,c;if(s)return l=r[e+\"Params\"],u=r.callbackScope||t,i&&wi.length&&$n(),a&&(ct=a),c=l?s.apply(u,l):s.call(u),ct=o,c},Wr=function(t){return Si(t),t.scrollTrigger&&t.scrollTrigger.kill(!!Wt),t.progress()<1&&Ee(t,\"onInterrupt\"),t},fr,ol=[],al=function(t){if(t)if(t=!t.name&&t.default||t,so()||t.headless){var e=t.name,i=Dt(t),r=e&&!i&&t.init?function(){this._props=[]}:t,s={init:Xr,render:Eo,add:go,kill:Ah,modifier:Fh,rawVars:0},o={targetTest:0,get:0,getSetter:ts,aliases:{},register:0};if(gr(),t!==r){if(pe[e])return;Ce(r,Ce(jn(t,s),o)),pr(r.prototype,pr(s,jn(t,o))),pe[r.prop=e]=r,t.targetTest&&(Vn.push(r),uo[e]=1),e=(e===\"css\"?\"CSS\":e.charAt(0).toUpperCase()+e.substr(1))+\"Plugin\"}Ya(e,r),t.register&&t.register(Kt,r,se)}else ol.push(t)},ot=255,Vr={aqua:[0,ot,ot],lime:[0,ot,0],silver:[192,192,192],black:[0,0,0],maroon:[128,0,0],teal:[0,128,128],blue:[0,0,ot],navy:[0,0,128],white:[ot,ot,ot],olive:[128,128,0],yellow:[ot,ot,0],orange:[ot,165,0],gray:[128,128,128],purple:[128,0,128],green:[0,128,0],red:[ot,0,0],pink:[ot,192,203],cyan:[0,ot,ot],transparent:[ot,ot,ot,0]},Us=function(t,e,i){return t+=t<0?1:t>1?-1:0,(t*6<1?e+(i-e)*t*6:t<.5?i:t*3<2?e+(i-e)*(2/3-t)*6:e)*ot+.5|0},ll=function(t,e,i){var r=t?li(t)?[t>>16,t>>8&ot,t&ot]:0:Vr.black,s,o,a,l,u,c,f,d,h,_;if(!r){if(t.substr(-1)===\",\"&&(t=t.substr(0,t.length-1)),Vr[t])r=Vr[t];else if(t.charAt(0)===\"#\"){if(t.length<6&&(s=t.charAt(1),o=t.charAt(2),a=t.charAt(3),t=\"#\"+s+s+o+o+a+a+(t.length===5?t.charAt(4)+t.charAt(4):\"\")),t.length===9)return r=parseInt(t.substr(1,6),16),[r>>16,r>>8&ot,r&ot,parseInt(t.substr(7),16)/255];t=parseInt(t.substr(1),16),r=[t>>16,t>>8&ot,t&ot]}else if(t.substr(0,3)===\"hsl\"){if(r=_=t.match(ka),!e)l=+r[0]%360/360,u=+r[1]/100,c=+r[2]/100,o=c<=.5?c*(u+1):c+u-c*u,s=c*2-o,r.length>3&&(r[3]*=1),r[0]=Us(l+1/3,s,o),r[1]=Us(l,s,o),r[2]=Us(l-1/3,s,o);else if(~t.indexOf(\"=\"))return r=t.match(oo),i&&r.length<4&&(r[3]=1),r}else r=t.match(ka)||Vr.transparent;r=r.map(Number)}return e&&!_&&(s=r[0]/ot,o=r[1]/ot,a=r[2]/ot,f=Math.max(s,o,a),d=Math.min(s,o,a),c=(f+d)/2,f===d?l=u=0:(h=f-d,u=c>.5?h/(2-f-d):h/(f+d),l=f===s?(o-a)/h+(o<a?6:0):f===o?(a-s)/h+2:(s-o)/h+4,l*=60),r[0]=~~(l+.5),r[1]=~~(u*100+.5),r[2]=~~(c*100+.5)),i&&r.length<4&&(r[3]=1),r},ul=function(t){var e=[],i=[],r=-1;return t.split(ai).forEach(function(s){var o=s.match(Yi)||[];e.push.apply(e,o),i.push(r+=o.length+1)}),e.c=i,e},Ba=function(t,e,i){var r=\"\",s=(t+r).match(ai),o=e?\"hsla(\":\"rgba(\",a=0,l,u,c,f;if(!s)return t;if(s=s.map(function(d){return(d=ll(d,e,1))&&o+(e?d[0]+\",\"+d[1]+\"%,\"+d[2]+\"%,\"+d[3]:d.join(\",\"))+\")\"}),i&&(c=ul(t),l=i.c,l.join(r)!==c.c.join(r)))for(u=t.replace(ai,\"1\").split(Yi),f=u.length-1;a<f;a++)r+=u[a]+(~l.indexOf(a)?s.shift()||o+\"0,0,0,0)\":(c.length?c:s.length?s:i).shift());if(!u)for(u=t.split(ai),f=u.length-1;a<f;a++)r+=u[a]+s[a];return r+u[f]},ai=function(){var n=\"(?:\\\\b(?:(?:rgb|rgba|hsl|hsla)\\\\(.+?\\\\))|\\\\B#(?:[0-9a-f]{3,4}){1,2}\\\\b\",t;for(t in Vr)n+=\"|\"+t+\"\\\\b\";return new RegExp(n+\")\",\"gi\")}(),ph=/hsl[a]?\\(/,_o=function(t){var e=t.join(\" \"),i;if(ai.lastIndex=0,ai.test(e))return i=ph.test(e),t[1]=Ba(t[1],i),t[0]=Ba(t[0],i,ul(t[1])),!0},qr,_e=function(){var n=Date.now,t=500,e=33,i=n(),r=i,s=1e3/240,o=s,a=[],l,u,c,f,d,h,_=function p(g){var E=n()-r,y=g===!0,S,D,v,T;if((E>t||E<0)&&(i+=E-e),r+=E,v=r-i,S=v-o,(S>0||y)&&(T=++f.frame,d=v-f.time*1e3,f.time=v=v/1e3,o+=S+(S>=s?4:s-S),D=1),y||(l=u(p)),D)for(h=0;h<a.length;h++)a[h](v,d,T,g)};return f={time:0,frame:0,tick:function(){_(!0)},deltaRatio:function(g){return d/(1e3/(g||60))},wake:function(){Va&&(!Gs&&so()&&(Ge=Gs=window,lo=Ge.document||{},we.gsap=Kt,(Ge.gsapVersions||(Ge.gsapVersions=[])).push(Kt.version),Ua(Yn||Ge.GreenSockGlobals||!Ge.gsap&&Ge||{}),ol.forEach(al)),c=typeof requestAnimationFrame!=\"undefined\"&&requestAnimationFrame,l&&f.sleep(),u=c||function(g){return setTimeout(g,o-f.time*1e3+1|0)},qr=1,_(2))},sleep:function(){(c?cancelAnimationFrame:clearTimeout)(l),qr=0,u=Xr},lagSmoothing:function(g,E){t=g||1/0,e=Math.min(E||33,t)},fps:function(g){s=1e3/(g||240),o=f.time*1e3+s},add:function(g,E,y){var S=E?function(D,v,T,b){g(D,v,T,b),f.remove(S)}:g;return f.remove(g),a[y?\"unshift\":\"push\"](S),gr(),S},remove:function(g,E){~(E=a.indexOf(g))&&a.splice(E,1)&&h>=E&&h--},_listeners:a},f}(),gr=function(){return!qr&&_e.wake()},tt={},_h=/^[\\d.\\-M][\\d.\\-,\\s]/,mh=/[\"']/g,gh=function(t){for(var e={},i=t.substr(1,t.length-3).split(\":\"),r=i[0],s=1,o=i.length,a,l,u;s<o;s++)l=i[s],a=s!==o-1?l.lastIndexOf(\",\"):l.length,u=l.substr(0,a),e[r]=isNaN(u)?u.replace(mh,\"\").trim():+u,r=l.substr(a+1).trim();return e},Dh=function(t){var e=t.indexOf(\"(\")+1,i=t.indexOf(\")\"),r=t.indexOf(\"(\",e);return t.substring(e,~r&&r<i?t.indexOf(\")\",i+1):i)},vh=function(t){var e=(t+\"\").split(\"(\"),i=tt[e[0]];return i&&e.length>1&&i.config?i.config.apply(null,~t.indexOf(\"{\")?[gh(e[1])]:Dh(t).split(\",\").map(Xa)):tt._CE&&_h.test(t)?tt._CE(\"\",t):i},cl=function(t){return function(e){return 1-t(1-e)}},hl=function n(t,e){for(var i=t._first,r;i;)i instanceof Ht?n(i,e):i.vars.yoyoEase&&(!i._yoyo||!i._repeat)&&i._yoyo!==e&&(i.timeline?n(i.timeline,e):(r=i._ease,i._ease=i._yEase,i._yEase=r,i._yoyo=e)),i=i._next},Vi=function(t,e){return t&&(Dt(t)?t:tt[t]||vh(t))||e},ji=function(t,e,i,r){i===void 0&&(i=function(l){return 1-e(1-l)}),r===void 0&&(r=function(l){return l<.5?e(l*2)/2:1-e((1-l)*2)/2});var s={easeIn:e,easeOut:i,easeInOut:r},o;return ne(t,function(a){tt[a]=we[a]=s,tt[o=a.toLowerCase()]=i;for(var l in s)tt[o+(l===\"easeIn\"?\".in\":l===\"easeOut\"?\".out\":\".inOut\")]=tt[a+\".\"+l]=s[l]}),s},fl=function(t){return function(e){return e<.5?(1-t(1-e*2))/2:.5+t((e-.5)*2)/2}},Ys=function n(t,e,i){var r=e>=1?e:1,s=(i||(t?.3:.45))/(e<1?e:1),o=s/qs*(Math.asin(1/r)||0),a=function(c){return c===1?1:r*Math.pow(2,-10*c)*Yc((c-o)*s)+1},l=t===\"out\"?a:t===\"in\"?function(u){return 1-a(1-u)}:fl(a);return s=qs/s,l.config=function(u,c){return n(t,u,c)},l},$s=function n(t,e){e===void 0&&(e=1.70158);var i=function(o){return o?--o*o*((e+1)*o+e)+1:0},r=t===\"out\"?i:t===\"in\"?function(s){return 1-i(1-s)}:fl(i);return r.config=function(s){return n(t,s)},r};ne(\"Linear,Quad,Cubic,Quart,Quint,Strong\",function(n,t){var e=t<5?t+1:t;ji(n+\",Power\"+(e-1),t?function(i){return Math.pow(i,e)}:function(i){return i},function(i){return 1-Math.pow(1-i,e)},function(i){return i<.5?Math.pow(i*2,e)/2:1-Math.pow((1-i)*2,e)/2})});tt.Linear.easeNone=tt.none=tt.Linear.easeIn;ji(\"Elastic\",Ys(\"in\"),Ys(\"out\"),Ys());(function(n,t){var e=1/t,i=2*e,r=2.5*e,s=function(a){return a<e?n*a*a:a<i?n*Math.pow(a-1.5/t,2)+.75:a<r?n*(a-=2.25/t)*a+.9375:n*Math.pow(a-2.625/t,2)+.984375};ji(\"Bounce\",function(o){return 1-s(1-o)},s)})(7.5625,2.75);ji(\"Expo\",function(n){return Math.pow(2,10*(n-1))*n+n*n*n*n*n*n*(1-n)});ji(\"Circ\",function(n){return-(Ha(1-n*n)-1)});ji(\"Sine\",function(n){return n===1?1:-Uc(n*Wc)+1});ji(\"Back\",$s(\"in\"),$s(\"out\"),$s());tt.SteppedEase=tt.steps=we.SteppedEase={config:function(t,e){t===void 0&&(t=1);var i=1/t,r=t+(e?0:1),s=e?1:0,o=1-at;return function(a){return((r*Kr(0,o,a)|0)+s)*i}}};dr.ease=tt[\"quad.out\"];ne(\"onComplete,onUpdate,onStart,onRepeat,onReverseComplete,onInterrupt\",function(n){return co+=n+\",\"+n+\"Params,\"});var mo=function(t,e){this.id=Vc++,t._gsap=this,this.target=t,this.harness=e,this.get=e?e.get:fo,this.set=e?e.getSetter:ts},Gr=function(){function n(e){this.vars=e,this._delay=+e.delay||0,(this._repeat=e.repeat===1/0?-2:e.repeat||0)&&(this._rDelay=e.repeatDelay||0,this._yoyo=!!e.yoyo||!!e.yoyoEase),this._ts=1,mr(this,+e.duration,1,1),this.data=e.data,ct&&(this._ctx=ct,ct.data.push(this)),qr||_e.wake()}var t=n.prototype;return t.delay=function(i){return i||i===0?(this.parent&&this.parent.smoothChildTiming&&this.startTime(this._start+i-this._delay),this._delay=i,this):this._delay},t.duration=function(i){return arguments.length?this.totalDuration(this._repeat>0?i+(i+this._rDelay)*this._repeat:i):this.totalDuration()&&this._dur},t.totalDuration=function(i){return arguments.length?(this._dirty=0,mr(this,this._repeat<0?i:(i-this._repeat*this._rDelay)/(this._repeat+1))):this._tDur},t.totalTime=function(i,r){if(gr(),!arguments.length)return this._tTime;var s=this._dp;if(s&&s.smoothChildTiming&&this._ts){for(Jn(this,i),!s._dp||s.parent||Ka(s,this);s&&s.parent;)s.parent._time!==s._start+(s._ts>=0?s._tTime/s._ts:(s.totalDuration()-s._tTime)/-s._ts)&&s.totalTime(s._tTime,!0),s=s.parent;!this.parent&&this._dp.autoRemoveChildren&&(this._ts>0&&i<this._tDur||this._ts<0&&i>0||!this._tDur&&!i)&&Ke(this._dp,this,this._start-this._delay)}return(this._tTime!==i||!this._dur&&!r||this._initted&&Math.abs(this._zTime)===at||!this._initted&&this._dur&&i||!i&&!this._initted&&(this.add||this._ptLookup))&&(this._ts||(this._pTime=i),ja(this,i,r)),this},t.time=function(i,r){return arguments.length?this.totalTime(Math.min(this.totalDuration(),i+Ma(this))%(this._dur+this._rDelay)||(i?this._dur:0),r):this._time},t.totalProgress=function(i,r){return arguments.length?this.totalTime(this.totalDuration()*i,r):this.totalDuration()?Math.min(1,this._tTime/this._tDur):this.rawTime()>=0&&this._initted?1:0},t.progress=function(i,r){return arguments.length?this.totalTime(this.duration()*(this._yoyo&&!(this.iteration()&1)?1-i:i)+Ma(this),r):this.duration()?Math.min(1,this._time/this._dur):this.rawTime()>0?1:0},t.iteration=function(i,r){var s=this.duration()+this._rDelay;return arguments.length?this.totalTime(this._time+(i-1)*s,r):this._repeat?_r(this._tTime,s)+1:1},t.timeScale=function(i,r){if(!arguments.length)return this._rts===-at?0:this._rts;if(this._rts===i)return this;var s=this.parent&&this._ts?Xn(this.parent._time,this):this._tTime;return this._rts=+i||0,this._ts=this._ps||i===-at?0:this._rts,this.totalTime(Kr(-Math.abs(this._delay),this.totalDuration(),s),r!==!1),Zn(this),th(this)},t.paused=function(i){return arguments.length?(this._ps!==i&&(this._ps=i,i?(this._pTime=this._tTime||Math.max(-this._delay,this.rawTime()),this._ts=this._act=0):(gr(),this._ts=this._rts,this.totalTime(this.parent&&!this.parent.smoothChildTiming?this.rawTime():this._tTime||this._pTime,this.progress()===1&&Math.abs(this._zTime)!==at&&(this._tTime-=at)))),this):this._ps},t.startTime=function(i){if(arguments.length){this._start=ft(i);var r=this.parent||this._dp;return r&&(r._sort||!this.parent)&&Ke(r,this,this._start-this._delay),this}return this._start},t.endTime=function(i){return this._start+(me(i)?this.totalDuration():this.duration())/Math.abs(this._ts||1)},t.rawTime=function(i){var r=this.parent||this._dp;return r?i&&(!this._ts||this._repeat&&this._time&&this.totalProgress()<1)?this._tTime%(this._dur+this._rDelay):this._ts?Xn(r.rawTime(i),this):this._tTime:this._tTime},t.revert=function(i){i===void 0&&(i=Kc);var r=Wt;return Wt=i,po(this)&&(this.timeline&&this.timeline.revert(i),this.totalTime(-.01,i.suppressEvents)),this.data!==\"nested\"&&i.kill!==!1&&this.kill(),Wt=r,this},t.globalTime=function(i){for(var r=this,s=arguments.length?i:r.rawTime();r;)s=r._start+s/(Math.abs(r._ts)||1),r=r._dp;return!this.parent&&this._sat?this._sat.globalTime(i):s},t.repeat=function(i){return arguments.length?(this._repeat=i===1/0?-2:i,Ia(this)):this._repeat===-2?1/0:this._repeat},t.repeatDelay=function(i){if(arguments.length){var r=this._time;return this._rDelay=i,Ia(this),r?this.time(r):this}return this._rDelay},t.yoyo=function(i){return arguments.length?(this._yoyo=i,this):this._yoyo},t.seek=function(i,r){return this.totalTime(ke(this,i),me(r))},t.restart=function(i,r){return this.play().totalTime(i?-this._delay:0,me(r)),this._dur||(this._zTime=-at),this},t.play=function(i,r){return i!=null&&this.seek(i,r),this.reversed(!1).paused(!1)},t.reverse=function(i,r){return i!=null&&this.seek(i||this.totalDuration(),r),this.reversed(!0).paused(!1)},t.pause=function(i,r){return i!=null&&this.seek(i,r),this.paused(!0)},t.resume=function(){return this.paused(!1)},t.reversed=function(i){return arguments.length?(!!i!==this.reversed()&&this.timeScale(-this._rts||(i?-at:0)),this):this._rts<0},t.invalidate=function(){return this._initted=this._act=0,this._zTime=-at,this},t.isActive=function(){var i=this.parent||this._dp,r=this._start,s;return!!(!i||this._ts&&this._initted&&i.isActive()&&(s=i.rawTime(!0))>=r&&s<this.endTime(!0)-at)},t.eventCallback=function(i,r,s){var o=this.vars;return arguments.length>1?(r?(o[i]=r,s&&(o[i+\"Params\"]=s),i===\"onUpdate\"&&(this._onUpdate=r)):delete o[i],this):o[i]},t.then=function(i){var r=this,s=r._prom;return new Promise(function(o){var a=Dt(i)?i:qa,l=function(){var c=r.then;r.then=null,s&&s(),Dt(a)&&(a=a(r))&&(a.then||a===r)&&(r.then=c),o(a),r.then=c};r._initted&&r.totalProgress()===1&&r._ts>=0||!r._tTime&&r._ts<0?l():r._prom=l})},t.kill=function(){Wr(this)},n}();Ce(Gr.prototype,{_time:0,_start:0,_end:0,_tTime:0,_tDur:0,_dirty:0,_repeat:0,_yoyo:!1,parent:null,_initted:!1,_rDelay:0,_ts:1,_dp:0,ratio:0,_zTime:-at,_prom:0,_ps:!1,_rts:1});var Ht=function(n){Na(t,n);function t(i,r){var s;return i===void 0&&(i={}),s=n.call(this,i)||this,s.labels={},s.smoothChildTiming=!!i.smoothChildTiming,s.autoRemoveChildren=!!i.autoRemoveChildren,s._sort=me(i.sortChildren),dt&&Ke(i.parent||dt,oi(s),r),i.reversed&&s.reverse(),i.paused&&s.paused(!0),i.scrollTrigger&&Qa(oi(s),i.scrollTrigger),s}var e=t.prototype;return e.to=function(r,s,o){return Yr(0,arguments,this),this},e.from=function(r,s,o){return Yr(1,arguments,this),this},e.fromTo=function(r,s,o,a){return Yr(2,arguments,this),this},e.set=function(r,s,o){return s.duration=0,s.parent=this,Ur(s).repeatDelay||(s.repeat=0),s.immediateRender=!!s.immediateRender,new Ct(r,s,ke(this,o),1),this},e.call=function(r,s,o){return Ke(this,Ct.delayedCall(0,r,s),o)},e.staggerTo=function(r,s,o,a,l,u,c){return o.duration=s,o.stagger=o.stagger||a,o.onComplete=u,o.onCompleteParams=c,o.parent=this,new Ct(r,o,ke(this,l)),this},e.staggerFrom=function(r,s,o,a,l,u,c){return o.runBackwards=1,Ur(o).immediateRender=me(o.immediateRender),this.staggerTo(r,s,o,a,l,u,c)},e.staggerFromTo=function(r,s,o,a,l,u,c,f){return a.startAt=o,Ur(a).immediateRender=me(a.immediateRender),this.staggerTo(r,s,a,l,u,c,f)},e.render=function(r,s,o){var a=this._time,l=this._dirty?this.totalDuration():this._tDur,u=this._dur,c=r<=0?0:ft(r),f=this._zTime<0!=r<0&&(this._initted||!u),d,h,_,p,g,E,y,S,D,v,T,b;if(this!==dt&&c>l&&r>=0&&(c=l),c!==this._tTime||o||f){if(a!==this._time&&u&&(c+=this._time-a,r+=this._time-a),d=c,D=this._start,S=this._ts,E=!S,f&&(u||(a=this._zTime),(r||!s)&&(this._zTime=r)),this._repeat){if(T=this._yoyo,g=u+this._rDelay,this._repeat<-1&&r<0)return this.totalTime(g*100+r,s,o);if(d=ft(c%g),c===l?(p=this._repeat,d=u):(v=ft(c/g),p=~~v,p&&p===v&&(d=u,p--),d>u&&(d=u)),v=_r(this._tTime,g),!a&&this._tTime&&v!==p&&this._tTime-v*g-this._dur<=0&&(v=p),T&&p&1&&(d=u-d,b=1),p!==v&&!this._lock){var x=T&&v&1,w=x===(T&&p&1);if(p<v&&(x=!x),a=x?0:c%u?u:c,this._lock=1,this.render(a||(b?0:ft(p*g)),s,!u)._lock=0,this._tTime=c,!s&&this.parent&&Ee(this,\"onRepeat\"),this.vars.repeatRefresh&&!b&&(this.invalidate()._lock=1,v=p),a&&a!==this._time||E!==!this._ts||this.vars.onRepeat&&!this.parent&&!this._act)return this;if(u=this._dur,l=this._tDur,w&&(this._lock=2,a=x?u:-1e-4,this.render(a,!0),this.vars.repeatRefresh&&!b&&this.invalidate()),this._lock=0,!this._ts&&!E)return this;hl(this,b)}}if(this._hasPause&&!this._forcing&&this._lock<2&&(y=nh(this,ft(a),ft(d)),y&&(c-=d-(d=y._start))),this._tTime=c,this._time=d,this._act=!S,this._initted||(this._onUpdate=this.vars.onUpdate,this._initted=1,this._zTime=r,a=0),!a&&c&&u&&!s&&!v&&(Ee(this,\"onStart\"),this._tTime!==c))return this;if(d>=a&&r>=0)for(h=this._first;h;){if(_=h._next,(h._act||d>=h._start)&&h._ts&&y!==h){if(h.parent!==this)return this.render(r,s,o);if(h.render(h._ts>0?(d-h._start)*h._ts:(h._dirty?h.totalDuration():h._tDur)+(d-h._start)*h._ts,s,o),d!==this._time||!this._ts&&!E){y=0,_&&(c+=this._zTime=-at);break}}h=_}else{h=this._last;for(var F=r<0?r:d;h;){if(_=h._prev,(h._act||F<=h._end)&&h._ts&&y!==h){if(h.parent!==this)return this.render(r,s,o);if(h.render(h._ts>0?(F-h._start)*h._ts:(h._dirty?h.totalDuration():h._tDur)+(F-h._start)*h._ts,s,o||Wt&&po(h)),d!==this._time||!this._ts&&!E){y=0,_&&(c+=this._zTime=F?-at:at);break}}h=_}}if(y&&!s&&(this.pause(),y.render(d>=a?0:-at)._zTime=d>=a?1:-1,this._ts))return this._start=D,Zn(this),this.render(r,s,o);this._onUpdate&&!s&&Ee(this,\"onUpdate\",!0),(c===l&&this._tTime>=this.totalDuration()||!c&&a)&&(D===this._start||Math.abs(S)!==Math.abs(this._ts))&&(this._lock||((r||!u)&&(c===l&&this._ts>0||!c&&this._ts<0)&&Si(this,1),!s&&!(r<0&&!a)&&(c||a||!l)&&(Ee(this,c===l&&r>=0?\"onComplete\":\"onReverseComplete\",!0),this._prom&&!(c<l&&this.timeScale()>0)&&this._prom())))}return this},e.add=function(r,s){var o=this;if(li(s)||(s=ke(this,s,r)),!(r instanceof Gr)){if(Gt(r))return r.forEach(function(a){return o.add(a,s)}),this;if(kt(r))return this.addLabel(r,s);if(Dt(r))r=Ct.delayedCall(0,r);else return this}return this!==r?Ke(this,r,s):this},e.getChildren=function(r,s,o,a){r===void 0&&(r=!0),s===void 0&&(s=!0),o===void 0&&(o=!0),a===void 0&&(a=-Pe);for(var l=[],u=this._first;u;)u._start>=a&&(u instanceof Ct?s&&l.push(u):(o&&l.push(u),r&&l.push.apply(l,u.getChildren(!0,s,o)))),u=u._next;return l},e.getById=function(r){for(var s=this.getChildren(1,1,1),o=s.length;o--;)if(s[o].vars.id===r)return s[o]},e.remove=function(r){return kt(r)?this.removeLabel(r):Dt(r)?this.killTweensOf(r):(r.parent===this&&Qn(this,r),r===this._recent&&(this._recent=this._last),Wi(this))},e.totalTime=function(r,s){return arguments.length?(this._forcing=1,!this._dp&&this._ts&&(this._start=ft(_e.time-(this._ts>0?r/this._ts:(this.totalDuration()-r)/-this._ts))),n.prototype.totalTime.call(this,r,s),this._forcing=0,this):this._tTime},e.addLabel=function(r,s){return this.labels[r]=ke(this,s),this},e.removeLabel=function(r){return delete this.labels[r],this},e.addPause=function(r,s,o){var a=Ct.delayedCall(0,s||Xr,o);return a.data=\"isPause\",this._hasPause=1,Ke(this,a,ke(this,r))},e.removePause=function(r){var s=this._first;for(r=ke(this,r);s;)s._start===r&&s.data===\"isPause\"&&Si(s),s=s._next},e.killTweensOf=function(r,s,o){for(var a=this.getTweensOf(r,o),l=a.length;l--;)Ei!==a[l]&&a[l].kill(r,s);return this},e.getTweensOf=function(r,s){for(var o=[],a=Re(r),l=this._first,u=li(s),c;l;)l instanceof Ct?Qc(l._targets,a)&&(u?(!Ei||l._initted&&l._ts)&&l.globalTime(0)<=s&&l.globalTime(l.totalDuration())>s:!s||l.isActive())&&o.push(l):(c=l.getTweensOf(a,s)).length&&o.push.apply(o,c),l=l._next;return o},e.tweenTo=function(r,s){s=s||{};var o=this,a=ke(o,r),l=s,u=l.startAt,c=l.onStart,f=l.onStartParams,d=l.immediateRender,h,_=Ct.to(o,Ce({ease:s.ease||\"none\",lazy:!1,immediateRender:!1,time:a,overwrite:\"auto\",duration:s.duration||Math.abs((a-(u&&\"time\"in u?u.time:o._time))/o.timeScale())||at,onStart:function(){if(o.pause(),!h){var g=s.duration||Math.abs((a-(u&&\"time\"in u?u.time:o._time))/o.timeScale());_._dur!==g&&mr(_,g,0,1).render(_._time,!0,!0),h=1}c&&c.apply(_,f||[])}},s));return d?_.render(0):_},e.tweenFromTo=function(r,s,o){return this.tweenTo(s,Ce({startAt:{time:ke(this,r)}},o))},e.recent=function(){return this._recent},e.nextLabel=function(r){return r===void 0&&(r=this._time),La(this,ke(this,r))},e.previousLabel=function(r){return r===void 0&&(r=this._time),La(this,ke(this,r),1)},e.currentLabel=function(r){return arguments.length?this.seek(r,!0):this.previousLabel(this._time+at)},e.shiftChildren=function(r,s,o){o===void 0&&(o=0);var a=this._first,l=this.labels,u;for(r=ft(r);a;)a._start>=o&&(a._start+=r,a._end+=r),a=a._next;if(s)for(u in l)l[u]>=o&&(l[u]+=r);return Wi(this)},e.invalidate=function(r){var s=this._first;for(this._lock=0;s;)s.invalidate(r),s=s._next;return n.prototype.invalidate.call(this,r)},e.clear=function(r){r===void 0&&(r=!0);for(var s=this._first,o;s;)o=s._next,this.remove(s),s=o;return this._dp&&(this._time=this._tTime=this._pTime=0),r&&(this.labels={}),Wi(this)},e.totalDuration=function(r){var s=0,o=this,a=o._last,l=Pe,u,c,f;if(arguments.length)return o.timeScale((o._repeat<0?o.duration():o.totalDuration())/(o.reversed()?-r:r));if(o._dirty){for(f=o.parent;a;)u=a._prev,a._dirty&&a.totalDuration(),c=a._start,c>l&&o._sort&&a._ts&&!o._lock?(o._lock=1,Ke(o,a,c-a._delay,1)._lock=0):l=c,c<0&&a._ts&&(s-=c,(!f&&!o._dp||f&&f.smoothChildTiming)&&(o._start+=ft(c/o._ts),o._time-=c,o._tTime-=c),o.shiftChildren(-c,!1,-1/0),l=0),a._end>s&&a._ts&&(s=a._end),a=u;mr(o,o===dt&&o._time>s?o._time:s,1,1),o._dirty=0}return o._tDur},t.updateRoot=function(r){if(dt._ts&&(ja(dt,Xn(r,dt)),$a=_e.frame),_e.frame>=Pa){Pa+=ge.autoSleep||120;var s=dt._first;if((!s||!s._ts)&&ge.autoSleep&&_e._listeners.length<2){for(;s&&!s._ts;)s=s._next;s||_e.sleep()}}},t}(Gr);Ce(Ht.prototype,{_lock:0,_hasPause:0,_forcing:0});var yh=function(t,e,i,r,s,o,a){var l=new se(this._pt,t,e,0,1,bo,null,s),u=0,c=0,f,d,h,_,p,g,E,y;for(l.b=i,l.e=r,i+=\"\",r+=\"\",(E=~r.indexOf(\"random(\"))&&(r=Dr(r)),o&&(y=[i,r],o(y,t,e),i=y[0],r=y[1]),d=i.match(Ws)||[];f=Ws.exec(r);)_=f[0],p=r.substring(u,f.index),h?h=(h+1)%5:p.substr(-5)===\"rgba(\"&&(h=1),_!==d[c++]&&(g=parseFloat(d[c-1])||0,l._pt={_next:l._pt,p:p||c===1?p:\",\",s:g,c:_.charAt(1)===\"=\"?$i(g,_)-g:parseFloat(_)-g,m:h&&h<4?Math.round:0},u=Ws.lastIndex);return l.c=u<r.length?r.substring(u,r.length):\"\",l.fp=a,(ao.test(r)||E)&&(l.e=0),this._pt=l,l},go=function(t,e,i,r,s,o,a,l,u,c){Dt(r)&&(r=r(s||0,t,o));var f=t[e],d=i!==\"get\"?i:Dt(f)?u?t[e.indexOf(\"set\")||!Dt(t[\"get\"+e.substr(3)])?e:\"get\"+e.substr(3)](u):t[e]():f,h=Dt(f)?u?Sh:_l:yo,_;if(kt(r)&&(~r.indexOf(\"random(\")&&(r=Dr(r)),r.charAt(1)===\"=\"&&(_=$i(d,r)+(Vt(d)||0),(_||_===0)&&(r=_))),!c||d!==r||io)return!isNaN(d*r)&&r!==\"\"?(_=new se(this._pt,t,e,+d||0,r-(d||0),typeof f==\"boolean\"?xh:ml,0,h),u&&(_.fp=u),a&&_.modifier(a,this,t),this._pt=_):(!f&&!(e in t)&&Kn(e,r),yh.call(this,t,e,d,r,h,l||ge.stringFilter,u))},bh=function(t,e,i,r,s){if(Dt(t)&&(t=$r(t,s,e,i,r)),!Qe(t)||t.style&&t.nodeType||Gt(t)||Wa(t))return kt(t)?$r(t,s,e,i,r):t;var o={},a;for(a in t)o[a]=$r(t[a],s,e,i,r);return o},Do=function(t,e,i,r,s,o){var a,l,u,c;if(pe[t]&&(a=new pe[t]).init(s,a.rawVars?e[t]:bh(e[t],r,s,o,i),i,r,o)!==!1&&(i._pt=l=new se(i._pt,s,t,0,1,a.render,a,0,a.priority),i!==fr))for(u=i._ptLookup[i._targets.indexOf(s)],c=a._props.length;c--;)u[a._props[c]]=l;return a},Ei,io,vo=function n(t,e,i){var r=t.vars,s=r.ease,o=r.startAt,a=r.immediateRender,l=r.lazy,u=r.onUpdate,c=r.runBackwards,f=r.yoyoEase,d=r.keyframes,h=r.autoRevert,_=t._dur,p=t._startAt,g=t._targets,E=t.parent,y=E&&E.data===\"nested\"?E.vars.targets:g,S=t._overwrite===\"auto\"&&!no,D=t.timeline,v,T,b,x,w,F,B,A,P,L,M,H,R;if(D&&(!d||!s)&&(s=\"none\"),t._ease=Vi(s,dr.ease),t._yEase=f?cl(Vi(f===!0?s:f,dr.ease)):0,f&&t._yoyo&&!t._repeat&&(f=t._yEase,t._yEase=t._ease,t._ease=f),t._from=!D&&!!r.runBackwards,!D||d&&!r.stagger){if(A=g[0]?Ci(g[0]).harness:0,H=A&&r[A.prop],v=jn(r,uo),p&&(p._zTime<0&&p.progress(1),e<0&&c&&a&&!h?p.render(-1,!0):p.revert(c&&_?Wn:Gc),p._lazy=0),o){if(Si(t._startAt=Ct.set(g,Ce({data:\"isStart\",overwrite:!1,parent:E,immediateRender:!0,lazy:!p&&me(l),startAt:null,delay:0,onUpdate:u&&function(){return Ee(t,\"onUpdate\")},stagger:0},o))),t._startAt._dp=0,t._startAt._sat=t,e<0&&(Wt||!a&&!h)&&t._startAt.revert(Wn),a&&_&&e<=0&&i<=0){e&&(t._zTime=e);return}}else if(c&&_&&!p){if(e&&(a=!1),b=Ce({overwrite:!1,data:\"isFromStart\",lazy:a&&!p&&me(l),immediateRender:a,stagger:0,parent:E},v),H&&(b[A.prop]=H),Si(t._startAt=Ct.set(g,b)),t._startAt._dp=0,t._startAt._sat=t,e<0&&(Wt?t._startAt.revert(Wn):t._startAt.render(-1,!0)),t._zTime=e,!a)n(t._startAt,at,at);else if(!e)return}for(t._pt=t._ptCache=0,l=_&&me(l)||l&&!_,T=0;T<g.length;T++){if(w=g[T],B=w._gsap||ho(g)[T]._gsap,t._ptLookup[T]=L={},Ks[B.id]&&wi.length&&$n(),M=y===g?T:y.indexOf(w),A&&(P=new A).init(w,H||v,t,M,y)!==!1&&(t._pt=x=new se(t._pt,w,P.name,0,1,P.render,P,0,P.priority),P._props.forEach(function(z){L[z]=x}),P.priority&&(F=1)),!A||H)for(b in v)pe[b]&&(P=Do(b,v,t,M,w,y))?P.priority&&(F=1):L[b]=x=go.call(t,w,b,\"get\",v[b],M,y,0,r.stringFilter);t._op&&t._op[T]&&t.kill(w,t._op[T]),S&&t._pt&&(Ei=t,dt.killTweensOf(w,L,t.globalTime(e)),R=!t.parent,Ei=0),t._pt&&l&&(Ks[B.id]=1)}F&&wo(t),t._onInit&&t._onInit(t)}t._onUpdate=u,t._initted=(!t._op||t._pt)&&!R,d&&e<=0&&D.render(Pe,!0,!0)},Eh=function(t,e,i,r,s,o,a,l){var u=(t._pt&&t._ptCache||(t._ptCache={}))[e],c,f,d,h;if(!u)for(u=t._ptCache[e]=[],d=t._ptLookup,h=t._targets.length;h--;){if(c=d[h][e],c&&c.d&&c.d._pt)for(c=c.d._pt;c&&c.p!==e&&c.fp!==e;)c=c._next;if(!c)return io=1,t.vars[e]=\"+=0\",vo(t,a),io=0,l?jr(e+\" not eligible for reset\"):1;u.push(c)}for(h=u.length;h--;)f=u[h],c=f._pt||f,c.s=(r||r===0)&&!s?r:c.s+(r||0)+o*c.c,c.c=i-c.s,f.e&&(f.e=vt(i)+Vt(f.e)),f.b&&(f.b=c.s+Vt(f.b))},wh=function(t,e){var i=t[0]?Ci(t[0]).harness:0,r=i&&i.aliases,s,o,a,l;if(!r)return e;s=pr({},e);for(o in r)if(o in s)for(l=r[o].split(\",\"),a=l.length;a--;)s[l[a]]=s[o];return s},Ch=function(t,e,i,r){var s=e.ease||r||\"power1.inOut\",o,a;if(Gt(e))a=i[t]||(i[t]=[]),e.forEach(function(l,u){return a.push({t:u/(e.length-1)*100,v:l,e:s})});else for(o in e)a=i[o]||(i[o]=[]),o===\"ease\"||a.push({t:parseFloat(t),v:e[o],e:s})},$r=function(t,e,i,r,s){return Dt(t)?t.call(e,i,r,s):kt(t)&&~t.indexOf(\"random(\")?Dr(t):t},dl=co+\"repeat,repeatDelay,yoyo,repeatRefresh,yoyoEase,autoRevert\",pl={};ne(dl+\",id,stagger,delay,duration,paused,scrollTrigger\",function(n){return pl[n]=1});var Ct=function(n){Na(t,n);function t(i,r,s,o){var a;typeof r==\"number\"&&(s.duration=r,r=s,s=null),a=n.call(this,o?r:Ur(r))||this;var l=a.vars,u=l.duration,c=l.delay,f=l.immediateRender,d=l.stagger,h=l.overwrite,_=l.keyframes,p=l.defaults,g=l.scrollTrigger,E=l.yoyoEase,y=r.parent||dt,S=(Gt(i)||Wa(i)?li(i[0]):\"length\"in r)?[i]:Re(i),D,v,T,b,x,w,F,B;if(a._targets=S.length?ho(S):jr(\"GSAP target \"+i+\" not found. https://gsap.com\",!ge.nullTargetWarn)||[],a._ptLookup=[],a._overwrite=h,_||d||Hn(u)||Hn(c)){if(r=a.vars,D=a.timeline=new Ht({data:\"nested\",defaults:p||{},targets:y&&y.data===\"nested\"?y.vars.targets:S}),D.kill(),D.parent=D._dp=oi(a),D._start=0,d||Hn(u)||Hn(c)){if(b=S.length,F=d&&el(d),Qe(d))for(x in d)~dl.indexOf(x)&&(B||(B={}),B[x]=d[x]);for(v=0;v<b;v++)T=jn(r,pl),T.stagger=0,E&&(T.yoyoEase=E),B&&pr(T,B),w=S[v],T.duration=+$r(u,oi(a),v,w,S),T.delay=(+$r(c,oi(a),v,w,S)||0)-a._delay,!d&&b===1&&T.delay&&(a._delay=c=T.delay,a._start+=c,T.delay=0),D.to(w,T,F?F(v,w,S):0),D._ease=tt.none;D.duration()?u=c=0:a.timeline=0}else if(_){Ur(Ce(D.vars.defaults,{ease:\"none\"})),D._ease=Vi(_.ease||r.ease||\"none\");var A=0,P,L,M;if(Gt(_))_.forEach(function(H){return D.to(S,H,\">\")}),D.duration();else{T={};for(x in _)x===\"ease\"||x===\"easeEach\"||Ch(x,_[x],T,_.easeEach);for(x in T)for(P=T[x].sort(function(H,R){return H.t-R.t}),A=0,v=0;v<P.length;v++)L=P[v],M={ease:L.e,duration:(L.t-(v?P[v-1].t:0))/100*u},M[x]=L.v,D.to(S,M,A),A+=M.duration;D.duration()<u&&D.to({},{duration:u-D.duration()})}}u||a.duration(u=D.duration())}else a.timeline=0;return h===!0&&!no&&(Ei=oi(a),dt.killTweensOf(S),Ei=0),Ke(y,oi(a),s),r.reversed&&a.reverse(),r.paused&&a.paused(!0),(f||!u&&!_&&a._start===ft(y._time)&&me(f)&&eh(oi(a))&&y.data!==\"nested\")&&(a._tTime=-at,a.render(Math.max(0,-c)||0)),g&&Qa(oi(a),g),a}var e=t.prototype;return e.render=function(r,s,o){var a=this._time,l=this._tDur,u=this._dur,c=r<0,f=r>l-at&&!c?l:r<at?0:r,d,h,_,p,g,E,y,S,D;if(!u)rh(this,r,s,o);else if(f!==this._tTime||!r||o||!this._initted&&this._tTime||this._startAt&&this._zTime<0!==c||this._lazy){if(d=f,S=this.timeline,this._repeat){if(p=u+this._rDelay,this._repeat<-1&&c)return this.totalTime(p*100+r,s,o);if(d=ft(f%p),f===l?(_=this._repeat,d=u):(g=ft(f/p),_=~~g,_&&_===g?(d=u,_--):d>u&&(d=u)),E=this._yoyo&&_&1,E&&(D=this._yEase,d=u-d),g=_r(this._tTime,p),d===a&&!o&&this._initted&&_===g)return this._tTime=f,this;_!==g&&(S&&this._yEase&&hl(S,E),this.vars.repeatRefresh&&!E&&!this._lock&&d!==p&&this._initted&&(this._lock=o=1,this.render(ft(p*_),!0).invalidate()._lock=0))}if(!this._initted){if(Za(this,c?r:d,o,s,f))return this._tTime=0,this;if(a!==this._time&&!(o&&this.vars.repeatRefresh&&_!==g))return this;if(u!==this._dur)return this.render(r,s,o)}if(this._tTime=f,this._time=d,!this._act&&this._ts&&(this._act=1,this._lazy=0),this.ratio=y=(D||this._ease)(d/u),this._from&&(this.ratio=y=1-y),!a&&f&&!s&&!g&&(Ee(this,\"onStart\"),this._tTime!==f))return this;for(h=this._pt;h;)h.r(y,h.d),h=h._next;S&&S.render(r<0?r:S._dur*S._ease(d/this._dur),s,o)||this._startAt&&(this._zTime=r),this._onUpdate&&!s&&(c&&Qs(this,r,s,o),Ee(this,\"onUpdate\")),this._repeat&&_!==g&&this.vars.onRepeat&&!s&&this.parent&&Ee(this,\"onRepeat\"),(f===this._tDur||!f)&&this._tTime===f&&(c&&!this._onUpdate&&Qs(this,r,!0,!0),(r||!u)&&(f===this._tDur&&this._ts>0||!f&&this._ts<0)&&Si(this,1),!s&&!(c&&!a)&&(f||a||E)&&(Ee(this,f===l?\"onComplete\":\"onReverseComplete\",!0),this._prom&&!(f<l&&this.timeScale()>0)&&this._prom()))}return this},e.targets=function(){return this._targets},e.invalidate=function(r){return(!r||!this.vars.runBackwards)&&(this._startAt=0),this._pt=this._op=this._onUpdate=this._lazy=this.ratio=0,this._ptLookup=[],this.timeline&&this.timeline.invalidate(r),n.prototype.invalidate.call(this,r)},e.resetTo=function(r,s,o,a,l){qr||_e.wake(),this._ts||this.play();var u=Math.min(this._dur,(this._dp._time-this._start)*this._ts),c;return this._initted||vo(this,u),c=this._ease(u/this._dur),Eh(this,r,s,o,a,c,u,l)?this.resetTo(r,s,o,a,1):(Jn(this,0),this.parent||Ga(this._dp,this,\"_first\",\"_last\",this._dp._sort?\"_start\":0),this.render(0))},e.kill=function(r,s){if(s===void 0&&(s=\"all\"),!r&&(!s||s===\"all\"))return this._lazy=this._pt=0,this.parent?Wr(this):this.scrollTrigger&&this.scrollTrigger.kill(!!Wt),this;if(this.timeline){var o=this.timeline.totalDuration();return this.timeline.killTweensOf(r,s,Ei&&Ei.vars.overwrite!==!0)._first||Wr(this),this.parent&&o!==this.timeline.totalDuration()&&mr(this,this._dur*this.timeline._tDur/o,0,1),this}var a=this._targets,l=r?Re(r):a,u=this._ptLookup,c=this._pt,f,d,h,_,p,g,E;if((!s||s===\"all\")&&Jc(a,l))return s===\"all\"&&(this._pt=0),Wr(this);for(f=this._op=this._op||[],s!==\"all\"&&(kt(s)&&(p={},ne(s,function(y){return p[y]=1}),s=p),s=wh(a,s)),E=a.length;E--;)if(~l.indexOf(a[E])){d=u[E],s===\"all\"?(f[E]=s,_=d,h={}):(h=f[E]=f[E]||{},_=s);for(p in _)g=d&&d[p],g&&((!(\"kill\"in g.d)||g.d.kill(p)===!0)&&Qn(this,g,\"_pt\"),delete d[p]),h!==\"all\"&&(h[p]=1)}return this._initted&&!this._pt&&c&&Wr(this),this},t.to=function(r,s){return new t(r,s,arguments[2])},t.from=function(r,s){return Yr(1,arguments)},t.delayedCall=function(r,s,o,a){return new t(s,0,{immediateRender:!1,lazy:!1,overwrite:!1,delay:r,onComplete:s,onReverseComplete:s,onCompleteParams:o,onReverseCompleteParams:o,callbackScope:a})},t.fromTo=function(r,s,o){return Yr(2,arguments)},t.set=function(r,s){return s.duration=0,s.repeatDelay||(s.repeat=0),new t(r,s)},t.killTweensOf=function(r,s,o){return dt.killTweensOf(r,s,o)},t}(Gr);Ce(Ct.prototype,{_targets:[],_lazy:0,_startAt:0,_op:0,_onInit:0});ne(\"staggerTo,staggerFrom,staggerFromTo\",function(n){Ct[n]=function(){var t=new Ht,e=Js.call(arguments,0);return e.splice(n===\"staggerFromTo\"?5:4,0,0),t[n].apply(t,e)}});var yo=function(t,e,i){return t[e]=i},_l=function(t,e,i){return t[e](i)},Sh=function(t,e,i,r){return t[e](r.fp,i)},Th=function(t,e,i){return t.setAttribute(e,i)},ts=function(t,e){return Dt(t[e])?_l:Gn(t[e])&&t.setAttribute?Th:yo},ml=function(t,e){return e.set(e.t,e.p,Math.round((e.s+e.c*t)*1e6)/1e6,e)},xh=function(t,e){return e.set(e.t,e.p,!!(e.s+e.c*t),e)},bo=function(t,e){var i=e._pt,r=\"\";if(!t&&e.b)r=e.b;else if(t===1&&e.e)r=e.e;else{for(;i;)r=i.p+(i.m?i.m(i.s+i.c*t):Math.round((i.s+i.c*t)*1e4)/1e4)+r,i=i._next;r+=e.c}e.set(e.t,e.p,r,e)},Eo=function(t,e){for(var i=e._pt;i;)i.r(t,i.d),i=i._next},Fh=function(t,e,i,r){for(var s=this._pt,o;s;)o=s._next,s.p===r&&s.modifier(t,e,i),s=o},Ah=function(t){for(var e=this._pt,i,r;e;)r=e._next,e.p===t&&!e.op||e.op===t?Qn(this,e,\"_pt\"):e.dep||(i=1),e=r;return!i},Oh=function(t,e,i,r){r.mSet(t,e,r.m.call(r.tween,i,r.mt),r)},wo=function(t){for(var e=t._pt,i,r,s,o;e;){for(i=e._next,r=s;r&&r.pr>e.pr;)r=r._next;(e._prev=r?r._prev:o)?e._prev._next=e:s=e,(e._next=r)?r._prev=e:o=e,e=i}t._pt=s},se=function(){function n(e,i,r,s,o,a,l,u,c){this.t=i,this.s=s,this.c=o,this.p=r,this.r=a||ml,this.d=l||this,this.set=u||yo,this.pr=c||0,this._next=e,e&&(e._prev=this)}var t=n.prototype;return t.modifier=function(i,r,s){this.mSet=this.mSet||this.set,this.set=Oh,this.m=i,this.mt=s,this.tween=r},n}();ne(co+\"parent,duration,ease,delay,overwrite,runBackwards,startAt,yoyo,immediateRender,repeat,repeatDelay,data,paused,reversed,lazy,callbackScope,stringFilter,id,yoyoEase,stagger,inherit,repeatRefresh,keyframes,autoRevert,scrollTrigger\",function(n){return uo[n]=1});we.TweenMax=we.TweenLite=Ct;we.TimelineLite=we.TimelineMax=Ht;dt=new Ht({sortChildren:!1,defaults:dr,autoRemoveChildren:!0,id:\"root\",smoothChildTiming:!0});ge.stringFilter=_o;var Ui=[],Un={},kh=[],za=0,Ph=0,js=function(t){return(Un[t]||kh).map(function(e){return e()})},ro=function(){var t=Date.now(),e=[];t-za>2&&(js(\"matchMediaInit\"),Ui.forEach(function(i){var r=i.queries,s=i.conditions,o,a,l,u;for(a in r)o=Ge.matchMedia(r[a]).matches,o&&(l=1),o!==s[a]&&(s[a]=o,u=1);u&&(i.revert(),l&&e.push(i))}),js(\"matchMediaRevert\"),e.forEach(function(i){return i.onMatch(i,function(r){return i.add(null,r)})}),za=t,js(\"matchMedia\"))},gl=function(){function n(e,i){this.selector=i&&to(i),this.data=[],this._r=[],this.isReverted=!1,this.id=Ph++,e&&this.add(e)}var t=n.prototype;return t.add=function(i,r,s){Dt(i)&&(s=r,r=i,i=Dt);var o=this,a=function(){var u=ct,c=o.selector,f;return u&&u!==o&&u.data.push(o),s&&(o.selector=to(s)),ct=o,f=r.apply(o,arguments),Dt(f)&&o._r.push(f),ct=u,o.selector=c,o.isReverted=!1,f};return o.last=a,i===Dt?a(o,function(l){return o.add(null,l)}):i?o[i]=a:a},t.ignore=function(i){var r=ct;ct=null,i(this),ct=r},t.getTweens=function(){var i=[];return this.data.forEach(function(r){return r instanceof n?i.push.apply(i,r.getTweens()):r instanceof Ct&&!(r.parent&&r.parent.data===\"nested\")&&i.push(r)}),i},t.clear=function(){this._r.length=this.data.length=0},t.kill=function(i,r){var s=this;if(i?function(){for(var a=s.getTweens(),l=s.data.length,u;l--;)u=s.data[l],u.data===\"isFlip\"&&(u.revert(),u.getChildren(!0,!0,!1).forEach(function(c){return a.splice(a.indexOf(c),1)}));for(a.map(function(c){return{g:c._dur||c._delay||c._sat&&!c._sat.vars.immediateRender?c.globalTime(0):-1/0,t:c}}).sort(function(c,f){return f.g-c.g||-1/0}).forEach(function(c){return c.t.revert(i)}),l=s.data.length;l--;)u=s.data[l],u instanceof Ht?u.data!==\"nested\"&&(u.scrollTrigger&&u.scrollTrigger.revert(),u.kill()):!(u instanceof Ct)&&u.revert&&u.revert(i);s._r.forEach(function(c){return c(i,s)}),s.isReverted=!0}():this.data.forEach(function(a){return a.kill&&a.kill()}),this.clear(),r)for(var o=Ui.length;o--;)Ui[o].id===this.id&&Ui.splice(o,1)},t.revert=function(i){this.kill(i||{})},n}(),Rh=function(){function n(e){this.contexts=[],this.scope=e,ct&&ct.data.push(this)}var t=n.prototype;return t.add=function(i,r,s){Qe(i)||(i={matches:i});var o=new gl(0,s||this.scope),a=o.conditions={},l,u,c;ct&&!o.selector&&(o.selector=ct.selector),this.contexts.push(o),r=o.add(\"onMatch\",r),o.queries=i;for(u in i)u===\"all\"?c=1:(l=Ge.matchMedia(i[u]),l&&(Ui.indexOf(o)<0&&Ui.push(o),(a[u]=l.matches)&&(c=1),l.addListener?l.addListener(ro):l.addEventListener(\"change\",ro)));return c&&r(o,function(f){return o.add(null,f)}),this},t.revert=function(i){this.kill(i||{})},t.kill=function(i){this.contexts.forEach(function(r){return r.kill(i,!0)})},n}(),qn={registerPlugin:function(){for(var t=arguments.length,e=new Array(t),i=0;i<t;i++)e[i]=arguments[i];e.forEach(function(r){return al(r)})},timeline:function(t){return new Ht(t)},getTweensOf:function(t,e){return dt.getTweensOf(t,e)},getProperty:function(t,e,i,r){kt(t)&&(t=Re(t)[0]);var s=Ci(t||{}).get,o=i?qa:Xa;return i===\"native\"&&(i=\"\"),t&&(e?o((pe[e]&&pe[e].get||s)(t,e,i,r)):function(a,l,u){return o((pe[a]&&pe[a].get||s)(t,a,l,u))})},quickSetter:function(t,e,i){if(t=Re(t),t.length>1){var r=t.map(function(c){return Kt.quickSetter(c,e,i)}),s=r.length;return function(c){for(var f=s;f--;)r[f](c)}}t=t[0]||{};var o=pe[e],a=Ci(t),l=a.harness&&(a.harness.aliases||{})[e]||e,u=o?function(c){var f=new o;fr._pt=0,f.init(t,i?c+i:c,fr,0,[t]),f.render(1,f),fr._pt&&Eo(1,fr)}:a.set(t,l);return o?u:function(c){return u(t,l,i?c+i:c,a,1)}},quickTo:function(t,e,i){var r,s=Kt.to(t,Ce((r={},r[e]=\"+=0.1\",r.paused=!0,r.stagger=0,r),i||{})),o=function(l,u,c){return s.resetTo(e,l,u,c)};return o.tween=s,o},isTweening:function(t){return dt.getTweensOf(t,!0).length>0},defaults:function(t){return t&&t.ease&&(t.ease=Vi(t.ease,dr.ease)),Ra(dr,t||{})},config:function(t){return Ra(ge,t||{})},registerEffect:function(t){var e=t.name,i=t.effect,r=t.plugins,s=t.defaults,o=t.extendTimeline;(r||\"\").split(\",\").forEach(function(a){return a&&!pe[a]&&!we[a]&&jr(e+\" effect requires \"+a+\" plugin.\")}),Vs[e]=function(a,l,u){return i(Re(a),Ce(l||{},s),u)},o&&(Ht.prototype[e]=function(a,l,u){return this.add(Vs[e](a,Qe(l)?l:(u=l)&&{},this),u)})},registerEase:function(t,e){tt[t]=Vi(e)},parseEase:function(t,e){return arguments.length?Vi(t,e):tt},getById:function(t){return dt.getById(t)},exportRoot:function(t,e){t===void 0&&(t={});var i=new Ht(t),r,s;for(i.smoothChildTiming=me(t.smoothChildTiming),dt.remove(i),i._dp=0,i._time=i._tTime=dt._time,r=dt._first;r;)s=r._next,(e||!(!r._dur&&r instanceof Ct&&r.vars.onComplete===r._targets[0]))&&Ke(i,r,r._start-r._delay),r=s;return Ke(dt,i,0),i},context:function(t,e){return t?new gl(t,e):ct},matchMedia:function(t){return new Rh(t)},matchMediaRefresh:function(){return Ui.forEach(function(t){var e=t.conditions,i,r;for(r in e)e[r]&&(e[r]=!1,i=1);i&&t.revert()})||ro()},addEventListener:function(t,e){var i=Un[t]||(Un[t]=[]);~i.indexOf(e)||i.push(e)},removeEventListener:function(t,e){var i=Un[t],r=i&&i.indexOf(e);r>=0&&i.splice(r,1)},utils:{wrap:hh,wrapYoyo:fh,distribute:el,random:rl,snap:il,normalize:ch,getUnit:Vt,clamp:oh,splitColor:ll,toArray:Re,selector:to,mapRange:sl,pipe:lh,unitize:uh,interpolate:dh,shuffle:tl},install:Ua,effects:Vs,ticker:_e,updateRoot:Ht.updateRoot,plugins:pe,globalTimeline:dt,core:{PropTween:se,globals:Ya,Tween:Ct,Timeline:Ht,Animation:Gr,getCache:Ci,_removeLinkedListItem:Qn,reverting:function(){return Wt},context:function(t){return t&&ct&&(ct.data.push(t),t._ctx=ct),ct},suppressOverwrites:function(t){return no=t}}};ne(\"to,from,fromTo,delayedCall,set,killTweensOf\",function(n){return qn[n]=Ct[n]});_e.add(Ht.updateRoot);fr=qn.to({},{duration:0});var Mh=function(t,e){for(var i=t._pt;i&&i.p!==e&&i.op!==e&&i.fp!==e;)i=i._next;return i},Ih=function(t,e){var i=t._targets,r,s,o;for(r in e)for(s=i.length;s--;)o=t._ptLookup[s][r],o&&(o=o.d)&&(o._pt&&(o=Mh(o,r)),o&&o.modifier&&o.modifier(e[r],t,i[s],r))},Xs=function(t,e){return{name:t,headless:1,rawVars:1,init:function(r,s,o){o._onInit=function(a){var l,u;if(kt(s)&&(l={},ne(s,function(c){return l[c]=1}),s=l),e){l={};for(u in s)l[u]=e(s[u]);s=l}Ih(a,s)}}}},Kt=qn.registerPlugin({name:\"attr\",init:function(t,e,i,r,s){var o,a,l;this.tween=i;for(o in e)l=t.getAttribute(o)||\"\",a=this.add(t,\"setAttribute\",(l||0)+\"\",e[o],r,s,0,0,o),a.op=o,a.b=l,this._props.push(o)},render:function(t,e){for(var i=e._pt;i;)Wt?i.set(i.t,i.p,i.b,i):i.r(t,i.d),i=i._next}},{name:\"endArray\",headless:1,init:function(t,e){for(var i=e.length;i--;)this.add(t,i,t[i]||0,e[i],0,0,0,0,0,1)}},Xs(\"roundProps\",eo),Xs(\"modifiers\"),Xs(\"snap\",il))||qn;Ct.version=Ht.version=Kt.version=\"3.14.2\";Va=1;so()&&gr();var Lh=tt.Power0,Bh=tt.Power1,zh=tt.Power2,Nh=tt.Power3,Hh=tt.Power4,Wh=tt.Linear,Vh=tt.Quad,Uh=tt.Cubic,Yh=tt.Quart,$h=tt.Quint,jh=tt.Strong,Xh=tt.Elastic,qh=tt.Back,Gh=tt.SteppedEase,Kh=tt.Bounce,Qh=tt.Sine,Zh=tt.Expo,Jh=tt.Circ;var Dl,xi,yr,Ao,Ki,tf,vl,Oo,ef=function(){return typeof window!=\"undefined\"},ci={},Gi=180/Math.PI,br=Math.PI/180,vr=Math.atan2,yl=1e8,ko=/([A-Z])/g,rf=/(left|right|width|margin|padding|x)/i,nf=/[\\s,\\(]\\S/,Ze={autoAlpha:\"opacity,visibility\",scale:\"scaleX,scaleY\",alpha:\"opacity\"},So=function(t,e){return e.set(e.t,e.p,Math.round((e.s+e.c*t)*1e4)/1e4+e.u,e)},sf=function(t,e){return e.set(e.t,e.p,t===1?e.e:Math.round((e.s+e.c*t)*1e4)/1e4+e.u,e)},of=function(t,e){return e.set(e.t,e.p,t?Math.round((e.s+e.c*t)*1e4)/1e4+e.u:e.b,e)},af=function(t,e){return e.set(e.t,e.p,t===1?e.e:t?Math.round((e.s+e.c*t)*1e4)/1e4+e.u:e.b,e)},lf=function(t,e){var i=e.s+e.c*t;e.set(e.t,e.p,~~(i+(i<0?-.5:.5))+e.u,e)},Fl=function(t,e){return e.set(e.t,e.p,t?e.e:e.b,e)},Al=function(t,e){return e.set(e.t,e.p,t!==1?e.b:e.e,e)},uf=function(t,e,i){return t.style[e]=i},cf=function(t,e,i){return t.style.setProperty(e,i)},hf=function(t,e,i){return t._gsap[e]=i},ff=function(t,e,i){return t._gsap.scaleX=t._gsap.scaleY=i},df=function(t,e,i,r,s){var o=t._gsap;o.scaleX=o.scaleY=i,o.renderTransform(s,o)},pf=function(t,e,i,r,s){var o=t._gsap;o[e]=i,o.renderTransform(s,o)},pt=\"transform\",De=pt+\"Origin\",_f=function n(t,e){var i=this,r=this.target,s=r.style,o=r._gsap;if(t in ci&&s){if(this.tfm=this.tfm||{},t!==\"transform\")t=Ze[t]||t,~t.indexOf(\",\")?t.split(\",\").forEach(function(a){return i.tfm[a]=ui(r,a)}):this.tfm[t]=o.x?o[t]:ui(r,t),t===De&&(this.tfm.zOrigin=o.zOrigin);else return Ze.transform.split(\",\").forEach(function(a){return n.call(i,a,e)});if(this.props.indexOf(pt)>=0)return;o.svg&&(this.svgo=r.getAttribute(\"data-svg-origin\"),this.props.push(De,e,\"\")),t=pt}(s||e)&&this.props.push(t,e,s[t])},Ol=function(t){t.translate&&(t.removeProperty(\"translate\"),t.removeProperty(\"scale\"),t.removeProperty(\"rotate\"))},mf=function(){var t=this.props,e=this.target,i=e.style,r=e._gsap,s,o;for(s=0;s<t.length;s+=3)t[s+1]?t[s+1]===2?e[t[s]](t[s+2]):e[t[s]]=t[s+2]:t[s+2]?i[t[s]]=t[s+2]:i.removeProperty(t[s].substr(0,2)===\"--\"?t[s]:t[s].replace(ko,\"-$1\").toLowerCase());if(this.tfm){for(o in this.tfm)r[o]=this.tfm[o];r.svg&&(r.renderTransform(),e.setAttribute(\"data-svg-origin\",this.svgo||\"\")),s=Oo(),(!s||!s.isStart)&&!i[pt]&&(Ol(i),r.zOrigin&&i[De]&&(i[De]+=\" \"+r.zOrigin+\"px\",r.zOrigin=0,r.renderTransform()),r.uncache=1)}},kl=function(t,e){var i={target:t,props:[],revert:mf,save:_f};return t._gsap||Kt.core.getCache(t),e&&t.style&&t.nodeType&&e.split(\",\").forEach(function(r){return i.save(r)}),i},Pl,To=function(t,e){var i=xi.createElementNS?xi.createElementNS((e||\"http://www.w3.org/1999/xhtml\").replace(/^https/,\"http\"),t):xi.createElement(t);return i&&i.style?i:xi.createElement(t)},Se=function n(t,e,i){var r=getComputedStyle(t);return r[e]||r.getPropertyValue(e.replace(ko,\"-$1\").toLowerCase())||r.getPropertyValue(e)||!i&&n(t,Er(e)||e,1)||\"\"},bl=\"O,Moz,ms,Ms,Webkit\".split(\",\"),Er=function(t,e,i){var r=e||Ki,s=r.style,o=5;if(t in s&&!i)return t;for(t=t.charAt(0).toUpperCase()+t.substr(1);o--&&!(bl[o]+t in s););return o<0?null:(o===3?\"ms\":o>=0?bl[o]:\"\")+t},xo=function(){ef()&&window.document&&(Dl=window,xi=Dl.document,yr=xi.documentElement,Ki=To(\"div\")||{style:{}},tf=To(\"div\"),pt=Er(pt),De=pt+\"Origin\",Ki.style.cssText=\"border-width:0;line-height:0;position:absolute;padding:0\",Pl=!!Er(\"perspective\"),Oo=Kt.core.reverting,Ao=1)},El=function(t){var e=t.ownerSVGElement,i=To(\"svg\",e&&e.getAttribute(\"xmlns\")||\"http://www.w3.org/2000/svg\"),r=t.cloneNode(!0),s;r.style.display=\"block\",i.appendChild(r),yr.appendChild(i);try{s=r.getBBox()}catch(o){}return i.removeChild(r),yr.removeChild(i),s},wl=function(t,e){for(var i=e.length;i--;)if(t.hasAttribute(e[i]))return t.getAttribute(e[i])},Rl=function(t){var e,i;try{e=t.getBBox()}catch(r){e=El(t),i=1}return e&&(e.width||e.height)||i||(e=El(t)),e&&!e.width&&!e.x&&!e.y?{x:+wl(t,[\"x\",\"cx\",\"x1\"])||0,y:+wl(t,[\"y\",\"cy\",\"y1\"])||0,width:0,height:0}:e},Ml=function(t){return!!(t.getCTM&&(!t.parentNode||t.ownerSVGElement)&&Rl(t))},Ai=function(t,e){if(e){var i=t.style,r;e in ci&&e!==De&&(e=pt),i.removeProperty?(r=e.substr(0,2),(r===\"ms\"||e.substr(0,6)===\"webkit\")&&(e=\"-\"+e),i.removeProperty(r===\"--\"?e:e.replace(ko,\"-$1\").toLowerCase())):i.removeAttribute(e)}},Fi=function(t,e,i,r,s,o){var a=new se(t._pt,e,i,0,1,o?Al:Fl);return t._pt=a,a.b=r,a.e=s,t._props.push(i),a},Cl={deg:1,rad:1,turn:1},gf={grid:1,flex:1},Oi=function n(t,e,i,r){var s=parseFloat(i)||0,o=(i+\"\").trim().substr((s+\"\").length)||\"px\",a=Ki.style,l=rf.test(e),u=t.tagName.toLowerCase()===\"svg\",c=(u?\"client\":\"offset\")+(l?\"Width\":\"Height\"),f=100,d=r===\"px\",h=r===\"%\",_,p,g,E;if(r===o||!s||Cl[r]||Cl[o])return s;if(o!==\"px\"&&!d&&(s=n(t,e,i,\"px\")),E=t.getCTM&&Ml(t),(h||o===\"%\")&&(ci[e]||~e.indexOf(\"adius\")))return _=E?t.getBBox()[l?\"width\":\"height\"]:t[c],vt(h?s/_*f:s/100*_);if(a[l?\"width\":\"height\"]=f+(d?o:r),p=r!==\"rem\"&&~e.indexOf(\"adius\")||r===\"em\"&&t.appendChild&&!u?t:t.parentNode,E&&(p=(t.ownerSVGElement||{}).parentNode),(!p||p===xi||!p.appendChild)&&(p=xi.body),g=p._gsap,g&&h&&g.width&&l&&g.time===_e.time&&!g.uncache)return vt(s/g.width*f);if(h&&(e===\"height\"||e===\"width\")){var y=t.style[e];t.style[e]=f+r,_=t[c],y?t.style[e]=y:Ai(t,e)}else(h||o===\"%\")&&!gf[Se(p,\"display\")]&&(a.position=Se(t,\"position\")),p===t&&(a.position=\"static\"),p.appendChild(Ki),_=Ki[c],p.removeChild(Ki),a.position=\"absolute\";return l&&h&&(g=Ci(p),g.time=_e.time,g.width=p[c]),vt(d?_*s/f:_&&s?f/_*s:0)},ui=function(t,e,i,r){var s;return Ao||xo(),e in Ze&&e!==\"transform\"&&(e=Ze[e],~e.indexOf(\",\")&&(e=e.split(\",\")[0])),ci[e]&&e!==\"transform\"?(s=Jr(t,r),s=e!==\"transformOrigin\"?s[e]:s.svg?s.origin:is(Se(t,De))+\" \"+s.zOrigin+\"px\"):(s=t.style[e],(!s||s===\"auto\"||r||~(s+\"\").indexOf(\"calc(\"))&&(s=es[e]&&es[e](t,e,i)||Se(t,e)||fo(t,e)||(e===\"opacity\"?1:0))),i&&!~(s+\"\").trim().indexOf(\" \")?Oi(t,e,s,i)+i:s},Df=function(t,e,i,r){if(!i||i===\"none\"){var s=Er(e,t,1),o=s&&Se(t,s,1);o&&o!==i?(e=s,i=o):e===\"borderColor\"&&(i=Se(t,\"borderTopColor\"))}var a=new se(this._pt,t.style,e,0,1,bo),l=0,u=0,c,f,d,h,_,p,g,E,y,S,D,v;if(a.b=i,a.e=r,i+=\"\",r+=\"\",r.substring(0,6)===\"var(--\"&&(r=Se(t,r.substring(4,r.indexOf(\")\")))),r===\"auto\"&&(p=t.style[e],t.style[e]=r,r=Se(t,e)||r,p?t.style[e]=p:Ai(t,e)),c=[i,r],_o(c),i=c[0],r=c[1],d=i.match(Yi)||[],v=r.match(Yi)||[],v.length){for(;f=Yi.exec(r);)g=f[0],y=r.substring(l,f.index),_?_=(_+1)%5:(y.substr(-5)===\"rgba(\"||y.substr(-5)===\"hsla(\")&&(_=1),g!==(p=d[u++]||\"\")&&(h=parseFloat(p)||0,D=p.substr((h+\"\").length),g.charAt(1)===\"=\"&&(g=$i(h,g)+D),E=parseFloat(g),S=g.substr((E+\"\").length),l=Yi.lastIndex-S.length,S||(S=S||ge.units[e]||D,l===r.length&&(r+=S,a.e+=S)),D!==S&&(h=Oi(t,e,p,S)||0),a._pt={_next:a._pt,p:y||u===1?y:\",\",s:h,c:E-h,m:_&&_<4||e===\"zIndex\"?Math.round:0});a.c=l<r.length?r.substring(l,r.length):\"\"}else a.r=e===\"display\"&&r===\"none\"?Al:Fl;return ao.test(r)&&(a.e=0),this._pt=a,a},Sl={top:\"0%\",bottom:\"100%\",left:\"0%\",right:\"100%\",center:\"50%\"},vf=function(t){var e=t.split(\" \"),i=e[0],r=e[1]||\"50%\";return(i===\"top\"||i===\"bottom\"||r===\"left\"||r===\"right\")&&(t=i,i=r,r=t),e[0]=Sl[i]||i,e[1]=Sl[r]||r,e.join(\" \")},yf=function(t,e){if(e.tween&&e.tween._time===e.tween._dur){var i=e.t,r=i.style,s=e.u,o=i._gsap,a,l,u;if(s===\"all\"||s===!0)r.cssText=\"\",l=1;else for(s=s.split(\",\"),u=s.length;--u>-1;)a=s[u],ci[a]&&(l=1,a=a===\"transformOrigin\"?De:pt),Ai(i,a);l&&(Ai(i,pt),o&&(o.svg&&i.removeAttribute(\"transform\"),r.scale=r.rotate=r.translate=\"none\",Jr(i,1),o.uncache=1,Ol(r)))}},es={clearProps:function(t,e,i,r,s){if(s.data!==\"isFromStart\"){var o=t._pt=new se(t._pt,e,i,0,0,yf);return o.u=r,o.pr=-10,o.tween=s,t._props.push(i),1}}},Zr=[1,0,0,1,0,0],Il={},Ll=function(t){return t===\"matrix(1, 0, 0, 1, 0, 0)\"||t===\"none\"||!t},Tl=function(t){var e=Se(t,pt);return Ll(e)?Zr:e.substr(7).match(oo).map(vt)},Po=function(t,e){var i=t._gsap||Ci(t),r=t.style,s=Tl(t),o,a,l,u;return i.svg&&t.getAttribute(\"transform\")?(l=t.transform.baseVal.consolidate().matrix,s=[l.a,l.b,l.c,l.d,l.e,l.f],s.join(\",\")===\"1,0,0,1,0,0\"?Zr:s):(s===Zr&&!t.offsetParent&&t!==yr&&!i.svg&&(l=r.display,r.display=\"block\",o=t.parentNode,(!o||!t.offsetParent&&!t.getBoundingClientRect().width)&&(u=1,a=t.nextElementSibling,yr.appendChild(t)),s=Tl(t),l?r.display=l:Ai(t,\"display\"),u&&(a?o.insertBefore(t,a):o?o.appendChild(t):yr.removeChild(t))),e&&s.length>6?[s[0],s[1],s[4],s[5],s[12],s[13]]:s)},Fo=function(t,e,i,r,s,o){var a=t._gsap,l=s||Po(t,!0),u=a.xOrigin||0,c=a.yOrigin||0,f=a.xOffset||0,d=a.yOffset||0,h=l[0],_=l[1],p=l[2],g=l[3],E=l[4],y=l[5],S=e.split(\" \"),D=parseFloat(S[0])||0,v=parseFloat(S[1])||0,T,b,x,w;i?l!==Zr&&(b=h*g-_*p)&&(x=D*(g/b)+v*(-p/b)+(p*y-g*E)/b,w=D*(-_/b)+v*(h/b)-(h*y-_*E)/b,D=x,v=w):(T=Rl(t),D=T.x+(~S[0].indexOf(\"%\")?D/100*T.width:D),v=T.y+(~(S[1]||S[0]).indexOf(\"%\")?v/100*T.height:v)),r||r!==!1&&a.smooth?(E=D-u,y=v-c,a.xOffset=f+(E*h+y*p)-E,a.yOffset=d+(E*_+y*g)-y):a.xOffset=a.yOffset=0,a.xOrigin=D,a.yOrigin=v,a.smooth=!!r,a.origin=e,a.originIsAbsolute=!!i,t.style[De]=\"0px 0px\",o&&(Fi(o,a,\"xOrigin\",u,D),Fi(o,a,\"yOrigin\",c,v),Fi(o,a,\"xOffset\",f,a.xOffset),Fi(o,a,\"yOffset\",d,a.yOffset)),t.setAttribute(\"data-svg-origin\",D+\" \"+v)},Jr=function(t,e){var i=t._gsap||new mo(t);if(\"x\"in i&&!e&&!i.uncache)return i;var r=t.style,s=i.scaleX<0,o=\"px\",a=\"deg\",l=getComputedStyle(t),u=Se(t,De)||\"0\",c,f,d,h,_,p,g,E,y,S,D,v,T,b,x,w,F,B,A,P,L,M,H,R,z,V,m,j,Z,Rt,nt,St;return c=f=d=p=g=E=y=S=D=0,h=_=1,i.svg=!!(t.getCTM&&Ml(t)),l.translate&&((l.translate!==\"none\"||l.scale!==\"none\"||l.rotate!==\"none\")&&(r[pt]=(l.translate!==\"none\"?\"translate3d(\"+(l.translate+\" 0 0\").split(\" \").slice(0,3).join(\", \")+\") \":\"\")+(l.rotate!==\"none\"?\"rotate(\"+l.rotate+\") \":\"\")+(l.scale!==\"none\"?\"scale(\"+l.scale.split(\" \").join(\",\")+\") \":\"\")+(l[pt]!==\"none\"?l[pt]:\"\")),r.scale=r.rotate=r.translate=\"none\"),b=Po(t,i.svg),i.svg&&(i.uncache?(z=t.getBBox(),u=i.xOrigin-z.x+\"px \"+(i.yOrigin-z.y)+\"px\",R=\"\"):R=!e&&t.getAttribute(\"data-svg-origin\"),Fo(t,R||u,!!R||i.originIsAbsolute,i.smooth!==!1,b)),v=i.xOrigin||0,T=i.yOrigin||0,b!==Zr&&(B=b[0],A=b[1],P=b[2],L=b[3],c=M=b[4],f=H=b[5],b.length===6?(h=Math.sqrt(B*B+A*A),_=Math.sqrt(L*L+P*P),p=B||A?vr(A,B)*Gi:0,y=P||L?vr(P,L)*Gi+p:0,y&&(_*=Math.abs(Math.cos(y*br))),i.svg&&(c-=v-(v*B+T*P),f-=T-(v*A+T*L))):(St=b[6],Rt=b[7],m=b[8],j=b[9],Z=b[10],nt=b[11],c=b[12],f=b[13],d=b[14],x=vr(St,Z),g=x*Gi,x&&(w=Math.cos(-x),F=Math.sin(-x),R=M*w+m*F,z=H*w+j*F,V=St*w+Z*F,m=M*-F+m*w,j=H*-F+j*w,Z=St*-F+Z*w,nt=Rt*-F+nt*w,M=R,H=z,St=V),x=vr(-P,Z),E=x*Gi,x&&(w=Math.cos(-x),F=Math.sin(-x),R=B*w-m*F,z=A*w-j*F,V=P*w-Z*F,nt=L*F+nt*w,B=R,A=z,P=V),x=vr(A,B),p=x*Gi,x&&(w=Math.cos(x),F=Math.sin(x),R=B*w+A*F,z=M*w+H*F,A=A*w-B*F,H=H*w-M*F,B=R,M=z),g&&Math.abs(g)+Math.abs(p)>359.9&&(g=p=0,E=180-E),h=vt(Math.sqrt(B*B+A*A+P*P)),_=vt(Math.sqrt(H*H+St*St)),x=vr(M,H),y=Math.abs(x)>2e-4?x*Gi:0,D=nt?1/(nt<0?-nt:nt):0),i.svg&&(R=t.getAttribute(\"transform\"),i.forceCSS=t.setAttribute(\"transform\",\"\")||!Ll(Se(t,pt)),R&&t.setAttribute(\"transform\",R))),Math.abs(y)>90&&Math.abs(y)<270&&(s?(h*=-1,y+=p<=0?180:-180,p+=p<=0?180:-180):(_*=-1,y+=y<=0?180:-180)),e=e||i.uncache,i.x=c-((i.xPercent=c&&(!e&&i.xPercent||(Math.round(t.offsetWidth/2)===Math.round(-c)?-50:0)))?t.offsetWidth*i.xPercent/100:0)+o,i.y=f-((i.yPercent=f&&(!e&&i.yPercent||(Math.round(t.offsetHeight/2)===Math.round(-f)?-50:0)))?t.offsetHeight*i.yPercent/100:0)+o,i.z=d+o,i.scaleX=vt(h),i.scaleY=vt(_),i.rotation=vt(p)+a,i.rotationX=vt(g)+a,i.rotationY=vt(E)+a,i.skewX=y+a,i.skewY=S+a,i.transformPerspective=D+o,(i.zOrigin=parseFloat(u.split(\" \")[2])||!e&&i.zOrigin||0)&&(r[De]=is(u)),i.xOffset=i.yOffset=0,i.force3D=ge.force3D,i.renderTransform=i.svg?Ef:Pl?Bl:bf,i.uncache=0,i},is=function(t){return(t=t.split(\" \"))[0]+\" \"+t[1]},Co=function(t,e,i){var r=Vt(e);return vt(parseFloat(e)+parseFloat(Oi(t,\"x\",i+\"px\",r)))+r},bf=function(t,e){e.z=\"0px\",e.rotationY=e.rotationX=\"0deg\",e.force3D=0,Bl(t,e)},Xi=\"0deg\",Qr=\"0px\",qi=\") \",Bl=function(t,e){var i=e||this,r=i.xPercent,s=i.yPercent,o=i.x,a=i.y,l=i.z,u=i.rotation,c=i.rotationY,f=i.rotationX,d=i.skewX,h=i.skewY,_=i.scaleX,p=i.scaleY,g=i.transformPerspective,E=i.force3D,y=i.target,S=i.zOrigin,D=\"\",v=E===\"auto\"&&t&&t!==1||E===!0;if(S&&(f!==Xi||c!==Xi)){var T=parseFloat(c)*br,b=Math.sin(T),x=Math.cos(T),w;T=parseFloat(f)*br,w=Math.cos(T),o=Co(y,o,b*w*-S),a=Co(y,a,-Math.sin(T)*-S),l=Co(y,l,x*w*-S+S)}g!==Qr&&(D+=\"perspective(\"+g+qi),(r||s)&&(D+=\"translate(\"+r+\"%, \"+s+\"%) \"),(v||o!==Qr||a!==Qr||l!==Qr)&&(D+=l!==Qr||v?\"translate3d(\"+o+\", \"+a+\", \"+l+\") \":\"translate(\"+o+\", \"+a+qi),u!==Xi&&(D+=\"rotate(\"+u+qi),c!==Xi&&(D+=\"rotateY(\"+c+qi),f!==Xi&&(D+=\"rotateX(\"+f+qi),(d!==Xi||h!==Xi)&&(D+=\"skew(\"+d+\", \"+h+qi),(_!==1||p!==1)&&(D+=\"scale(\"+_+\", \"+p+qi),y.style[pt]=D||\"translate(0, 0)\"},Ef=function(t,e){var i=e||this,r=i.xPercent,s=i.yPercent,o=i.x,a=i.y,l=i.rotation,u=i.skewX,c=i.skewY,f=i.scaleX,d=i.scaleY,h=i.target,_=i.xOrigin,p=i.yOrigin,g=i.xOffset,E=i.yOffset,y=i.forceCSS,S=parseFloat(o),D=parseFloat(a),v,T,b,x,w;l=parseFloat(l),u=parseFloat(u),c=parseFloat(c),c&&(c=parseFloat(c),u+=c,l+=c),l||u?(l*=br,u*=br,v=Math.cos(l)*f,T=Math.sin(l)*f,b=Math.sin(l-u)*-d,x=Math.cos(l-u)*d,u&&(c*=br,w=Math.tan(u-c),w=Math.sqrt(1+w*w),b*=w,x*=w,c&&(w=Math.tan(c),w=Math.sqrt(1+w*w),v*=w,T*=w)),v=vt(v),T=vt(T),b=vt(b),x=vt(x)):(v=f,x=d,T=b=0),(S&&!~(o+\"\").indexOf(\"px\")||D&&!~(a+\"\").indexOf(\"px\"))&&(S=Oi(h,\"x\",o,\"px\"),D=Oi(h,\"y\",a,\"px\")),(_||p||g||E)&&(S=vt(S+_-(_*v+p*b)+g),D=vt(D+p-(_*T+p*x)+E)),(r||s)&&(w=h.getBBox(),S=vt(S+r/100*w.width),D=vt(D+s/100*w.height)),w=\"matrix(\"+v+\",\"+T+\",\"+b+\",\"+x+\",\"+S+\",\"+D+\")\",h.setAttribute(\"transform\",w),y&&(h.style[pt]=w)},wf=function(t,e,i,r,s){var o=360,a=kt(s),l=parseFloat(s)*(a&&~s.indexOf(\"rad\")?Gi:1),u=l-r,c=r+u+\"deg\",f,d;return a&&(f=s.split(\"_\")[1],f===\"short\"&&(u%=o,u!==u%(o/2)&&(u+=u<0?o:-o)),f===\"cw\"&&u<0?u=(u+o*yl)%o-~~(u/o)*o:f===\"ccw\"&&u>0&&(u=(u-o*yl)%o-~~(u/o)*o)),t._pt=d=new se(t._pt,e,i,r,u,sf),d.e=c,d.u=\"deg\",t._props.push(i),d},xl=function(t,e){for(var i in e)t[i]=e[i];return t},Cf=function(t,e,i){var r=xl({},i._gsap),s=\"perspective,force3D,transformOrigin,svgOrigin\",o=i.style,a,l,u,c,f,d,h,_;r.svg?(u=i.getAttribute(\"transform\"),i.setAttribute(\"transform\",\"\"),o[pt]=e,a=Jr(i,1),Ai(i,pt),i.setAttribute(\"transform\",u)):(u=getComputedStyle(i)[pt],o[pt]=e,a=Jr(i,1),o[pt]=u);for(l in ci)u=r[l],c=a[l],u!==c&&s.indexOf(l)<0&&(h=Vt(u),_=Vt(c),f=h!==_?Oi(i,l,u,_):parseFloat(u),d=parseFloat(c),t._pt=new se(t._pt,a,l,f,d-f,So),t._pt.u=_||0,t._props.push(l));xl(a,r)};ne(\"padding,margin,Width,Radius\",function(n,t){var e=\"Top\",i=\"Right\",r=\"Bottom\",s=\"Left\",o=(t<3?[e,i,r,s]:[e+s,e+i,r+i,r+s]).map(function(a){return t<2?n+a:\"border\"+a+n});es[t>1?\"border\"+n:n]=function(a,l,u,c,f){var d,h;if(arguments.length<4)return d=o.map(function(_){return ui(a,_,u)}),h=d.join(\" \"),h.split(d[0]).length===5?d[0]:h;d=(c+\"\").split(\" \"),h={},o.forEach(function(_,p){return h[_]=d[p]=d[p]||d[(p-1)/2|0]}),a.init(l,h,f)}});var Ro={name:\"css\",register:xo,targetTest:function(t){return t.style&&t.nodeType},init:function(t,e,i,r,s){var o=this._props,a=t.style,l=i.vars.startAt,u,c,f,d,h,_,p,g,E,y,S,D,v,T,b,x,w;Ao||xo(),this.styles=this.styles||kl(t),x=this.styles.props,this.tween=i;for(p in e)if(p!==\"autoRound\"&&(c=e[p],!(pe[p]&&Do(p,e,i,r,t,s)))){if(h=typeof c,_=es[p],h===\"function\"&&(c=c.call(i,r,t,s),h=typeof c),h===\"string\"&&~c.indexOf(\"random(\")&&(c=Dr(c)),_)_(this,t,p,c,i)&&(b=1);else if(p.substr(0,2)===\"--\")u=(getComputedStyle(t).getPropertyValue(p)+\"\").trim(),c+=\"\",ai.lastIndex=0,ai.test(u)||(g=Vt(u),E=Vt(c),E?g!==E&&(u=Oi(t,p,u,E)+E):g&&(c+=g)),this.add(a,\"setProperty\",u,c,r,s,0,0,p),o.push(p),x.push(p,0,a[p]);else if(h!==\"undefined\"){if(l&&p in l?(u=typeof l[p]==\"function\"?l[p].call(i,r,t,s):l[p],kt(u)&&~u.indexOf(\"random(\")&&(u=Dr(u)),Vt(u+\"\")||u===\"auto\"||(u+=ge.units[p]||Vt(ui(t,p))||\"\"),(u+\"\").charAt(1)===\"=\"&&(u=ui(t,p))):u=ui(t,p),d=parseFloat(u),y=h===\"string\"&&c.charAt(1)===\"=\"&&c.substr(0,2),y&&(c=c.substr(2)),f=parseFloat(c),p in Ze&&(p===\"autoAlpha\"&&(d===1&&ui(t,\"visibility\")===\"hidden\"&&f&&(d=0),x.push(\"visibility\",0,a.visibility),Fi(this,a,\"visibility\",d?\"inherit\":\"hidden\",f?\"inherit\":\"hidden\",!f)),p!==\"scale\"&&p!==\"transform\"&&(p=Ze[p],~p.indexOf(\",\")&&(p=p.split(\",\")[0]))),S=p in ci,S){if(this.styles.save(p),w=c,h===\"string\"&&c.substring(0,6)===\"var(--\"){if(c=Se(t,c.substring(4,c.indexOf(\")\"))),c.substring(0,5)===\"calc(\"){var F=t.style.perspective;t.style.perspective=c,c=Se(t,\"perspective\"),F?t.style.perspective=F:Ai(t,\"perspective\")}f=parseFloat(c)}if(D||(v=t._gsap,v.renderTransform&&!e.parseTransform||Jr(t,e.parseTransform),T=e.smoothOrigin!==!1&&v.smooth,D=this._pt=new se(this._pt,a,pt,0,1,v.renderTransform,v,0,-1),D.dep=1),p===\"scale\")this._pt=new se(this._pt,v,\"scaleY\",v.scaleY,(y?$i(v.scaleY,y+f):f)-v.scaleY||0,So),this._pt.u=0,o.push(\"scaleY\",p),p+=\"X\";else if(p===\"transformOrigin\"){x.push(De,0,a[De]),c=vf(c),v.svg?Fo(t,c,0,T,0,this):(E=parseFloat(c.split(\" \")[2])||0,E!==v.zOrigin&&Fi(this,v,\"zOrigin\",v.zOrigin,E),Fi(this,a,p,is(u),is(c)));continue}else if(p===\"svgOrigin\"){Fo(t,c,1,T,0,this);continue}else if(p in Il){wf(this,v,p,d,y?$i(d,y+c):c);continue}else if(p===\"smoothOrigin\"){Fi(this,v,\"smooth\",v.smooth,c);continue}else if(p===\"force3D\"){v[p]=c;continue}else if(p===\"transform\"){Cf(this,c,t);continue}}else p in a||(p=Er(p)||p);if(S||(f||f===0)&&(d||d===0)&&!nf.test(c)&&p in a)g=(u+\"\").substr((d+\"\").length),f||(f=0),E=Vt(c)||(p in ge.units?ge.units[p]:g),g!==E&&(d=Oi(t,p,u,E)),this._pt=new se(this._pt,S?v:a,p,d,(y?$i(d,y+f):f)-d,!S&&(E===\"px\"||p===\"zIndex\")&&e.autoRound!==!1?lf:So),this._pt.u=E||0,S&&w!==c?(this._pt.b=u,this._pt.e=w,this._pt.r=af):g!==E&&E!==\"%\"&&(this._pt.b=u,this._pt.r=of);else if(p in a)Df.call(this,t,p,u,y?y+c:c);else if(p in t)this.add(t,p,u||t[p],y?y+c:c,r,s);else if(p!==\"parseTransform\"){Kn(p,c);continue}S||(p in a?x.push(p,0,a[p]):typeof t[p]==\"function\"?x.push(p,2,t[p]()):x.push(p,1,u||t[p])),o.push(p)}}b&&wo(this)},render:function(t,e){if(e.tween._time||!Oo())for(var i=e._pt;i;)i.r(t,i.d),i=i._next;else e.styles.revert()},get:ui,aliases:Ze,getSetter:function(t,e,i){var r=Ze[e];return r&&r.indexOf(\",\")<0&&(e=r),e in ci&&e!==De&&(t._gsap.x||ui(t,\"x\"))?i&&vl===i?e===\"scale\"?ff:hf:(vl=i||{})&&(e===\"scale\"?df:pf):t.style&&!Gn(t.style[e])?uf:~e.indexOf(\"-\")?cf:ts(t,e)},core:{_removeProperty:Ai,_getMatrix:Po}};Kt.utils.checkPrefix=Er;Kt.core.getStyleSaver=kl;(function(n,t,e,i){var r=ne(n+\",\"+t+\",\"+e,function(s){ci[s]=1});ne(t,function(s){ge.units[s]=\"deg\",Il[s]=1}),Ze[r[13]]=n+\",\"+t,ne(i,function(s){var o=s.split(\":\");Ze[o[1]]=r[o[0]]})})(\"x,y,z,scale,scaleX,scaleY,xPercent,yPercent\",\"rotation,rotationX,rotationY,skewX,skewY\",\"transform,transformOrigin,svgOrigin,force3D,smoothOrigin,transformPerspective\",\"0:translateX,1:translateY,2:translateZ,8:rotate,8:rotationZ,8:rotateZ,9:rotateX,10:rotateY\");ne(\"x,y,z,top,right,bottom,left,width,height,fontSize,padding,margin,perspective\",function(n){ge.units[n]=\"px\"});Kt.registerPlugin(Ro);var _t=Kt.registerPlugin(Ro)||Kt,Xd=_t.core.Tween;var Mo=\"production\",zl=window.matchMedia(\"(any-pointer:coarse)\").matches,Qi=Object.freeze({NAME:Mo,IS_PROD:Mo===\"production\",IS_DEV:Mo===\"development\",IS_MOBILE:zl,IS_DESKTOP:!zl}),wr=Object.freeze({FIRST_LOADED:\"is-first-loaded\",LOADING:\"is-loading\",LOADED:\"is-loaded\",READY:\"is-ready\",FONTS_LOADED:\"fonts-loaded\",LAZY_CONTAINER:\"c-lazy\",LAZY_LOADED:\"-lazy-loaded\"}),tn=Object.freeze({RESIZE_END:\"loco.resizeEnd\"}),Cr=Object.freeze({EAGER:[{family:\"PP Locomotive New\",style:\"normal\",weight:\"300\"},{family:\"Helvetica Now Display\",style:\"normal\",weight:\"400\"},{family:\"Helvetica Now Display\",style:\"normal\",weight:\"500\"}]});var rs=class extends de{constructor(n){super(n),this.onUpdateBind=this.onUpdate.bind(this),this.onResizeBind=this.onResize.bind(this),this.onToggleBind=this.onToggle.bind(this),this.$container=this.$(\"container\")[0],this.$pattern=this.$(\"pattern\")[0],this.prevCount=null,this.currentTranslate=0,this.maxTranslate=this.$container.offsetWidth,this.idleVelocity=1,this.scrollVelocity=.1,this.scrollLerp=.8,this.scrollDirection=1,this.railDirection=this.getData(\"direction\"),this.showFrom=parseInt(this.getData(\"from\"))||!1,this.showTo=parseInt(this.getData(\"to\"))||!1,this.data=[],this.$items=[],this.glyphs=[\"\\u{1F6D1}\",\"\\u{1F51D}\",\"\\u{1F378}\",\"\\u26FA\",\"\\u{1F616}\"]}init(){this.bindEvents(),Nn(Cr.EAGER).then(n=>{this.onFontsLoaded(n)})}destroy(){super.destroy(),this.unbindEvents(),this.stop()}bindEvents(){window.addEventListener(tn.RESIZE_END,this.onResizeBind),window.addEventListener(\"toggleRail\",this.onToggleBind)}unbindEvents(){window.removeEventListener(tn.RESIZE_END,this.onResizeBind),window.removeEventListener(\"toggleRail\",this.onToggleBind)}onResize(){this.repeatPattern()}onFontsLoaded(){this.repeatPattern()}onUpdate(){this.currentTranslate=(this.currentTranslate+this.idleVelocity*this.scrollDirection*this.railDirection+this.scrollVelocity*this.scrollDirection*this.railDirection)%this.maxTranslate;for(let[n,t]of this.$items.entries()){let e,i=this.data[n].left+this.data[n].width;this.currentTranslate<i*-1?e=this.maxTranslate:this.currentTranslate>this.maxTranslate-i?e=-this.maxTranslate:e=0,this.data[n].translate=e,t.style.transform=`translate3d(${e}px,0,0)`}this.$container.style.transform=`translate3d(${this.currentTranslate}px,0,0)`}onScroll(n){let{velocity:t,direction:e}=n;Qi.IS_MOBILE||(this.scrollDirection=e!=0?e:this.scrollDirection,this.scrollDirection=this.scrollDirection*-1,this.scrollVelocity=Math.round(Math.abs(t))*this.scrollLerp)}onToggle(n){let{way:t}=n.detail;t===\"enter\"?this.start():this.stop()}start(){this.isPlaying||(this.isPlaying=!0,_t.ticker.add(this.onUpdateBind))}stop(){this.isPlaying&&(this.isPlaying=!1,_t.ticker.remove(this.onUpdateBind))}computeMetrics(n=!1){if(n){this.$items=this.el.querySelectorAll(\"[data-rail-item]\"),this.data=[],this.currentTranslate=0;for(let[t,e]of this.$items.entries()){let{left:i,width:r}=e.getBoundingClientRect();this.data[t]={left:i,width:r,translate:0}}}else for(let[t,e]of this.$items.entries()){let{left:i,width:r}=e.getBoundingClientRect();this.data[t].left=i-this.currentTranslate-this.data[t].translate,this.data[t].width=r}}repeatPattern(){if(this.showFrom&&window.innerWidth<this.showFrom||this.showTo&&window.innerWidth>this.showTo)return;let n=this.$pattern.offsetWidth,t=Math.ceil(window.innerWidth/n)+1;if(this.maxTranslate=t*n,t===this.prevCount)return this.computeMetrics();this.prevCount=t;let e=this.$container.querySelectorAll(\"[data-clone]\");for(let i of e)i.remove();for(let i=0;i<t-1;i++){let r=this.$pattern.cloneNode(!0);r.querySelector(\".c-rail_glyph\").innerHTML=this.glyphs[i],r.setAttribute(\"data-clone\",\"\"),r.setAttribute(\"aria-hidden\",\"true\"),this.$container.appendChild(r)}requestAnimationFrame(()=>{this.computeMetrics(!0)})}};var Ve=document.documentElement,ip=document.body;var Nl=\"5.0.1\";var Tf=\"1.3.17\";function Vl(n,t,e){return Math.max(n,Math.min(t,e))}function xf(n,t,e){return(1-e)*n+e*t}function Ff(n,t,e,i){return xf(n,t,1-Math.exp(-e*i))}function Af(n,t){return(n%t+t)%t}var Of=class{constructor(){I(this,\"isRunning\",!1);I(this,\"value\",0);I(this,\"from\",0);I(this,\"to\",0);I(this,\"currentTime\",0);I(this,\"lerp\");I(this,\"duration\");I(this,\"easing\");I(this,\"onUpdate\")}advance(n){var e;if(!this.isRunning)return;let t=!1;if(this.duration&&this.easing){this.currentTime+=n;let i=Vl(0,this.currentTime/this.duration,1);t=i>=1;let r=t?1:this.easing(i);this.value=this.from+(this.to-this.from)*r}else this.lerp?(this.value=Ff(this.value,this.to,this.lerp*60,n),Math.round(this.value)===this.to&&(this.value=this.to,t=!0)):(this.value=this.to,t=!0);t&&this.stop(),(e=this.onUpdate)==null||e.call(this,this.value,t)}stop(){this.isRunning=!1}fromTo(n,t,{lerp:e,duration:i,easing:r,onStart:s,onUpdate:o}){this.from=this.value=n,this.to=t,this.lerp=e,this.duration=i,this.easing=r,this.currentTime=0,this.isRunning=!0,s==null||s(),this.onUpdate=o}};function kf(n,t){let e;return function(...i){let r=this;clearTimeout(e),e=setTimeout(()=>{e=void 0,n.apply(r,i)},t)}}var Pf=class{constructor(n,t,{autoResize:e=!0,debounce:i=250}={}){I(this,\"width\",0);I(this,\"height\",0);I(this,\"scrollHeight\",0);I(this,\"scrollWidth\",0);I(this,\"debouncedResize\");I(this,\"wrapperResizeObserver\");I(this,\"contentResizeObserver\");I(this,\"resize\",()=>{this.onWrapperResize(),this.onContentResize()});I(this,\"onWrapperResize\",()=>{this.wrapper instanceof Window?(this.width=window.innerWidth,this.height=window.innerHeight):(this.width=this.wrapper.clientWidth,this.height=this.wrapper.clientHeight)});I(this,\"onContentResize\",()=>{this.wrapper instanceof Window?(this.scrollHeight=this.content.scrollHeight,this.scrollWidth=this.content.scrollWidth):(this.scrollHeight=this.wrapper.scrollHeight,this.scrollWidth=this.wrapper.scrollWidth)});this.wrapper=n,this.content=t,e&&(this.debouncedResize=kf(this.resize,i),this.wrapper instanceof Window?window.addEventListener(\"resize\",this.debouncedResize,!1):(this.wrapperResizeObserver=new ResizeObserver(this.debouncedResize),this.wrapperResizeObserver.observe(this.wrapper)),this.contentResizeObserver=new ResizeObserver(this.debouncedResize),this.contentResizeObserver.observe(this.content)),this.resize()}destroy(){var n,t;(n=this.wrapperResizeObserver)==null||n.disconnect(),(t=this.contentResizeObserver)==null||t.disconnect(),this.wrapper===window&&this.debouncedResize&&window.removeEventListener(\"resize\",this.debouncedResize,!1)}get limit(){return{x:this.scrollWidth-this.width,y:this.scrollHeight-this.height}}},Ul=class{constructor(){I(this,\"events\",{})}emit(n,...t){var i;let e=this.events[n]||[];for(let r=0,s=e.length;r<s;r++)(i=e[r])==null||i.call(e,...t)}on(n,t){var e;return(e=this.events[n])!=null&&e.push(t)||(this.events[n]=[t]),()=>{var i;this.events[n]=(i=this.events[n])==null?void 0:i.filter(r=>t!==r)}}off(n,t){var e;this.events[n]=(e=this.events[n])==null?void 0:e.filter(i=>t!==i)}destroy(){this.events={}}},Hl=100/6,ki={passive:!1},Rf=class{constructor(n,t={wheelMultiplier:1,touchMultiplier:1}){I(this,\"touchStart\",{x:0,y:0});I(this,\"lastDelta\",{x:0,y:0});I(this,\"window\",{width:0,height:0});I(this,\"emitter\",new Ul);I(this,\"onTouchStart\",n=>{let{clientX:t,clientY:e}=n.targetTouches?n.targetTouches[0]:n;this.touchStart.x=t,this.touchStart.y=e,this.lastDelta={x:0,y:0},this.emitter.emit(\"scroll\",{deltaX:0,deltaY:0,event:n})});I(this,\"onTouchMove\",n=>{let{clientX:t,clientY:e}=n.targetTouches?n.targetTouches[0]:n,i=-(t-this.touchStart.x)*this.options.touchMultiplier,r=-(e-this.touchStart.y)*this.options.touchMultiplier;this.touchStart.x=t,this.touchStart.y=e,this.lastDelta={x:i,y:r},this.emitter.emit(\"scroll\",{deltaX:i,deltaY:r,event:n})});I(this,\"onTouchEnd\",n=>{this.emitter.emit(\"scroll\",{deltaX:this.lastDelta.x,deltaY:this.lastDelta.y,event:n})});I(this,\"onWheel\",n=>{let{deltaX:t,deltaY:e,deltaMode:i}=n,r=i===1?Hl:i===2?this.window.width:1,s=i===1?Hl:i===2?this.window.height:1;t*=r,e*=s,t*=this.options.wheelMultiplier,e*=this.options.wheelMultiplier,this.emitter.emit(\"scroll\",{deltaX:t,deltaY:e,event:n})});I(this,\"onWindowResize\",()=>{this.window={width:window.innerWidth,height:window.innerHeight}});this.element=n,this.options=t,window.addEventListener(\"resize\",this.onWindowResize,!1),this.onWindowResize(),this.element.addEventListener(\"wheel\",this.onWheel,ki),this.element.addEventListener(\"touchstart\",this.onTouchStart,ki),this.element.addEventListener(\"touchmove\",this.onTouchMove,ki),this.element.addEventListener(\"touchend\",this.onTouchEnd,ki)}on(n,t){return this.emitter.on(n,t)}destroy(){this.emitter.destroy(),window.removeEventListener(\"resize\",this.onWindowResize,!1),this.element.removeEventListener(\"wheel\",this.onWheel,ki),this.element.removeEventListener(\"touchstart\",this.onTouchStart,ki),this.element.removeEventListener(\"touchmove\",this.onTouchMove,ki),this.element.removeEventListener(\"touchend\",this.onTouchEnd,ki)}},Wl=n=>Math.min(1,1.001-Math.pow(2,-10*n)),Yl=class{constructor({wrapper:n=window,content:t=document.documentElement,eventsTarget:e=n,smoothWheel:i=!0,syncTouch:r=!1,syncTouchLerp:s=.075,touchInertiaExponent:o=1.7,duration:a,easing:l,lerp:u=.1,infinite:c=!1,orientation:f=\"vertical\",gestureOrientation:d=f===\"horizontal\"?\"both\":\"vertical\",touchMultiplier:h=1,wheelMultiplier:_=1,autoResize:p=!0,prevent:g,virtualScroll:E,overscroll:y=!0,autoRaf:S=!1,anchors:D=!1,autoToggle:v=!1,allowNestedScroll:T=!1,__experimental__naiveDimensions:b=!1,naiveDimensions:x=b,stopInertiaOnNavigate:w=!1}={}){I(this,\"_isScrolling\",!1);I(this,\"_isStopped\",!1);I(this,\"_isLocked\",!1);I(this,\"_preventNextNativeScrollEvent\",!1);I(this,\"_resetVelocityTimeout\",null);I(this,\"_rafId\",null);I(this,\"isTouching\");I(this,\"time\",0);I(this,\"userData\",{});I(this,\"lastVelocity\",0);I(this,\"velocity\",0);I(this,\"direction\",0);I(this,\"options\");I(this,\"targetScroll\");I(this,\"animatedScroll\");I(this,\"animate\",new Of);I(this,\"emitter\",new Ul);I(this,\"dimensions\");I(this,\"virtualScroll\");I(this,\"onScrollEnd\",n=>{n instanceof CustomEvent||(this.isScrolling===\"smooth\"||this.isScrolling===!1)&&n.stopPropagation()});I(this,\"dispatchScrollendEvent\",()=>{this.options.wrapper.dispatchEvent(new CustomEvent(\"scrollend\",{bubbles:this.options.wrapper===window,detail:{lenisScrollEnd:!0}}))});I(this,\"onTransitionEnd\",n=>{n.propertyName.includes(\"overflow\")&&this.checkOverflow()});I(this,\"onClick\",n=>{let e=n.composedPath().filter(i=>i instanceof HTMLAnchorElement&&i.getAttribute(\"href\"));if(this.options.anchors){let i=e.find(r=>{var s;return(s=r.getAttribute(\"href\"))==null?void 0:s.includes(\"#\")});if(i){let r=i.getAttribute(\"href\");if(r){let s=typeof this.options.anchors==\"object\"&&this.options.anchors?this.options.anchors:void 0,o=`#${r.split(\"#\")[1]}`;this.scrollTo(o,s)}}}this.options.stopInertiaOnNavigate&&e.find(r=>r.host===window.location.host)&&this.reset()});I(this,\"onPointerDown\",n=>{n.button===1&&this.reset()});I(this,\"onVirtualScroll\",n=>{if(typeof this.options.virtualScroll==\"function\"&&this.options.virtualScroll(n)===!1)return;let{deltaX:t,deltaY:e,event:i}=n;if(this.emitter.emit(\"virtual-scroll\",{deltaX:t,deltaY:e,event:i}),i.ctrlKey||i.lenisStopPropagation)return;let r=i.type.includes(\"touch\"),s=i.type.includes(\"wheel\");this.isTouching=i.type===\"touchstart\"||i.type===\"touchmove\";let o=t===0&&e===0;if(this.options.syncTouch&&r&&i.type===\"touchstart\"&&o&&!this.isStopped&&!this.isLocked){this.reset();return}let l=this.options.gestureOrientation===\"vertical\"&&e===0||this.options.gestureOrientation===\"horizontal\"&&t===0;if(o||l)return;let u=i.composedPath();u=u.slice(0,u.indexOf(this.rootElement));let c=this.options.prevent;if(u.find(g=>{var E,y,S;return g instanceof HTMLElement&&(typeof c==\"function\"&&(c==null?void 0:c(g))||((E=g.hasAttribute)==null?void 0:E.call(g,\"data-lenis-prevent\"))||r&&((y=g.hasAttribute)==null?void 0:y.call(g,\"data-lenis-prevent-touch\"))||s&&((S=g.hasAttribute)==null?void 0:S.call(g,\"data-lenis-prevent-wheel\"))||this.options.allowNestedScroll&&this.checkNestedScroll(g,{deltaX:t,deltaY:e}))}))return;if(this.isStopped||this.isLocked){i.cancelable&&i.preventDefault();return}if(!(this.options.syncTouch&&r||this.options.smoothWheel&&s)){this.isScrolling=\"native\",this.animate.stop(),i.lenisStopPropagation=!0;return}let d=e;this.options.gestureOrientation===\"both\"?d=Math.abs(e)>Math.abs(t)?e:t:this.options.gestureOrientation===\"horizontal\"&&(d=t),(!this.options.overscroll||this.options.infinite||this.options.wrapper!==window&&this.limit>0&&(this.animatedScroll>0&&this.animatedScroll<this.limit||this.animatedScroll===0&&e>0||this.animatedScroll===this.limit&&e<0))&&(i.lenisStopPropagation=!0),i.cancelable&&i.preventDefault();let h=r&&this.options.syncTouch,p=r&&i.type===\"touchend\";p&&(d=Math.sign(this.velocity)*Math.pow(Math.abs(this.velocity),this.options.touchInertiaExponent)),this.scrollTo(this.targetScroll+d,Mn({programmatic:!1},h?{lerp:p?this.options.syncTouchLerp:1}:{lerp:this.options.lerp,duration:this.options.duration,easing:this.options.easing}))});I(this,\"onNativeScroll\",()=>{if(this._resetVelocityTimeout!==null&&(clearTimeout(this._resetVelocityTimeout),this._resetVelocityTimeout=null),this._preventNextNativeScrollEvent){this._preventNextNativeScrollEvent=!1;return}if(this.isScrolling===!1||this.isScrolling===\"native\"){let n=this.animatedScroll;this.animatedScroll=this.targetScroll=this.actualScroll,this.lastVelocity=this.velocity,this.velocity=this.animatedScroll-n,this.direction=Math.sign(this.animatedScroll-n),this.isStopped||(this.isScrolling=\"native\"),this.emit(),this.velocity!==0&&(this._resetVelocityTimeout=setTimeout(()=>{this.lastVelocity=this.velocity,this.velocity=0,this.isScrolling=!1,this.emit()},400))}});I(this,\"raf\",n=>{let t=n-(this.time||n);this.time=n,this.animate.advance(t*.001),this.options.autoRaf&&(this._rafId=requestAnimationFrame(this.raf))});window.lenisVersion=Tf,(!n||n===document.documentElement)&&(n=window),typeof a==\"number\"&&typeof l!=\"function\"?l=Wl:typeof l==\"function\"&&typeof a!=\"number\"&&(a=1),this.options={wrapper:n,content:t,eventsTarget:e,smoothWheel:i,syncTouch:r,syncTouchLerp:s,touchInertiaExponent:o,duration:a,easing:l,lerp:u,infinite:c,gestureOrientation:d,orientation:f,touchMultiplier:h,wheelMultiplier:_,autoResize:p,prevent:g,virtualScroll:E,overscroll:y,autoRaf:S,anchors:D,autoToggle:v,allowNestedScroll:T,naiveDimensions:x,stopInertiaOnNavigate:w},this.dimensions=new Pf(n,t,{autoResize:p}),this.updateClassName(),this.targetScroll=this.animatedScroll=this.actualScroll,this.options.wrapper.addEventListener(\"scroll\",this.onNativeScroll,!1),this.options.wrapper.addEventListener(\"scrollend\",this.onScrollEnd,{capture:!0}),(this.options.anchors||this.options.stopInertiaOnNavigate)&&this.options.wrapper.addEventListener(\"click\",this.onClick,!1),this.options.wrapper.addEventListener(\"pointerdown\",this.onPointerDown,!1),this.virtualScroll=new Rf(e,{touchMultiplier:h,wheelMultiplier:_}),this.virtualScroll.on(\"scroll\",this.onVirtualScroll),this.options.autoToggle&&(this.checkOverflow(),this.rootElement.addEventListener(\"transitionend\",this.onTransitionEnd,{passive:!0})),this.options.autoRaf&&(this._rafId=requestAnimationFrame(this.raf))}destroy(){this.emitter.destroy(),this.options.wrapper.removeEventListener(\"scroll\",this.onNativeScroll,!1),this.options.wrapper.removeEventListener(\"scrollend\",this.onScrollEnd,{capture:!0}),this.options.wrapper.removeEventListener(\"pointerdown\",this.onPointerDown,!1),(this.options.anchors||this.options.stopInertiaOnNavigate)&&this.options.wrapper.removeEventListener(\"click\",this.onClick,!1),this.virtualScroll.destroy(),this.dimensions.destroy(),this.cleanUpClassName(),this._rafId&&cancelAnimationFrame(this._rafId)}on(n,t){return this.emitter.on(n,t)}off(n,t){return this.emitter.off(n,t)}get overflow(){let n=this.isHorizontal?\"overflow-x\":\"overflow-y\";return getComputedStyle(this.rootElement)[n]}checkOverflow(){[\"hidden\",\"clip\"].includes(this.overflow)?this.internalStop():this.internalStart()}setScroll(n){this.isHorizontal?this.options.wrapper.scrollTo({left:n,behavior:\"instant\"}):this.options.wrapper.scrollTo({top:n,behavior:\"instant\"})}resize(){this.dimensions.resize(),this.animatedScroll=this.targetScroll=this.actualScroll,this.emit()}emit(){this.emitter.emit(\"scroll\",this)}reset(){this.isLocked=!1,this.isScrolling=!1,this.animatedScroll=this.targetScroll=this.actualScroll,this.lastVelocity=this.velocity=0,this.animate.stop()}start(){if(this.isStopped){if(this.options.autoToggle){this.rootElement.style.removeProperty(\"overflow\");return}this.internalStart()}}internalStart(){this.isStopped&&(this.reset(),this.isStopped=!1,this.emit())}stop(){if(!this.isStopped){if(this.options.autoToggle){this.rootElement.style.setProperty(\"overflow\",\"clip\");return}this.internalStop()}}internalStop(){this.isStopped||(this.reset(),this.isStopped=!0,this.emit())}scrollTo(n,{offset:t=0,immediate:e=!1,lock:i=!1,programmatic:r=!0,lerp:s=r?this.options.lerp:void 0,duration:o=r?this.options.duration:void 0,easing:a=r?this.options.easing:void 0,onStart:l,onComplete:u,force:c=!1,userData:f}={}){if(!((this.isStopped||this.isLocked)&&!c)){if(typeof n==\"string\"&&[\"top\",\"left\",\"start\",\"#\"].includes(n))n=0;else if(typeof n==\"string\"&&[\"bottom\",\"right\",\"end\"].includes(n))n=this.limit;else{let d;if(typeof n==\"string\"?(d=document.querySelector(n),d||(n===\"#top\"?n=0:console.warn(\"Lenis: Target not found\",n))):n instanceof HTMLElement&&(n!=null&&n.nodeType)&&(d=n),d){if(this.options.wrapper!==window){let _=this.rootElement.getBoundingClientRect();t-=this.isHorizontal?_.left:_.top}let h=d.getBoundingClientRect();n=(this.isHorizontal?h.left:h.top)+this.animatedScroll}}if(typeof n==\"number\"){if(n+=t,n=Math.round(n),this.options.infinite){if(r){this.targetScroll=this.animatedScroll=this.scroll;let d=n-this.animatedScroll;d>this.limit/2?n=n-this.limit:d<-this.limit/2&&(n=n+this.limit)}}else n=Vl(0,n,this.limit);if(n===this.targetScroll){l==null||l(this),u==null||u(this);return}if(this.userData=f!=null?f:{},e){this.animatedScroll=this.targetScroll=n,this.setScroll(this.scroll),this.reset(),this.preventNextNativeScrollEvent(),this.emit(),u==null||u(this),this.userData={},requestAnimationFrame(()=>{this.dispatchScrollendEvent()});return}r||(this.targetScroll=n),typeof o==\"number\"&&typeof a!=\"function\"?a=Wl:typeof a==\"function\"&&typeof o!=\"number\"&&(o=1),this.animate.fromTo(this.animatedScroll,n,{duration:o,easing:a,lerp:s,onStart:()=>{i&&(this.isLocked=!0),this.isScrolling=\"smooth\",l==null||l(this)},onUpdate:(d,h)=>{this.isScrolling=\"smooth\",this.lastVelocity=this.velocity,this.velocity=d-this.animatedScroll,this.direction=Math.sign(this.velocity),this.animatedScroll=d,this.setScroll(this.scroll),r&&(this.targetScroll=d),h||this.emit(),h&&(this.reset(),this.emit(),u==null||u(this),this.userData={},requestAnimationFrame(()=>{this.dispatchScrollendEvent()}),this.preventNextNativeScrollEvent())}})}}}preventNextNativeScrollEvent(){this._preventNextNativeScrollEvent=!0,requestAnimationFrame(()=>{this._preventNextNativeScrollEvent=!1})}checkNestedScroll(n,{deltaX:t,deltaY:e}){var v,T;let i=Date.now(),r=(v=n._lenis)!=null?v:n._lenis={},s,o,a,l,u,c,f,d,h=this.options.gestureOrientation;if(i-((T=r.time)!=null?T:0)>2e3){r.time=Date.now();let b=window.getComputedStyle(n);r.computedStyle=b;let x=b.overflowX,w=b.overflowY;if(s=[\"auto\",\"overlay\",\"scroll\"].includes(x),o=[\"auto\",\"overlay\",\"scroll\"].includes(w),r.hasOverflowX=s,r.hasOverflowY=o,!s&&!o||h===\"vertical\"&&!o||h===\"horizontal\"&&!s)return!1;u=n.scrollWidth,c=n.scrollHeight,f=n.clientWidth,d=n.clientHeight,a=u>f,l=c>d,r.isScrollableX=a,r.isScrollableY=l,r.scrollWidth=u,r.scrollHeight=c,r.clientWidth=f,r.clientHeight=d}else a=r.isScrollableX,l=r.isScrollableY,s=r.hasOverflowX,o=r.hasOverflowY,u=r.scrollWidth,c=r.scrollHeight,f=r.clientWidth,d=r.clientHeight;if(!s&&!o||!a&&!l||h===\"vertical\"&&(!o||!l)||h===\"horizontal\"&&(!s||!a))return!1;let _;if(h===\"horizontal\")_=\"x\";else if(h===\"vertical\")_=\"y\";else{let b=t!==0,x=e!==0;b&&s&&a&&(_=\"x\"),x&&o&&l&&(_=\"y\")}if(!_)return!1;let p,g,E,y,S;if(_===\"x\")p=n.scrollLeft,g=u-f,E=t,y=s,S=a;else if(_===\"y\")p=n.scrollTop,g=c-d,E=e,y=o,S=l;else return!1;return(E>0?p<g:p>0)&&y&&S}get rootElement(){return this.options.wrapper===window?document.documentElement:this.options.wrapper}get limit(){return this.options.naiveDimensions?this.isHorizontal?this.rootElement.scrollWidth-this.rootElement.clientWidth:this.rootElement.scrollHeight-this.rootElement.clientHeight:this.dimensions.limit[this.isHorizontal?\"x\":\"y\"]}get isHorizontal(){return this.options.orientation===\"horizontal\"}get actualScroll(){var t,e;let n=this.options.wrapper;return this.isHorizontal?(t=n.scrollX)!=null?t:n.scrollLeft:(e=n.scrollY)!=null?e:n.scrollTop}get scroll(){return this.options.infinite?Af(this.animatedScroll,this.limit):this.animatedScroll}get progress(){return this.limit===0?1:this.scroll/this.limit}get isScrolling(){return this._isScrolling}set isScrolling(n){this._isScrolling!==n&&(this._isScrolling=n,this.updateClassName())}get isStopped(){return this._isStopped}set isStopped(n){this._isStopped!==n&&(this._isStopped=n,this.updateClassName())}get isLocked(){return this._isLocked}set isLocked(n){this._isLocked!==n&&(this._isLocked=n,this.updateClassName())}get isSmooth(){return this.isScrolling===\"smooth\"}get className(){let n=\"lenis\";return this.options.autoToggle&&(n+=\" lenis-autoToggle\"),this.isStopped&&(n+=\" lenis-stopped\"),this.isLocked&&(n+=\" lenis-locked\"),this.isScrolling&&(n+=\" lenis-scrolling\"),this.isScrolling===\"smooth\"&&(n+=\" lenis-smooth\"),n}updateClassName(){this.cleanUpClassName(),this.rootElement.className=`${this.rootElement.className} ${this.className}`.trim()}cleanUpClassName(){this.rootElement.className=this.rootElement.className.replace(/lenis(-\\w+)?/g,\"\").trim()}};var Sr=class{constructor({scrollElements:t,rootMargin:e=\"-1px -1px -1px -1px\",root:i=null,IORaf:r}){this.scrollElements=t,this.rootMargin=e,this.root=i,this.IORaf=r,this._init()}_init(){let t={root:this.root,rootMargin:this.rootMargin},e=i=>{i.forEach(r=>{let s=this.scrollElements.find(o=>o.$el===r.target);r.isIntersecting?(s&&(s.isAlreadyIntersected=!0),this._setInview(r)):s&&s.isAlreadyIntersected&&this._setOutOfView(r)})};this.observer=new IntersectionObserver(e,t);for(let i of this.scrollElements){let r=i.$el;this.observe(r)}}destroy(){this.observer.disconnect()}observe(t){t&&this.observer.observe(t)}unobserve(t){t&&this.observer.unobserve(t)}_setInview(t){let e=this.scrollElements.find(i=>i.$el===t.target);this.IORaf&&(e==null||e.setInteractivityOn()),!this.IORaf&&(e==null||e.setInview())}_setOutOfView(t){let e=this.scrollElements.find(i=>i.$el===t.target);this.IORaf&&(e==null||e.setInteractivityOff()),!this.IORaf&&(e==null||e.setOutOfView()),!(e!=null&&e.attributes.scrollRepeat)&&!this.IORaf&&this.unobserve(t.target)}};function $l(n,t,e){return e<n?n:e>t?t:e}function Io(n,t,e,i,r){let s=t-n,o=i-e;return e+((r-n)/s*o||0)}function jl(n,t,e){return Io(n,t,0,1,e)}function Lo(n,t){return n.reduce((e,i)=>Math.abs(i-t)<Math.abs(e-t)?i:e)}var Mf=\"is-inview\",Xl=\"--progress\",en=class{constructor({$el:t,id:e,subscribeElementUpdateFn:i,unsubscribeElementUpdateFn:r,needRaf:s,scrollOrientation:o,lenisInstance:a}){this.startPositionHandlers={start:(t,e,i)=>t-e+i,middle:(t,e,i,r)=>t-e+i+r*.5,end:(t,e,i,r)=>t-e+i+r,fold:()=>0};this.endPositionHandlers={start:(t,e)=>t-e,middle:(t,e,i)=>t-e+i*.5,end:(t,e,i)=>t-e+i};var l,u,c,f,d;this.$el=t,this.id=e,this.needRaf=s,this.scrollOrientation=o,this.lenisInstance=a,this.subscribeElementUpdateFn=i,this.unsubscribeElementUpdateFn=r,this.attributes={scrollClass:(l=this.$el.dataset.scrollClass)!=null?l:Mf,scrollOffset:(u=this.$el.dataset.scrollOffset)!=null?u:\"0,0\",scrollPosition:(c=this.$el.dataset.scrollPosition)!=null?c:\"start,end\",scrollCssProgress:this.$el.dataset.scrollCssProgress!==void 0,scrollEventProgress:(f=this.$el.dataset.scrollEventProgress)!=null?f:null,scrollSpeed:this.$el.dataset.scrollSpeed!==void 0?parseFloat(this.$el.dataset.scrollSpeed):null,scrollRepeat:this.$el.dataset.scrollRepeat!==void 0,scrollCall:(d=this.$el.dataset.scrollCall)!=null?d:null,scrollIgnoreFold:this.$el.dataset.scrollIgnoreFold!==void 0,scrollEnableTouchSpeed:this.$el.dataset.scrollEnableTouchSpeed!==void 0},this.intersection={start:0,end:0},this.metrics={offsetStart:0,offsetEnd:0,bcr:{}},this.currentScroll=this.lenisInstance.scroll,this.translateValue=0,this.progress=0,this.lastProgress=null,this.isInview=!1,this.isInteractive=!1,this.isAlreadyIntersected=!1,this.isInFold=!1,this.isFirstResize=!0,this.getWindowSize=this.scrollOrientation===\"vertical\"?()=>this.lenisInstance.dimensions.height:()=>this.lenisInstance.dimensions.width,this.getMetricsStart=this.scrollOrientation===\"vertical\"?h=>h.top:h=>h.left,this.getMetricsSize=this.scrollOrientation===\"vertical\"?h=>h.height:h=>h.width,this._init()}_init(){this.needRaf&&this._resize()}onResize({currentScroll:t}){this.currentScroll=t,this._resize()}onRender({currentScroll:t,smooth:e}){let i=this.getWindowSize();if(this.currentScroll=t,this._computeProgress(),this.attributes.scrollSpeed&&!isNaN(this.attributes.scrollSpeed))if(!this.attributes.scrollEnableTouchSpeed&&!e)this.translateValue&&(this.$el.style.transform=\"translate3d(0, 0, 0)\"),this.translateValue=0;else{if(this.isInFold){let r=Math.max(0,this.progress);this.translateValue=r*i*this.attributes.scrollSpeed*-1}else{let r=Io(0,1,-1,1,this.progress);this.translateValue=r*i*this.attributes.scrollSpeed*-1}this.$el.style.transform=this.scrollOrientation===\"vertical\"?`translate3d(0, ${this.translateValue}px, 0)`:`translate3d(${this.translateValue}px, 0, 0)`}}setInview(){if(this.isInview)return;this.isInview=!0,this.$el.classList.add(this.attributes.scrollClass);let t=\"enter\",e=this._getScrollCallFrom();this.attributes.scrollCall&&this._dispatchCall(t,e)}setOutOfView(){if(!(this.isInview&&this.attributes.scrollRepeat))return;this.isInview=!1,this.$el.classList.remove(this.attributes.scrollClass);let t=\"leave\",e=this._getScrollCallFrom();this.attributes.scrollCall&&this._dispatchCall(t,e)}setInteractivityOn(){this.isInteractive||(this.isInteractive=!0,this.subscribeElementUpdateFn(this))}setInteractivityOff(){this.isInteractive&&(this.isInteractive=!1,this.unsubscribeElementUpdateFn(this),this.lastProgress!==null&&this._computeProgress(Lo([0,1],this.lastProgress)))}_resize(){this.metrics.bcr=this.$el.getBoundingClientRect(),this._computeMetrics(),this._computeIntersection(),this.isFirstResize&&(this.isFirstResize=!1,this.isInFold&&this.setInview())}_computeMetrics(){let t=this.getWindowSize(),e=this.getMetricsStart(this.metrics.bcr),i=this.getMetricsSize(this.metrics.bcr);this.metrics.offsetStart=this.currentScroll+e-this.translateValue,this.metrics.offsetEnd=this.metrics.offsetStart+i,this.metrics.offsetStart<t&&!this.attributes.scrollIgnoreFold?this.isInFold=!0:this.isInFold=!1}_computeIntersection(){var h,_,p,g,E,y,S,D;let t=this.getWindowSize(),e=this.getMetricsSize(this.metrics.bcr),i=this.attributes.scrollOffset.split(\",\"),r=(_=(h=i[0])==null?void 0:h.trim())!=null?_:\"0\",s=(g=(p=i[1])==null?void 0:p.trim())!=null?g:\"0\",o=this.attributes.scrollPosition.split(\",\"),a=(y=(E=o[0])==null?void 0:E.trim())!=null?y:\"start\",l=(D=(S=o[1])==null?void 0:S.trim())!=null?D:\"end\",u=r.includes(\"%\")?t*parseInt(r.replace(\"%\",\"\").trim())*.01:parseInt(r),c=s.includes(\"%\")?t*parseInt(s.replace(\"%\",\"\").trim())*.01:parseInt(s);this.isInFold&&(a=\"fold\");let f=this.startPositionHandlers[a];this.intersection.start=f?f(this.metrics.offsetStart,t,u,e):this.metrics.offsetStart-t+u;let d=this.endPositionHandlers[l];if(this.intersection.end=d?d(this.metrics.offsetStart,c,e):this.metrics.offsetStart-c+e,this.intersection.end<=this.intersection.start)switch(l){case\"start\":this.intersection.end=this.intersection.start+1;break;case\"middle\":this.intersection.end=this.intersection.start+e*.5;break;case\"end\":this.intersection.end=this.intersection.start+e;break;default:this.intersection.end=this.intersection.start+1;break}}_computeProgress(t){let e=t!=null?t:$l(0,1,jl(this.intersection.start,this.intersection.end,this.currentScroll));this.progress=e,e!==this.lastProgress&&(this.lastProgress=e,this.attributes.scrollCssProgress&&this._setCssProgress(e),this.attributes.scrollEventProgress&&this._setCustomEventProgress(e),e>0&&e<1&&this.setInview(),e===0&&this.setOutOfView(),e===1&&this.setOutOfView())}_setCssProgress(t=0){this.$el.style.setProperty(Xl,t.toString())}_setCustomEventProgress(t=0){let e=this.attributes.scrollEventProgress;if(!e)return;let i=new CustomEvent(e,{detail:{target:this.$el,progress:t}});window.dispatchEvent(i)}_getScrollCallFrom(){let t=Lo([this.intersection.start,this.intersection.end],this.currentScroll);return this.intersection.start===t?\"start\":\"end\"}destroy(){this.attributes.scrollCssProgress&&this.$el.style.removeProperty(Xl),this.attributes.scrollSpeed&&this.$el.style.removeProperty(\"transform\"),this.isInview&&this.attributes.scrollClass&&this.$el.classList.remove(this.attributes.scrollClass)}_dispatchCall(t,e){let i=this.attributes.scrollCall;if(!i)return;let r=new CustomEvent(i,{detail:{target:this.$el,way:t,from:e}});window.dispatchEvent(r)}};var If=[\"scrollOffset\",\"scrollPosition\",\"scrollCssProgress\",\"scrollEventProgress\",\"scrollSpeed\"],Lf=\"-1px -1px -1px -1px\",Bf=\"100% 100% 100% 100%\",zf=\"0,0\",Nf=\"top,bottom\",rn=class{constructor({$el:t,triggerRootMargin:e,rafRootMargin:i,scrollOrientation:r,lenisInstance:s}){if(!t){console.error(\"Please provide a DOM Element as scrollContainer\");return}this.$scrollContainer=t,this.lenisInstance=s,this.scrollOrientation=r,this.triggerRootMargin=e!=null?e:Lf,this.rafRootMargin=i!=null?i:Bf,this.scrollElements=[],this.triggeredScrollElements=[],this.RAFScrollElements=[],this.scrollElementsToUpdate=[],this._init()}_init(){let t=this.$scrollContainer.querySelectorAll(\"[data-scroll]\"),e=this.toElementArray(t);this._subscribeScrollElements(e);let i=this.lenisInstance.options.wrapper===window?null:this.lenisInstance.options.wrapper;this.IOTriggerInstance=new Sr({scrollElements:[...this.triggeredScrollElements],root:i,rootMargin:this.triggerRootMargin,IORaf:!1}),this.IORafInstance=new Sr({scrollElements:[...this.RAFScrollElements],root:i,rootMargin:this.rafRootMargin,IORaf:!0})}destroy(){this.IOTriggerInstance.destroy(),this.IORafInstance.destroy(),this._unsubscribeAllScrollElements()}onResize({currentScroll:t}){for(let e of this.RAFScrollElements)e.onResize({currentScroll:t})}onRender({currentScroll:t,smooth:e}){for(let i of this.scrollElementsToUpdate)i.onRender({currentScroll:t,smooth:e})}removeScrollElements(t){let e=t.querySelectorAll(\"[data-scroll]\");if(!e.length)return;let i=new Set(Array.from(e));for(let r=0;r<this.triggeredScrollElements.length;r++){let s=this.triggeredScrollElements[r];i.has(s.$el)&&(this.IOTriggerInstance.unobserve(s.$el),this.triggeredScrollElements.splice(r,1))}for(let r=0;r<this.RAFScrollElements.length;r++){let s=this.RAFScrollElements[r];i.has(s.$el)&&(this.IORafInstance.unobserve(s.$el),this.RAFScrollElements.splice(r,1))}e.forEach(r=>{let s=this.scrollElementsToUpdate.find(a=>a.$el===r),o=this.scrollElements.find(a=>a.$el===r);s&&this._unsubscribeElementUpdate(s),o&&(this.scrollElements=this.scrollElements.filter(a=>a.id!=o.id))})}addScrollElements(t){let e=t.querySelectorAll(\"[data-scroll]\"),i=[];this.scrollElements.forEach(a=>{i.push(a.id)});let s=Math.max(...i,0)+1,o=this.toElementArray(e);this._subscribeScrollElements(o,s,!0)}_subscribeScrollElements(t,e=0,i=!1){for(let r=0;r<t.length;r++){let s=t[r],o=this._checkRafNeeded(s),a=new en({$el:s,id:e+r,scrollOrientation:this.scrollOrientation,lenisInstance:this.lenisInstance,subscribeElementUpdateFn:this._subscribeElementUpdate.bind(this),unsubscribeElementUpdateFn:this._unsubscribeElementUpdate.bind(this),needRaf:o});this.scrollElements.push(a),o?(this.RAFScrollElements.push(a),i&&(this.IORafInstance.scrollElements.push(a),this.IORafInstance.observe(a.$el))):(this.triggeredScrollElements.push(a),i&&(this.IOTriggerInstance.scrollElements.push(a),this.IOTriggerInstance.observe(a.$el)))}}_unsubscribeAllScrollElements(){for(let t of this.scrollElements)t.destroy();this.scrollElements=[],this.RAFScrollElements=[],this.triggeredScrollElements=[],this.scrollElementsToUpdate=[]}_subscribeElementUpdate(t){this.scrollElementsToUpdate.push(t)}_unsubscribeElementUpdate(t){this.scrollElementsToUpdate=this.scrollElementsToUpdate.filter(e=>e.id!=t.id)}toElementArray(t){return Array.from(t)}_checkRafNeeded(t){let e=[...If],i=r=>{e=e.filter(s=>s!==r)};if(t.dataset.scrollOffset){if(t.dataset.scrollOffset.split(\",\").map(s=>s.replace(\"%\",\"\").trim()).join(\",\")!==zf)return!0;i(\"scrollOffset\")}else i(\"scrollOffset\");if(t.dataset.scrollPosition){if(t.dataset.scrollPosition.trim()!==Nf)return!0;i(\"scrollPosition\")}else i(\"scrollPosition\");if(t.dataset.scrollSpeed&&!isNaN(parseFloat(t.dataset.scrollSpeed)))return!0;i(\"scrollSpeed\");for(let r of e)if(r in t.dataset)return!0;return!1}};var nn=class{constructor({lenisOptions:t={},triggerRootMargin:e,rafRootMargin:i,autoStart:r=!0,scrollCallback:s=()=>{},initCustomTicker:o,destroyCustomTicker:a}={}){this.lenisInstance=null;this.coreInstance=null;window.locomotiveScrollVersion=Nl,Object.assign(this,{lenisOptions:t,triggerRootMargin:e,rafRootMargin:i,autoStart:r,scrollCallback:s,initCustomTicker:o,destroyCustomTicker:a}),this._onRenderBind=this._onRender.bind(this),this._onScrollToBind=this._onScrollTo.bind(this),this._onResizeBind=this._onResize.bind(this),this.rafPlaying=!1,this.isTouchDevice=\"ontouchstart\"in window||navigator.maxTouchPoints>0,this._init()}_init(){this.lenisInstance=new Yl(Mn({},this.lenisOptions)),this.scrollCallback&&this.lenisInstance.on(\"scroll\",this.scrollCallback),document.documentElement.setAttribute(\"data-scroll-orientation\",this.lenisInstance.options.orientation),requestAnimationFrame(()=>{this.coreInstance=new rn({$el:this.lenisInstance.rootElement,triggerRootMargin:this.triggerRootMargin,rafRootMargin:this.rafRootMargin,scrollOrientation:this.lenisInstance.options.orientation,lenisInstance:this.lenisInstance}),this._bindEvents(),this.initCustomTicker&&!this.destroyCustomTicker?console.warn(\"initCustomTicker callback is declared, but destroyCustomTicker is not. Please pay attention. It could cause trouble.\"):!this.initCustomTicker&&this.destroyCustomTicker&&console.warn(\"destroyCustomTicker callback is declared, but initCustomTicker is not. Please pay attention. It could cause trouble.\"),this.autoStart&&this.start()})}destroy(){var t;this.stop(),this._unbindEvents(),(t=this.lenisInstance)==null||t.destroy(),requestAnimationFrame(()=>{var e;(e=this.coreInstance)==null||e.destroy()})}_bindEvents(){this._bindScrollToEvents(),this.lenisInstance&&(this._originalOnContentResize=this.lenisInstance.dimensions.onContentResize.bind(this.lenisInstance.dimensions),this._originalOnWrapperResize=this.lenisInstance.dimensions.onWrapperResize.bind(this.lenisInstance.dimensions),this.lenisInstance.dimensions.onContentResize=()=>{var t;(t=this._originalOnContentResize)==null||t.call(this),this._onResizeBind()},this.lenisInstance.dimensions.onWrapperResize=()=>{var t;(t=this._originalOnWrapperResize)==null||t.call(this),this._onResizeBind()})}_unbindEvents(){this._unbindScrollToEvents(),this.lenisInstance&&(this._originalOnContentResize&&(this.lenisInstance.dimensions.onContentResize=this._originalOnContentResize),this._originalOnWrapperResize&&(this.lenisInstance.dimensions.onWrapperResize=this._originalOnWrapperResize))}_bindScrollToEvents(t){var r;let e=t||((r=this.lenisInstance)==null?void 0:r.rootElement),i=e==null?void 0:e.querySelectorAll(\"[data-scroll-to]\");i!=null&&i.length&&i.forEach(s=>{s.addEventListener(\"click\",this._onScrollToBind,!1)})}_unbindScrollToEvents(t){var r;let e=t||((r=this.lenisInstance)==null?void 0:r.rootElement),i=e==null?void 0:e.querySelectorAll(\"[data-scroll-to]\");i!=null&&i.length&&i.forEach(s=>{s.removeEventListener(\"click\",this._onScrollToBind,!1)})}_onResize(){var t,e,i;(i=this.coreInstance)==null||i.onResize({currentScroll:(e=(t=this.lenisInstance)==null?void 0:t.scroll)!=null?e:0,smooth:!this.isTouchDevice})}_onRender(){var t,e,i,r;(t=this.lenisInstance)==null||t.raf(Date.now()),(r=this.coreInstance)==null||r.onRender({currentScroll:(i=(e=this.lenisInstance)==null?void 0:e.scroll)!=null?i:0,smooth:!this.isTouchDevice})}_onScrollTo(t){var o,a;t.preventDefault();let e=(o=t.currentTarget)!=null?o:null;if(!e)return;let i=e.getAttribute(\"data-scroll-to-href\")||e.getAttribute(\"href\"),r=e.getAttribute(\"data-scroll-to-offset\")||0,s=e.getAttribute(\"data-scroll-to-duration\")||((a=this.lenisInstance)==null?void 0:a.options.duration);i&&this.scrollTo(i,{offset:typeof r==\"string\"?parseInt(r):r,duration:typeof s==\"string\"?parseInt(s):s})}start(){var t;this.rafPlaying||((t=this.lenisInstance)==null||t.start(),this.rafPlaying=!0,this.initCustomTicker?this.initCustomTicker(this._onRenderBind):this._raf())}stop(){var t;this.rafPlaying&&((t=this.lenisInstance)==null||t.stop(),this.rafPlaying=!1,this.destroyCustomTicker?this.destroyCustomTicker(this._onRenderBind):this.rafInstance&&cancelAnimationFrame(this.rafInstance))}removeScrollElements(t){var e;if(!t){console.error(\"Please provide a DOM Element as $oldContainer\");return}this._unbindScrollToEvents(t),(e=this.coreInstance)==null||e.removeScrollElements(t)}addScrollElements(t){var e;if(!t){console.error(\"Please provide a DOM Element as $newContainer\");return}(e=this.coreInstance)==null||e.addScrollElements(t),requestAnimationFrame(()=>{this._bindScrollToEvents(t)})}resize(){this._onResizeBind()}scrollTo(t,e){var i;(i=this.lenisInstance)==null||i.scrollTo(t,{offset:e==null?void 0:e.offset,lerp:e==null?void 0:e.lerp,duration:e==null?void 0:e.duration,immediate:e==null?void 0:e.immediate,lock:e==null?void 0:e.lock,force:e==null?void 0:e.force,easing:e==null?void 0:e.easing,onComplete:e==null?void 0:e.onComplete})}_raf(){this._onRenderBind(),this.rafInstance=requestAnimationFrame(()=>this._raf())}};var sn=class extends de{constructor(t){super(t),this.onScrollBind=this.onScroll.bind(this),this.changeHeaderThemeBind=this.changeHeaderTheme.bind(this)}init(){this.scroll=new nn({modularInstance:this,scrollCallback:this.onScrollBind}),history.scrollRestoration&&(history.scrollRestoration=\"manual\",window.scrollTo(0,0)),this.bindEvents()}destroy(){this.unbindEvents(),this.scroll.destroy()}bindEvents(){window.addEventListener(\"changeHeaderTheme\",this.changeHeaderThemeBind)}unbindEvents(){window.removeEventListener(\"changeHeaderTheme\",this.changeHeaderThemeBind)}onScroll({scroll:t,limit:e,velocity:i,direction:r,progress:s}){s>this.lastProgress?this.scrollDirection!=1&&(this.scrollDirection=1):this.scrollDirection!=-1&&(this.scrollDirection=-1),this.scrollDirection<0?Ve.classList.add(\"is-scrolling-up\"):Ve.classList.remove(\"is-scrolling-up\"),this.lastProgress=s,this.call(\"onScroll\",{velocity:i,direction:r},\"Rail\")}scrollTo(t){var s;let r=t,{target:e}=r,i=Ns(r,[\"target\"]);i=Object.assign({duration:1},i),(s=this.scroll)==null||s.scrollTo(e,i)}changeHeaderTheme(t){var r;let{target:e,way:i}=t.detail;if(i==\"enter\"){let s=(r=e==null?void 0:e.parentNode)==null?void 0:r.getAttribute(\"data-theme\");s&&Ve.setAttribute(\"data-header-theme\",s)}}addScrollElements(t){var e;(e=this.scroll)==null||e.addScrollElements(t)}removeScrollElements(t){var e;(e=this.scroll)==null||e.removeScrollElements(t)}};var Hf=/(?:^\\s+|\\s+$)/g,Wf=/([\\uD800-\\uDBFF][\\uDC00-\\uDFFF](?:[\\u200D\\uFE0F][\\uD800-\\uDBFF][\\uDC00-\\uDFFF]){2,}|\\uD83D\\uDC69(?:\\u200D(?:(?:\\uD83D\\uDC69\\u200D)?\\uD83D\\uDC67|(?:\\uD83D\\uDC69\\u200D)?\\uD83D\\uDC66)|\\uD83C[\\uDFFB-\\uDFFF])|\\uD83D\\uDC69\\u200D(?:\\uD83D\\uDC69\\u200D)?\\uD83D\\uDC66\\u200D\\uD83D\\uDC66|\\uD83D\\uDC69\\u200D(?:\\uD83D\\uDC69\\u200D)?\\uD83D\\uDC67\\u200D(?:\\uD83D[\\uDC66\\uDC67])|\\uD83C\\uDFF3\\uFE0F\\u200D\\uD83C\\uDF08|(?:\\uD83C[\\uDFC3\\uDFC4\\uDFCA]|\\uD83D[\\uDC6E\\uDC71\\uDC73\\uDC77\\uDC81\\uDC82\\uDC86\\uDC87\\uDE45-\\uDE47\\uDE4B\\uDE4D\\uDE4E\\uDEA3\\uDEB4-\\uDEB6]|\\uD83E[\\uDD26\\uDD37-\\uDD39\\uDD3D\\uDD3E\\uDDD6-\\uDDDD])(?:\\uD83C[\\uDFFB-\\uDFFF])\\u200D[\\u2642\\u2640]\\uFE0F|\\uD83D\\uDC69(?:\\uD83C[\\uDFFB-\\uDFFF])\\u200D(?:\\uD83C[\\uDF3E\\uDF73\\uDF93\\uDFA4\\uDFA8\\uDFEB\\uDFED]|\\uD83D[\\uDCBB\\uDD27\\uDCBC\\uDD2C\\uDE80\\uDE92])|(?:\\uD83C[\\uDFC3\\uDFC4\\uDFCA]|\\uD83D[\\uDC6E\\uDC6F\\uDC71\\uDC73\\uDC77\\uDC81\\uDC82\\uDC86\\uDC87\\uDE45-\\uDE47\\uDE4B\\uDE4D\\uDE4E\\uDEA3\\uDEB4-\\uDEB6]|\\uD83E[\\uDD26\\uDD37-\\uDD39\\uDD3C-\\uDD3E\\uDDD6-\\uDDDF])\\u200D[\\u2640\\u2642]\\uFE0F|\\uD83C\\uDDFD\\uD83C\\uDDF0|\\uD83C\\uDDF6\\uD83C\\uDDE6|\\uD83C\\uDDF4\\uD83C\\uDDF2|\\uD83C\\uDDE9(?:\\uD83C[\\uDDEA\\uDDEC\\uDDEF\\uDDF0\\uDDF2\\uDDF4\\uDDFF])|\\uD83C\\uDDF7(?:\\uD83C[\\uDDEA\\uDDF4\\uDDF8\\uDDFA\\uDDFC])|\\uD83C\\uDDE8(?:\\uD83C[\\uDDE6\\uDDE8\\uDDE9\\uDDEB-\\uDDEE\\uDDF0-\\uDDF5\\uDDF7\\uDDFA-\\uDDFF])|(?:\\u26F9|\\uD83C[\\uDFCC\\uDFCB]|\\uD83D\\uDD75)(?:\\uFE0F\\u200D[\\u2640\\u2642]|(?:\\uD83C[\\uDFFB-\\uDFFF])\\u200D[\\u2640\\u2642])\\uFE0F|(?:\\uD83D\\uDC41\\uFE0F\\u200D\\uD83D\\uDDE8|\\uD83D\\uDC69(?:\\uD83C[\\uDFFB-\\uDFFF])\\u200D[\\u2695\\u2696\\u2708]|\\uD83D\\uDC69\\u200D[\\u2695\\u2696\\u2708]|\\uD83D\\uDC68(?:(?:\\uD83C[\\uDFFB-\\uDFFF])\\u200D[\\u2695\\u2696\\u2708]|\\u200D[\\u2695\\u2696\\u2708]))\\uFE0F|\\uD83C\\uDDF2(?:\\uD83C[\\uDDE6\\uDDE8-\\uDDED\\uDDF0-\\uDDFF])|\\uD83D\\uDC69\\u200D(?:\\uD83C[\\uDF3E\\uDF73\\uDF93\\uDFA4\\uDFA8\\uDFEB\\uDFED]|\\uD83D[\\uDCBB\\uDCBC\\uDD27\\uDD2C\\uDE80\\uDE92]|\\u2764\\uFE0F\\u200D(?:\\uD83D\\uDC8B\\u200D(?:\\uD83D[\\uDC68\\uDC69])|\\uD83D[\\uDC68\\uDC69]))|\\uD83C\\uDDF1(?:\\uD83C[\\uDDE6-\\uDDE8\\uDDEE\\uDDF0\\uDDF7-\\uDDFB\\uDDFE])|\\uD83C\\uDDEF(?:\\uD83C[\\uDDEA\\uDDF2\\uDDF4\\uDDF5])|\\uD83C\\uDDED(?:\\uD83C[\\uDDF0\\uDDF2\\uDDF3\\uDDF7\\uDDF9\\uDDFA])|\\uD83C\\uDDEB(?:\\uD83C[\\uDDEE-\\uDDF0\\uDDF2\\uDDF4\\uDDF7])|[#\\*0-9]\\uFE0F\\u20E3|\\uD83C\\uDDE7(?:\\uD83C[\\uDDE6\\uDDE7\\uDDE9-\\uDDEF\\uDDF1-\\uDDF4\\uDDF6-\\uDDF9\\uDDFB\\uDDFC\\uDDFE\\uDDFF])|\\uD83C\\uDDE6(?:\\uD83C[\\uDDE8-\\uDDEC\\uDDEE\\uDDF1\\uDDF2\\uDDF4\\uDDF6-\\uDDFA\\uDDFC\\uDDFD\\uDDFF])|\\uD83C\\uDDFF(?:\\uD83C[\\uDDE6\\uDDF2\\uDDFC])|\\uD83C\\uDDF5(?:\\uD83C[\\uDDE6\\uDDEA-\\uDDED\\uDDF0-\\uDDF3\\uDDF7-\\uDDF9\\uDDFC\\uDDFE])|\\uD83C\\uDDFB(?:\\uD83C[\\uDDE6\\uDDE8\\uDDEA\\uDDEC\\uDDEE\\uDDF3\\uDDFA])|\\uD83C\\uDDF3(?:\\uD83C[\\uDDE6\\uDDE8\\uDDEA-\\uDDEC\\uDDEE\\uDDF1\\uDDF4\\uDDF5\\uDDF7\\uDDFA\\uDDFF])|\\uD83C\\uDFF4\\uDB40\\uDC67\\uDB40\\uDC62(?:\\uDB40\\uDC77\\uDB40\\uDC6C\\uDB40\\uDC73|\\uDB40\\uDC73\\uDB40\\uDC63\\uDB40\\uDC74|\\uDB40\\uDC65\\uDB40\\uDC6E\\uDB40\\uDC67)\\uDB40\\uDC7F|\\uD83D\\uDC68(?:\\u200D(?:\\u2764\\uFE0F\\u200D(?:\\uD83D\\uDC8B\\u200D)?\\uD83D\\uDC68|(?:(?:\\uD83D[\\uDC68\\uDC69])\\u200D)?\\uD83D\\uDC66\\u200D\\uD83D\\uDC66|(?:(?:\\uD83D[\\uDC68\\uDC69])\\u200D)?\\uD83D\\uDC67\\u200D(?:\\uD83D[\\uDC66\\uDC67])|\\uD83C[\\uDF3E\\uDF73\\uDF93\\uDFA4\\uDFA8\\uDFEB\\uDFED]|\\uD83D[\\uDCBB\\uDCBC\\uDD27\\uDD2C\\uDE80\\uDE92])|(?:\\uD83C[\\uDFFB-\\uDFFF])\\u200D(?:\\uD83C[\\uDF3E\\uDF73\\uDF93\\uDFA4\\uDFA8\\uDFEB\\uDFED]|\\uD83D[\\uDCBB\\uDCBC\\uDD27\\uDD2C\\uDE80\\uDE92]))|\\uD83C\\uDDF8(?:\\uD83C[\\uDDE6-\\uDDEA\\uDDEC-\\uDDF4\\uDDF7-\\uDDF9\\uDDFB\\uDDFD-\\uDDFF])|\\uD83C\\uDDF0(?:\\uD83C[\\uDDEA\\uDDEC-\\uDDEE\\uDDF2\\uDDF3\\uDDF5\\uDDF7\\uDDFC\\uDDFE\\uDDFF])|\\uD83C\\uDDFE(?:\\uD83C[\\uDDEA\\uDDF9])|\\uD83C\\uDDEE(?:\\uD83C[\\uDDE8-\\uDDEA\\uDDF1-\\uDDF4\\uDDF6-\\uDDF9])|\\uD83C\\uDDF9(?:\\uD83C[\\uDDE6\\uDDE8\\uDDE9\\uDDEB-\\uDDED\\uDDEF-\\uDDF4\\uDDF7\\uDDF9\\uDDFB\\uDDFC\\uDDFF])|\\uD83C\\uDDEC(?:\\uD83C[\\uDDE6\\uDDE7\\uDDE9-\\uDDEE\\uDDF1-\\uDDF3\\uDDF5-\\uDDFA\\uDDFC\\uDDFE])|\\uD83C\\uDDFA(?:\\uD83C[\\uDDE6\\uDDEC\\uDDF2\\uDDF3\\uDDF8\\uDDFE\\uDDFF])|\\uD83C\\uDDEA(?:\\uD83C[\\uDDE6\\uDDE8\\uDDEA\\uDDEC\\uDDED\\uDDF7-\\uDDFA])|\\uD83C\\uDDFC(?:\\uD83C[\\uDDEB\\uDDF8])|(?:\\u26F9|\\uD83C[\\uDFCB\\uDFCC]|\\uD83D\\uDD75)(?:\\uD83C[\\uDFFB-\\uDFFF])|(?:\\uD83C[\\uDFC3\\uDFC4\\uDFCA]|\\uD83D[\\uDC6E\\uDC71\\uDC73\\uDC77\\uDC81\\uDC82\\uDC86\\uDC87\\uDE45-\\uDE47\\uDE4B\\uDE4D\\uDE4E\\uDEA3\\uDEB4-\\uDEB6]|\\uD83E[\\uDD26\\uDD37-\\uDD39\\uDD3D\\uDD3E\\uDDD6-\\uDDDD])(?:\\uD83C[\\uDFFB-\\uDFFF])|(?:[\\u261D\\u270A-\\u270D]|\\uD83C[\\uDF85\\uDFC2\\uDFC7]|\\uD83D[\\uDC42\\uDC43\\uDC46-\\uDC50\\uDC66\\uDC67\\uDC70\\uDC72\\uDC74-\\uDC76\\uDC78\\uDC7C\\uDC83\\uDC85\\uDCAA\\uDD74\\uDD7A\\uDD90\\uDD95\\uDD96\\uDE4C\\uDE4F\\uDEC0\\uDECC]|\\uD83E[\\uDD18-\\uDD1C\\uDD1E\\uDD1F\\uDD30-\\uDD36\\uDDD1-\\uDDD5])(?:\\uD83C[\\uDFFB-\\uDFFF])|\\uD83D\\uDC68(?:\\u200D(?:(?:(?:\\uD83D[\\uDC68\\uDC69])\\u200D)?\\uD83D\\uDC67|(?:(?:\\uD83D[\\uDC68\\uDC69])\\u200D)?\\uD83D\\uDC66)|\\uD83C[\\uDFFB-\\uDFFF])|(?:[\\u261D\\u26F9\\u270A-\\u270D]|\\uD83C[\\uDF85\\uDFC2-\\uDFC4\\uDFC7\\uDFCA-\\uDFCC]|\\uD83D[\\uDC42\\uDC43\\uDC46-\\uDC50\\uDC66-\\uDC69\\uDC6E\\uDC70-\\uDC78\\uDC7C\\uDC81-\\uDC83\\uDC85-\\uDC87\\uDCAA\\uDD74\\uDD75\\uDD7A\\uDD90\\uDD95\\uDD96\\uDE45-\\uDE47\\uDE4B-\\uDE4F\\uDEA3\\uDEB4-\\uDEB6\\uDEC0\\uDECC]|\\uD83E[\\uDD18-\\uDD1C\\uDD1E\\uDD1F\\uDD26\\uDD30-\\uDD39\\uDD3D\\uDD3E\\uDDD1-\\uDDDD])(?:\\uD83C[\\uDFFB-\\uDFFF])?|(?:[\\u231A\\u231B\\u23E9-\\u23EC\\u23F0\\u23F3\\u25FD\\u25FE\\u2614\\u2615\\u2648-\\u2653\\u267F\\u2693\\u26A1\\u26AA\\u26AB\\u26BD\\u26BE\\u26C4\\u26C5\\u26CE\\u26D4\\u26EA\\u26F2\\u26F3\\u26F5\\u26FA\\u26FD\\u2705\\u270A\\u270B\\u2728\\u274C\\u274E\\u2753-\\u2755\\u2757\\u2795-\\u2797\\u27B0\\u27BF\\u2B1B\\u2B1C\\u2B50\\u2B55]|\\uD83C[\\uDC04\\uDCCF\\uDD8E\\uDD91-\\uDD9A\\uDDE6-\\uDDFF\\uDE01\\uDE1A\\uDE2F\\uDE32-\\uDE36\\uDE38-\\uDE3A\\uDE50\\uDE51\\uDF00-\\uDF20\\uDF2D-\\uDF35\\uDF37-\\uDF7C\\uDF7E-\\uDF93\\uDFA0-\\uDFCA\\uDFCF-\\uDFD3\\uDFE0-\\uDFF0\\uDFF4\\uDFF8-\\uDFFF]|\\uD83D[\\uDC00-\\uDC3E\\uDC40\\uDC42-\\uDCFC\\uDCFF-\\uDD3D\\uDD4B-\\uDD4E\\uDD50-\\uDD67\\uDD7A\\uDD95\\uDD96\\uDDA4\\uDDFB-\\uDE4F\\uDE80-\\uDEC5\\uDECC\\uDED0-\\uDED2\\uDEEB\\uDEEC\\uDEF4-\\uDEF8]|\\uD83E[\\uDD10-\\uDD3A\\uDD3C-\\uDD3E\\uDD40-\\uDD45\\uDD47-\\uDD4C\\uDD50-\\uDD6B\\uDD80-\\uDD97\\uDDC0\\uDDD0-\\uDDE6])|(?:[#\\*0-9\\xA9\\xAE\\u203C\\u2049\\u2122\\u2139\\u2194-\\u2199\\u21A9\\u21AA\\u231A\\u231B\\u2328\\u23CF\\u23E9-\\u23F3\\u23F8-\\u23FA\\u24C2\\u25AA\\u25AB\\u25B6\\u25C0\\u25FB-\\u25FE\\u2600-\\u2604\\u260E\\u2611\\u2614\\u2615\\u2618\\u261D\\u2620\\u2622\\u2623\\u2626\\u262A\\u262E\\u262F\\u2638-\\u263A\\u2640\\u2642\\u2648-\\u2653\\u2660\\u2663\\u2665\\u2666\\u2668\\u267B\\u267F\\u2692-\\u2697\\u2699\\u269B\\u269C\\u26A0\\u26A1\\u26AA\\u26AB\\u26B0\\u26B1\\u26BD\\u26BE\\u26C4\\u26C5\\u26C8\\u26CE\\u26CF\\u26D1\\u26D3\\u26D4\\u26E9\\u26EA\\u26F0-\\u26F5\\u26F7-\\u26FA\\u26FD\\u2702\\u2705\\u2708-\\u270D\\u270F\\u2712\\u2714\\u2716\\u271D\\u2721\\u2728\\u2733\\u2734\\u2744\\u2747\\u274C\\u274E\\u2753-\\u2755\\u2757\\u2763\\u2764\\u2795-\\u2797\\u27A1\\u27B0\\u27BF\\u2934\\u2935\\u2B05-\\u2B07\\u2B1B\\u2B1C\\u2B50\\u2B55\\u3030\\u303D\\u3297\\u3299]|\\uD83C[\\uDC04\\uDCCF\\uDD70\\uDD71\\uDD7E\\uDD7F\\uDD8E\\uDD91-\\uDD9A\\uDDE6-\\uDDFF\\uDE01\\uDE02\\uDE1A\\uDE2F\\uDE32-\\uDE3A\\uDE50\\uDE51\\uDF00-\\uDF21\\uDF24-\\uDF93\\uDF96\\uDF97\\uDF99-\\uDF9B\\uDF9E-\\uDFF0\\uDFF3-\\uDFF5\\uDFF7-\\uDFFF]|\\uD83D[\\uDC00-\\uDCFD\\uDCFF-\\uDD3D\\uDD49-\\uDD4E\\uDD50-\\uDD67\\uDD6F\\uDD70\\uDD73-\\uDD7A\\uDD87\\uDD8A-\\uDD8D\\uDD90\\uDD95\\uDD96\\uDDA4\\uDDA5\\uDDA8\\uDDB1\\uDDB2\\uDDBC\\uDDC2-\\uDDC4\\uDDD1-\\uDDD3\\uDDDC-\\uDDDE\\uDDE1\\uDDE3\\uDDE8\\uDDEF\\uDDF3\\uDDFA-\\uDE4F\\uDE80-\\uDEC5\\uDECB-\\uDED2\\uDEE0-\\uDEE5\\uDEE9\\uDEEB\\uDEEC\\uDEF0\\uDEF3-\\uDEF8]|\\uD83E[\\uDD10-\\uDD3A\\uDD3C-\\uDD3E\\uDD40-\\uDD45\\uDD47-\\uDD4C\\uDD50-\\uDD6B\\uDD80-\\uDD97\\uDDC0\\uDDD0-\\uDDE6])\\uFE0F)/;function ns(n){var t=n.nodeType,e=\"\";if(t===1||t===9||t===11){if(typeof n.textContent==\"string\")return n.textContent;for(n=n.firstChild;n;n=n.nextSibling)e+=ns(n)}else if(t===3||t===4)return n.nodeValue;return e}function Ue(n,t,e,i,r){if(n+=\"\",e&&(n=n.trim?n.trim():n.replace(Hf,\"\")),t&&t!==\"\")return n.replace(/>/g,\"&gt;\").replace(/</g,\"&lt;\").split(t);for(var s=[],o=n.length,a=0,l,u;a<o;a++)u=n.charAt(a),(u.charCodeAt(0)>=55296&&u.charCodeAt(0)<=56319||n.charCodeAt(a+1)>=65024&&n.charCodeAt(a+1)<=65039)&&(l=((n.substr(a,12).split(Wf)||[])[1]||\"\").length||2,u=n.substr(a,l),s.emoji=1,a+=l-1),s.push(r?u:u===\">\"?\"&gt;\":u===\"<\"?\"&lt;\":i&&u===\" \"&&(n.charAt(a-1)===\" \"||n.charAt(a+1)===\" \")?\"&nbsp;\":u);return s}var ss=function(){function n(e){this.chars=Ue(e),this.sets=[],this.length=50;for(var i=0;i<20;i++)this.sets[i]=Gl(80,this.chars)}var t=n.prototype;return t.grow=function(i){for(var r=0;r<20;r++)this.sets[r]+=Gl(i-this.length,this.chars);this.length=i},n}(),Zi,Zl,Jl=function(){return Zi||typeof window!=\"undefined\"&&(Zi=window.gsap)&&Zi.registerPlugin&&Zi},Vf=1,ql=/\\s+/g,Gl=function(t,e){for(var i=e.length,r=\"\";--t>-1;)r+=e[~~(Math.random()*i)];return r},Bo=\"ABCDEFGHIJKLMNOPQRSTUVWXYZ\",Kl=Bo.toLowerCase(),Uf={upperCase:new ss(Bo),lowerCase:new ss(Kl),upperAndLowerCase:new ss(Bo+Kl)},Ql=function(){Zl=Zi=Jl()},on={version:\"3.14.2\",name:\"scrambleText\",register:function(t,e,i){Zi=t,Ql()},init:function(t,e,i,r,s){if(Zl||Ql(),this.prop=\"innerHTML\"in t?\"innerHTML\":\"textContent\"in t?\"textContent\":0,!!this.prop){this.target=t,typeof e!=\"object\"&&(e={text:e});var o=e.text||e.value||\"\",a=e.trim!==!1,l=this,u,c,f,d;return l.delimiter=u=e.delimiter||\"\",l.original=Ue(ns(t).replace(ql,\" \").split(\"&nbsp;\").join(\"\"),u,a),(o===\"{original}\"||o===!0||o==null)&&(o=l.original.join(u)),l.text=Ue((o||\"\").replace(ql,\" \"),u,a),l.hasClass=!!(e.newClass||e.oldClass),l.newClass=e.newClass,l.oldClass=e.oldClass,d=u===\"\",l.textHasEmoji=d&&!!l.text.emoji,l.charsHaveEmoji=!!e.chars&&!!Ue(e.chars).emoji,l.length=d?l.original.length:l.original.join(u).length,l.lengthDif=(d?l.text.length:l.text.join(u).length)-l.length,l.fillChar=e.fillChar||e.chars&&~e.chars.indexOf(\" \")?\"&nbsp;\":\"\",l.charSet=f=Uf[e.chars||\"upperCase\"]||new ss(e.chars),l.speed=.05/(e.speed||1),l.prevScrambleTime=0,l.setIndex=Math.random()*20|0,c=l.length+Math.max(l.lengthDif,0),c>f.length&&f.grow(c),l.chars=f.sets[l.setIndex],l.revealDelay=e.revealDelay||0,l.tweenLength=e.tweenLength!==!1,l.tween=i,l.rightToLeft=!!e.rightToLeft,l._props.push(\"scrambleText\",\"text\"),Vf}},render:function(t,e){var i=e.target,r=e.prop,s=e.text,o=e.delimiter,a=e.tween,l=e.prevScrambleTime,u=e.revealDelay,c=e.setIndex,f=e.chars,d=e.charSet,h=e.length,_=e.textHasEmoji,p=e.charsHaveEmoji,g=e.lengthDif,E=e.tweenLength,y=e.oldClass,S=e.newClass,D=e.rightToLeft,v=e.fillChar,T=e.speed,b=e.original,x=e.hasClass,w=s.length,F=a._time,B=F-l,A,P,L,M,H,R,z,V,m,j,Z;u&&(a._from&&(F=a._dur-F),t=F===0?0:F<u?1e-6:F===a._dur?1:a._ease((F-u)/(a._dur-u))),t<0?t=0:t>1&&(t=1),D&&(t=1-t),A=~~(t*w+.5),t?((B>T||B<-T)&&(e.setIndex=c=(c+(Math.random()*19|0))%20,e.chars=d.sets[c],e.prevScrambleTime+=B),M=f):M=b.join(o),Z=a._from?t:1-t,j=h+(E?a._from?Z*Z*Z:1-Z*Z*Z:1)*g,D?t===1&&(a._from||a.data===\"isFromStart\")?(L=\"\",M=b.join(o)):(z=s.slice(A).join(o),p?L=Ue(M).slice(0,j-(_?Ue(z):z).length+.5|0).join(\"\"):L=M.substr(0,j-(_?Ue(z):z).length+.5|0),M=z):(L=s.slice(0,A).join(o),P=(_?Ue(L):L).length,p?M=Ue(M).slice(P,j+.5|0).join(\"\"):M=M.substr(P,j-P+.5|0)),x?(V=D?y:S,m=D?S:y,H=V&&A!==0,R=m&&A!==w,z=(H?\"<span class='\"+V+\"'>\":\"\")+L+(H?\"</span>\":\"\")+(R?\"<span class='\"+m+\"'>\":\"\")+o+M+(R?\"</span>\":\"\")):z=L+o+M,i[r]=v===\"&nbsp;\"&&~z.indexOf(\"  \")?z.split(\"  \").join(\"&nbsp;&nbsp;\"):z}};on.emojiSafeSplit=Ue;on.getText=ns;Jl()&&Zi.registerPlugin(on);_t.registerPlugin(on);var an=class extends de{constructor(t){super(t),this.inViewBind=this.inView.bind(this)}init(){this.bindEvents()}destroy(){this.unbindEvents()}bindEvents(){window.addEventListener(\"randomize\",this.inViewBind)}unbindEvents(){window.removeEventListener(\"randomize\",this.inViewBind)}inView(t){let{target:e}=t.detail;[...e.querySelectorAll(\"p\")].forEach((r,s)=>{_t.to(r,{opacity:1,duration:0,delay:.1*s}),_t.to(r,{scrambleText:r.innerHTML,duration:1.5,delay:.1*s})})}};var ln,Tr,tu=typeof Symbol==\"function\"?Symbol():\"_split\",No,Yf=()=>No||Ji.register(window.gsap),eu=typeof Intl!=\"undefined\"&&\"Segmenter\"in Intl?new Intl.Segmenter:0,un=n=>typeof n==\"string\"?un(document.querySelectorAll(n)):\"length\"in n?Array.from(n).reduce((t,e)=>(typeof e==\"string\"?t.push(...un(e)):t.push(e),t),[]):[n],iu=n=>un(n).filter(t=>t instanceof HTMLElement),Ho=[],zo=function(){},$f={add:n=>n()},jf=/\\s+/g,ru=new RegExp(\"\\\\p{RI}\\\\p{RI}|\\\\p{Emoji}(\\\\p{EMod}|\\\\u{FE0F}\\\\u{20E3}?|[\\\\u{E0020}-\\\\u{E007E}]+\\\\u{E007F})?(\\\\u{200D}\\\\p{Emoji}(\\\\p{EMod}|\\\\u{FE0F}\\\\u{20E3}?|[\\\\u{E0020}-\\\\u{E007E}]+\\\\u{E007F})?)*|.\",\"gu\"),os={left:0,top:0,width:0,height:0},Xf=(n,t)=>{for(;++t<n.length&&n[t]===os;);return n[t]||os},nu=({element:n,html:t,ariaL:e,ariaH:i})=>{n.innerHTML=t,e?n.setAttribute(\"aria-label\",e):n.removeAttribute(\"aria-label\"),i?n.setAttribute(\"aria-hidden\",i):n.removeAttribute(\"aria-hidden\")},su=(n,t)=>{if(t){let e=new Set(n.join(\"\").match(t)||Ho),i=n.length,r,s,o,a;if(e.size)for(;--i>-1;){s=n[i];for(o of e)if(o.startsWith(s)&&o.length>s.length){for(r=0,a=s;o.startsWith(a+=n[i+ ++r])&&a.length<o.length;);if(r&&a.length===o.length){n[i]=o,n.splice(i+1,r);break}}}}return n},ou=n=>window.getComputedStyle(n).display===\"inline\"&&(n.style.display=\"inline-block\"),xr=(n,t,e)=>t.insertBefore(typeof n==\"string\"?document.createTextNode(n):n,e),Wo=(n,t,e)=>{let i=t[n+\"sClass\"]||\"\",{tag:r=\"div\",aria:s=\"auto\",propIndex:o=!1}=t,a=n===\"line\"?\"block\":\"inline-block\",l=i.indexOf(\"++\")>-1,u=c=>{let f=document.createElement(r),d=e.length+1;return i&&(f.className=i+(l?\" \"+i+d:\"\")),o&&f.style.setProperty(\"--\"+n,d+\"\"),s!==\"none\"&&f.setAttribute(\"aria-hidden\",\"true\"),r!==\"span\"&&(f.style.position=\"relative\",f.style.display=a),f.textContent=c,e.push(f),f};return l&&(i=i.replace(\"++\",\"\")),u.collection=e,u},qf=(n,t,e,i)=>{let r=Wo(\"line\",e,i),s=window.getComputedStyle(n).textAlign||\"left\";return(o,a)=>{let l=r(\"\");for(l.style.textAlign=s,n.insertBefore(l,t[o]);o<a;o++)l.appendChild(t[o]);l.normalize()}},au=(n,t,e,i,r,s,o,a,l,u)=>{var c;let f=Array.from(n.childNodes),d=0,{wordDelimiter:h,reduceWhiteSpace:_=!0,prepareText:p}=t,g=n.getBoundingClientRect(),E=g,y=!_&&window.getComputedStyle(n).whiteSpace.substring(0,3)===\"pre\",S=0,D=e.collection,v,T,b,x,w,F,B,A,P,L,M,H,R,z,V,m,j,Z;for(typeof h==\"object\"?(b=h.delimiter||h,T=h.replaceWith||\"\"):T=h===\"\"?\"\":h||\" \",v=T!==\" \";d<f.length;d++)if(x=f[d],x.nodeType===3){for(V=x.textContent||\"\",_?V=V.replace(jf,\" \"):y&&(V=V.replace(/\\n/g,T+`\n`)),p&&(V=p(V,n)),x.textContent=V,w=T||b?V.split(b||T):V.match(a)||Ho,j=w[w.length-1],A=v?j.slice(-1)===\" \":!j,j||w.pop(),E=g,B=v?w[0].charAt(0)===\" \":!w[0],B&&xr(\" \",n,x),w[0]||w.shift(),su(w,l),s&&u||(x.textContent=\"\"),P=1;P<=w.length;P++)if(m=w[P-1],!_&&y&&m.charAt(0)===`\n`&&((c=x.previousSibling)==null||c.remove(),xr(document.createElement(\"br\"),n,x),m=m.slice(1)),!_&&m===\"\")xr(T,n,x);else if(m===\" \")n.insertBefore(document.createTextNode(\" \"),x);else{if(v&&m.charAt(0)===\" \"&&xr(\" \",n,x),S&&P===1&&!B&&D.indexOf(S.parentNode)>-1?(F=D[D.length-1],F.appendChild(document.createTextNode(i?\"\":m))):(F=e(i?\"\":m),xr(F,n,x),S&&P===1&&!B&&F.insertBefore(S,F.firstChild)),i)for(M=eu?su([...eu.segment(m)].map(Rt=>Rt.segment),l):m.match(a)||Ho,Z=0;Z<M.length;Z++)F.appendChild(M[Z]===\" \"?document.createTextNode(\" \"):i(M[Z]));if(s&&u){if(V=x.textContent=V.substring(m.length+1,V.length),L=F.getBoundingClientRect(),L.top>E.top&&L.left<=E.left){for(H=n.cloneNode(),R=n.childNodes[0];R&&R!==F;)z=R,R=R.nextSibling,H.appendChild(z);n.parentNode.insertBefore(H,n),r&&ou(H)}E=L}(P<w.length||A)&&xr(P>=w.length?\" \":v&&m.slice(-1)===\" \"?\" \"+T:T,n,x)}n.removeChild(x),S=0}else x.nodeType===1&&(o&&o.indexOf(x)>-1?(D.indexOf(x.previousSibling)>-1&&D[D.length-1].appendChild(x),S=x):(au(x,t,e,i,r,s,o,a,l,!0),S=0),r&&ou(x))},lu=class uu{constructor(t,e){this.isSplit=!1,Yf(),this.elements=iu(t),this.chars=[],this.words=[],this.lines=[],this.masks=[],this.vars=e,this.elements.forEach(o=>{var a;e.overwrite!==!1&&((a=o[tu])==null||a._data.orig.filter(({element:l})=>l===o).forEach(nu)),o[tu]=this}),this._split=()=>this.isSplit&&this.split(this.vars);let i=[],r,s=()=>{let o=i.length,a;for(;o--;){a=i[o];let l=a.element.offsetWidth;if(l!==a.width){a.width=l,this._split();return}}};this._data={orig:i,obs:typeof ResizeObserver!=\"undefined\"&&new ResizeObserver(()=>{clearTimeout(r),r=setTimeout(s,200)})},zo(this),this.split(e)}split(t){return(this._ctx||$f).add(()=>{this.isSplit&&this.revert(),this.vars=t=t||this.vars||{};let{type:e=\"chars,words,lines\",aria:i=\"auto\",deepSlice:r=!0,smartWrap:s,onSplit:o,autoSplit:a=!1,specialChars:l,mask:u}=this.vars,c=e.indexOf(\"lines\")>-1,f=e.indexOf(\"chars\")>-1,d=e.indexOf(\"words\")>-1,h=f&&!d&&!c,_=l&&(\"push\"in l?new RegExp(\"(?:\"+l.join(\"|\")+\")\",\"gu\"):l),p=_?new RegExp(_.source+\"|\"+ru.source,\"gu\"):ru,g=!!t.ignore&&iu(t.ignore),{orig:E,animTime:y,obs:S}=this._data,D;(f||d||c)&&(this.elements.forEach((v,T)=>{E[T]={element:v,html:v.innerHTML,ariaL:v.getAttribute(\"aria-label\"),ariaH:v.getAttribute(\"aria-hidden\")},i===\"auto\"?v.setAttribute(\"aria-label\",(v.textContent||\"\").trim()):i===\"hidden\"&&v.setAttribute(\"aria-hidden\",\"true\");let b=[],x=[],w=[],F=f?Wo(\"char\",t,b):null,B=Wo(\"word\",t,x),A,P,L,M;if(au(v,t,B,F,h,r&&(c||h),g,p,_,!1),c){let H=un(v.childNodes),R=qf(v,H,t,w),z,V=[],m=0,j=H.map(nt=>nt.nodeType===1?nt.getBoundingClientRect():os),Z=os,Rt;for(A=0;A<H.length;A++)z=H[A],z.nodeType===1&&(z.nodeName===\"BR\"?((!A||H[A-1].nodeName!==\"BR\")&&(V.push(z),R(m,A+1)),m=A+1,Z=Xf(j,A)):(Rt=j[A],A&&Rt.top>Z.top&&Rt.left<Z.left+Z.width-1&&(R(m,A),m=A),Z=Rt));m<A&&R(m,A),V.forEach(nt=>{var St;return(St=nt.parentNode)==null?void 0:St.removeChild(nt)})}if(!d){for(A=0;A<x.length;A++)if(P=x[A],f||!P.nextSibling||P.nextSibling.nodeType!==3)if(s&&!c){for(L=document.createElement(\"span\"),L.style.whiteSpace=\"nowrap\";P.firstChild;)L.appendChild(P.firstChild);P.replaceWith(L)}else P.replaceWith(...P.childNodes);else M=P.nextSibling,M&&M.nodeType===3&&(M.textContent=(P.textContent||\"\")+(M.textContent||\"\"),P.remove());x.length=0,v.normalize()}this.lines.push(...w),this.words.push(...x),this.chars.push(...b)}),u&&this[u]&&this.masks.push(...this[u].map(v=>{let T=v.cloneNode();return v.replaceWith(T),T.appendChild(v),v.className&&(T.className=v.className.trim()+\"-mask\"),T.style.overflow=\"clip\",T}))),this.isSplit=!0,Tr&&c&&(a?Tr.addEventListener(\"loadingdone\",this._split):Tr.status===\"loading\"&&console.warn(\"SplitText called before fonts loaded\")),(D=o&&o(this))&&D.totalTime&&(this._data.anim=y?D.totalTime(y):D),c&&a&&this.elements.forEach((v,T)=>{E[T].width=v.offsetWidth,S&&S.observe(v)})}),this}kill(){let{obs:t}=this._data;t&&t.disconnect(),Tr==null||Tr.removeEventListener(\"loadingdone\",this._split)}revert(){var t,e;if(this.isSplit){let{orig:i,anim:r}=this._data;this.kill(),i.forEach(nu),this.chars.length=this.words.length=this.lines.length=i.length=this.masks.length=0,this.isSplit=!1,r&&(this._data.animTime=r.totalTime(),r.revert()),(e=(t=this.vars).onRevert)==null||e.call(t,this)}return this}static create(t,e){return new uu(t,e)}static register(t){ln=ln||t||window.gsap,ln&&(un=ln.utils.toArray,zo=ln.core.context||zo),!No&&window.innerWidth>0&&(Tr=document.fonts,No=!0)}};lu.version=\"3.14.2\";var Ji=lu;function cu(n,t){for(var e=0;e<t.length;e++){var i=t[e];i.enumerable=i.enumerable||!1,i.configurable=!0,\"value\"in i&&(i.writable=!0),Object.defineProperty(n,i.key,i)}}function Gf(n,t,e){return t&&cu(n.prototype,t),e&&cu(n,e),n}var Ut,us,Kf,Te,Pi,Ri,Ar,fu,tr,hn,du,hi,Ye,pu,_u=function(){return Ut||typeof window!=\"undefined\"&&(Ut=window.gsap)&&Ut.registerPlugin&&Ut},mu=1,Fr=[],X=[],$e=[],fn=Date.now,Vo=function(t,e){return e},Qf=function(){var t=hn.core,e=t.bridge||{},i=t._scrollers,r=t._proxies;i.push.apply(i,X),r.push.apply(r,$e),X=i,$e=r,Vo=function(o,a){return e[o](a)}},di=function(t,e){return~$e.indexOf(t)&&$e[$e.indexOf(t)+1][e]},dn=function(t){return!!~du.indexOf(t)},ae=function(t,e,i,r,s){return t.addEventListener(e,i,{passive:r!==!1,capture:!!s})},oe=function(t,e,i,r){return t.removeEventListener(e,i,!!r)},as=\"scrollLeft\",ls=\"scrollTop\",Uo=function(){return hi&&hi.isPressed||X.cache++},cs=function(t,e){var i=function r(s){if(s||s===0){mu&&(Te.history.scrollRestoration=\"manual\");var o=hi&&hi.isPressed;s=r.v=Math.round(s)||(hi&&hi.iOS?1:0),t(s),r.cacheID=X.cache,o&&Vo(\"ss\",s)}else(e||X.cache!==r.cacheID||Vo(\"ref\"))&&(r.cacheID=X.cache,r.v=t());return r.v+r.offset};return i.offset=0,t&&i},Qt={s:as,p:\"left\",p2:\"Left\",os:\"right\",os2:\"Right\",d:\"width\",d2:\"Width\",a:\"x\",sc:cs(function(n){return arguments.length?Te.scrollTo(n,Ft.sc()):Te.pageXOffset||Pi[as]||Ri[as]||Ar[as]||0})},Ft={s:ls,p:\"top\",p2:\"Top\",os:\"bottom\",os2:\"Bottom\",d:\"height\",d2:\"Height\",a:\"y\",op:Qt,sc:cs(function(n){return arguments.length?Te.scrollTo(Qt.sc(),n):Te.pageYOffset||Pi[ls]||Ri[ls]||Ar[ls]||0})},le=function(t,e){return(e&&e._ctx&&e._ctx.selector||Ut.utils.toArray)(t)[0]||(typeof t==\"string\"&&Ut.config().nullTargetWarn!==!1?console.warn(\"Element not found:\",t):null)},Zf=function(t,e){for(var i=e.length;i--;)if(e[i]===t||e[i].contains(t))return!0;return!1},fi=function(t,e){var i=e.s,r=e.sc;dn(t)&&(t=Pi.scrollingElement||Ri);var s=X.indexOf(t),o=r===Ft.sc?1:2;!~s&&(s=X.push(t)-1),X[s+o]||ae(t,\"scroll\",Uo);var a=X[s+o],l=a||(X[s+o]=cs(di(t,i),!0)||(dn(t)?r:cs(function(u){return arguments.length?t[i]=u:t[i]})));return l.target=t,a||(l.smooth=Ut.getProperty(t,\"scrollBehavior\")===\"smooth\"),l},hs=function(t,e,i){var r=t,s=t,o=fn(),a=o,l=e||50,u=Math.max(500,l*3),c=function(_,p){var g=fn();p||g-o>l?(s=r,r=_,a=o,o=g):i?r+=_:r=s+(_-s)/(g-a)*(o-a)},f=function(){s=r=i?0:r,a=o=0},d=function(_){var p=a,g=s,E=fn();return(_||_===0)&&_!==r&&c(_),o===a||E-a>u?0:(r+(i?g:-g))/((i?E:o)-p)*1e3};return{update:c,reset:f,getVelocity:d}},cn=function(t,e){return e&&!t._gsapAllow&&t.preventDefault(),t.changedTouches?t.changedTouches[0]:t},hu=function(t){var e=Math.max.apply(Math,t),i=Math.min.apply(Math,t);return Math.abs(e)>=Math.abs(i)?e:i},gu=function(){hn=Ut.core.globals().ScrollTrigger,hn&&hn.core&&Qf()},Du=function(t){return Ut=t||_u(),!us&&Ut&&typeof document!=\"undefined\"&&document.body&&(Te=window,Pi=document,Ri=Pi.documentElement,Ar=Pi.body,du=[Te,Pi,Ri,Ar],Kf=Ut.utils.clamp,pu=Ut.core.context||function(){},tr=\"onpointerenter\"in Ar?\"pointer\":\"mouse\",fu=yt.isTouch=Te.matchMedia&&Te.matchMedia(\"(hover: none), (pointer: coarse)\").matches?1:\"ontouchstart\"in Te||navigator.maxTouchPoints>0||navigator.msMaxTouchPoints>0?2:0,Ye=yt.eventTypes=(\"ontouchstart\"in Ri?\"touchstart,touchmove,touchcancel,touchend\":\"onpointerdown\"in Ri?\"pointerdown,pointermove,pointercancel,pointerup\":\"mousedown,mousemove,mouseup,mouseup\").split(\",\"),setTimeout(function(){return mu=0},500),gu(),us=1),us};Qt.op=Ft;X.cache=0;var yt=function(){function n(e){this.init(e)}var t=n.prototype;return t.init=function(i){us||Du(Ut)||console.warn(\"Please gsap.registerPlugin(Observer)\"),hn||gu();var r=i.tolerance,s=i.dragMinimum,o=i.type,a=i.target,l=i.lineHeight,u=i.debounce,c=i.preventDefault,f=i.onStop,d=i.onStopDelay,h=i.ignore,_=i.wheelSpeed,p=i.event,g=i.onDragStart,E=i.onDragEnd,y=i.onDrag,S=i.onPress,D=i.onRelease,v=i.onRight,T=i.onLeft,b=i.onUp,x=i.onDown,w=i.onChangeX,F=i.onChangeY,B=i.onChange,A=i.onToggleX,P=i.onToggleY,L=i.onHover,M=i.onHoverEnd,H=i.onMove,R=i.ignoreCheck,z=i.isNormalizer,V=i.onGestureStart,m=i.onGestureEnd,j=i.onWheel,Z=i.onEnable,Rt=i.onDisable,nt=i.onClick,St=i.scrollSpeed,Yt=i.capture,Tt=i.allowClicks,ee=i.lockAxis,$t=i.onLockAxis;this.target=a=le(a)||Ri,this.vars=i,h&&(h=Ut.utils.toArray(h)),r=r||1e-9,s=s||0,_=_||1,St=St||1,o=o||\"wheel,touch,pointer\",u=u!==!1,l||(l=parseFloat(Te.getComputedStyle(Ar).lineHeight)||22);var mi,ie,re,et,bt,fe,ve,C=this,ye=0,ei=0,gi=i.passive||!c&&i.passive!==!1,mt=fi(a,Qt),ii=fi(a,Ft),Di=mt(),Ii=ii(),Mt=~o.indexOf(\"touch\")&&!~o.indexOf(\"pointer\")&&Ye[0]===\"pointerdown\",vi=dn(a),Et=a.ownerDocument||Pi,Be=[0,0,0],Oe=[0,0,0],ri=0,Br=function(){return ri=fn()},xt=function(W,it){return(C.event=W)&&h&&Zf(W.target,h)||it&&Mt&&W.pointerType!==\"touch\"||R&&R(W,it)},An=function(){C._vx.reset(),C._vy.reset(),ie.pause(),f&&f(C)},ni=function(){var W=C.deltaX=hu(Be),it=C.deltaY=hu(Oe),O=Math.abs(W)>=r,U=Math.abs(it)>=r;B&&(O||U)&&B(C,W,it,Be,Oe),O&&(v&&C.deltaX>0&&v(C),T&&C.deltaX<0&&T(C),w&&w(C),A&&C.deltaX<0!=ye<0&&A(C),ye=C.deltaX,Be[0]=Be[1]=Be[2]=0),U&&(x&&C.deltaY>0&&x(C),b&&C.deltaY<0&&b(C),F&&F(C),P&&C.deltaY<0!=ei<0&&P(C),ei=C.deltaY,Oe[0]=Oe[1]=Oe[2]=0),(et||re)&&(H&&H(C),re&&(g&&re===1&&g(C),y&&y(C),re=0),et=!1),fe&&!(fe=!1)&&$t&&$t(C),bt&&(j(C),bt=!1),mi=0},ur=function(W,it,O){Be[O]+=W,Oe[O]+=it,C._vx.update(W),C._vy.update(it),u?mi||(mi=requestAnimationFrame(ni)):ni()},cr=function(W,it){ee&&!ve&&(C.axis=ve=Math.abs(W)>Math.abs(it)?\"x\":\"y\",fe=!0),ve!==\"y\"&&(Be[2]+=W,C._vx.update(W,!0)),ve!==\"x\"&&(Oe[2]+=it,C._vy.update(it,!0)),u?mi||(mi=requestAnimationFrame(ni)):ni()},yi=function(W){if(!xt(W,1)){W=cn(W,c);var it=W.clientX,O=W.clientY,U=it-C.x,N=O-C.y,Y=C.isDragging;C.x=it,C.y=O,(Y||(U||N)&&(Math.abs(C.startX-it)>=s||Math.abs(C.startY-O)>=s))&&(re||(re=Y?2:1),Y||(C.isDragging=!0),cr(U,N))}},Li=C.onPress=function($){xt($,1)||$&&$.button||(C.axis=ve=null,ie.pause(),C.isPressed=!0,$=cn($),ye=ei=0,C.startX=C.x=$.clientX,C.startY=C.y=$.clientY,C._vx.reset(),C._vy.reset(),ae(z?a:Et,Ye[1],yi,gi,!0),C.deltaX=C.deltaY=0,S&&S(C))},Q=C.onRelease=function($){if(!xt($,1)){oe(z?a:Et,Ye[1],yi,!0);var W=!isNaN(C.y-C.startY),it=C.isDragging,O=it&&(Math.abs(C.x-C.startX)>3||Math.abs(C.y-C.startY)>3),U=cn($);!O&&W&&(C._vx.reset(),C._vy.reset(),c&&Tt&&Ut.delayedCall(.08,function(){if(fn()-ri>300&&!$.defaultPrevented){if($.target.click)$.target.click();else if(Et.createEvent){var N=Et.createEvent(\"MouseEvents\");N.initMouseEvent(\"click\",!0,!0,Te,1,U.screenX,U.screenY,U.clientX,U.clientY,!1,!1,!1,!1,0,null),$.target.dispatchEvent(N)}}})),C.isDragging=C.isGesturing=C.isPressed=!1,f&&it&&!z&&ie.restart(!0),re&&ni(),E&&it&&E(C),D&&D(C,O)}},Bi=function(W){return W.touches&&W.touches.length>1&&(C.isGesturing=!0)&&V(W,C.isDragging)},ze=function(){return(C.isGesturing=!1)||m(C)},Ne=function(W){if(!xt(W)){var it=mt(),O=ii();ur((it-Di)*St,(O-Ii)*St,1),Di=it,Ii=O,f&&ie.restart(!0)}},He=function(W){if(!xt(W)){W=cn(W,c),j&&(bt=!0);var it=(W.deltaMode===1?l:W.deltaMode===2?Te.innerHeight:1)*_;ur(W.deltaX*it,W.deltaY*it,0),f&&!z&&ie.restart(!0)}},zi=function(W){if(!xt(W)){var it=W.clientX,O=W.clientY,U=it-C.x,N=O-C.y;C.x=it,C.y=O,et=!0,f&&ie.restart(!0),(U||N)&&cr(U,N)}},hr=function(W){C.event=W,L(C)},si=function(W){C.event=W,M(C)},zr=function(W){return xt(W)||cn(W,c)&&nt(C)};ie=C._dc=Ut.delayedCall(d||.25,An).pause(),C.deltaX=C.deltaY=0,C._vx=hs(0,50,!0),C._vy=hs(0,50,!0),C.scrollX=mt,C.scrollY=ii,C.isDragging=C.isGesturing=C.isPressed=!1,pu(this),C.enable=function($){return C.isEnabled||(ae(vi?Et:a,\"scroll\",Uo),o.indexOf(\"scroll\")>=0&&ae(vi?Et:a,\"scroll\",Ne,gi,Yt),o.indexOf(\"wheel\")>=0&&ae(a,\"wheel\",He,gi,Yt),(o.indexOf(\"touch\")>=0&&fu||o.indexOf(\"pointer\")>=0)&&(ae(a,Ye[0],Li,gi,Yt),ae(Et,Ye[2],Q),ae(Et,Ye[3],Q),Tt&&ae(a,\"click\",Br,!0,!0),nt&&ae(a,\"click\",zr),V&&ae(Et,\"gesturestart\",Bi),m&&ae(Et,\"gestureend\",ze),L&&ae(a,tr+\"enter\",hr),M&&ae(a,tr+\"leave\",si),H&&ae(a,tr+\"move\",zi)),C.isEnabled=!0,C.isDragging=C.isGesturing=C.isPressed=et=re=!1,C._vx.reset(),C._vy.reset(),Di=mt(),Ii=ii(),$&&$.type&&Li($),Z&&Z(C)),C},C.disable=function(){C.isEnabled&&(Fr.filter(function($){return $!==C&&dn($.target)}).length||oe(vi?Et:a,\"scroll\",Uo),C.isPressed&&(C._vx.reset(),C._vy.reset(),oe(z?a:Et,Ye[1],yi,!0)),oe(vi?Et:a,\"scroll\",Ne,Yt),oe(a,\"wheel\",He,Yt),oe(a,Ye[0],Li,Yt),oe(Et,Ye[2],Q),oe(Et,Ye[3],Q),oe(a,\"click\",Br,!0),oe(a,\"click\",zr),oe(Et,\"gesturestart\",Bi),oe(Et,\"gestureend\",ze),oe(a,tr+\"enter\",hr),oe(a,tr+\"leave\",si),oe(a,tr+\"move\",zi),C.isEnabled=C.isPressed=C.isDragging=!1,Rt&&Rt(C))},C.kill=C.revert=function(){C.disable();var $=Fr.indexOf(C);$>=0&&Fr.splice($,1),hi===C&&(hi=0)},Fr.push(C),z&&dn(a)&&(hi=C),C.enable(p)},Gf(n,[{key:\"velocityX\",get:function(){return this._vx.getVelocity()}},{key:\"velocityY\",get:function(){return this._vy.getVelocity()}}]),n}();yt.version=\"3.14.2\";yt.create=function(n){return new yt(n)};yt.register=Du;yt.getAll=function(){return Fr.slice()};yt.getById=function(n){return Fr.filter(function(t){return t.vars.id===n})[0]};_u()&&Ut.registerPlugin(yt);var k,Pr,G,lt,Ae,rt,na,xs,xn,yn,_n,fs,Zt,Os,Qo,ce,vu,yu,Rr,Lu,Yo,Bu,ue,Zo,zu,Nu,Mi,Jo,sa,Mr,oa,bn,ta,$o,ds=1,Jt=Date.now,jo=Jt(),Le=0,mn=0,bu=function(t,e,i){var r=Fe(t)&&(t.substr(0,6)===\"clamp(\"||t.indexOf(\"max\")>-1);return i[\"_\"+e+\"Clamp\"]=r,r?t.substr(6,t.length-7):t},Eu=function(t,e){return e&&(!Fe(t)||t.substr(0,6)!==\"clamp(\")?\"clamp(\"+t+\")\":t},Jf=function n(){return mn&&requestAnimationFrame(n)},wu=function(){return Os=1},Cu=function(){return Os=0},Je=function(t){return t},gn=function(t){return Math.round(t*1e5)/1e5||0},Hu=function(){return typeof window!=\"undefined\"},Wu=function(){return k||Hu()&&(k=window.gsap)&&k.registerPlugin&&k},or=function(t){return!!~na.indexOf(t)},Vu=function(t){return(t===\"Height\"?oa:G[\"inner\"+t])||Ae[\"client\"+t]||rt[\"client\"+t]},Uu=function(t){return di(t,\"getBoundingClientRect\")||(or(t)?function(){return Ts.width=G.innerWidth,Ts.height=oa,Ts}:function(){return pi(t)})},td=function(t,e,i){var r=i.d,s=i.d2,o=i.a;return(o=di(t,\"getBoundingClientRect\"))?function(){return o()[r]}:function(){return(e?Vu(s):t[\"client\"+s])||0}},ed=function(t,e){return!e||~$e.indexOf(t)?Uu(t):function(){return Ts}},ti=function(t,e){var i=e.s,r=e.d2,s=e.d,o=e.a;return Math.max(0,(i=\"scroll\"+r)&&(o=di(t,i))?o()-Uu(t)()[s]:or(t)?(Ae[i]||rt[i])-Vu(r):t[i]-t[\"offset\"+r])},ps=function(t,e){for(var i=0;i<Rr.length;i+=3)(!e||~e.indexOf(Rr[i+1]))&&t(Rr[i],Rr[i+1],Rr[i+2])},Fe=function(t){return typeof t==\"string\"},te=function(t){return typeof t==\"function\"},Dn=function(t){return typeof t==\"number\"},er=function(t){return typeof t==\"object\"},pn=function(t,e,i){return t&&t.progress(e?0:1)&&i&&t.pause()},Xo=function(t,e){if(t.enabled){var i=t._ctx?t._ctx.add(function(){return e(t)}):e(t);i&&i.totalTime&&(t.callbackAnimation=i)}},Or=Math.abs,Yu=\"left\",$u=\"top\",aa=\"right\",la=\"bottom\",rr=\"width\",nr=\"height\",En=\"Right\",wn=\"Left\",Cn=\"Top\",Sn=\"Bottom\",At=\"padding\",Me=\"margin\",Lr=\"Width\",ua=\"Height\",Pt=\"px\",Ie=function(t){return G.getComputedStyle(t)},id=function(t){var e=Ie(t).position;t.style.position=e===\"absolute\"||e===\"fixed\"?e:\"relative\"},Su=function(t,e){for(var i in e)i in t||(t[i]=e[i]);return t},pi=function(t,e){var i=e&&Ie(t)[Qo]!==\"matrix(1, 0, 0, 1, 0, 0)\"&&k.to(t,{x:0,y:0,xPercent:0,yPercent:0,rotation:0,rotationX:0,rotationY:0,scale:1,skewX:0,skewY:0}).progress(1),r=t.getBoundingClientRect();return i&&i.progress(0).kill(),r},Fs=function(t,e){var i=e.d2;return t[\"offset\"+i]||t[\"client\"+i]||0},ju=function(t){var e=[],i=t.labels,r=t.duration(),s;for(s in i)e.push(i[s]/r);return e},rd=function(t){return function(e){return k.utils.snap(ju(t),e)}},ca=function(t){var e=k.utils.snap(t),i=Array.isArray(t)&&t.slice(0).sort(function(r,s){return r-s});return i?function(r,s,o){o===void 0&&(o=.001);var a;if(!s)return e(r);if(s>0){for(r-=o,a=0;a<i.length;a++)if(i[a]>=r)return i[a];return i[a-1]}else for(a=i.length,r+=o;a--;)if(i[a]<=r)return i[a];return i[0]}:function(r,s,o){o===void 0&&(o=.001);var a=e(r);return!s||Math.abs(a-r)<o||a-r<0==s<0?a:e(s<0?r-t:r+t)}},nd=function(t){return function(e,i){return ca(ju(t))(e,i.direction)}},_s=function(t,e,i,r){return i.split(\",\").forEach(function(s){return t(e,s,r)})},Bt=function(t,e,i,r,s){return t.addEventListener(e,i,{passive:!r,capture:!!s})},Lt=function(t,e,i,r){return t.removeEventListener(e,i,!!r)},ms=function(t,e,i){i=i&&i.wheelHandler,i&&(t(e,\"wheel\",i),t(e,\"touchmove\",i))},Tu={startColor:\"green\",endColor:\"red\",indent:0,fontSize:\"16px\",fontWeight:\"normal\"},gs={toggleActions:\"play\",anticipatePin:0},As={top:0,left:0,center:.5,bottom:1,right:1},Es=function(t,e){if(Fe(t)){var i=t.indexOf(\"=\"),r=~i?+(t.charAt(i-1)+1)*parseFloat(t.substr(i+1)):0;~i&&(t.indexOf(\"%\")>i&&(r*=e/100),t=t.substr(0,i-1)),t=r+(t in As?As[t]*e:~t.indexOf(\"%\")?parseFloat(t)*e/100:parseFloat(t)||0)}return t},Ds=function(t,e,i,r,s,o,a,l){var u=s.startColor,c=s.endColor,f=s.fontSize,d=s.indent,h=s.fontWeight,_=lt.createElement(\"div\"),p=or(i)||di(i,\"pinType\")===\"fixed\",g=t.indexOf(\"scroller\")!==-1,E=p?rt:i,y=t.indexOf(\"start\")!==-1,S=y?u:c,D=\"border-color:\"+S+\";font-size:\"+f+\";color:\"+S+\";font-weight:\"+h+\";pointer-events:none;white-space:nowrap;font-family:sans-serif,Arial;z-index:1000;padding:4px 8px;border-width:0;border-style:solid;\";return D+=\"position:\"+((g||l)&&p?\"fixed;\":\"absolute;\"),(g||l||!p)&&(D+=(r===Ft?aa:la)+\":\"+(o+parseFloat(d))+\"px;\"),a&&(D+=\"box-sizing:border-box;text-align:left;width:\"+a.offsetWidth+\"px;\"),_._isStart=y,_.setAttribute(\"class\",\"gsap-marker-\"+t+(e?\" marker-\"+e:\"\")),_.style.cssText=D,_.innerText=e||e===0?t+\"-\"+e:t,E.children[0]?E.insertBefore(_,E.children[0]):E.appendChild(_),_._offset=_[\"offset\"+r.op.d2],ws(_,0,r,y),_},ws=function(t,e,i,r){var s={display:\"block\"},o=i[r?\"os2\":\"p2\"],a=i[r?\"p2\":\"os2\"];t._isFlipped=r,s[i.a+\"Percent\"]=r?-100:0,s[i.a]=r?\"1px\":0,s[\"border\"+o+Lr]=1,s[\"border\"+a+Lr]=0,s[i.p]=e+\"px\",k.set(t,s)},q=[],ea={},Fn,xu=function(){return Jt()-Le>34&&(Fn||(Fn=requestAnimationFrame(_i)))},kr=function(){(!ue||!ue.isPressed||ue.startX>rt.clientWidth)&&(X.cache++,ue?Fn||(Fn=requestAnimationFrame(_i)):_i(),Le||lr(\"scrollStart\"),Le=Jt())},qo=function(){Nu=G.innerWidth,zu=G.innerHeight},vn=function(t){X.cache++,(t===!0||!Zt&&!Bu&&!lt.fullscreenElement&&!lt.webkitFullscreenElement&&(!Zo||Nu!==G.innerWidth||Math.abs(G.innerHeight-zu)>G.innerHeight*.25))&&xs.restart(!0)},ar={},sd=[],Xu=function n(){return Lt(K,\"scrollEnd\",n)||ir(!0)},lr=function(t){return ar[t]&&ar[t].map(function(e){return e()})||sd},xe=[],qu=function(t){for(var e=0;e<xe.length;e+=5)(!t||xe[e+4]&&xe[e+4].query===t)&&(xe[e].style.cssText=xe[e+1],xe[e].getBBox&&xe[e].setAttribute(\"transform\",xe[e+2]||\"\"),xe[e+3].uncache=1)},Gu=function(){return X.forEach(function(t){return te(t)&&++t.cacheID&&(t.rec=t())})},ha=function(t,e){var i;for(ce=0;ce<q.length;ce++)i=q[ce],i&&(!e||i._ctx===e)&&(t?i.kill(1):i.revert(!0,!0));bn=!0,e&&qu(e),e||lr(\"revert\")},Ku=function(t,e){X.cache++,(e||!he)&&X.forEach(function(i){return te(i)&&i.cacheID++&&(i.rec=0)}),Fe(t)&&(G.history.scrollRestoration=sa=t)},he,sr=0,Fu,od=function(){if(Fu!==sr){var t=Fu=sr;requestAnimationFrame(function(){return t===sr&&ir(!0)})}},Qu=function(){rt.appendChild(Mr),oa=!ue&&Mr.offsetHeight||G.innerHeight,rt.removeChild(Mr)},Au=function(t){return xn(\".gsap-marker-start, .gsap-marker-end, .gsap-marker-scroller-start, .gsap-marker-scroller-end\").forEach(function(e){return e.style.display=t?\"none\":\"block\"})},ir=function(t,e){if(Ae=lt.documentElement,rt=lt.body,na=[G,lt,Ae,rt],Le&&!t&&!bn){Bt(K,\"scrollEnd\",Xu);return}Qu(),he=K.isRefreshing=!0,bn||Gu();var i=lr(\"refreshInit\");Lu&&K.sort(),e||ha(),X.forEach(function(r){te(r)&&(r.smooth&&(r.target.style.scrollBehavior=\"auto\"),r(0))}),q.slice(0).forEach(function(r){return r.refresh()}),bn=!1,q.forEach(function(r){if(r._subPinOffset&&r.pin){var s=r.vars.horizontal?\"offsetWidth\":\"offsetHeight\",o=r.pin[s];r.revert(!0,1),r.adjustPinSpacing(r.pin[s]-o),r.refresh()}}),ta=1,Au(!0),q.forEach(function(r){var s=ti(r.scroller,r._dir),o=r.vars.end===\"max\"||r._endClamp&&r.end>s,a=r._startClamp&&r.start>=s;(o||a)&&r.setPositions(a?s-1:r.start,o?Math.max(a?s:r.start+1,s):r.end,!0)}),Au(!1),ta=0,i.forEach(function(r){return r&&r.render&&r.render(-1)}),X.forEach(function(r){te(r)&&(r.smooth&&requestAnimationFrame(function(){return r.target.style.scrollBehavior=\"smooth\"}),r.rec&&r(r.rec))}),Ku(sa,1),xs.pause(),sr++,he=2,_i(2),q.forEach(function(r){return te(r.vars.onRefresh)&&r.vars.onRefresh(r)}),he=K.isRefreshing=!1,lr(\"refresh\")},ia=0,Cs=1,Tn,_i=function(t){if(t===2||!he&&!bn){K.isUpdating=!0,Tn&&Tn.update(0);var e=q.length,i=Jt(),r=i-jo>=50,s=e&&q[0].scroll();if(Cs=ia>s?-1:1,he||(ia=s),r&&(Le&&!Os&&i-Le>200&&(Le=0,lr(\"scrollEnd\")),_n=jo,jo=i),Cs<0){for(ce=e;ce-- >0;)q[ce]&&q[ce].update(0,r);Cs=1}else for(ce=0;ce<e;ce++)q[ce]&&q[ce].update(0,r);K.isUpdating=!1}Fn=0},ra=[Yu,$u,la,aa,Me+Sn,Me+En,Me+Cn,Me+wn,\"display\",\"flexShrink\",\"float\",\"zIndex\",\"gridColumnStart\",\"gridColumnEnd\",\"gridRowStart\",\"gridRowEnd\",\"gridArea\",\"justifySelf\",\"alignSelf\",\"placeSelf\",\"order\"],Ss=ra.concat([rr,nr,\"boxSizing\",\"max\"+Lr,\"max\"+ua,\"position\",Me,At,At+Cn,At+En,At+Sn,At+wn]),ad=function(t,e,i){Ir(i);var r=t._gsap;if(r.spacerIsNative)Ir(r.spacerState);else if(t._gsap.swappedIn){var s=e.parentNode;s&&(s.insertBefore(t,e),s.removeChild(e))}t._gsap.swappedIn=!1},Go=function(t,e,i,r){if(!t._gsap.swappedIn){for(var s=ra.length,o=e.style,a=t.style,l;s--;)l=ra[s],o[l]=i[l];o.position=i.position===\"absolute\"?\"absolute\":\"relative\",i.display===\"inline\"&&(o.display=\"inline-block\"),a[la]=a[aa]=\"auto\",o.flexBasis=i.flexBasis||\"auto\",o.overflow=\"visible\",o.boxSizing=\"border-box\",o[rr]=Fs(t,Qt)+Pt,o[nr]=Fs(t,Ft)+Pt,o[At]=a[Me]=a[$u]=a[Yu]=\"0\",Ir(r),a[rr]=a[\"max\"+Lr]=i[rr],a[nr]=a[\"max\"+ua]=i[nr],a[At]=i[At],t.parentNode!==e&&(t.parentNode.insertBefore(e,t),e.appendChild(t)),t._gsap.swappedIn=!0}},ld=/([A-Z])/g,Ir=function(t){if(t){var e=t.t.style,i=t.length,r=0,s,o;for((t.t._gsap||k.core.getCache(t.t)).uncache=1;r<i;r+=2)o=t[r+1],s=t[r],o?e[s]=o:e[s]&&e.removeProperty(s.replace(ld,\"-$1\").toLowerCase())}},vs=function(t){for(var e=Ss.length,i=t.style,r=[],s=0;s<e;s++)r.push(Ss[s],i[Ss[s]]);return r.t=t,r},ud=function(t,e,i){for(var r=[],s=t.length,o=i?8:0,a;o<s;o+=2)a=t[o],r.push(a,a in e?e[a]:t[o+1]);return r.t=t.t,r},Ts={left:0,top:0},Ou=function(t,e,i,r,s,o,a,l,u,c,f,d,h,_){te(t)&&(t=t(l)),Fe(t)&&t.substr(0,3)===\"max\"&&(t=d+(t.charAt(4)===\"=\"?Es(\"0\"+t.substr(3),i):0));var p=h?h.time():0,g,E,y;if(h&&h.seek(0),isNaN(t)||(t=+t),Dn(t))h&&(t=k.utils.mapRange(h.scrollTrigger.start,h.scrollTrigger.end,0,d,t)),a&&ws(a,i,r,!0);else{te(e)&&(e=e(l));var S=(t||\"0\").split(\" \"),D,v,T,b;y=le(e,l)||rt,D=pi(y)||{},(!D||!D.left&&!D.top)&&Ie(y).display===\"none\"&&(b=y.style.display,y.style.display=\"block\",D=pi(y),b?y.style.display=b:y.style.removeProperty(\"display\")),v=Es(S[0],D[r.d]),T=Es(S[1]||\"0\",i),t=D[r.p]-u[r.p]-c+v+s-T,a&&ws(a,T,r,i-T<20||a._isStart&&T>20),i-=i-T}if(_&&(l[_]=t||-.001,t<0&&(t=0)),o){var x=t+i,w=o._isStart;g=\"scroll\"+r.d2,ws(o,x,r,w&&x>20||!w&&(f?Math.max(rt[g],Ae[g]):o.parentNode[g])<=x+1),f&&(u=pi(a),f&&(o.style[r.op.p]=u[r.op.p]-r.op.m-o._offset+Pt))}return h&&y&&(g=pi(y),h.seek(d),E=pi(y),h._caScrollDist=g[r.p]-E[r.p],t=t/h._caScrollDist*d),h&&h.seek(p),h?t:Math.round(t)},cd=/(webkit|moz|length|cssText|inset)/i,ku=function(t,e,i,r){if(t.parentNode!==e){var s=t.style,o,a;if(e===rt){t._stOrig=s.cssText,a=Ie(t);for(o in a)!+o&&!cd.test(o)&&a[o]&&typeof s[o]==\"string\"&&o!==\"0\"&&(s[o]=a[o]);s.top=i,s.left=r}else s.cssText=t._stOrig;k.core.getCache(t).uncache=1,e.appendChild(t)}},Zu=function(t,e,i){var r=e,s=r;return function(o){var a=Math.round(t());return a!==r&&a!==s&&Math.abs(a-r)>3&&Math.abs(a-s)>3&&(o=a,i&&i()),s=r,r=Math.round(o),r}},ys=function(t,e,i){var r={};r[e.p]=\"+=\"+i,k.set(t,r)},Pu=function(t,e){var i=fi(t,e),r=\"_scroll\"+e.p2,s=function o(a,l,u,c,f){var d=o.tween,h=l.onComplete,_={};u=u||i();var p=Zu(i,u,function(){d.kill(),o.tween=0});return f=c&&f||0,c=c||a-u,d&&d.kill(),l[r]=a,l.inherit=!1,l.modifiers=_,_[r]=function(){return p(u+c*d.ratio+f*d.ratio*d.ratio)},l.onUpdate=function(){X.cache++,o.tween&&_i()},l.onComplete=function(){o.tween=0,h&&h.call(d)},d=o.tween=k.to(t,l),d};return t[r]=i,i.wheelHandler=function(){return s.tween&&s.tween.kill()&&(s.tween=0)},Bt(t,\"wheel\",i.wheelHandler),K.isTouch&&Bt(t,\"touchmove\",i.wheelHandler),s},K=function(){function n(e,i){Pr||n.register(k)||console.warn(\"Please gsap.registerPlugin(ScrollTrigger)\"),Jo(this),this.init(e,i)}var t=n.prototype;return t.init=function(i,r){if(this.progress=this.start=0,this.vars&&this.kill(!0,!0),!mn){this.update=this.refresh=this.kill=Je;return}i=Su(Fe(i)||Dn(i)||i.nodeType?{trigger:i}:i,gs);var s=i,o=s.onUpdate,a=s.toggleClass,l=s.id,u=s.onToggle,c=s.onRefresh,f=s.scrub,d=s.trigger,h=s.pin,_=s.pinSpacing,p=s.invalidateOnRefresh,g=s.anticipatePin,E=s.onScrubComplete,y=s.onSnapComplete,S=s.once,D=s.snap,v=s.pinReparent,T=s.pinSpacer,b=s.containerAnimation,x=s.fastScrollEnd,w=s.preventOverlaps,F=i.horizontal||i.containerAnimation&&i.horizontal!==!1?Qt:Ft,B=!f&&f!==0,A=le(i.scroller||G),P=k.core.getCache(A),L=or(A),M=(\"pinType\"in i?i.pinType:di(A,\"pinType\")||L&&\"fixed\")===\"fixed\",H=[i.onEnter,i.onLeave,i.onEnterBack,i.onLeaveBack],R=B&&i.toggleActions.split(\" \"),z=\"markers\"in i?i.markers:gs.markers,V=L?0:parseFloat(Ie(A)[\"border\"+F.p2+Lr])||0,m=this,j=i.onRefreshInit&&function(){return i.onRefreshInit(m)},Z=td(A,L,F),Rt=ed(A,L),nt=0,St=0,Yt=0,Tt=fi(A,F),ee,$t,mi,ie,re,et,bt,fe,ve,C,ye,ei,gi,mt,ii,Di,Ii,Mt,vi,Et,Be,Oe,ri,Br,xt,An,ni,ur,cr,yi,Li,Q,Bi,ze,Ne,He,zi,hr,si;if(m._startClamp=m._endClamp=!1,m._dir=F,g*=45,m.scroller=A,m.scroll=b?b.time.bind(b):Tt,ie=Tt(),m.vars=i,r=r||i.animation,\"refreshPriority\"in i&&(Lu=1,i.refreshPriority===-9999&&(Tn=m)),P.tweenScroll=P.tweenScroll||{top:Pu(A,Ft),left:Pu(A,Qt)},m.tweenTo=ee=P.tweenScroll[F.p],m.scrubDuration=function(O){Bi=Dn(O)&&O,Bi?Q?Q.duration(O):Q=k.to(r,{ease:\"expo\",totalProgress:\"+=0\",inherit:!1,duration:Bi,paused:!0,onComplete:function(){return E&&E(m)}}):(Q&&Q.progress(1).kill(),Q=0)},r&&(r.vars.lazy=!1,r._initted&&!m.isReverted||r.vars.immediateRender!==!1&&i.immediateRender!==!1&&r.duration()&&r.render(0,!0,!0),m.animation=r.pause(),r.scrollTrigger=m,m.scrubDuration(f),yi=0,l||(l=r.vars.id)),D&&((!er(D)||D.push)&&(D={snapTo:D}),\"scrollBehavior\"in rt.style&&k.set(L?[rt,Ae]:A,{scrollBehavior:\"auto\"}),X.forEach(function(O){return te(O)&&O.target===(L?lt.scrollingElement||Ae:A)&&(O.smooth=!1)}),mi=te(D.snapTo)?D.snapTo:D.snapTo===\"labels\"?rd(r):D.snapTo===\"labelsDirectional\"?nd(r):D.directional!==!1?function(O,U){return ca(D.snapTo)(O,Jt()-St<500?0:U.direction)}:k.utils.snap(D.snapTo),ze=D.duration||{min:.1,max:2},ze=er(ze)?yn(ze.min,ze.max):yn(ze,ze),Ne=k.delayedCall(D.delay||Bi/2||.1,function(){var O=Tt(),U=Jt()-St<500,N=ee.tween;if((U||Math.abs(m.getVelocity())<10)&&!N&&!Os&&nt!==O){var Y=(O-et)/mt,It=r&&!B?r.totalProgress():Y,J=U?0:(It-Li)/(Jt()-_n)*1e3||0,wt=k.utils.clamp(-Y,1-Y,Or(J/2)*J/.185),jt=Y+(D.inertia===!1?0:wt),gt,ut,st=D,We=st.onStart,ht=st.onInterrupt,be=st.onComplete;if(gt=mi(jt,m),Dn(gt)||(gt=jt),ut=Math.max(0,Math.round(et+gt*mt)),O<=bt&&O>=et&&ut!==O){if(N&&!N._initted&&N.data<=Or(ut-O))return;D.inertia===!1&&(wt=gt-Y),ee(ut,{duration:ze(Or(Math.max(Or(jt-It),Or(gt-It))*.185/J/.05||0)),ease:D.ease||\"power3\",data:Or(ut-O),onInterrupt:function(){return Ne.restart(!0)&&ht&&ht(m)},onComplete:function(){m.update(),nt=Tt(),r&&!B&&(Q?Q.resetTo(\"totalProgress\",gt,r._tTime/r._tDur):r.progress(gt)),yi=Li=r&&!B?r.totalProgress():m.progress,y&&y(m),be&&be(m)}},O,wt*mt,ut-O-wt*mt),We&&We(m,ee.tween)}}else m.isActive&&nt!==O&&Ne.restart(!0)}).pause()),l&&(ea[l]=m),d=m.trigger=le(d||h!==!0&&h),si=d&&d._gsap&&d._gsap.stRevert,si&&(si=si(m)),h=h===!0?d:le(h),Fe(a)&&(a={targets:d,className:a}),h&&(_===!1||_===Me||(_=!_&&h.parentNode&&h.parentNode.style&&Ie(h.parentNode).display===\"flex\"?!1:At),m.pin=h,$t=k.core.getCache(h),$t.spacer?ii=$t.pinState:(T&&(T=le(T),T&&!T.nodeType&&(T=T.current||T.nativeElement),$t.spacerIsNative=!!T,T&&($t.spacerState=vs(T))),$t.spacer=Mt=T||lt.createElement(\"div\"),Mt.classList.add(\"pin-spacer\"),l&&Mt.classList.add(\"pin-spacer-\"+l),$t.pinState=ii=vs(h)),i.force3D!==!1&&k.set(h,{force3D:!0}),m.spacer=Mt=$t.spacer,cr=Ie(h),Br=cr[_+F.os2],Et=k.getProperty(h),Be=k.quickSetter(h,F.a,Pt),Go(h,Mt,cr),Ii=vs(h)),z){ei=er(z)?Su(z,Tu):Tu,C=Ds(\"scroller-start\",l,A,F,ei,0),ye=Ds(\"scroller-end\",l,A,F,ei,0,C),vi=C[\"offset\"+F.op.d2];var zr=le(di(A,\"content\")||A);fe=this.markerStart=Ds(\"start\",l,zr,F,ei,vi,0,b),ve=this.markerEnd=Ds(\"end\",l,zr,F,ei,vi,0,b),b&&(hr=k.quickSetter([fe,ve],F.a,Pt)),!M&&!($e.length&&di(A,\"fixedMarkers\")===!0)&&(id(L?rt:A),k.set([C,ye],{force3D:!0}),An=k.quickSetter(C,F.a,Pt),ur=k.quickSetter(ye,F.a,Pt))}if(b){var $=b.vars.onUpdate,W=b.vars.onUpdateParams;b.eventCallback(\"onUpdate\",function(){m.update(0,0,1),$&&$.apply(b,W||[])})}if(m.previous=function(){return q[q.indexOf(m)-1]},m.next=function(){return q[q.indexOf(m)+1]},m.revert=function(O,U){if(!U)return m.kill(!0);var N=O!==!1||!m.enabled,Y=Zt;N!==m.isReverted&&(N&&(He=Math.max(Tt(),m.scroll.rec||0),Yt=m.progress,zi=r&&r.progress()),fe&&[fe,ve,C,ye].forEach(function(It){return It.style.display=N?\"none\":\"block\"}),N&&(Zt=m,m.update(N)),h&&(!v||!m.isActive)&&(N?ad(h,Mt,ii):Go(h,Mt,Ie(h),xt)),N||m.update(N),Zt=Y,m.isReverted=N)},m.refresh=function(O,U,N,Y){if(!((Zt||!m.enabled)&&!U)){if(h&&O&&Le){Bt(n,\"scrollEnd\",Xu);return}!he&&j&&j(m),Zt=m,ee.tween&&!N&&(ee.tween.kill(),ee.tween=0),Q&&Q.pause(),p&&r&&(r.revert({kill:!1}).invalidate(),r.getChildren?r.getChildren(!0,!0,!1).forEach(function(bi){return bi.vars.immediateRender&&bi.render(0,!0,!0)}):r.vars.immediateRender&&r.render(0,!0,!0)),m.isReverted||m.revert(!0,!0),m._subPinOffset=!1;var It=Z(),J=Rt(),wt=b?b.duration():ti(A,F),jt=mt<=.01||!mt,gt=0,ut=Y||0,st=er(N)?N.end:i.end,We=i.endTrigger||d,ht=er(N)?N.start:i.start||(i.start===0||!d?0:h?\"0 0\":\"0 100%\"),be=m.pinnedContainer=i.pinnedContainer&&le(i.pinnedContainer,m),je=d&&Math.max(0,q.indexOf(m))||0,zt=je,Nt,Xt,Ni,On,qt,Ot,Xe,Ls,_a,Nr,qe,Hr,kn;for(z&&er(N)&&(Hr=k.getProperty(C,F.p),kn=k.getProperty(ye,F.p));zt-- >0;)Ot=q[zt],Ot.end||Ot.refresh(0,1)||(Zt=m),Xe=Ot.pin,Xe&&(Xe===d||Xe===h||Xe===be)&&!Ot.isReverted&&(Nr||(Nr=[]),Nr.unshift(Ot),Ot.revert(!0,!0)),Ot!==q[zt]&&(je--,zt--);for(te(ht)&&(ht=ht(m)),ht=bu(ht,\"start\",m),et=Ou(ht,d,It,F,Tt(),fe,C,m,J,V,M,wt,b,m._startClamp&&\"_startClamp\")||(h?-.001:0),te(st)&&(st=st(m)),Fe(st)&&!st.indexOf(\"+=\")&&(~st.indexOf(\" \")?st=(Fe(ht)?ht.split(\" \")[0]:\"\")+st:(gt=Es(st.substr(2),It),st=Fe(ht)?ht:(b?k.utils.mapRange(0,b.duration(),b.scrollTrigger.start,b.scrollTrigger.end,et):et)+gt,We=d)),st=bu(st,\"end\",m),bt=Math.max(et,Ou(st||(We?\"100% 0\":wt),We,It,F,Tt()+gt,ve,ye,m,J,V,M,wt,b,m._endClamp&&\"_endClamp\"))||-.001,gt=0,zt=je;zt--;)Ot=q[zt]||{},Xe=Ot.pin,Xe&&Ot.start-Ot._pinPush<=et&&!b&&Ot.end>0&&(Nt=Ot.end-(m._startClamp?Math.max(0,Ot.start):Ot.start),(Xe===d&&Ot.start-Ot._pinPush<et||Xe===be)&&isNaN(ht)&&(gt+=Nt*(1-Ot.progress)),Xe===h&&(ut+=Nt));if(et+=gt,bt+=gt,m._startClamp&&(m._startClamp+=gt),m._endClamp&&!he&&(m._endClamp=bt||-.001,bt=Math.min(bt,ti(A,F))),mt=bt-et||(et-=.01)&&.001,jt&&(Yt=k.utils.clamp(0,1,k.utils.normalize(et,bt,He))),m._pinPush=ut,fe&&gt&&(Nt={},Nt[F.a]=\"+=\"+gt,be&&(Nt[F.p]=\"-=\"+Tt()),k.set([fe,ve],Nt)),h&&!(ta&&m.end>=ti(A,F)))Nt=Ie(h),On=F===Ft,Ni=Tt(),Oe=parseFloat(Et(F.a))+ut,!wt&&bt>1&&(qe=(L?lt.scrollingElement||Ae:A).style,qe={style:qe,value:qe[\"overflow\"+F.a.toUpperCase()]},L&&Ie(rt)[\"overflow\"+F.a.toUpperCase()]!==\"scroll\"&&(qe.style[\"overflow\"+F.a.toUpperCase()]=\"scroll\")),Go(h,Mt,Nt),Ii=vs(h),Xt=pi(h,!0),Ls=M&&fi(A,On?Qt:Ft)(),_?(xt=[_+F.os2,mt+ut+Pt],xt.t=Mt,zt=_===At?Fs(h,F)+mt+ut:0,zt&&(xt.push(F.d,zt+Pt),Mt.style.flexBasis!==\"auto\"&&(Mt.style.flexBasis=zt+Pt)),Ir(xt),be&&q.forEach(function(bi){bi.pin===be&&bi.vars.pinSpacing!==!1&&(bi._subPinOffset=!0)}),M&&Tt(He)):(zt=Fs(h,F),zt&&Mt.style.flexBasis!==\"auto\"&&(Mt.style.flexBasis=zt+Pt)),M&&(qt={top:Xt.top+(On?Ni-et:Ls)+Pt,left:Xt.left+(On?Ls:Ni-et)+Pt,boxSizing:\"border-box\",position:\"fixed\"},qt[rr]=qt[\"max\"+Lr]=Math.ceil(Xt.width)+Pt,qt[nr]=qt[\"max\"+ua]=Math.ceil(Xt.height)+Pt,qt[Me]=qt[Me+Cn]=qt[Me+En]=qt[Me+Sn]=qt[Me+wn]=\"0\",qt[At]=Nt[At],qt[At+Cn]=Nt[At+Cn],qt[At+En]=Nt[At+En],qt[At+Sn]=Nt[At+Sn],qt[At+wn]=Nt[At+wn],Di=ud(ii,qt,v),he&&Tt(0)),r?(_a=r._initted,Yo(1),r.render(r.duration(),!0,!0),ri=Et(F.a)-Oe+mt+ut,ni=Math.abs(mt-ri)>1,M&&ni&&Di.splice(Di.length-2,2),r.render(0,!0,!0),_a||r.invalidate(!0),r.parent||r.totalTime(r.totalTime()),Yo(0)):ri=mt,qe&&(qe.value?qe.style[\"overflow\"+F.a.toUpperCase()]=qe.value:qe.style.removeProperty(\"overflow-\"+F.a));else if(d&&Tt()&&!b)for(Xt=d.parentNode;Xt&&Xt!==rt;)Xt._pinOffset&&(et-=Xt._pinOffset,bt-=Xt._pinOffset),Xt=Xt.parentNode;Nr&&Nr.forEach(function(bi){return bi.revert(!1,!0)}),m.start=et,m.end=bt,ie=re=he?He:Tt(),!b&&!he&&(ie<He&&Tt(He),m.scroll.rec=0),m.revert(!1,!0),St=Jt(),Ne&&(nt=-1,Ne.restart(!0)),Zt=0,r&&B&&(r._initted||zi)&&r.progress()!==zi&&r.progress(zi||0,!0).render(r.time(),!0,!0),(jt||Yt!==m.progress||b||p||r&&!r._initted)&&(r&&!B&&(r._initted||Yt||r.vars.immediateRender!==!1)&&r.totalProgress(b&&et<-.001&&!Yt?k.utils.normalize(et,bt,0):Yt,!0),m.progress=jt||(ie-et)/mt===Yt?0:Yt),h&&_&&(Mt._pinOffset=Math.round(m.progress*ri)),Q&&Q.invalidate(),isNaN(Hr)||(Hr-=k.getProperty(C,F.p),kn-=k.getProperty(ye,F.p),ys(C,F,Hr),ys(fe,F,Hr-(Y||0)),ys(ye,F,kn),ys(ve,F,kn-(Y||0))),jt&&!he&&m.update(),c&&!he&&!gi&&(gi=!0,c(m),gi=!1)}},m.getVelocity=function(){return(Tt()-re)/(Jt()-_n)*1e3||0},m.endAnimation=function(){pn(m.callbackAnimation),r&&(Q?Q.progress(1):r.paused()?B||pn(r,m.direction<0,1):pn(r,r.reversed()))},m.labelToScroll=function(O){return r&&r.labels&&(et||m.refresh()||et)+r.labels[O]/r.duration()*mt||0},m.getTrailing=function(O){var U=q.indexOf(m),N=m.direction>0?q.slice(0,U).reverse():q.slice(U+1);return(Fe(O)?N.filter(function(Y){return Y.vars.preventOverlaps===O}):N).filter(function(Y){return m.direction>0?Y.end<=et:Y.start>=bt})},m.update=function(O,U,N){if(!(b&&!N&&!O)){var Y=he===!0?He:m.scroll(),It=O?0:(Y-et)/mt,J=It<0?0:It>1?1:It||0,wt=m.progress,jt,gt,ut,st,We,ht,be,je;if(U&&(re=ie,ie=b?Tt():Y,D&&(Li=yi,yi=r&&!B?r.totalProgress():J)),g&&h&&!Zt&&!ds&&Le&&(!J&&et<Y+(Y-re)/(Jt()-_n)*g?J=1e-4:J===1&&bt>Y+(Y-re)/(Jt()-_n)*g&&(J=.9999)),J!==wt&&m.enabled){if(jt=m.isActive=!!J&&J<1,gt=!!wt&&wt<1,ht=jt!==gt,We=ht||!!J!=!!wt,m.direction=J>wt?1:-1,m.progress=J,We&&!Zt&&(ut=J&&!wt?0:J===1?1:wt===1?2:3,B&&(st=!ht&&R[ut+1]!==\"none\"&&R[ut+1]||R[ut],je=r&&(st===\"complete\"||st===\"reset\"||st in r))),w&&(ht||je)&&(je||f||!r)&&(te(w)?w(m):m.getTrailing(w).forEach(function(Ni){return Ni.endAnimation()})),B||(Q&&!Zt&&!ds?(Q._dp._time-Q._start!==Q._time&&Q.render(Q._dp._time-Q._start),Q.resetTo?Q.resetTo(\"totalProgress\",J,r._tTime/r._tDur):(Q.vars.totalProgress=J,Q.invalidate().restart())):r&&r.totalProgress(J,!!(Zt&&(St||O)))),h){if(O&&_&&(Mt.style[_+F.os2]=Br),!M)Be(gn(Oe+ri*J));else if(We){if(be=!O&&J>wt&&bt+1>Y&&Y+1>=ti(A,F),v)if(!O&&(jt||be)){var zt=pi(h,!0),Nt=Y-et;ku(h,rt,zt.top+(F===Ft?Nt:0)+Pt,zt.left+(F===Ft?0:Nt)+Pt)}else ku(h,Mt);Ir(jt||be?Di:Ii),ni&&J<1&&jt||Be(Oe+(J===1&&!be?ri:0))}}D&&!ee.tween&&!Zt&&!ds&&Ne.restart(!0),a&&(ht||S&&J&&(J<1||!$o))&&xn(a.targets).forEach(function(Ni){return Ni.classList[jt||S?\"add\":\"remove\"](a.className)}),o&&!B&&!O&&o(m),We&&!Zt?(B&&(je&&(st===\"complete\"?r.pause().totalProgress(1):st===\"reset\"?r.restart(!0).pause():st===\"restart\"?r.restart(!0):r[st]()),o&&o(m)),(ht||!$o)&&(u&&ht&&Xo(m,u),H[ut]&&Xo(m,H[ut]),S&&(J===1?m.kill(!1,1):H[ut]=0),ht||(ut=J===1?1:3,H[ut]&&Xo(m,H[ut]))),x&&!jt&&Math.abs(m.getVelocity())>(Dn(x)?x:2500)&&(pn(m.callbackAnimation),Q?Q.progress(1):pn(r,st===\"reverse\"?1:!J,1))):B&&o&&!Zt&&o(m)}if(ur){var Xt=b?Y/b.duration()*(b._caScrollDist||0):Y;An(Xt+(C._isFlipped?1:0)),ur(Xt)}hr&&hr(-Y/b.duration()*(b._caScrollDist||0))}},m.enable=function(O,U){m.enabled||(m.enabled=!0,Bt(A,\"resize\",vn),L||Bt(A,\"scroll\",kr),j&&Bt(n,\"refreshInit\",j),O!==!1&&(m.progress=Yt=0,ie=re=nt=Tt()),U!==!1&&m.refresh())},m.getTween=function(O){return O&&ee?ee.tween:Q},m.setPositions=function(O,U,N,Y){if(b){var It=b.scrollTrigger,J=b.duration(),wt=It.end-It.start;O=It.start+wt*O/J,U=It.start+wt*U/J}m.refresh(!1,!1,{start:Eu(O,N&&!!m._startClamp),end:Eu(U,N&&!!m._endClamp)},Y),m.update()},m.adjustPinSpacing=function(O){if(xt&&O){var U=xt.indexOf(F.d)+1;xt[U]=parseFloat(xt[U])+O+Pt,xt[1]=parseFloat(xt[1])+O+Pt,Ir(xt)}},m.disable=function(O,U){if(O!==!1&&m.revert(!0,!0),m.enabled&&(m.enabled=m.isActive=!1,U||Q&&Q.pause(),He=0,$t&&($t.uncache=1),j&&Lt(n,\"refreshInit\",j),Ne&&(Ne.pause(),ee.tween&&ee.tween.kill()&&(ee.tween=0)),!L)){for(var N=q.length;N--;)if(q[N].scroller===A&&q[N]!==m)return;Lt(A,\"resize\",vn),L||Lt(A,\"scroll\",kr)}},m.kill=function(O,U){m.disable(O,U),Q&&!U&&Q.kill(),l&&delete ea[l];var N=q.indexOf(m);N>=0&&q.splice(N,1),N===ce&&Cs>0&&ce--,N=0,q.forEach(function(Y){return Y.scroller===m.scroller&&(N=1)}),N||he||(m.scroll.rec=0),r&&(r.scrollTrigger=null,O&&r.revert({kill:!1}),U||r.kill()),fe&&[fe,ve,C,ye].forEach(function(Y){return Y.parentNode&&Y.parentNode.removeChild(Y)}),Tn===m&&(Tn=0),h&&($t&&($t.uncache=1),N=0,q.forEach(function(Y){return Y.pin===h&&N++}),N||($t.spacer=0)),i.onKill&&i.onKill(m)},q.push(m),m.enable(!1,!1),si&&si(m),r&&r.add&&!mt){var it=m.update;m.update=function(){m.update=it,X.cache++,et||bt||m.refresh()},k.delayedCall(.01,m.update),mt=.01,et=bt=0}else m.refresh();h&&od()},n.register=function(i){return Pr||(k=i||Wu(),Hu()&&window.document&&n.enable(),Pr=mn),Pr},n.defaults=function(i){if(i)for(var r in i)gs[r]=i[r];return gs},n.disable=function(i,r){mn=0,q.forEach(function(o){return o[r?\"kill\":\"disable\"](i)}),Lt(G,\"wheel\",kr),Lt(lt,\"scroll\",kr),clearInterval(fs),Lt(lt,\"touchcancel\",Je),Lt(rt,\"touchstart\",Je),_s(Lt,lt,\"pointerdown,touchstart,mousedown\",wu),_s(Lt,lt,\"pointerup,touchend,mouseup\",Cu),xs.kill(),ps(Lt);for(var s=0;s<X.length;s+=3)ms(Lt,X[s],X[s+1]),ms(Lt,X[s],X[s+2])},n.enable=function(){if(G=window,lt=document,Ae=lt.documentElement,rt=lt.body,k&&(xn=k.utils.toArray,yn=k.utils.clamp,Jo=k.core.context||Je,Yo=k.core.suppressOverwrites||Je,sa=G.history.scrollRestoration||\"auto\",ia=G.pageYOffset||0,k.core.globals(\"ScrollTrigger\",n),rt)){mn=1,Mr=document.createElement(\"div\"),Mr.style.height=\"100vh\",Mr.style.position=\"absolute\",Qu(),Jf(),yt.register(k),n.isTouch=yt.isTouch,Mi=yt.isTouch&&/(iPad|iPhone|iPod|Mac)/g.test(navigator.userAgent),Zo=yt.isTouch===1,Bt(G,\"wheel\",kr),na=[G,lt,Ae,rt],k.matchMedia?(n.matchMedia=function(u){var c=k.matchMedia(),f;for(f in u)c.add(f,u[f]);return c},k.addEventListener(\"matchMediaInit\",function(){Gu(),ha()}),k.addEventListener(\"matchMediaRevert\",function(){return qu()}),k.addEventListener(\"matchMedia\",function(){ir(0,1),lr(\"matchMedia\")}),k.matchMedia().add(\"(orientation: portrait)\",function(){return qo(),qo})):console.warn(\"Requires GSAP 3.11.0 or later\"),qo(),Bt(lt,\"scroll\",kr);var i=rt.hasAttribute(\"style\"),r=rt.style,s=r.borderTopStyle,o=k.core.Animation.prototype,a,l;for(o.revert||Object.defineProperty(o,\"revert\",{value:function(){return this.time(-.01,!0)}}),r.borderTopStyle=\"solid\",a=pi(rt),Ft.m=Math.round(a.top+Ft.sc())||0,Qt.m=Math.round(a.left+Qt.sc())||0,s?r.borderTopStyle=s:r.removeProperty(\"border-top-style\"),i||(rt.setAttribute(\"style\",\"\"),rt.removeAttribute(\"style\")),fs=setInterval(xu,250),k.delayedCall(.5,function(){return ds=0}),Bt(lt,\"touchcancel\",Je),Bt(rt,\"touchstart\",Je),_s(Bt,lt,\"pointerdown,touchstart,mousedown\",wu),_s(Bt,lt,\"pointerup,touchend,mouseup\",Cu),Qo=k.utils.checkPrefix(\"transform\"),Ss.push(Qo),Pr=Jt(),xs=k.delayedCall(.2,ir).pause(),Rr=[lt,\"visibilitychange\",function(){var u=G.innerWidth,c=G.innerHeight;lt.hidden?(vu=u,yu=c):(vu!==u||yu!==c)&&vn()},lt,\"DOMContentLoaded\",ir,G,\"load\",ir,G,\"resize\",vn],ps(Bt),q.forEach(function(u){return u.enable(0,1)}),l=0;l<X.length;l+=3)ms(Lt,X[l],X[l+1]),ms(Lt,X[l],X[l+2])}},n.config=function(i){\"limitCallbacks\"in i&&($o=!!i.limitCallbacks);var r=i.syncInterval;r&&clearInterval(fs)||(fs=r)&&setInterval(xu,r),\"ignoreMobileResize\"in i&&(Zo=n.isTouch===1&&i.ignoreMobileResize),\"autoRefreshEvents\"in i&&(ps(Lt)||ps(Bt,i.autoRefreshEvents||\"none\"),Bu=(i.autoRefreshEvents+\"\").indexOf(\"resize\")===-1)},n.scrollerProxy=function(i,r){var s=le(i),o=X.indexOf(s),a=or(s);~o&&X.splice(o,a?6:2),r&&(a?$e.unshift(G,r,rt,r,Ae,r):$e.unshift(s,r))},n.clearMatchMedia=function(i){q.forEach(function(r){return r._ctx&&r._ctx.query===i&&r._ctx.kill(!0,!0)})},n.isInViewport=function(i,r,s){var o=(Fe(i)?le(i):i).getBoundingClientRect(),a=o[s?rr:nr]*r||0;return s?o.right-a>0&&o.left+a<G.innerWidth:o.bottom-a>0&&o.top+a<G.innerHeight},n.positionInViewport=function(i,r,s){Fe(i)&&(i=le(i));var o=i.getBoundingClientRect(),a=o[s?rr:nr],l=r==null?a/2:r in As?As[r]*a:~r.indexOf(\"%\")?parseFloat(r)*a/100:parseFloat(r)||0;return s?(o.left+l)/G.innerWidth:(o.top+l)/G.innerHeight},n.killAll=function(i){if(q.slice(0).forEach(function(s){return s.vars.id!==\"ScrollSmoother\"&&s.kill()}),i!==!0){var r=ar.killAll||[];ar={},r.forEach(function(s){return s()})}},n}();K.version=\"3.14.2\";K.saveStyles=function(n){return n?xn(n).forEach(function(t){if(t&&t.style){var e=xe.indexOf(t);e>=0&&xe.splice(e,5),xe.push(t,t.style.cssText,t.getBBox&&t.getAttribute(\"transform\"),k.core.getCache(t),Jo())}}):xe};K.revert=function(n,t){return ha(!n,t)};K.create=function(n,t){return new K(n,t)};K.refresh=function(n){return n?vn(!0):(Pr||K.register())&&ir(!0)};K.update=function(n){return++X.cache&&_i(n===!0?2:0)};K.clearScrollMemory=Ku;K.maxScroll=function(n,t){return ti(n,t?Qt:Ft)};K.getScrollFunc=function(n,t){return fi(le(n),t?Qt:Ft)};K.getById=function(n){return ea[n]};K.getAll=function(){return q.filter(function(n){return n.vars.id!==\"ScrollSmoother\"})};K.isScrolling=function(){return!!Le};K.snapDirectional=ca;K.addEventListener=function(n,t){var e=ar[n]||(ar[n]=[]);~e.indexOf(t)||e.push(t)};K.removeEventListener=function(n,t){var e=ar[n],i=e&&e.indexOf(t);i>=0&&e.splice(i,1)};K.batch=function(n,t){var e=[],i={},r=t.interval||.016,s=t.batchMax||1e9,o=function(u,c){var f=[],d=[],h=k.delayedCall(r,function(){c(f,d),f=[],d=[]}).pause();return function(_){f.length||h.restart(!0),f.push(_.trigger),d.push(_),s<=f.length&&h.progress(1)}},a;for(a in t)i[a]=a.substr(0,2)===\"on\"&&te(t[a])&&a!==\"onRefreshInit\"?o(a,t[a]):t[a];return te(s)&&(s=s(),Bt(K,\"refresh\",function(){return s=t.batchMax()})),xn(n).forEach(function(l){var u={};for(a in i)u[a]=i[a];u.trigger=l,e.push(K.create(u))}),e};var Ru=function(t,e,i,r){return e>r?t(r):e<0&&t(0),i>r?(r-e)/(i-e):i<0?e/(e-i):1},Ko=function n(t,e){e===!0?t.style.removeProperty(\"touch-action\"):t.style.touchAction=e===!0?\"auto\":e?\"pan-\"+e+(yt.isTouch?\" pinch-zoom\":\"\"):\"none\",t===Ae&&n(rt,e)},bs={auto:1,scroll:1},hd=function(t){var e=t.event,i=t.target,r=t.axis,s=(e.changedTouches?e.changedTouches[0]:e).target,o=s._gsap||k.core.getCache(s),a=Jt(),l;if(!o._isScrollT||a-o._isScrollT>2e3){for(;s&&s!==rt&&(s.scrollHeight<=s.clientHeight&&s.scrollWidth<=s.clientWidth||!(bs[(l=Ie(s)).overflowY]||bs[l.overflowX]));)s=s.parentNode;o._isScroll=s&&s!==i&&!or(s)&&(bs[(l=Ie(s)).overflowY]||bs[l.overflowX]),o._isScrollT=a}(o._isScroll||r===\"x\")&&(e.stopPropagation(),e._gsapAllow=!0)},Ju=function(t,e,i,r){return yt.create({target:t,capture:!0,debounce:!1,lockAxis:!0,type:e,onWheel:r=r&&hd,onPress:r,onDrag:r,onScroll:r,onEnable:function(){return i&&Bt(lt,yt.eventTypes[0],Iu,!1,!0)},onDisable:function(){return Lt(lt,yt.eventTypes[0],Iu,!0)}})},fd=/(input|label|select|textarea)/i,Mu,Iu=function(t){var e=fd.test(t.target.tagName);(e||Mu)&&(t._gsapAllow=!0,Mu=e)},dd=function(t){er(t)||(t={}),t.preventDefault=t.isNormalizer=t.allowClicks=!0,t.type||(t.type=\"wheel,touch\"),t.debounce=!!t.debounce,t.id=t.id||\"normalizer\";var e=t,i=e.normalizeScrollX,r=e.momentum,s=e.allowNestedScroll,o=e.onRelease,a,l,u=le(t.target)||Ae,c=k.core.globals().ScrollSmoother,f=c&&c.get(),d=Mi&&(t.content&&le(t.content)||f&&t.content!==!1&&!f.smooth()&&f.content()),h=fi(u,Ft),_=fi(u,Qt),p=1,g=(yt.isTouch&&G.visualViewport?G.visualViewport.scale*G.visualViewport.width:G.outerWidth)/G.innerWidth,E=0,y=te(r)?function(){return r(a)}:function(){return r||2.8},S,D,v=Ju(u,t.type,!0,s),T=function(){return D=!1},b=Je,x=Je,w=function(){l=ti(u,Ft),x=yn(Mi?1:0,l),i&&(b=yn(0,ti(u,Qt))),S=sr},F=function(){d._gsap.y=gn(parseFloat(d._gsap.y)+h.offset)+\"px\",d.style.transform=\"matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, \"+parseFloat(d._gsap.y)+\", 0, 1)\",h.offset=h.cacheID=0},B=function(){if(D){requestAnimationFrame(T);var z=gn(a.deltaY/2),V=x(h.v-z);if(d&&V!==h.v+h.offset){h.offset=V-h.v;var m=gn((parseFloat(d&&d._gsap.y)||0)-h.offset);d.style.transform=\"matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, \"+m+\", 0, 1)\",d._gsap.y=m+\"px\",h.cacheID=X.cache,_i()}return!0}h.offset&&F(),D=!0},A,P,L,M,H=function(){w(),A.isActive()&&A.vars.scrollY>l&&(h()>l?A.progress(1)&&h(l):A.resetTo(\"scrollY\",l))};return d&&k.set(d,{y:\"+=0\"}),t.ignoreCheck=function(R){return Mi&&R.type===\"touchmove\"&&B(R)||p>1.05&&R.type!==\"touchstart\"||a.isGesturing||R.touches&&R.touches.length>1},t.onPress=function(){D=!1;var R=p;p=gn((G.visualViewport&&G.visualViewport.scale||1)/g),A.pause(),R!==p&&Ko(u,p>1.01?!0:i?!1:\"x\"),P=_(),L=h(),w(),S=sr},t.onRelease=t.onGestureStart=function(R,z){if(h.offset&&F(),!z)M.restart(!0);else{X.cache++;var V=y(),m,j;i&&(m=_(),j=m+V*.05*-R.velocityX/.227,V*=Ru(_,m,j,ti(u,Qt)),A.vars.scrollX=b(j)),m=h(),j=m+V*.05*-R.velocityY/.227,V*=Ru(h,m,j,ti(u,Ft)),A.vars.scrollY=x(j),A.invalidate().duration(V).play(.01),(Mi&&A.vars.scrollY>=l||m>=l-1)&&k.to({},{onUpdate:H,duration:V})}o&&o(R)},t.onWheel=function(){A._ts&&A.pause(),Jt()-E>1e3&&(S=0,E=Jt())},t.onChange=function(R,z,V,m,j){if(sr!==S&&w(),z&&i&&_(b(m[2]===z?P+(R.startX-R.x):_()+z-m[1])),V){h.offset&&F();var Z=j[2]===V,Rt=Z?L+R.startY-R.y:h()+V-j[1],nt=x(Rt);Z&&Rt!==nt&&(L+=nt-Rt),h(nt)}(V||z)&&_i()},t.onEnable=function(){Ko(u,i?!1:\"x\"),K.addEventListener(\"refresh\",H),Bt(G,\"resize\",H),h.smooth&&(h.target.style.scrollBehavior=\"auto\",h.smooth=_.smooth=!1),v.enable()},t.onDisable=function(){Ko(u,!0),Lt(G,\"resize\",H),K.removeEventListener(\"refresh\",H),v.kill()},t.lockAxis=t.lockAxis!==!1,a=new yt(t),a.iOS=Mi,Mi&&!h()&&h(1),Mi&&k.ticker.add(Je),M=a._dc,A=k.to(a,{ease:\"power4\",paused:!0,inherit:!1,scrollX:i?\"+=0.1\":\"+=0\",scrollY:\"+=0.1\",modifiers:{scrollY:Zu(h,h(),function(){return A.pause()})},onUpdate:_i,onComplete:M.vars.onComplete}),a};K.sort=function(n){if(te(n))return q.sort(n);var t=G.pageYOffset||0;return K.getAll().forEach(function(e){return e._sortY=e.trigger?t+e.trigger.getBoundingClientRect().top:e.start+G.innerHeight}),q.sort(n||function(e,i){return(e.vars.refreshPriority||0)*-1e6+(e.vars.containerAnimation?1e6:e._sortY)-((i.vars.containerAnimation?1e6:i._sortY)+(i.vars.refreshPriority||0)*-1e6)})};K.observe=function(n){return new yt(n)};K.normalizeScroll=function(n){if(typeof n==\"undefined\")return ue;if(n===!0&&ue)return ue.enable();if(n===!1){ue&&ue.kill(),ue=n;return}var t=n instanceof yt?n:dd(n);return ue&&ue.target===t.target&&ue.kill(),or(t.target)&&(ue=t),t};K.core={_getVelocityProp:hs,_inputObserver:Ju,_scrollers:X,_proxies:$e,bridge:{ss:function(){Le||lr(\"scrollStart\"),Le=Jt()},ref:function(){return Zt}}};Wu()&&k.registerPlugin(K);_t.registerPlugin(Ji);_t.registerPlugin(K);var ks=class extends de{constructor(n){super(n),this.onProgressBind=this.onProgress.bind(this),this.delay=parseFloat(this.getData(\"delay\"))||0,this.stagger=parseFloat(this.getData(\"stagger\"))||.1,this.metrics=[]}init(){this.bindEvents(),Nn(Cr.EAGER).then(n=>{this.onFontsLoaded(n)})}destroy(){super.destroy(),this.unbindEvents(),this.splitObject&&this.splitObject.revert()}unbindEvents(){window.removeEventListener(\"progressEvent\",this.onProgressBind)}bindEvents(){window.addEventListener(\"progressEvent\",this.onProgressBind)}onFontsLoaded(n){this.split()}onProgress(n){if(!this.splitObject||!this.splitObject.lines)return;let{progress:t}=n.detail;this.splitObject.lines.forEach((e,i)=>{if(this.metrics[i]){let{from:r,to:s}=this.metrics[i],o=_t.utils.clamp(-25,0,_t.utils.mapRange(r,s,-25,0,t)),a=_t.utils.clamp(0,1,_t.utils.mapRange(r,s,0,1,t));_t.set(e,{x:o,opacity:a})}})}split(){this.splitObject=Ji.create(this.el,{type:\"lines\",tag:\"span\",autoSplit:!0,onSplit:n=>{this.computeMetrics(n)}}),this.computeMetrics(this.splitObject)}computeMetrics(n){this.metrics=n.lines.map((t,e,i)=>{let r=e/i.length,s=r+1/i.length;return{from:r,to:s}})}};_t.registerPlugin(Ji);var Ps=class extends de{constructor(n){super(n),this.onFadeinTextProgressBind=this.onFadeinTextProgress.bind(this),this.$texts=this.el,this.progress=0,this.metrics=[],this.baseColor=getComputedStyle(this.el).getPropertyValue(\"--color-cta-fadein\"),this.targetColor=getComputedStyle(this.el).getPropertyValue(\"--color\")}init(){this.bindEvents(),this.splitText()}destroy(){this.unbindEvents(),this.split&&this.split.revert()}bindEvents(){window.addEventListener(\"fadeinTextProgress\",this.onFadeinTextProgressBind)}unbindEvents(){window.removeEventListener(\"fadeinTextProgress\",this.onFadeinTextProgressBind)}onFadeinTextProgress(n){let{target:t,progress:e}=n.detail;!this.el.contains(t)||!this.split||(this.progress=e,this.computeProgress())}splitText(){this.split=Ji.create(this.$texts,{type:\"lines\",linesClass:\"c-fadein-text_line\",autoSplit:!0,onSplit:n=>{this.computeMetrics(n),requestAnimationFrame(()=>{this.computeProgress()})}}),this.computeMetrics(this.split)}computeMetrics(n){this.metrics=[];let t=n.lines.map(r=>r.getBoundingClientRect().width),e=t.reduce((r,s)=>r+s,0),i=0;for(let r=0;r<n.lines.length;r++){let s=i/e,o=t[r]/e;i+=t[r],this.metrics.push({from:s,to:s+o})}}computeProgress(){for(let n=0;n<this.split.lines.length;n++){let t=this.split.lines[n],{from:e,to:i}=this.metrics[n],r=_t.utils.clamp(0,1,_t.utils.mapRange(e,i,0,1,this.progress));t.style.setProperty(\"--progress\",`${r}`),this.updateGradient(t,r)}}updateGradient(n,t){let i=t,r=0,s=100,o=_t.utils.mapRange(0,1,-100,100+100,i),a=Math.max(o-100,0),l=Math.min(o+100,100),u=`linear-gradient(to right, ${this.targetColor} ${r}%, ${this.targetColor} ${a}%, ${this.targetColor} ${o}%, ${this.baseColor} ${l}%, ${this.baseColor} ${s}%)`;n.style.setProperty(\"--background\",`${u}`)}};var pd=.25,_d=new RegExp(\"\\\\p{Extended_Pictographic}|\\\\r|\\\\n|.\",\"gu\"),Rs=class extends de{constructor(n){super(n)}init(){this.onItemEnterBind=this.onItemEnter.bind(this),this.onItemLeaveBind=this.onItemLeave.bind(this),this.update()}update(){this.reset(),this.el.addEventListener(\"mouseenter\",this.onItemEnterBind),this.el.addEventListener(\"mouseleave\",this.onItemLeaveBind)}reset(){this.el.removeEventListener(\"mouseenter\",this.onItemEnterBind),this.el.removeEventListener(\"mouseleave\",this.onItemLeaveBind)}shuffle(n){for(var t=typeof n==\"string\"?n.split(\"\"):n,e=t.length,i=e-1;i>0;i--){var r=Math.floor(Math.random()*(i+1)),s=t[i];t[i]=t[r],t[r]=s}return t.join(\"\")}onItemEnter(n){let t=n.currentTarget,e=[];t.dataset.hoverShuffle==\"children\"?t.querySelectorAll(\"[data-hover-shuffle-child]\").forEach(s=>{e.push(s),s.setAttribute(\"aria-label\",s.innerText)}):(e=[t],t.setAttribute(\"aria-label\",t.innerText)),this.tw=_t.timeline({onComplete:()=>{e.forEach(s=>{s.innerText=s.getAttribute(\"aria-label\"),s.removeAttribute(\"aria-label\")})}});let i=4,r=pd/i;for(let s=0;s<i;s++)for(let o of e)this.tw.add(()=>{this.shuffleElementTexts(o,this.shuffle)},r*s)}onItemLeave(n){this.tw&&this.tw.kill();let t=n.currentTarget,e=[];t.dataset.hoverShuffle==\"children\"?t.querySelectorAll(\"[data-hover-shuffle-child]\").forEach(i=>{e.push(i)}):e=[t],e.forEach(i=>{i.getAttribute(\"aria-label\")&&(i.innerText=i.getAttribute(\"aria-label\")),i.removeAttribute(\"aria-label\")})}shuffleElementTexts(n,t){if(!n.children.length&&n.innerText){let e=n.innerText.replace(`\n`,` \n `).split(\" \");for(let i=0;i<e.length;i++){let r=[...e[i].matchAll(_d)].map(s=>s[0]);e[i]=t(r)}n.innerText=e.join(\" \")}}};var sc=vc(ec(),1);var Is;Hi(void 0,null,function*(){if(Qi.IS_DEV){let n=yield Promise.resolve().then(()=>(nc(),rc));Is=n==null?void 0:n.gridHelper}});function oc(){(0,sc.default)(),Is==null||Is()}var da=(n,t,e=!1)=>{let i=null;return(...r)=>{clearTimeout(i);let s=()=>{i=null,e||n(...r)};e&&!i&&n(...r),i=setTimeout(s,t)}};var Ed=\"@vercel/analytics\",wd=\"1.6.1\",Cd=()=>{window.va||(window.va=function(...t){(window.vaq=window.vaq||[]).push(t)})};function ac(){return typeof window!=\"undefined\"}function lc(){try{let n=\"production\";if(n===\"development\"||n===\"test\")return\"development\"}catch(n){}return\"production\"}function Sd(n=\"auto\"){if(n===\"auto\"){window.vam=lc();return}window.vam=n}function Td(){return(ac()?window.vam:lc())||\"production\"}function pa(){return Td()===\"development\"}function xd(n){return n.scriptSrc?n.scriptSrc:pa()?\"https://va.vercel-scripts.com/v1/script.debug.js\":n.basePath?`${n.basePath}/insights/script.js`:\"/_vercel/insights/script.js\"}function uc(n={debug:!0}){var t;if(!ac())return;Sd(n.mode),Cd(),n.beforeSend&&((t=window.va)==null||t.call(window,\"beforeSend\",n.beforeSend));let e=xd(n);if(document.head.querySelector(`script[src*=\"${e}\"]`))return;let i=document.createElement(\"script\");i.src=e,i.defer=!0,i.dataset.sdkn=Ed+(n.framework?`/${n.framework}`:\"\"),i.dataset.sdkv=wd,n.disableAutoTrack&&(i.dataset.disableAutoTrack=\"1\"),n.endpoint?i.dataset.endpoint=n.endpoint:n.basePath&&(i.dataset.endpoint=`${n.basePath}/insights`),n.dsn&&(i.dataset.dsn=n.dsn),i.onerror=()=>{let r=pa()?\"Please check if any ad blockers are enabled and try again.\":\"Be sure to enable Web Analytics for your project and deploy again. See https://vercel.com/docs/analytics/quickstart for more information.\";console.log(`[Vercel Web Analytics] Failed to load script from ${e}. ${r}`)},pa()&&n.debug===!1&&(i.dataset.debug=\"false\"),document.head.appendChild(i)}var cc=new wa({modules:fa});function Fd(){Ad(),hc(),document.documentElement.style.setProperty(\"--vh-initial\",`${window.innerHeight*.01}px`),oc(),cc.init(cc),setTimeout(()=>{Ve.classList.add(wr.FIRST_LOADED),Ve.classList.add(wr.LOADED),Ve.classList.remove(wr.LOADING),setTimeout(()=>{Ve.classList.add(wr.READY)},100)},100),uc(),Fa&&Oa(Cr.EAGER,Qi.IS_DEV).then(n=>{Ve.classList.add(wr.FONTS_LOADED),Qi.IS_DEV&&(console.group(\"Eager fonts loaded!\",n.length,\"/\",document.fonts.size),console.group(\"State of eager fonts:\"),n.forEach(t=>console.log(t.family,t.style,t.weight,t.status)),console.groupEnd(),console.group(\"State of all fonts:\"),document.fonts.forEach(t=>console.log(t.family,t.style,t.weight,t.status)),console.groupEnd())})}function Ad(){let n=new CustomEvent(tn.RESIZE_END);window.addEventListener(\"resize\",da(()=>{window.dispatchEvent(n)},200,!1)),window.addEventListener(\"resize\",hc),window.addEventListener(\"orientationchange\",da(()=>{Od()},200,!1))}function Od(){document.documentElement.style.setProperty(\"--vh-initial\",`${window.innerHeight*.01}px`)}function hc(){let n=Ve.offsetWidth*.01,t=window.innerHeight*.01;document.documentElement.style.setProperty(\"--vw\",`${n}px`),document.documentElement.style.setProperty(\"--vh\",`${t}px`)}window.addEventListener(\"load\",n=>{Fd()});})();\n/*! Bundled license information:\n\nsvg4everybody/dist/svg4everybody.js:\n  (*! svg4everybody v2.1.9 | github.com/jonathantneal/svg4everybody *)\n\ngsap/gsap-core.js:\n  (*!\n   * GSAP 3.14.2\n   * https://gsap.com\n   *\n   * @license Copyright 2008-2025, GreenSock. All rights reserved.\n   * Subject to the terms at https://gsap.com/standard-license\n   * @author: Jack Doyle, jack@greensock.com\n  *)\n\ngsap/CSSPlugin.js:\n  (*!\n   * CSSPlugin 3.14.2\n   * https://gsap.com\n   *\n   * Copyright 2008-2025, GreenSock. All rights reserved.\n   * Subject to the terms at https://gsap.com/standard-license\n   * @author: Jack Doyle, jack@greensock.com\n  *)\n\ngsap/utils/strings.js:\n  (*!\n   * strings: 3.14.2\n   * https://gsap.com\n   *\n   * Copyright 2008-2025, GreenSock. All rights reserved.\n   * Subject to the terms at https://gsap.com/standard-license\n   * @author: Jack Doyle, jack@greensock.com\n  *)\n\ngsap/ScrambleTextPlugin.js:\n  (*!\n   * ScrambleTextPlugin 3.14.2\n   * https://gsap.com\n   *\n   * @license Copyright 2008-2025, GreenSock. All rights reserved.\n   * Subject to the terms at https://gsap.com/standard-license\n   * @author: Jack Doyle, jack@greensock.com\n  *)\n\ngsap/SplitText.js:\n  (*!\n   * SplitText 3.14.2\n   * https://gsap.com\n   *\n   * @license Copyright 2025, GreenSock. All rights reserved. Subject to the terms at https://gsap.com/standard-license.\n   * @author: Jack Doyle\n   *)\n\ngsap/Observer.js:\n  (*!\n   * Observer 3.14.2\n   * https://gsap.com\n   *\n   * @license Copyright 2008-2025, GreenSock. All rights reserved.\n   * Subject to the terms at https://gsap.com/standard-license\n   * @author: Jack Doyle, jack@greensock.com\n  *)\n\ngsap/ScrollTrigger.js:\n  (*!\n   * ScrollTrigger 3.14.2\n   * https://gsap.com\n   *\n   * @license Copyright 2008-2025, GreenSock. All rights reserved.\n   * Subject to the terms at https://gsap.com/standard-license\n   * @author: Jack Doyle, jack@greensock.com\n  *)\n*/\n//# sourceMappingURL=app.js.map\n"
  },
  {
    "path": "www/landing/assets/scripts/vendors.js",
    "content": ""
  },
  {
    "path": "www/landing/assets/site.webmanifest",
    "content": "{\n    \"name\": \"Locomotive Boilerplate\",\n    \"short_name\": \"Boilerplate\",\n    \"icons\": [\n        {\n            \"src\": \"assets/images/favicons/android-chrome-144x144.png\",\n            \"sizes\": \"144x144\",\n            \"type\": \"image/png\"\n        }\n    ],\n    \"theme_color\": \"#ffffff\",\n    \"background_color\": \"#ffffff\",\n    \"display\": \"standalone\"\n}\n"
  },
  {
    "path": "www/landing/assets/styles/critical.css",
    "content": ""
  },
  {
    "path": "www/landing/assets/styles/main.css",
    "content": "/*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */html{line-height:1.15;-webkit-text-size-adjust:100%}body{margin:0}main{display:block}h1{font-size:2em;margin:.67em 0}hr{box-sizing:content-box;height:0;overflow:visible}pre{font-family:monospace,monospace;font-size:1em}a{background-color:transparent}abbr[title]{border-bottom:none;text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted}b,strong{font-weight:bolder}code,kbd,samp{font-family:monospace,monospace;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-0.25em}sup{top:-0.5em}img{border-style:none}button,input,optgroup,select,textarea{font-family:inherit;font-size:100%;line-height:1.15;margin:0}button,input{overflow:visible}button,select{text-transform:none}button,[type=button],[type=reset],[type=submit]{-webkit-appearance:button}button::-moz-focus-inner,[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner{border-style:none;padding:0}button:-moz-focusring,[type=button]:-moz-focusring,[type=reset]:-moz-focusring,[type=submit]:-moz-focusring{outline:1px dotted ButtonText}fieldset{padding:.35em .75em .625em}legend{box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal}progress{vertical-align:baseline}textarea{overflow:auto}[type=checkbox],[type=radio]{box-sizing:border-box;padding:0}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}details{display:block}summary{display:list-item}template{display:none}[hidden]{display:none}html.lenis,html.lenis body{height:auto}.lenis:not(.lenis-autoToggle).lenis-stopped{overflow:clip}.lenis [data-lenis-prevent],.lenis [data-lenis-prevent-wheel],.lenis [data-lenis-prevent-touch]{overscroll-behavior:contain}.lenis.lenis-smooth iframe{pointer-events:none}.lenis.lenis-autoToggle{transition-property:overflow;transition-duration:1ms;transition-behavior:allow-discrete}:root{--spacing-2xs-mobile: 6;--spacing-2xs-desktop: 10;--spacing-xs-mobile: 14;--spacing-xs-desktop: 16;--spacing-sm-mobile: 28;--spacing-sm-desktop: 32;--spacing-md-mobile: 42;--spacing-md-desktop: 56;--spacing-lg-mobile: 72;--spacing-lg-desktop: 96;--spacing-xl-mobile: 90;--spacing-xl-desktop: 120;--spacing-2xl-mobile: 96;--spacing-2xl-desktop: 160;--spacing-3xl-mobile: 112;--spacing-3xl-desktop: 224}:root{--grid-columns: 4;--grid-gutter: 0.625rem;--grid-margin: 0.625rem;--container-width: calc(100% - 2 * var(--grid-margin))}@media(max-width: 699px){:root{--header-height: 2.125rem}}@media(min-width: 700px){:root{--grid-gutter: 1rem;--grid-margin: 1.25rem;--header-height: 3.75rem}}html{box-sizing:border-box}template,[hidden]{display:none}*,:before,:after{box-sizing:inherit}address{font-style:inherit}dfn,cite,em,i{font-style:italic}b,strong{font-weight:500}a{text-decoration:none}a svg{pointer-events:none}ul,ol{margin:0;padding:0;list-style:none}p,figure{margin:0;padding:0}h1,h2,h3,h4,h5,h6{margin:0}a,area,button,input,label,select,textarea,[tabindex]{touch-action:manipulation}[hreflang]>abbr[title]{text-decoration:none}table{border-spacing:0;border-collapse:collapse}hr{display:block;margin:1em 0;padding:0;height:1px;border:0;border-top:1px solid #ccc}audio,canvas,iframe,img,svg,video{vertical-align:middle}audio:not([controls]){display:none;height:0}img,svg{height:auto}img[width],img[height],svg[width],svg[height]{max-width:none}img{font-style:italic}svg{fill:currentColor}button:focus,button:hover,.c-button:focus,.c-button:hover{text-decoration:none}button,.c-button{display:inline-block;overflow:visible;margin:0;padding:0;outline:0;border:0;background:none rgba(0,0,0,0);color:inherit;vertical-align:middle;text-align:center;text-decoration:none;text-transform:none;font:inherit;line-height:normal;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;user-select:none}@font-face{font-display:swap;font-family:\"Helvetica Now Display\";src:url(\"../fonts/HelveticaNowDisplay-Medium.woff2\") format(\"woff2\"),url(\"../fonts/HelveticaNowDisplay-Medium.woff\") format(\"woff\");font-weight:500;font-style:normal}@font-face{font-display:swap;font-family:\"Helvetica Now Display\";src:url(\"../fonts/HelveticaNowDisplay-Regular.woff2\") format(\"woff2\"),url(\"../fonts/HelveticaNowDisplay-Regular.woff\") format(\"woff\");font-weight:400;font-style:normal}@font-face{font-display:swap;font-family:\"PP Locomotive New\";src:url(\"../fonts/PPLocomotiveNew-Light.woff2\") format(\"woff2\"),url(\"../fonts/PPLocomotiveNew-Light.woff\") format(\"woff\");font-weight:300;font-style:normal}html{min-height:100%;line-height:1.5;font-family:\"Helvetica Now Display\",-apple-system,BlinkMacSystemFont,avenir next,avenir,segoe ui,helvetica neue,helvetica,Cantarell,Ubuntu,roboto,noto,arial,sans-serif;color:#000;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}@media(max-width: 699px){html{font-size:14px}}@media(min-width: 700px)and (max-width: 999px){html{font-size:14px}}@media(min-width: 1000px)and (max-width: 1199px){html{font-size:15px}}@media(min-width: 1200px)and (max-width: 1599px){html{font-size:16px}}@media(min-width: 1600px)and (max-width: 1999px){html{font-size:17px}}@media(min-width: 2000px)and (max-width: 2399px){html{font-size:18px}}@media(min-width: 2400px){html{font-size:20px}}html.is-loading{cursor:wait}::-moz-selection{background-color:#fff;color:#000;text-shadow:none}::selection{background-color:#fff;color:#000;text-shadow:none}a{color:inherit}[data-theme=dark] *:focus-visible:not(input):not(textarea):not(select){outline-color:#fff;outline-style:solid;outline-width:2px;outline-offset:2px}[data-theme=white] *:focus-visible:not(input):not(textarea):not(select){outline-color:#202ded;outline-style:solid;outline-width:2px;outline-offset:2px}[data-theme=blue] *:focus-visible:not(input):not(textarea):not(select){outline-color:#fff;outline-style:solid;outline-width:2px;outline-offset:2px}*:focus-visible:not(input):not(textarea):not(select){outline-color:currentColor;outline-style:solid;outline-width:2px;outline-offset:2px}input:focus-visible,select:focus-visible,textarea:focus-visible{outline-color:var(--color-theme-dark);outline-style:solid;outline-width:2px;outline-offset:0px}.o-container{margin-right:auto;margin-left:auto;padding-left:var(--grid-margin);padding-right:var(--grid-margin)}:root{--icon-width: 1.5rem;--icon-ratio: 1}.o-icon{display:inline-block;vertical-align:middle}.o-icon svg{display:block;width:var(--icon-width);height:calc(var(--icon-width)*1/(var(--icon-ratio)))}.svg-logo-lenis{--icon-width: 4.1875rem;--icon-ratio: 67/72}.svg-logo-locomotive{--icon-width: 4.9375rem;--icon-ratio: 79/35}.svg-arrow-external{--icon-width: 0.75rem}.svg-inview-01,.svg-inview-02,.svg-inview-03,.svg-inview-04,.svg-inview-05,.svg-inview-06{--icon-width: calc(24 * var(--vw, 1vw))}.svg-progress-01,.svg-progress-02,.svg-progress-03,.svg-progress-04,.svg-progress-05{--icon-width: calc(24 * var(--vw, 1vw));--icon-ratio: 224/350}.svg-parallax-01,.svg-parallax-02,.svg-parallax-03,.svg-parallax-04,.svg-parallax-05{--icon-width: calc(24 * var(--vw, 1vw))}.o-grid{display:grid;width:100%}.o-grid:is(ul,ol){margin:0;padding:0;list-style:none}.o-grid.-cols{grid-template-columns:repeat(var(--grid-columns), 1fr)}.o-grid.-col-4{grid-template-columns:repeat(4, 1fr)}.o-grid.-col-2{grid-template-columns:repeat(2, 1fr)}@media(min-width: 1000px){.o-grid.-col-4\\@from-medium{grid-template-columns:repeat(4, 1fr)}}.o-grid.-gutters{gap:var(--grid-gutter);-moz-column-gap:var(--grid-gutter);column-gap:var(--grid-gutter)}.o-grid.-full-height{height:100%}.o-grid.-top-items{align-items:start}.o-grid.-right-items{justify-items:end}.o-grid.-bottom-items{align-items:end}.o-grid.-left-items{justify-items:start}.o-grid.-center-items{align-items:center;justify-items:center}.o-grid.-center-items-x{justify-items:center}.o-grid.-center-items-y{align-items:center}.o-grid.-stretch-items{align-items:stretch;justify-items:stretch}.o-grid.-top-cells{align-content:start}.o-grid.-right-cells{justify-content:end}.o-grid.-bottom-cells{align-content:end}.o-grid.-left-cells{justify-content:start}.o-grid.-center-cells{align-content:center;justify-content:center}.o-grid.-center-cells-x{justify-content:center}.o-grid.-center-cells-y{align-content:center}.o-grid.-stretch-cells{align-content:stretch;justify-content:stretch}.o-grid.-space-around-cells{align-content:space-around;justify-content:space-around}.o-grid.-space-around-cells-x{justify-content:space-around}.o-grid.-space-around-cells-y{align-content:space-around}.o-grid.-space-between-cells{justify-content:space-between;align-content:space-between}.o-grid.-space-between-cells-x{justify-content:space-between}.o-grid.-space-between-cells-y{align-content:space-between}.o-grid.-space-evenly-cells{justify-content:space-evenly;align-content:space-evenly}.o-grid.-space-evenly-cells-x{justify-content:space-evenly}.o-grid.-space-evenly-cells-y{align-content:space-evenly}.o-grid_item{grid-column-start:var(--gc-start, 1);grid-column-end:var(--gc-end, -1)}.o-grid_item.-align-end{align-self:end}:root{--font-size-serif-large: clamp(100px, 0.2083333333 * calc(100 * var(--vw, 1vw)), 300px);--font-size-serif-medium: clamp(40px, 0.0833333333 * calc(100 * var(--vw, 1vw)), 120px);--font-size-h1: clamp(54px, 0.0833333333 * calc(100 * var(--vw, 1vw)), 120px);--font-size-h2: clamp(32px, 0.0625 * calc(100 * var(--vw, 1vw)), 90px);--font-size-h3: clamp(14px, 0.0194444444 * calc(100 * var(--vw, 1vw)), 28px)}.c-heading{font-family:\"Helvetica Now Display\",-apple-system,BlinkMacSystemFont,avenir next,avenir,segoe ui,helvetica neue,helvetica,Cantarell,Ubuntu,roboto,noto,arial,sans-serif;font-weight:400;line-height:1;letter-spacing:-0.03em}.c-heading.-h1{font-size:var(--font-size-h1)}.c-heading.-h2{font-size:var(--font-size-h2)}.c-heading.-h3{font-size:var(--font-size-h3)}.c-heading-serif{font-family:\"PP Locomotive New\",-apple-system,BlinkMacSystemFont,avenir next,avenir,segoe ui,helvetica neue,helvetica,Cantarell,Ubuntu,roboto,noto,arial,sans-serif;font-weight:300;line-height:.85;letter-spacing:-0.03em}.c-heading-serif.-large{font-size:var(--font-size-serif-large)}.c-heading-serif.-medium{font-size:var(--font-size-serif-medium)}:root{--font-size-body-regular: 1rem;--font-size-body-medium: 1.3125rem;--font-size-label: 1rem;--font-size-label-small: 0.75rem}.c-text{font-family:\"Helvetica Now Display\",-apple-system,BlinkMacSystemFont,avenir next,avenir,segoe ui,helvetica neue,helvetica,Cantarell,Ubuntu,roboto,noto,arial,sans-serif;font-weight:500;line-height:1.2;letter-spacing:-0.01em}.c-text.-body-regular{font-size:var(--font-size-body-regular)}.c-text.-body-medium{font-size:var(--font-size-body-medium)}.c-text.-label{font-size:var(--font-size-label)}.c-text.-label-small{font-size:var(--font-size-label-small)}.c-button{--button-height: 3.5rem;--button-padding: 1rem;--button-gap: 1rem;--button-color-text: var(--color-background);--button-color-background: var(--color-text);--button-color-stroke: var(--color-text);--button-hover-color-text: var(--color-text);--button-hover-color-background: var(--color-background);position:relative;overflow:hidden;border-radius:4px;color:var(--button-color-text);border:1px solid var(--button-color-stroke);background-color:var(--button-color-background)}.c-button.-stroke{--button-color-text: currentColor;--button-color-background: transparent;--button-hover-color-text: var(--color-background);--button-hover-color-background: var(--color-text)}.c-button_wrap:nth-child(2){position:absolute;top:-1px;left:-1px;width:calc(100% + 2px);height:calc(100% + 2px);color:var(--button-hover-color-text);background-color:var(--button-hover-color-background);clip-path:inset(10% -100% 10% 100% round 4px 4px 4px 4px);transition:clip-path .5s cubic-bezier(0.77, 0, 0.175, 1)}.c-button:hover .c-button_wrap:nth-child(2){clip-path:inset(0 0 0 0 round 4px 4px 4px 4px)}.c-button_inner{display:inline-flex;align-items:center;-moz-column-gap:var(--button-gap);column-gap:var(--button-gap);min-height:var(--button-height);padding:0 var(--button-padding);transition:transform .5s cubic-bezier(0.77, 0, 0.175, 1)}.c-button:hover .c-button_wrap:nth-child(1) .c-button_inner{transform:translate3d(calc(-1 * var(--icon-width) - var(--button-gap)), 0, 0)}.c-button_wrap:nth-child(2) .c-button_inner{position:absolute;top:-1px;left:-1px;width:calc(100% + 2px);height:calc(100% + 2px);flex-direction:row-reverse;transform:translate3d(calc(var(--icon-width) + var(--button-gap)), 0, 0)}.c-button:hover .c-button_wrap:nth-child(2) .c-button_inner{transform:translate3d(0, 0, 0)}.c-button_label{font-family:\"Helvetica Now Display\",-apple-system,BlinkMacSystemFont,avenir next,avenir,segoe ui,helvetica neue,helvetica,Cantarell,Ubuntu,roboto,noto,arial,sans-serif;font-weight:500;line-height:1.2;letter-spacing:-0.01em;font-size:var(--font-size-label)}.c-form_item{position:relative;margin-bottom:1.875rem}.c-form_label,.c-form_checkboxLabel,.c-form_radioLabel{display:block;margin-bottom:.625rem}.c-form_input,.c-form_textarea,.c-form_select_input{padding:.625rem;border:1px solid #d3d3d3;background-color:#fff}.c-form_input:hover,.c-form_textarea:hover,.c-form_select_input:hover{border-color:#a9a9a9}.c-form_input:focus,.c-form_textarea:focus,.c-form_select_input:focus{border-color:dimgray}.c-form_input::-moz-placeholder, .c-form_textarea::-moz-placeholder, .c-form_select_input::-moz-placeholder{color:gray}.c-form_input::placeholder,.c-form_textarea::placeholder,.c-form_select_input::placeholder{color:gray}.c-form_checkboxLabel,.c-form_radioLabel{position:relative;display:inline-block;margin-right:.625rem;margin-bottom:0;padding-left:1.75rem;cursor:pointer}.c-form_checkboxLabel::before,.c-form_radioLabel::before,.c-form_checkboxLabel::after,.c-form_radioLabel::after{position:absolute;top:50%;left:0;display:inline-block;margin-top:-0.5625rem;padding:0;width:1.125rem;height:1.125rem;content:\"\"}.c-form_checkboxLabel::before,.c-form_radioLabel::before{background-color:#fff;border:1px solid #d3d3d3}.c-form_checkboxLabel::after,.c-form_radioLabel::after{border-color:rgba(0,0,0,0);background-color:rgba(0,0,0,0);background-image:url(\"data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20version%3D%221.1%22%20x%3D%220%22%20y%3D%220%22%20width%3D%2213%22%20height%3D%2210.5%22%20viewBox%3D%220%200%2013%2010.5%22%20enable-background%3D%22new%200%200%2013%2010.5%22%20xml%3Aspace%3D%22preserve%22%3E%3Cpath%20fill%3D%22%23424242%22%20d%3D%22M4.8%205.8L2.4%203.3%200%205.7l4.8%204.8L13%202.4c0%200-2.4-2.4-2.4-2.4L4.8%205.8z%22%2F%3E%3C%2Fsvg%3E\");background-position:center;background-size:.75rem;background-repeat:no-repeat;opacity:0}.c-form_checkboxLabel:hover::before,.c-form_radioLabel:hover::before{border-color:#a9a9a9}.c-form_checkbox:focus+.c-form_checkboxLabel::before,.c-form_radio:focus+.c-form_checkboxLabel::before,.c-form_checkbox:focus+.c-form_radioLabel::before,.c-form_radio:focus+.c-form_radioLabel::before{border-color:dimgray}.c-form_checkbox:checked+.c-form_checkboxLabel::after,.c-form_radio:checked+.c-form_checkboxLabel::after,.c-form_checkbox:checked+.c-form_radioLabel::after,.c-form_radio:checked+.c-form_radioLabel::after{opacity:1}.c-form_checkbox,.c-form_radio{position:absolute;width:0;opacity:0}.c-form_radioLabel::before,.c-form_radioLabel::after{border-radius:50%}.c-form_radioLabel::after{background-image:url(\"data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20version%3D%221.1%22%20x%3D%220%22%20y%3D%220%22%20width%3D%2213%22%20height%3D%2213%22%20viewBox%3D%220%200%2013%2013%22%20enable-background%3D%22new%200%200%2013%2013%22%20xml%3Aspace%3D%22preserve%22%3E%3Ccircle%20fill%3D%22%23424242%22%20cx%3D%226.5%22%20cy%3D%226.5%22%20r%3D%226.5%22%2F%3E%3C%2Fsvg%3E\");background-size:.375rem}.c-form_select{position:relative;cursor:pointer}.c-form_select::after{position:absolute;top:0;right:0;bottom:0;z-index:2;width:2.5rem;background-image:url(\"data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20version%3D%221.1%22%20x%3D%220%22%20y%3D%220%22%20width%3D%2213%22%20height%3D%2211.3%22%20viewBox%3D%220%200%2013%2011.3%22%20enable-background%3D%22new%200%200%2013%2011.3%22%20xml%3Aspace%3D%22preserve%22%3E%3Cpolygon%20fill%3D%22%23424242%22%20points%3D%226.5%2011.3%203.3%205.6%200%200%206.5%200%2013%200%209.8%205.6%20%22%2F%3E%3C%2Fsvg%3E\");background-position:center;background-size:.5rem;background-repeat:no-repeat;content:\"\";pointer-events:none}.c-form_select_input{position:relative;z-index:1;padding-right:2.5rem;cursor:pointer}.c-form_textarea{min-height:12.5rem}[data-header-theme=blue] .c-header{--color-header-text: white;--color-header-background: #202ded}[data-header-theme=black] .c-header{--color-header-text: white;--color-header-background: black}[data-header-theme=white] .c-header{--color-header-text: #202ded;--color-header-background: white}.c-header{position:fixed;top:0;width:100%;display:grid;align-items:center;grid-template-columns:repeat(3, 1fr);-moz-column-gap:var(--grid-gutter);column-gap:var(--grid-gutter);color:var(--color-header-text);background-color:var(--color-header-background);padding:var(--grid-margin);z-index:200}@media(max-width: 699px){.c-header{align-items:flex-start}}@media(min-width: 700px){.c-header{height:var(--header-height)}}html.is-first-loaded .c-header{transition:color .15s,background-color .15s}.c-header_col{display:flex;justify-content:space-between;align-items:center}.c-header_col.-center{justify-content:center;align-items:center}@media(max-width: 699px){.c-header_col{flex-direction:column;align-items:flex-start;gap:var(--grid-margin)}.c-header_col:last-of-type{align-items:flex-end}}.c-header-theme-toggler{position:absolute;top:calc(-1*var(--header-height));bottom:var(--header-height);left:0;width:100%;pointer-events:none}.c-hero_sticky{position:sticky;bottom:0}.c-hero_main{display:grid;gap:var(--grid-gutter);align-items:flex-end;min-height:100svh;padding-bottom:var(--grid-margin);position:relative;z-index:10}.c-hero_main.-footer{min-height:100svh}@media(max-width: 699px){.c-hero_main{grid-template-rows:1fr auto 1fr}}@media(min-width: 700px){.c-hero_main{grid-template-columns:1fr 1fr}}.c-hero_heading{display:flex;flex-direction:column;row-gap:clamp(calc(0.0625rem * var(--spacing-md-mobile)),var(--spacing-md-desktop)/14.4*1vw,calc(0.0625rem * var(--spacing-md-desktop)));height:100%}@media(max-width: 699px){.c-hero_heading{grid-row:2/3}}@media(min-width: 700px){.c-hero_heading{grid-column:2/3;grid-row:1/2}}@media(max-width: 699px){.c-hero_nav{grid-row:3/4}}@media(min-width: 700px){.c-hero_nav{grid-column:1/2;grid-row:1/2}}.c-hero_title{margin-block:auto}.c-footer .c-hero_title{margin-top:auto;margin-bottom:0}.c-hero_links_item+.c-hero_links_item{margin-top:.5rem}.c-hero_description_container{display:grid;grid-template-columns:1fr 1fr;-moz-column-gap:var(--grid-gutter);column-gap:var(--grid-gutter);align-items:flex-end}.c-hero_version{display:flex;justify-content:flex-end;-moz-column-gap:.5em;column-gap:.5em}@media(max-width: 699px){.c-hero_version{position:absolute;bottom:var(--grid-margin);right:0}}.c-hero_version span{transition:transform .75s cubic-bezier(0.165, 0.84, 0.44, 1);transform:translate3d(0, 100%, 0)}.c-hero_version span:nth-child(1){position:relative;top:.1em}.c-hero_version.is-inview span{transform:translate3d(0, 0, 0)}.c-hero_line{display:block;clip-path:inset(-5% 0)}.c-hero_word{display:inline-block;transform:translate3d(0, -110%, 0)}html.is-first-loaded .c-hero_word{transition:transform .6s cubic-bezier(0.165, 0.84, 0.44, 1);transition-delay:calc(var(--index)*.1s)}html.is-ready .c-hero_word.-hero{transform:translate3d(0, 0, 0)}.is-inview .c-hero_word.-footer{transform:translate3d(0, 0, 0)}.c-rail{position:relative;overflow:hidden;padding:clamp(calc(0.0625rem * var(--spacing-md-mobile)),var(--spacing-md-desktop)/14.4*1vw,calc(0.0625rem * var(--spacing-md-desktop))) 0}.c-rail_inner{display:inline-flex;align-items:center;white-space:nowrap}.c-rail_item{font-family:\"PP Locomotive New\",-apple-system,BlinkMacSystemFont,avenir next,avenir,segoe ui,helvetica neue,helvetica,Cantarell,Ubuntu,roboto,noto,arial,sans-serif;font-weight:300;line-height:.85;letter-spacing:-0.03em;font-size:var(--font-size-serif-medium);padding-right:.5em}.c-rail_item .c-icon{transform:translateY(-0.075em)}.c-rail_glyph{display:inline-block;padding-left:.5em;width:100px;text-align:center}@media(min-width: 1000px){.c-rail_glyph{width:140px}}@media(min-width: 1200px){.c-rail_glyph{width:170px}}.c-cascade{position:relative}.c-cascade_text{display:flex;flex-direction:column;max-width:13.75rem}@media(max-width: 1199px){.c-cascade_text{margin-left:50%;margin-bottom:clamp(calc(0.0625rem * var(--spacing-xl-mobile)),var(--spacing-xl-desktop)/14.4*1vw,calc(0.0625rem * var(--spacing-xl-desktop)))}}@media(min-width: 1200px){.c-cascade_text{position:absolute;top:0;left:calc((100% + var(--grid-gutter))/4*3)}}.c-cascade_container{display:flex;justify-content:center;margin-left:calc(-1*var(--grid-margin));margin-right:calc(-1*var(--grid-margin));overflow:hidden}.c-cascade_inner{width:auto}.c-cascade_item+.c-cascade_item{margin-left:calc(var(--item-index)*2.35em);margin-top:-1em}.c-cascade_item:nth-child(odd){opacity:.35}.c-cascade_line{display:block;perspective:100vw;transform-style:preserve-3d}.c-cascade_word{display:inline-block;white-space:nowrap;transform:rotate3d(1, 0, 0, clamp(0deg, 90deg + (var(--progress) - calc(var(--item-index) / 8)) / (calc((var(--item-index) + 1) / 8) - calc(var(--item-index) / 8)) * (0deg - 90deg), 90deg));opacity:clamp(0,0 + (var(--progress) - calc(var(--item-index) / 8))/(calc((var(--item-index) + 1) / 8) - calc(var(--item-index) / 8))*(1 - 0),1);transform-origin:top;clip-path:inset(0)}.c-cascade_glyph{position:absolute;bottom:0;left:0;font-size:var(--font-size-serif-medium)}.c-section-heading{display:flex;flex-direction:column}.c-section-heading_line+.c-section-heading_line{margin-top:.05em}@media(max-width: 999px){.c-section-heading_line{display:flex;flex-wrap:wrap}}@media(min-width: 1000px){.c-section-heading_line:last-child{display:grid;grid-template-columns:1fr auto 1fr;-moz-column-gap:var(--grid-gutter);column-gap:var(--grid-gutter);align-items:flex-end}}.c-section-heading_word{display:inline-block;width:100%;text-align:center}@media(max-width: 999px){.c-section-heading_line:last-child .c-section-heading_word{margin-bottom:3.125rem}}@media(min-width: 1000px){.c-section-heading_line:last-child .c-section-heading_word{grid-column:2/3;margin-bottom:-0.02em}}.c-section-heading_label{display:flex;align-items:center}@media(max-width: 999px){.c-section-heading_label{flex:0 0 50%}.c-section-heading_label.-left{flex-direction:column}.c-section-heading_label.-right{flex-direction:column-reverse}}@media(min-width: 1000px){.c-section-heading_label{justify-content:center;-moz-column-gap:.5em;column-gap:.5em;grid-row:1/2}.c-section-heading_label.-left{grid-column:1/2}.c-section-heading_label.-right{grid-column:3/4}}.c-tool{position:relative;background-color:#202ded;overflow:hidden}.c-tool.-parallax{padding-bottom:clamp(calc(0.0625rem * var(--spacing-sm-mobile)),var(--spacing-sm-desktop)/14.4*1vw,calc(0.0625rem * var(--spacing-sm-desktop)))}.c-tool.-parallax:before{content:\"\";position:absolute;bottom:0;left:0;width:100%;height:clamp(calc(0.0625rem * var(--spacing-xl-mobile)),var(--spacing-xl-desktop)/14.4*1vw,calc(0.0625rem * var(--spacing-xl-desktop)));background-image:linear-gradient(to bottom, hsla(236, 85%, 53%, 0) 0%, hsla(236, 85%, 53%, 0.013) 8.1%, hsla(236, 85%, 53%, 0.049) 15.5%, hsla(236, 85%, 53%, 0.104) 22.5%, hsla(236, 85%, 53%, 0.175) 29%, hsla(236, 85%, 53%, 0.259) 35.3%, hsla(236, 85%, 53%, 0.352) 41.2%, hsla(236, 85%, 53%, 0.45) 47.1%, hsla(236, 85%, 53%, 0.55) 52.9%, hsla(236, 85%, 53%, 0.648) 58.8%, hsla(236, 85%, 53%, 0.741) 64.7%, hsla(236, 85%, 53%, 0.825) 71%, hsla(236, 85%, 53%, 0.896) 77.5%, hsla(236, 85%, 53%, 0.951) 84.5%, hsla(236, 85%, 53%, 0.987) 91.9%, hsl(236, 85%, 53%) 100%);z-index:1}.c-tool_head{position:relative;display:grid;-moz-column-gap:var(--grid-gutter);column-gap:var(--grid-gutter);z-index:1;padding-top:.5rem}@media(max-width: 999px){.c-tool_head{grid-template-columns:repeat(4, 1fr)}}@media(min-width: 1000px){.c-tool_head{grid-template-columns:repeat(3, 1fr)}}.c-tool_head::before{content:\"\";position:absolute;top:0;left:0;width:100%;height:1px;background-color:currentColor;transform-origin:top right;transform:scale3d(0, 1, 1)}html.is-first-loaded .c-tool_head::before{transition:transform .75s cubic-bezier(0.77, 0, 0.175, 1)}html.is-first-loaded .c-tool.is-inview .c-tool_head::before{transform:scale3d(1, 1, 1)}@media(min-width: 1000px){.c-tool_head{margin-left:calc((100% + var(--grid-gutter))/4)}}@media(max-width: 999px){.c-tool_index{grid-column:span 2}}@media(min-width: 1000px){.c-tool_index{grid-column:span 1}}@media(max-width: 699px){.c-tool_label{grid-column:span 2}}@media(min-width: 700px){.c-tool_label{grid-column:span 1}}@media(max-width: 699px){.c-tool_description{grid-column:1/-1;grid-row:3/4;max-width:17.5rem;margin-top:.625rem}}@media(min-width: 700px){.c-tool_description{grid-column:span 1;grid-column-end:-1}}.c-tool_title{grid-column:1/-1;max-width:31.25rem}@media(max-width: 699px){.c-tool_title{grid-row:2/3;margin-top:.8em;margin-bottom:.4em}}@media(max-width: 699px){.c-tool.-parallax .c-tool_playground{margin-top:clamp(calc(0.0625rem * var(--spacing-md-mobile)),var(--spacing-md-desktop)/14.4*1vw,calc(0.0625rem * var(--spacing-md-desktop)))}}.c-tool_playground{position:relative;aspect-ratio:var(--container-ratio);width:100%}.c-tool_shape{position:absolute}.c-tool.-inview .c-tool_shape{left:calc(var(--left, 0)/1440*100%);top:calc(var(--top, 0)/(1/(var(--container-ratio))*1440)*100%);transform:translateX(-50%) translateY(-50%)}.c-tool.-inview .c-tool_shape.-first{--top: 502;--left: 90}.c-tool.-inview .c-tool_shape.-second{--top: 700;--left: 355}.c-tool.-inview .c-tool_shape.-third{--top: 475;--left: 655}.c-tool.-inview .c-tool_shape.-fourth{--top: 250;--left: 987}.c-tool.-inview .c-tool_shape.-fifth{--top: 345;--left: 1310}.c-tool.-inview .c-tool_shape.-sixth{--top: 750;--left: 1050}.c-tool.-inview .c-tool_shape.-first svg{transform:rotate(calc(var(--progress) * -90deg))}.c-tool.-inview .c-tool_shape.-fifth svg{transform:rotate(calc(var(--progress) * 150deg))}.c-tool.-progress .c-tool_shape{top:50%;left:50%;transform:translateX(-50%) translateY(-50%)}.c-tool.-progress .c-tool_shape.-fourth{z-index:1}.c-tool.-parallax .c-tool_shape{left:calc(var(--left, 0));top:calc(var(--top, 0));transform:translateX(-50%) translateY(-50%)}.c-tool.-parallax .c-tool_shape.-first{--top: 40%;--left: 16%}.c-tool.-parallax .c-tool_shape.-second{--top: 55%;--left: 34%}.c-tool.-parallax .c-tool_shape.-third{--top: 30%;--left: 53%}.c-tool.-parallax .c-tool_shape.-fourth{--top: 65%;--left: 68%}.c-tool.-parallax .c-tool_shape.-fifth{--top: 40%;--left: 86%}.c-tool.-inview .c-tool_shape_svg{transform:scale3d(0, 0, 1)}html.is-first-loaded .c-tool.-inview .c-tool_shape_svg{transition:transform .5s cubic-bezier(0.165, 0.84, 0.44, 1)}.c-tool.-inview .c-tool_shape.is-inview .c-tool_shape_svg{transform:scale3d(1, 1, 1)}.c-tool.-progress .c-tool_shape_svg{display:block;transform:translate3d(calc((0.5 + 0.5 * var(--progress)) * var(--index) * 100%), 0, 0)}@media(max-width: 699px){.c-features-grid{--rows: 6;--columns: 2;--cell-ratio: 180/220;--grid-image: url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' xml:space='preserve' viewBox='0 0 361.5 1980'%3E%3Cpath fill='%23282828' fill-rule='evenodd' d='M173 1760H1.5c-.3 0-.5.2-.5.5s.2.5.5.5H173c4.4 0 8 3.6 8 8v211h1v-211c0-4.4 3.6-8 8-8h171.5v-1H190c-4.4 0-8-3.6-8-8v-203c0-4.4 3.6-8 8-8h171.5v-1H190c-4.4 0-8-3.6-8-8v-203c0-4.4 3.6-8 8-8h171.5v-1H190c-4.4 0-8-3.6-8-8v-203c0-4.4 3.6-8 8-8h171.5v-1H190c-4.4 0-8-3.6-8-8V889c0-4.4 3.6-8 8-8h171.5v-1H190c-4.4 0-8-3.6-8-8V669c0-4.4 3.6-8 8-8h171.5v-1H190c-4.4 0-8-3.6-8-8V449c0-4.4 3.6-8 8-8h171.5v-1H190c-4.4 0-8-3.6-8-8V229c0-4.4 3.6-8 8-8h171.5v-1H190c-4.4 0-8-3.6-8-8V.5c0-.3-.2-.5-.5-.5s-.5.2-.5.5V212c0 4.4-3.6 8-8 8H1.5c-.3 0-.5.2-.5.5s.2.5.5.5H173c4.4 0 8 3.6 8 8v203c0 4.4-3.6 8-8 8H1.5c-.3 0-.5.2-.5.5s.2.5.5.5H173c4.4 0 8 3.6 8 8v203c0 4.4-3.6 8-8 8H1.5c-.3 0-.5.2-.5.5s.2.5.5.5H173c4.4 0 8 3.6 8 8v203c0 4.4-3.6 8-8 8H1.5c-.3 0-.5.2-.5.5s.2.5.5.5H173c4.4 0 8 3.6 8 8v203c0 4.4-3.6 8-8 8H1.5c-.3 0-.5.2-.5.5s.2.5.5.5H173c4.4 0 8 3.6 8 8v203c0 4.4-3.6 8-8 8H1.5c-.3 0-.5.2-.5.5s.2.5.5.5H173c4.4 0 8 3.6 8 8v203c0 4.4-3.6 8-8 8H1.5c-.3 0-.5.2-.5.5s.2.5.5.5H173c4.4 0 8 3.6 8 8v203c0 4.4-3.6 8-8 8z' clip-rule='evenodd'/%3E%3C/svg%3E%0A\")}}@media(min-width: 700px){.c-features-grid{--rows: 6;--columns: 4;--cell-ratio: 1;--grid-image: url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 1400 4198'%3E%3Cpath fill='%23282828' fill-rule='evenodd' d='M342 349a8 8 0 0 0 8-8V.5a.5.5 0 0 1 1 0V341a8 8 0 0 0 8 8h333.5a8 8 0 0 0 8-8V.5a.5.5 0 0 1 1 0V341a8 8 0 0 0 8 8h333a8 8 0 0 0 8-8V.5c0-.276.22-.5.5-.5s.5.224.5.5V341a8 8 0 0 0 8 8h340c.28 0 .5.224.5.5s-.22.5-.5.5h-340a8 8 0 0 0-8 8v333a8 8 0 0 0 8 8h340c.28 0 .5.224.5.5s-.22.5-.5.5h-340a8 8 0 0 0-8 8v333c0 4.42 3.58 8 8 8h339c.28 0 .5.22.5.5s-.22.5-.5.5h-339c-4.42 0-8 3.58-8 8v333c0 4.42 3.58 8 8 8h339c.28 0 .5.22.5.5s-.22.5-.5.5h-339c-4.42 0-8 3.58-8 8v333c0 4.42 3.58 8 8 8h339c.28 0 .5.22.5.5s-.22.5-.5.5h-339c-4.42 0-8 3.58-8 8v333c0 4.42 3.58 8 8 8h339c.28 0 .5.22.5.5s-.22.5-.5.5h-339c-4.42 0-8 3.58-8 8v333c0 4.42 3.58 8 8 8h339c.28 0 .5.22.5.5s-.22.5-.5.5h-339c-4.42 0-8 3.58-8 8v333c0 4.42 3.58 8 8 8h339c.28 0 .5.22.5.5s-.22.5-.5.5h-339c-4.42 0-8 3.58-8 8v333c0 4.42 3.58 8 8 8h339c.28 0 .5.22.5.5s-.22.5-.5.5h-339c-4.42 0-8 3.58-8 8v333c0 4.42 3.58 8 8 8h339c.28 0 .5.22.5.5s-.22.5-.5.5h-339c-4.42 0-8 3.58-8 8v333c0 4.42 3.58 8 8 8h339c.28 0 .5.22.5.5s-.22.5-.5.5h-339c-4.42 0-8 3.58-8 8v339.5c0 .28-.22.5-.5.5s-.5-.22-.5-.5V3858c0-4.42-3.58-8-8-8h-333a8 8 0 0 0-8 8v339.5c0 .28-.224.5-.5.5s-.5-.22-.5-.5V3858a8 8 0 0 0-8-8H359a8 8 0 0 0-8 8v339.5c0 .28-.224.5-.5.5s-.5-.22-.5-.5V3858a8 8 0 0 0-8-8H.5c-.276 0-.5-.22-.5-.5s.224-.5.5-.5H342a8 8 0 0 0 8-8v-333a8 8 0 0 0-8-8H.5c-.276 0-.5-.22-.5-.5s.224-.5.5-.5H342a8 8 0 0 0 8-8v-333a8 8 0 0 0-8-8H.5c-.276 0-.5-.22-.5-.5s.224-.5.5-.5H342a8 8 0 0 0 8-8v-333a8 8 0 0 0-8-8H.5c-.276 0-.5-.22-.5-.5s.224-.5.5-.5H342a8 8 0 0 0 8-8v-333a8 8 0 0 0-8-8H.5c-.276 0-.5-.22-.5-.5s.224-.5.5-.5H342a8 8 0 0 0 8-8v-333a8 8 0 0 0-8-8H.5c-.276 0-.5-.22-.5-.5s.224-.5.5-.5H342a8 8 0 0 0 8-8v-333a8 8 0 0 0-8-8H.5c-.276 0-.5-.22-.5-.5s.224-.5.5-.5H342a8 8 0 0 0 8-8v-333a8 8 0 0 0-8-8H.5c-.276 0-.5-.22-.5-.5s.224-.5.5-.5H342a8 8 0 0 0 8-8v-333a8 8 0 0 0-8-8H.5c-.276 0-.5-.22-.5-.5s.224-.5.5-.5H342a8 8 0 0 0 8-8V708a8 8 0 0 0-8-8H.5a.5.5 0 0 1 0-1H342a8 8 0 0 0 8-8V358a8 8 0 0 0-8-8H.5a.5.5 0 0 1 0-1H342Zm17 1a8 8 0 0 0-8 8v333a8 8 0 0 0 8 8h333.5a8 8 0 0 0 8-8V358a8 8 0 0 0-8-8H359Zm350.5 0a8 8 0 0 0-8 8v333a8 8 0 0 0 8 8h333a8 8 0 0 0 8-8V358a8 8 0 0 0-8-8h-333Zm341 358a8 8 0 0 0-8-8h-333a8 8 0 0 0-8 8v333a8 8 0 0 0 8 8h333c4.42 0 8-3.58 8-8V708Zm0 350c0-4.42-3.58-8-8-8h-333a8 8 0 0 0-8 8v333a8 8 0 0 0 8 8h333c4.42 0 8-3.58 8-8v-333Zm0 350c0-4.42-3.58-8-8-8h-333a8 8 0 0 0-8 8v333a8 8 0 0 0 8 8h333c4.42 0 8-3.58 8-8v-333Zm0 350c0-4.42-3.58-8-8-8h-333a8 8 0 0 0-8 8v333a8 8 0 0 0 8 8h333c4.42 0 8-3.58 8-8v-333Zm0 350c0-4.42-3.58-8-8-8h-333a8 8 0 0 0-8 8v333a8 8 0 0 0 8 8h333c4.42 0 8-3.58 8-8v-333Zm0 350c0-4.42-3.58-8-8-8h-333a8 8 0 0 0-8 8v333a8 8 0 0 0 8 8h333c4.42 0 8-3.58 8-8v-333Zm0 350c0-4.42-3.58-8-8-8h-333a8 8 0 0 0-8 8v333a8 8 0 0 0 8 8h333c4.42 0 8-3.58 8-8v-333Zm0 350c0-4.42-3.58-8-8-8h-333a8 8 0 0 0-8 8v333a8 8 0 0 0 8 8h333c4.42 0 8-3.58 8-8v-333Zm0 350c0-4.42-3.58-8-8-8h-333a8 8 0 0 0-8 8v333a8 8 0 0 0 8 8h333c4.42 0 8-3.58 8-8v-333Zm-358 341a8 8 0 0 0 8-8v-333a8 8 0 0 0-8-8H359a8 8 0 0 0-8 8v333a8 8 0 0 0 8 8h333.5ZM351 3491a8 8 0 0 0 8 8h333.5a8 8 0 0 0 8-8v-333a8 8 0 0 0-8-8H359a8 8 0 0 0-8 8v333Zm0-350a8 8 0 0 0 8 8h333.5a8 8 0 0 0 8-8v-333a8 8 0 0 0-8-8H359a8 8 0 0 0-8 8v333Zm0-350a8 8 0 0 0 8 8h333.5a8 8 0 0 0 8-8v-333a8 8 0 0 0-8-8H359a8 8 0 0 0-8 8v333Zm0-350a8 8 0 0 0 8 8h333.5a8 8 0 0 0 8-8v-333a8 8 0 0 0-8-8H359a8 8 0 0 0-8 8v333Zm0-350a8 8 0 0 0 8 8h333.5a8 8 0 0 0 8-8v-333a8 8 0 0 0-8-8H359a8 8 0 0 0-8 8v333Zm0-350a8 8 0 0 0 8 8h333.5a8 8 0 0 0 8-8v-333a8 8 0 0 0-8-8H359a8 8 0 0 0-8 8v333Zm0-350a8 8 0 0 0 8 8h333.5a8 8 0 0 0 8-8v-333a8 8 0 0 0-8-8H359a8 8 0 0 0-8 8v333Zm0-350a8 8 0 0 0 8 8h333.5a8 8 0 0 0 8-8V708a8 8 0 0 0-8-8H359a8 8 0 0 0-8 8v333Z' clip-rule='evenodd'/%3E%3C/svg%3E%0A\")}}.c-features-grid{position:relative}.c-features-grid:before{content:\"\";display:block;width:100%;padding-top:calc((var(--rows) + 2)/var(--columns)*1/(var(--cell-ratio))*100%);pointer-events:none}.c-features-grid:after{content:\"\";position:absolute;top:0;left:0;width:100%;height:100%;background-size:cover;background-image:var(--grid-image);pointer-events:none}.c-features-grid_container{position:absolute;top:0;left:0;width:100%;height:100%;z-index:1}.c-features-grid_container::before,.c-features-grid_container::after{content:\"\";position:absolute;left:0;width:100%;padding-top:calc(1/var(--columns)*1/(var(--cell-ratio))*100%);background-color:var(--color-background);z-index:1}.c-features-grid_container::before{top:0;-webkit-mask-image:-webkit-linear-gradient(bottom, rgba(0, 0, 0, 0), rgb(0, 0, 0))}.c-features-grid_container::after{bottom:0;-webkit-mask-image:-webkit-linear-gradient(top, rgba(0, 0, 0, 0), rgb(0, 0, 0))}.c-features-grid_inner{position:relative;display:grid;grid-template-columns:repeat(var(--columns), 1fr);grid-template-rows:repeat(var(--rows), 1fr);width:100%;height:100%;padding-top:calc(1/var(--columns)*1/(var(--cell-ratio))*100%);padding-bottom:calc(1/var(--columns)*1/(var(--cell-ratio))*100%);pointer-events:none}@media(max-width: 699px){.c-features-grid_inner{grid-template-areas:\"locomotive lenis\" \". scrollbar\" \"normalized sticky\" \"io sticky\" \"direction scroll-to\" \". custom-easing\"}}@media(min-width: 700px){.c-features-grid_inner{grid-template-areas:\"scrollbar  . lenis locomotive\" \". normalized  . .\" \". . sticky .\" \"io . sticky .\" \". scroll-to sticky direction\" \". custom-easing sticky direction\"}}.c-features-grid_cell{position:relative;text-align:left}.c-features-grid_cell.-lenis{grid-area:lenis}.c-features-grid_cell.-locomotive{grid-area:locomotive}.c-features-grid_cell.-scrollbar{grid-area:scrollbar}.c-features-grid_cell.-normalized{grid-area:normalized}.c-features-grid_cell.-sticky{grid-area:sticky}.c-features-grid_cell.-io{grid-area:io}.c-features-grid_cell.-scroll-to{grid-area:scroll-to}.c-features-grid_cell.-direction{grid-area:direction}.c-features-grid_cell.-custom-easing{grid-area:custom-easing}@media(min-width: 700px){.c-features-grid_cell.-io{transition:transform .75s cubic-bezier(0.165, 0.84, 0.44, 1)}.c-features-grid_cell.-io.is-inview{transform:translate3d(100%, 0, 0)}}.c-features-grid_cell_ratio{display:flex;aspect-ratio:var(--cell-ratio);padding:1rem;pointer-events:auto}@media(min-width: 700px){.c-features-grid_cell.-sticky .c-features-grid_cell_ratio{position:sticky;top:calc(var(--header-height) + 1px);z-index:1}.c-features-grid_cell.-sticky .c-features-grid_cell_ratio::before{content:\"\";position:absolute;background-color:var(--color-background);z-index:-1;top:-1px;left:0px;width:calc(100% + 1px);height:calc(100% + 1px);border:1px solid #282828;border-radius:calc(var(--vw, 1vw)*.6)}}.c-features-grid_cell.-direction .c-features-grid_cell_ratio{position:relative}@media(min-width: 700px){.c-features-grid_cell.-io .c-features-grid_cell_ratio{z-index:1}.c-features-grid_cell.-io .c-features-grid_cell_ratio::before{content:\"\";position:absolute;top:-1px;left:0px;width:calc(100% + 1px);height:calc(100% + 1px);background-color:var(--color-background);border-top:1px solid #282828;border-right:1px solid #282828;border-bottom:1px solid #282828;border-top-right-radius:calc(var(--vw, 1vw)*.6);border-bottom-right-radius:calc(var(--vw, 1vw)*.6);z-index:-1}.c-features-grid_cell.-io.is-inview .c-features-grid_cell_ratio::before{border-left:1px solid #282828;border-radius:calc(var(--vw, 1vw)*.6)}}.c-features-grid_cell_inner{position:relative;display:flex;flex-direction:column;justify-content:space-between;align-items:flex-start;width:100%;padding-right:1.875rem}.c-features-grid_cell_inner.-logo{padding-right:0}.c-features-grid_link{position:absolute;top:0;left:0;width:100%;height:100%;z-index:2}@media(hover: hover){.c-features-grid_link::before{content:\"\";position:absolute;top:0;left:0;width:100%;height:100%;opacity:.07;background-color:currentColor;clip-path:polygon(80% 20%, 80% 20%, 80% 20%, 20% 80%, 20% 80%, 20% 80%, 20% 80%, 80% 20%);transition:clip-path .25s cubic-bezier(0.165, 0.84, 0.44, 1)}.c-features-grid_link:hover::before{animation-play-state:running;clip-path:polygon(15% 5%, 85% 5%, 95% 15%, 95% 85%, 85% 95%, 15% 95%, 5% 85%, 5% 15%)}}.c-features-grid_title{display:inline-block;text-wrap:balance}.c-features-grid_cell.-direction .c-features-grid_title{transition:transform .5s cubic-bezier(0.165, 0.84, 0.44, 1)}.c-features-grid_cell.-link .c-features-grid_title{position:absolute;bottom:0;left:0;clip-path:inset(0 -1rem)}.c-features_direction_title{display:flex;gap:.625rem}.c-features_direction_arrows{position:relative;clip-path:inset(0)}.c-features_direction_arrows span{--translate: 0%;display:block;transition:transform .6s cubic-bezier(0.165, 0.84, 0.44, 1)}.c-features_direction_arrows span:nth-of-type(1){transform:translate3d(0, var(--translate), 0)}.c-features_direction_arrows span:nth-of-type(2){position:absolute;transform:translate3d(0, calc(var(--translate) + 100%), 0);top:0;left:0}html.is-scrolling-up .c-features_direction_arrows span{--translate: -100%}.c-features-grid_title_label{display:inline-block}@media(hover: none){.c-features-grid_title_label:nth-child(2){display:none}}@media(hover: hover){.c-features-grid_title_label{transition:transform .5s cubic-bezier(0.23, 1, 0.32, 1)}.c-features-grid_title_label:nth-child(2){position:absolute;top:0;left:0;transform:translate3d(-1rem, -100%, 0)}.c-features-grid_cell:hover .c-features-grid_title_label:nth-child(1){transform:translate3d(1rem, 100%, 0)}.c-features-grid_cell:hover .c-features-grid_title_label:nth-child(2){transform:translate3d(0, 0, 0)}}.c-features-grid_desc{max-width:13.75rem}@media(max-width: 699px){.c-features-grid_desc{opacity:.6}}.c-features-grid_index{position:absolute;top:0;right:0}.c-features-grid_logo{display:flex;justify-content:center;align-items:center;width:100%;height:100%}@media(hover: hover){.c-features-grid_logo svg{transition:transform .5s cubic-bezier(0.23, 1, 0.32, 1)}.c-features-grid_cell:hover .c-features-grid_logo svg{transform:scale3d(0.95, 0.95, 1);animation:blink 100ms step-start 3}}.c-features-grid_icon-container{position:absolute;top:.625rem;right:.625rem;display:flex;overflow:hidden}.c-features-grid_icon{padding:.375rem}.c-features-grid_icon:nth-child(2){position:absolute;top:0;left:0;width:100%;height:100%;transform:translate3d(-100%, 100%, 0)}html.is-first-loaded .c-features-grid_icon{transition:transform .5s cubic-bezier(0.23, 1, 0.32, 1)}html.is-first-loaded .c-features-grid_cell:hover .c-features-grid_icon:nth-child(1){transform:translate3d(100%, -100%, 0)}html.is-first-loaded .c-features-grid_cell:hover .c-features-grid_icon:nth-child(2){transform:translate3d(0, 0, 0)}@keyframes blink{50%{opacity:0}}.c-sticky-heading{height:300vh}@media(max-aspect-ratio: 1.25/1){.c-sticky-heading{height:auto;padding-top:clamp(calc(0.0625rem * var(--spacing-2xl-mobile)),var(--spacing-2xl-desktop)/14.4*1vw,calc(0.0625rem * var(--spacing-2xl-desktop)))}}.c-sticky-heading_inner{position:sticky;top:0;display:flex;align-items:flex-end;width:100%;height:calc(var(--vh, 1vh)*100);overflow:hidden}@media(max-aspect-ratio: 1.25/1){.c-sticky-heading_inner{align-items:start;height:auto;position:relative;padding-top:clamp(calc(0.0625rem * var(--spacing-xs-mobile)),var(--spacing-xs-desktop)/14.4*1vw,calc(0.0625rem * var(--spacing-xs-desktop)))}}.c-sticky-heading_title{font-family:\"PP Locomotive New\",-apple-system,BlinkMacSystemFont,avenir next,avenir,segoe ui,helvetica neue,helvetica,Cantarell,Ubuntu,roboto,noto,arial,sans-serif;font-weight:300;line-height:.85;letter-spacing:-0.03em;font-size:calc(0.5*100*var(--vw, 1vw));width:auto;padding-right:calc(var(--grid-margin)*2);transform:translate3d(calc(-1 * var(--progress) * (100% - var(--vw, 1vw) * 100)), 0, 0)}@media(max-aspect-ratio: 1.25/1){.c-sticky-heading_title{font-size:calc(0.6041666667*49*var(--vw, 1vw));transform:none}}.c-sticky-heading_description{margin-left:calc(100vw - 13.75rem - var(--grid-margin)*2);max-width:13.75rem;margin-bottom:clamp(calc(0.0625rem * var(--spacing-sm-mobile)),var(--spacing-sm-desktop)/14.4*1vw,calc(0.0625rem * var(--spacing-sm-desktop)))}@media(min-width: 1000px){.c-sticky-heading_description{max-width:17.5rem;margin-left:50vw;font-size:calc(0.5*100*var(--vw, 1vw));margin-bottom:-0.075em}}.c-sticky_scroll{display:block;position:absolute;top:0;height:100%;width:100%}.c-list{position:relative}.c-list::before{content:\"\";position:absolute;top:0;left:0;width:100%;height:1px;background-color:currentColor;transform-origin:top right;transform:scale3d(0, 1, 1)}html.is-first-loaded .c-list::before{transition:transform .5s cubic-bezier(0.77, 0, 0.175, 1)}html.is-first-loaded .c-list.is-inview::before{transform:scale3d(1, 1, 1)}@media(min-width: 1000px){.c-list{display:grid;grid-template-columns:repeat(4, 1fr);-moz-column-gap:var(--grid-gutter);column-gap:var(--grid-gutter)}}[data-theme=dark] .c-list *:focus-visible:not(input):not(textarea):not(select){outline-color:#fff;outline-style:solid;outline-width:2px;outline-offset:-4px}[data-theme=white] .c-list *:focus-visible:not(input):not(textarea):not(select){outline-color:#202ded;outline-style:solid;outline-width:2px;outline-offset:-4px}[data-theme=blue] .c-list *:focus-visible:not(input):not(textarea):not(select){outline-color:#fff;outline-style:solid;outline-width:2px;outline-offset:-4px}.c-list *:focus-visible:not(input):not(textarea):not(select){outline-color:currentColor;outline-style:solid;outline-width:2px;outline-offset:2px;padding-inline:.5rem}.c-list_inner{font-size:0}@media(min-width: 1000px){.c-list_inner{grid-column:2/-1}}.c-list_item_inner{position:relative;clip-path:inset(0);padding-block:.75rem}.c-list_item_inner::before{content:\"\";position:absolute;top:0;left:0;width:100%;height:1px;background-color:currentColor;transform-origin:top right;transform:scale3d(0, 1, 1)}html.is-first-loaded .c-list_item_inner::before{transition:transform .5s cubic-bezier(0.77, 0, 0.175, 1)}html.is-first-loaded .c-list.is-inview .c-list_item_inner::before{transform:scale3d(1, 1, 1);transition-delay:calc((var(--index) + 1)*.08s)}@media(max-width: 699px){.c-list_item_inner{display:flex;flex-direction:column}.-showcase .c-list_item_inner{display:grid;grid-template-columns:1fr;gap:.9375rem;padding-right:1.875rem}.-perks .c-list_item_inner{padding-block:1.25rem}}@media(min-width: 700px){.c-list_item_inner{display:grid;align-items:center}}@media(min-width: 700px)and (max-width: 999px){.c-list_item_inner{grid-template-columns:1fr 1fr}.c-list.-showcase .c-list_item_inner{grid-template-columns:4fr 2fr 1fr}}@media(min-width: 1000px){.c-list_item_inner{grid-template-columns:1fr 2fr}.c-list.-showcase .c-list_item_inner{grid-template-columns:4fr 2fr 1fr}}.c-list_item_inner .c-list-anchor{text-align:end}@media(max-width: 699px){.c-list_item_inner .c-list-anchor{position:absolute;right:0;bottom:0}.-showcase .c-list_item_inner .c-list-anchor{top:.625rem}}@media(max-width: 699px){.c-list_title.-body-regular{--font-size-body-regular: var(--font-size-body-medium)}}@media(min-width: 1000px){.c-list_title{grid-column:1/2}}@media(max-width: 699px){.c-list_description{margin-top:.5rem}.-showcase .c-list_description{display:none}}@media(min-width: 1000px){.c-list_description{grid-column:2/-1}.c-list.-showcase .c-list_description{grid-column:auto}}.c-list_title,.c-list_description,.c-list-anchor{opacity:0;transform:translate3d(0, 100%, 0)}html.is-first-loaded .c-list_title,html.is-first-loaded .c-list_description,html.is-first-loaded .c-list-anchor{transition:transform .5s cubic-bezier(0.165, 0.84, 0.44, 1),opacity .5s cubic-bezier(0.165, 0.84, 0.44, 1)}html.is-first-loaded .c-list.is-inview .c-list_title,html.is-first-loaded .c-list.is-inview .c-list_description,html.is-first-loaded .c-list.is-inview .c-list-anchor{opacity:1;transform:translate3d(0, 0, 0);transition-delay:calc((var(--index) + 1)*.08s + .25s)}.c-footer_attributes{align-items:flex-start}@media(max-width: 999px){.c-footer_attributes div{white-space:nowrap}}.c-footer_attributes div p{line-height:1.25;opacity:0}@media(max-width: 999px){.c-footer_attributes div:nth-of-type(1){grid-column:3/1}}@media(max-width: 999px){.c-footer_attributes div:nth-of-type(2){grid-column:5/3;margin-top:10rem}}@media(min-width: 1000px){.c-footer_attributes div:nth-of-type(2){margin-top:15rem}}@media(max-width: 999px){.c-footer_attributes div:nth-of-type(3){grid-column:5/2;margin-top:5rem}}@media(min-width: 1000px){.c-footer_attributes div:nth-of-type(3){margin-top:10rem}}@media(max-width: 999px){.c-footer_attributes div:nth-of-type(4){grid-column:3/1;margin-top:5rem}}@media(min-width: 1000px){.c-footer_attributes div:nth-of-type(4){margin-top:25rem}}.c-footer_thanks{grid-column:5/2;margin-top:calc(clamp(calc(0.0625rem * var(--spacing-3xl-mobile)),var(--spacing-3xl-desktop)/14.4*1vw,calc(0.0625rem * var(--spacing-3xl-desktop)))*1.5)}@media(min-width: 1000px){.c-footer_thanks{grid-column:5/3;margin-top:clamp(calc(0.0625rem * var(--spacing-3xl-mobile)),var(--spacing-3xl-desktop)/14.4*1vw,calc(0.0625rem * var(--spacing-3xl-desktop)))}}.c-footer_website{opacity:0;transform:translate3d(0, 100%, 0);transition:transform .75s cubic-bezier(0.165, 0.84, 0.44, 1),opacity .75s cubic-bezier(0.165, 0.84, 0.44, 1)}.c-footer_website.is-inview{opacity:1;transform:translate3d(0, 0, 0)}.c-fadein-text_line{background:var(--background);-webkit-background-clip:text;color:rgba(0,0,0,0)}.fadeInText.-blue{--color-cta-fadein: #898fe9;--color: white}.fadeInText.-white{--color-cta-fadein: #cacdff;--color: #202ded}.fadeInText.-black{--color-cta-fadein: #424242;--color: white}.c-preloader{position:fixed;top:0;left:0;width:100%;height:100%;z-index:1000;cursor:wait;background-color:#202ded;pointer-events:none}html.is-ready .c-preloader{transition:opacity .6s cubic-bezier(0.215, 0.61, 0.355, 1),visibility 0s .6s cubic-bezier(0.215, 0.61, 0.355, 1);opacity:0;visibility:hidden}.u-gc-2\\/3{--gc-start: 2;--gc-end: 3}@media(min-width: 1000px){.u-gc-2\\/5\\@from-medium{--gc-start: 2;--gc-end: 5}}:root{--color-text: #202ded;--color-background: white}[data-theme=white]{color:var(--color-text);background-color:var(--color-background)}[data-theme=blue]{--color-text: white;--color-background: #202ded;color:var(--color-text);background-color:var(--color-background)}[data-theme=black]{--color-text: white;--color-background: black;color:var(--color-text);background-color:var(--color-background)}.u-relative{position:relative}.u-clipped{clip-path:polygon(0% 0, 100% 0%, 100% 100%, 0 100%)}.u-max-w300{max-width:18.75rem}.u-max-w440{max-width:27.5rem}.u-glyph{font-family:\"PP Locomotive New\",-apple-system,BlinkMacSystemFont,avenir next,avenir,segoe ui,helvetica neue,helvetica,Cantarell,Ubuntu,roboto,noto,arial,sans-serif;font-feature-settings:\"dlig\" on,\"ss01\" on,\"salt\" on;font-weight:400}.u-hover-underline{position:relative}@media(hover: hover){.u-hover-underline::before{content:\"\";position:absolute;bottom:-0.1em;left:0;width:100%;height:1px;background-color:currentColor;transform:scale3d(0, 1, 1);transition:transform .25s cubic-bezier(0.165, 0.84, 0.44, 1);transform-origin:top right}.u-hover-underline:hover::before,.u-hover:hover .u-hover-underline::before{transform:scale3d(1, 1, 1);transform-origin:top left}}.u-screen-reader-text{position:absolute !important;overflow:hidden;clip:rect(0 0 0 0);margin:0;padding:0;width:1px;height:1px;border:0}@media not print{.u-screen-reader-text\\@screen{position:absolute !important;overflow:hidden;clip:rect(0 0 0 0);margin:0;padding:0;width:1px;height:1px;border:0}}.u-screen-reader-text.-focusable:focus,.u-screen-reader-text.-focusable:active{clip:auto;width:auto;height:auto}.u-external-icon{font-size:.85em}.u-text-balance{text-wrap:balance}@media(max-width: 999px){.u-hidden-md{display:none}}.u-padding-top-sm{padding-top:clamp(calc(0.0625rem * var(--spacing-sm-mobile)), var(--spacing-sm-desktop) / 14.4 * 1vw, calc(0.0625rem * var(--spacing-sm-desktop))) !important}.u-padding-top-md{padding-top:clamp(calc(0.0625rem * var(--spacing-md-mobile)), var(--spacing-md-desktop) / 14.4 * 1vw, calc(0.0625rem * var(--spacing-md-desktop))) !important}.u-padding-top-lg{padding-top:clamp(calc(0.0625rem * var(--spacing-lg-mobile)), var(--spacing-lg-desktop) / 14.4 * 1vw, calc(0.0625rem * var(--spacing-lg-desktop))) !important}.u-padding-bottom-lg{padding-bottom:clamp(calc(0.0625rem * var(--spacing-lg-mobile)), var(--spacing-lg-desktop) / 14.4 * 1vw, calc(0.0625rem * var(--spacing-lg-desktop))) !important}.u-padding-bottom-2xl{padding-bottom:clamp(calc(0.0625rem * var(--spacing-2xl-mobile)), var(--spacing-2xl-desktop) / 14.4 * 1vw, calc(0.0625rem * var(--spacing-2xl-desktop))) !important}.u-padding-bottom-3xl{padding-bottom:clamp(calc(0.0625rem * var(--spacing-3xl-mobile)), var(--spacing-3xl-desktop) / 14.4 * 1vw, calc(0.0625rem * var(--spacing-3xl-desktop))) !important}.u-margin-top-2xs{margin-top:clamp(calc(0.0625rem * var(--spacing-2xs-mobile)), var(--spacing-2xs-desktop) / 14.4 * 1vw, calc(0.0625rem * var(--spacing-2xs-desktop))) !important}.u-margin-top-sm{margin-top:clamp(calc(0.0625rem * var(--spacing-sm-mobile)), var(--spacing-sm-desktop) / 14.4 * 1vw, calc(0.0625rem * var(--spacing-sm-desktop))) !important}.u-margin-top-xl{margin-top:clamp(calc(0.0625rem * var(--spacing-xl-mobile)), var(--spacing-xl-desktop) / 14.4 * 1vw, calc(0.0625rem * var(--spacing-xl-desktop))) !important}.u-margin-bottom-3xl{margin-bottom:clamp(calc(0.0625rem * var(--spacing-3xl-mobile)), var(--spacing-3xl-desktop) / 14.4 * 1vw, calc(0.0625rem * var(--spacing-3xl-desktop))) !important}"
  },
  {
    "path": "www/landing/assets.json",
    "content": "{\n    \"version\": 1768591940829\n}"
  },
  {
    "path": "www/landing/index.html",
    "content": "<!doctype html>\n<html class=\"is-loading\" lang=\"en\" data-header-theme=\"blue\">\n    <head>\n        <meta charset=\"utf-8\">\n\n\n\n        <title>Locomotive Scroll — Detection of elements in viewport & smooth scrolling with parallax effects</title>\n        <meta name=\"description\" content=\"Locomotive Scroll is a lightweight JavaScript library that provides smooth scrolling animations and advanced scroll interactions for web applications.\">\n        <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n\n        \n        <meta property=\"og:title\" content=\"Locomotive Scroll — Detection of elements in viewport & smooth scrolling with parallax effects\">\n        <meta property=\"og:description\" content=\"Locomotive Scroll is a lightweight JavaScript library that provides smooth scrolling animations and advanced scroll interactions for web applications.\">\n        <meta property=\"og:type\" content=\"website\">\n        <meta property=\"og:url\" content=\"https://scroll.locomotive.ca\">\n        <meta property=\"og:image\" content=\"https://scroll.locomotive.ca/assets/images/og-image.png\">\n        <meta property=\"og:image:width\" content=\"1200\">\n        <meta property=\"og:image:height\" content=\"630\">\n        <meta property=\"og:image:alt\" content=\"Locomotive Scroll — Detection of elements in viewport & smooth scrolling with parallax effects\">\n\n        \n        <meta name=\"twitter:card\" content=\"summary_large_image\">\n        <meta name=\"twitter:title\" content=\"Locomotive Scroll — Detection of elements in viewport & smooth scrolling with parallax effects\">\n        <meta name=\"twitter:description\" content=\"Locomotive Scroll is a lightweight JavaScript library that provides smooth scrolling animations and advanced scroll interactions for web applications.\">\n        <meta name=\"twitter:image\" content=\"https://scroll.locomotive.ca/assets/images/og-image.png\">\n        <meta name=\"twitter:image:alt\" content=\"Locomotive Scroll — Detection of elements in viewport & smooth scrolling with parallax effects\">\n\n        <meta name=\"theme-color\" content=\"#ffffff\">\n        <meta name=\"msapplication-TileColor\" content=\"#ffffff\">\n        <link rel=\"manifest\" href=\"assets/site.webmanifest\">\n        <link rel=\"apple-touch-icon\" sizes=\"180x180\" href=\"assets/images/favicons/apple-touch-icon.png\">\n        <link rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"assets/images/favicons/favicon-32x32.png\">\n        <link rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"assets/images/favicons/favicon-16x16.png\">\n        <link rel=\"mask-icon\" href=\"assets/images/favicons/safari-pinned-tab.svg\" color=\"#000000\">\n        <link id=\"main-css\" rel=\"stylesheet\" href=\"assets/styles/main.css?v=1768510647719\">\n    </head>\n    <body data-module-load>\n        <!-- Preloader -->\n        <div class=\"c-preloader\"></div>\n\n        <div data-load-container>\n                            <div data-module-scroll=\"main\">\n                    <header class=\"c-header\">\n    <div class=\"c-header_col\">\n        <p class=\"c-text -body-regular\">Locomotive Scroll</p>\n        <p class=\"c-text -body-regular || u-hidden-md\">Version 5.0</p>\n    </div>\n    <div class=\"c-header_col  || -center\">\n        <a class=\"c-text -body-regular || u-hover-underline\" href=\"https://github.com/locomotivemtl/locomotive-scroll\" data-load=\"false\"><span data-module-hover-shuffle>Github</span><span class=\"u-external-icon\">↗</span></a>\n    </div>\n    <div class=\"c-header_col\">\n        <a class=\"c-text -body-regular || u-hover-underline\" href=\"https://scroll.locomotive.ca/docs\" data-load=\"false\"><span data-module-hover-shuffle>Documentation</span><span class=\"u-external-icon\">↗</span></a>\n        <p class=\"u-hidden-md\">©2026</p>\n    </div>\n</header>\n                    \n                        <main>\n                            \n    <section class=\"o-container || u-relative\" data-theme=\"blue\">\n\n    <div\n        class=\"c-header-theme-toggler -hero\"\n        data-scroll\n        data-scroll-repeat\n        data-scroll-call=\"changeHeaderTheme\"\n        data-scroll-ignore-fold\n    ></div>\n\n    <div class=\"c-hero\">\n        <div class=\"c-hero_sticky\">\n\n            <div class=\"c-hero_main\">\n                <div class=\"c-hero_heading\">\n                    <h1 class=\"c-hero_title || c-heading -h1\">\n                        <span class=\"c-hero_line\" style=\"--index: 0\">\n                            <span class=\"u-glyph || c-hero_word || -hero\" aria-hidden=\"true\">🟦🔁</span>\n                        </span>\n                        <span class=\"c-hero_line\" style=\"--index: 1\">\n                            <span class=\"c-hero_word || -hero\">Locomotive®</span>\n                        </span>\n                        <span class=\"c-hero_line\" style=\"--index: 2\">\n                            <span class=\"c-hero_word || -hero\">Scroll</span>\n                        </span>\n                    </h1>\n\n                    <div class=\"c-hero_description_container || fadeInText -blue\">\n                        <div role=\"group\" class=\"c-text -body-medium || u-max-w440 || c-hero_description\" data-module-fade-in-text data-scroll data-scroll-offset=\"10%,30%\" data-scroll-event-progress=\"fadeinTextProgress\">\n                            A lightweight scroll library for modern web experiences. Detection, animation, and smooth scrolling — all in 9.4kB. Built on top of Lenis.\n                        </div>\n                        <p class=\"c-hero_version || c-text -body-medium || u-clipped\" data-scroll data-scroll-offset=\"25%\">\n                            <span class=\"u-glyph\" aria-hidden=\"true\">🔻</span>\n                            <span>Version 5.0</span>\n                        </p>\n                    </div>\n                </div>\n                <nav class=\"c-hero_nav\">\n                    <ul class=\"c-hero_links\">\n                        <li class=\"c-hero_links_item\">\n                            \n\n\n\n\n    \n\n\n\n\n\n\n<a\n    class=\"c-button\"\n    href=\"https://github.com/locomotivemtl/locomotive-scroll\"        data-load=\"false\"    >\n                    <span\n                class=\"c-button_wrap\"\n                            >\n                <span class=\"c-button_inner\">\n                                            \n\n\n\n\n    <span class=\"o-icon  c-button_icon\">\n        <svg class=\"svg-github\" focusable=\"false\" aria-hidden=\"true\">\n            <use xlink:href=\"assets/images/sprite.svg?v=1768510647719#github\"></use>\n        </svg>\n    </span>\n                    \n                                            <span class=\"c-button_label\">\n                            View on Github\n                        </span>\n                                    </span>\n            </span>\n                    <span\n                class=\"c-button_wrap\"\n                                    aria-hidden=\"true\"\n                            >\n                <span class=\"c-button_inner\">\n                                            \n\n\n\n\n    <span class=\"o-icon  c-button_icon\">\n        <svg class=\"svg-github\" focusable=\"false\" aria-hidden=\"true\">\n            <use xlink:href=\"assets/images/sprite.svg?v=1768510647719#github\"></use>\n        </svg>\n    </span>\n                    \n                                            <span class=\"c-button_label\">\n                            View on Github\n                        </span>\n                                    </span>\n            </span>\n        </a>\n                        </li>\n                        <li class=\"c-hero_links_item\">\n                            \n\n\n\n\n    \n\n    \n\n\n\n\n<a\n    class=\"c-button -stroke\"\n    href=\"https://scroll.locomotive.ca/docs\"        data-load=\"false\"    >\n                    <span\n                class=\"c-button_wrap\"\n                            >\n                <span class=\"c-button_inner\">\n                                            \n\n\n\n\n    <span class=\"o-icon  c-button_icon\">\n        <svg class=\"svg-doc\" focusable=\"false\" aria-hidden=\"true\">\n            <use xlink:href=\"assets/images/sprite.svg?v=1768510647719#doc\"></use>\n        </svg>\n    </span>\n                    \n                                            <span class=\"c-button_label\">\n                            Read documentation\n                        </span>\n                                    </span>\n            </span>\n                    <span\n                class=\"c-button_wrap\"\n                                    aria-hidden=\"true\"\n                            >\n                <span class=\"c-button_inner\">\n                                            \n\n\n\n\n    <span class=\"o-icon  c-button_icon\">\n        <svg class=\"svg-doc\" focusable=\"false\" aria-hidden=\"true\">\n            <use xlink:href=\"assets/images/sprite.svg?v=1768510647719#doc\"></use>\n        </svg>\n    </span>\n                    \n                                            <span class=\"c-button_label\">\n                            Read documentation\n                        </span>\n                                    </span>\n            </span>\n        </a>\n                        </li>\n                    </ul>\n                </nav>\n            </div>\n        </div>\n    </div>\n</section>\n    <section class=\"u-relative\" data-theme=\"white\">\n\n    <div\n        class=\"c-header-theme-toggler\"\n        data-scroll\n        data-scroll-repeat\n        data-scroll-call=\"changeHeaderTheme\"\n        data-scroll-offset=\"100%,0\"\n        data-scroll-ignore-fold\n    ></div>\n\n    <div\n    class=\"c-rail\"\n    data-module-rail\n    data-values=\"rail\"\n    data-rail-direction=\"-1\"\n    data-scroll\n    data-scroll-call=\"toggleRail\"    \n    data-scroll-repeat\n>\n    <div class=\"c-rail_inner\" data-rail=\"container\" aria-hidden=\"true\">\n        <div data-rail=\"pattern\">\n            <p class=\"c-rail_item\" data-rail-item>\n                Version (5.0)\n                <span class=\"c-rail_glyph\" aria-hidden=\"true\">🏢</span>\n            </p>\n        </div>\n    </div>\n</div>\n\n\n    <div class=\"o-container\">\n        \n\n        \n\n<div class=\"c-list -perks \" data-scroll>\n    <ul class=\"c-list_inner\">\n                    <li class=\"c-list_item | c-text -body-regular\" style=\"--index: 0\">\n                                    <div class=\"c-list_item_inner\">\n                        <p class=\"c-list_title || c-text -body-regular\">Built on top of Lenis</p>\n                        <p class=\"c-list_description || c-text -body-regular\">Latest stable release with improved touch handling and performance fixes. No more greedy CSS transforms!</p>\n                    </div>\n                            </li>\n                    <li class=\"c-list_item | c-text -body-regular\" style=\"--index: 1\">\n                                    <div class=\"c-list_item_inner\">\n                        <p class=\"c-list_title || c-text -body-regular\">TypeScript First</p>\n                        <p class=\"c-list_description || c-text -body-regular\">Fully typed. Better autocomplete, fewer bugs, happier developers.</p>\n                    </div>\n                            </li>\n                    <li class=\"c-list_item | c-text -body-regular\" style=\"--index: 2\">\n                                    <div class=\"c-list_item_inner\">\n                        <p class=\"c-list_title || c-text -body-regular\">Dual Intersection Observers</p>\n                        <p class=\"c-list_description || c-text -body-regular\">Separate observers for simple triggers vs. continuous animations. No wasted RAF cycles.</p>\n                    </div>\n                            </li>\n                    <li class=\"c-list_item | c-text -body-regular\" style=\"--index: 3\">\n                                    <div class=\"c-list_item_inner\">\n                        <p class=\"c-list_title || c-text -body-regular\">Smart Touch Detection</p>\n                        <p class=\"c-list_description || c-text -body-regular\">Parallax auto-disabled on mobile. Opt-in with one attribute.</p>\n                    </div>\n                            </li>\n                    <li class=\"c-list_item | c-text -body-regular\" style=\"--index: 4\">\n                                    <div class=\"c-list_item_inner\">\n                        <p class=\"c-list_title || c-text -body-regular\">Production Ready</p>\n                        <p class=\"c-list_description || c-text -body-regular\">Accessible by default. Native scrollbar, keyboard nav, and proper cleanup for SPAs.</p>\n                    </div>\n                            </li>\n                    <li class=\"c-list_item | c-text -body-regular\" style=\"--index: 5\">\n                                    <div class=\"c-list_item_inner\">\n                        <p class=\"c-list_title || c-text -body-regular\">Lightweight</p>\n                        <p class=\"c-list_description || c-text -body-regular\">Only 9.4kB gzipped</p>\n                    </div>\n                            </li>\n            </ul>\n</div>\n        \n        <div class=\"o-grid -gutters -col-4@from-medium || u-margin-top-xl u-margin-bottom-3xl\">\n            <div class=\"o-grid_item u-gc-2/5@from-medium\">\n                <p class=\"c-heading -h2\">\n                    Version 5 is a complete rewrite. Designed for modern workflows, built on top of Lenis, and optimized for production.\n                </p>\n            </div>\n        </div>\n\n        \n        <div class=\"c-cascade || u-margin-3xl-top\" aria-hidden=\"true\">\n            <div class=\"c-cascade_text || || fadeInText -white\">\n                <span class=\"u-glyph\" aria-hidden=\"true\">⛵</span>\n                <div class=\"c-text -body-medium || u-margin-top-2xs\" role=\"group\" data-module-fade-in-text data-scroll data-scroll-offset=\"0, 25%\" data-scroll-event-progress=\"fadeinTextProgress\">This library has evolved considerably over the years. From jQuery to vanilla ES6, from custom engines to Lenis foundation.</div>\n            </div>\n            <div class=\"c-cascade_container\" data-scroll data-scroll-css-progress data-scroll-offset=\"10%, 60%\">\n                <div class=\"c-cascade_inner\">\n                                            <div class=\"c-cascade_item || c-heading -h2\" style=\"--item-index: 0\">\n                            <span class=\"c-cascade_line\">\n                                <span class=\"c-cascade_word\">Locomotive®</span>\n                            </span>\n                            <span class=\"c-cascade_line\">\n                                <span class=\"c-cascade_word\">Scroll</span>\n                            </span>\n                        </div>\n                                            <div class=\"c-cascade_item || c-heading -h2\" style=\"--item-index: 1\">\n                            <span class=\"c-cascade_line\">\n                                <span class=\"c-cascade_word\">Locomotive®</span>\n                            </span>\n                            <span class=\"c-cascade_line\">\n                                <span class=\"c-cascade_word\">Scroll</span>\n                            </span>\n                        </div>\n                                            <div class=\"c-cascade_item || c-heading -h2\" style=\"--item-index: 2\">\n                            <span class=\"c-cascade_line\">\n                                <span class=\"c-cascade_word\">Locomotive®</span>\n                            </span>\n                            <span class=\"c-cascade_line\">\n                                <span class=\"c-cascade_word\">Scroll</span>\n                            </span>\n                        </div>\n                                            <div class=\"c-cascade_item || c-heading -h2\" style=\"--item-index: 3\">\n                            <span class=\"c-cascade_line\">\n                                <span class=\"c-cascade_word\">Locomotive®</span>\n                            </span>\n                            <span class=\"c-cascade_line\">\n                                <span class=\"c-cascade_word\">Scroll</span>\n                            </span>\n                        </div>\n                                            <div class=\"c-cascade_item || c-heading -h2\" style=\"--item-index: 4\">\n                            <span class=\"c-cascade_line\">\n                                <span class=\"c-cascade_word\">Locomotive®</span>\n                            </span>\n                            <span class=\"c-cascade_line\">\n                                <span class=\"c-cascade_word\">Scroll</span>\n                            </span>\n                        </div>\n                                            <div class=\"c-cascade_item || c-heading -h2\" style=\"--item-index: 5\">\n                            <span class=\"c-cascade_line\">\n                                <span class=\"c-cascade_word\">Locomotive®</span>\n                            </span>\n                            <span class=\"c-cascade_line\">\n                                <span class=\"c-cascade_word\">Scroll</span>\n                            </span>\n                        </div>\n                                            <div class=\"c-cascade_item || c-heading -h2\" style=\"--item-index: 6\">\n                            <span class=\"c-cascade_line\">\n                                <span class=\"c-cascade_word\">Locomotive®</span>\n                            </span>\n                            <span class=\"c-cascade_line\">\n                                <span class=\"c-cascade_word\">Scroll</span>\n                            </span>\n                        </div>\n                                            <div class=\"c-cascade_item || c-heading -h2\" style=\"--item-index: 7\">\n                            <span class=\"c-cascade_line\">\n                                <span class=\"c-cascade_word\">Locomotive®</span>\n                            </span>\n                            <span class=\"c-cascade_line\">\n                                <span class=\"c-cascade_word\">Scroll</span>\n                            </span>\n                        </div>\n                                    </div>\n            </div>\n            <p class=\"c-cascade_glyph || u-glyph\" aria-hidden=\"true\">👀</p>\n        </div>\n    </div>\n\n\n\n</section>\n    <section class=\"u-relative || u-clipped || u-padding-bottom-2xl\" data-theme=\"blue\">\n\n    <div\n        class=\"c-header-theme-toggler\"\n        data-scroll\n        data-scroll-repeat\n        data-scroll-call=\"changeHeaderTheme\"\n        data-scroll-offset=\"100%\"\n    ></div>\n\n    <h2 class=\"c-heading-serif -large || c-section-heading || u-padding-bottom-3xl u-padding-top-md\">\n    <span class=\"c-section-heading_line\">\n        <span class=\"c-section-heading_word\">\n            Built-in\n        </span>\n    </span>\n    <span class=\"c-section-heading_line\">\n        <span class=\"c-section-heading_word\">\n            Tools\n        </span>\n\n                    <span class=\"c-text -body-medium || c-section-heading_label -left\">\n                <span class=\"u-glyph\" aria-hidden=\"true\">🔴</span>Work faster\n            </span>\n        \n                    <span class=\"c-text -body-medium || c-section-heading_label -right\">\n                Work smarter<span class=\"u-glyph\" aria-hidden=\"true\">🔴</span>\n            </span>\n        \n    </span>\n</h2>\n\n    <div class=\"c-tool -inview\" data-scroll data-scroll-offset=\"5%\">\n        <div class=\"o-container\">\n            <div class=\"c-tool_head\">\n                <span class=\"c-tool_index\">01</span>\n                <span class=\"c-tool_label\">In-view detection</span>\n                <span class=\"c-tool_description\">Add classes, trigger callbacks, or fire custom events when elements enter the viewport. Built on Intersection Observer for native performance.</span>\n                <h3 class=\"c-tool_title || c-heading -h2\">\n                    In-view detection\n                </h3>\n            </div>\n        </div>\n\n        <div class=\"c-tool_playground\" style=\"--container-ratio: 7/5\">\n            <div class=\"c-tool_shape -first\" data-scroll data-scroll-offset=\"10%\" data-scroll-repeat>\n                <div class=\"c-tool_shape_inner\" data-scroll data-scroll-speed=\"0.01\" data-scroll-css-progress>\n                    \n\n\n\n\n    <span class=\"o-icon c-tool_shape_svg \">\n        <svg class=\"svg-inview-01\" focusable=\"false\" aria-hidden=\"true\">\n            <use xlink:href=\"assets/images/sprite.svg?v=1768510647719#inview-01\"></use>\n        </svg>\n    </span>\n                </div>\n            </div>\n            <div class=\"c-tool_shape -second\" data-scroll data-scroll-offset=\"30%\" data-scroll-repeat>\n                <div class=\"c-tool_shape_inner\" data-scroll data-scroll-speed=\"0.1\">\n                    \n\n\n\n\n    <span class=\"o-icon c-tool_shape_svg \">\n        <svg class=\"svg-inview-02\" focusable=\"false\" aria-hidden=\"true\">\n            <use xlink:href=\"assets/images/sprite.svg?v=1768510647719#inview-02\"></use>\n        </svg>\n    </span>\n                </div>\n            </div>\n            <div class=\"c-tool_shape -third\" data-scroll data-scroll-offset=\"25%\" data-scroll-repeat>\n                <div class=\"c-tool_shape_inner\" data-scroll data-scroll-speed=\"0.02\">\n                    \n\n\n\n\n    <span class=\"o-icon c-tool_shape_svg \">\n        <svg class=\"svg-inview-03\" focusable=\"false\" aria-hidden=\"true\">\n            <use xlink:href=\"assets/images/sprite.svg?v=1768510647719#inview-03\"></use>\n        </svg>\n    </span>\n                </div>\n            </div>\n            <div class=\"c-tool_shape -fourth\" data-scroll data-scroll-offset=\"45%\" data-scroll-repeat>\n                <div class=\"c-tool_shape_inner\" data-scroll data-scroll-speed=\"0.05\">\n                    \n\n\n\n\n    <span class=\"o-icon c-tool_shape_svg \">\n        <svg class=\"svg-inview-04\" focusable=\"false\" aria-hidden=\"true\">\n            <use xlink:href=\"assets/images/sprite.svg?v=1768510647719#inview-04\"></use>\n        </svg>\n    </span>\n                </div>\n            </div>\n            <div class=\"c-tool_shape -fifth\" data-scroll data-scroll-offset=\"20%\" data-scroll-repeat>\n                <div class=\"c-tool_shape_inner\" data-scroll data-scroll-speed=\"0.15\" data-scroll-css-progress>\n                    \n\n\n\n\n    <span class=\"o-icon c-tool_shape_svg \">\n        <svg class=\"svg-inview-05\" focusable=\"false\" aria-hidden=\"true\">\n            <use xlink:href=\"assets/images/sprite.svg?v=1768510647719#inview-05\"></use>\n        </svg>\n    </span>\n                </div>\n            </div>\n            <div class=\"c-tool_shape -sixth\" data-scroll data-scroll-offset=\"60%\" data-scroll-repeat>\n                <div class=\"c-tool_shape_inner\" data-scroll data-scroll-speed=\"0.05\">\n                    \n\n\n\n\n    <span class=\"o-icon c-tool_shape_svg \">\n        <svg class=\"svg-inview-06\" focusable=\"false\" aria-hidden=\"true\">\n            <use xlink:href=\"assets/images/sprite.svg?v=1768510647719#inview-06\"></use>\n        </svg>\n    </span>\n                </div>\n            </div>\n        </div>\n    </div>\n\n    <div class=\"c-tool -progress\" data-scroll data-scroll-offset=\"5%\">\n        <div class=\"o-container\">\n            <div class=\"c-tool_head\">\n                <span class=\"c-tool_index\">02</span>\n                <span class=\"c-tool_label\">Progress tracking</span>\n                <span class=\"c-tool_description\">Get real-time scroll progress (0-1) as CSS variables or JavaScript events. Perfect for progress bars, scroll-driven animations, or custom interactions.</span>\n                <h3 class=\"c-tool_title || c-heading -h2\">\n                    Progress tracking\n                </h3>\n            </div>\n        </div>\n\n        <div class=\"c-tool_playground\" style=\"--container-ratio: 12/5\">\n            <div class=\"c-tool_shape -first\" style=\"--index: -2\" data-scroll data-scroll-css-progress>\n                <div class=\"c-tool_shape_inner\">\n                    \n\n\n\n\n    <span class=\"o-icon c-tool_shape_svg \">\n        <svg class=\"svg-progress-01\" focusable=\"false\" aria-hidden=\"true\">\n            <use xlink:href=\"assets/images/sprite.svg?v=1768510647719#progress-01\"></use>\n        </svg>\n    </span>\n                </div>\n            </div>\n            <div class=\"c-tool_shape -second\" style=\"--index: -1\" data-scroll data-scroll-css-progress>\n                <div class=\"c-tool_shape_inner\">\n                    \n\n\n\n\n    <span class=\"o-icon c-tool_shape_svg \">\n        <svg class=\"svg-progress-02\" focusable=\"false\" aria-hidden=\"true\">\n            <use xlink:href=\"assets/images/sprite.svg?v=1768510647719#progress-02\"></use>\n        </svg>\n    </span>\n                </div>\n            </div>\n            <div class=\"c-tool_shape -third\" style=\"--index: 0\" data-scroll data-scroll-css-progress>\n                <div class=\"c-tool_shape_inner\">\n                    \n\n\n\n\n    <span class=\"o-icon c-tool_shape_svg \">\n        <svg class=\"svg-progress-03\" focusable=\"false\" aria-hidden=\"true\">\n            <use xlink:href=\"assets/images/sprite.svg?v=1768510647719#progress-03\"></use>\n        </svg>\n    </span>\n                </div>\n            </div>\n            <div class=\"c-tool_shape -fourth\" style=\"--index: 1\" data-scroll data-scroll-css-progress>\n                <div class=\"c-tool_shape_inner\">\n                    \n\n\n\n\n    <span class=\"o-icon c-tool_shape_svg \">\n        <svg class=\"svg-progress-04\" focusable=\"false\" aria-hidden=\"true\">\n            <use xlink:href=\"assets/images/sprite.svg?v=1768510647719#progress-04\"></use>\n        </svg>\n    </span>\n                </div>\n            </div>\n            <div class=\"c-tool_shape -fifth\" style=\"--index: 2\" data-scroll data-scroll-css-progress>\n                <div class=\"c-tool_shape_inner\">\n                    \n\n\n\n\n    <span class=\"o-icon c-tool_shape_svg \">\n        <svg class=\"svg-progress-05\" focusable=\"false\" aria-hidden=\"true\">\n            <use xlink:href=\"assets/images/sprite.svg?v=1768510647719#progress-05\"></use>\n        </svg>\n    </span>\n                </div>\n            </div>\n        </div>\n    </div>\n\n    <div class=\"c-tool -parallax\" data-scroll data-scroll-offset=\"5%\">\n        <div class=\"o-container\">\n            <div class=\"c-tool_head\">\n                <span class=\"c-tool_index\">02</span>\n                <span class=\"c-tool_label\">Parallax effects</span>\n                <span class=\"c-tool_description\">Create smooth parallax effects instantly with a single data-scroll-speed attribute. No complex setup, no math, just add a number and it works.</span>\n                <h3 class=\"c-tool_title || c-heading -h2\">\n                    Parallax effects\n                </h3>\n            </div>\n        </div>\n\n        <div class=\"c-tool_playground\" style=\"--container-ratio: 10/5\">\n            <div class=\"c-tool_shape -first\">\n                <div class=\"c-tool_shape_inner\" data-scroll data-scroll-speed=\"0.04\" data-scroll-enable-touch-speed>\n                    \n\n\n\n\n    <span class=\"o-icon c-tool_shape_svg \">\n        <svg class=\"svg-parallax-01\" focusable=\"false\" aria-hidden=\"true\">\n            <use xlink:href=\"assets/images/sprite.svg?v=1768510647719#parallax-01\"></use>\n        </svg>\n    </span>\n                </div>\n            </div>\n            <div class=\"c-tool_shape -second\">\n                <div class=\"c-tool_shape_inner\" data-scroll data-scroll-speed=\"0.2\" data-scroll-enable-touch-speed>\n                    \n\n\n\n\n    <span class=\"o-icon c-tool_shape_svg \">\n        <svg class=\"svg-parallax-02\" focusable=\"false\" aria-hidden=\"true\">\n            <use xlink:href=\"assets/images/sprite.svg?v=1768510647719#parallax-02\"></use>\n        </svg>\n    </span>\n                </div>\n            </div>\n            <div class=\"c-tool_shape -third\">\n                <div class=\"c-tool_shape_inner\" data-scroll data-scroll-speed=\"0.3\" data-scroll-enable-touch-speed>\n                    \n\n\n\n\n    <span class=\"o-icon c-tool_shape_svg \">\n        <svg class=\"svg-parallax-03\" focusable=\"false\" aria-hidden=\"true\">\n            <use xlink:href=\"assets/images/sprite.svg?v=1768510647719#parallax-03\"></use>\n        </svg>\n    </span>\n                </div>\n            </div>\n            <div class=\"c-tool_shape -fourth\">\n                <div class=\"c-tool_shape_inner\" data-scroll data-scroll-speed=\"0.15\" data-scroll-enable-touch-speed>\n                    \n\n\n\n\n    <span class=\"o-icon c-tool_shape_svg \">\n        <svg class=\"svg-parallax-04\" focusable=\"false\" aria-hidden=\"true\">\n            <use xlink:href=\"assets/images/sprite.svg?v=1768510647719#parallax-04\"></use>\n        </svg>\n    </span>\n                </div>\n            </div>\n            <div class=\"c-tool_shape -fifth\">\n                <div class=\"c-tool_shape_inner\" data-scroll data-scroll-speed=\"0.25\" data-scroll-enable-touch-speed>\n                    \n\n\n\n\n    <span class=\"o-icon c-tool_shape_svg \">\n        <svg class=\"svg-parallax-05\" focusable=\"false\" aria-hidden=\"true\">\n            <use xlink:href=\"assets/images/sprite.svg?v=1768510647719#parallax-05\"></use>\n        </svg>\n    </span>\n                </div>\n            </div>\n        </div>\n        </div>\n    </div>\n</section>\n    <section class=\"u-relative || o-container\" data-theme=\"black\" id=\"features\">\n\n    <div\n        class=\"c-header-theme-toggler\"\n        data-scroll\n        data-scroll-repeat\n        data-scroll-call=\"changeHeaderTheme\"\n        data-scroll-offset=\"100%\"\n    ></div>\n\n    <h2 class=\"c-heading-serif -large || c-section-heading || u-padding-bottom-3xl u-padding-top-md\">\n    <span class=\"c-section-heading_line\">\n        <span class=\"c-section-heading_word\">\n            Features\n        </span>\n    </span>\n    <span class=\"c-section-heading_line\">\n        <span class=\"c-section-heading_word\">\n            \n        </span>\n\n        \n        \n    </span>\n</h2>\n\n    <div class=\"o-grid -col-2 -gutters\">\n        <div class=\"o-grid_item u-gc-2/3\">\n            <div class=\"u-max-w300 || c-text -body-medium || fadeInText -black\">\n                <span class=\"u-glyph\" aria-hidden=\"true\">⛵</span>\n                <div role=\"group\" class=\"u-margin-top-sm\" data-module-fade-in-text data-scroll data-scroll-offset=\"0, 25%\" data-scroll-event-progress=\"fadeinTextProgress\">Locomotive Scroll is a thin, opinionated wrapper around Lenis. You get all of Lenis's power plus our detection and animation layer.</div>\n            </div>\n        </div>\n    </div>\n\n    <div class=\"c-features-grid\">\n        <div class=\"c-features-grid_container\">\n            <div class=\"c-features-grid_inner\">\n\n                <div class=\"c-features-grid_cell -lenis -link\">\n                    <div class=\"c-features-grid_cell_ratio\">\n                        <a href=\"https://lenis.darkroom.engineering/\" class=\"c-features-grid_link\" target=\"_blank\">\n                            <span class=\"u-screen-reader-text\">Visit Lenis website</span>\n                            <span class=\"c-features-grid_icon-container\">\n                                \n\n\n\n\n    <span class=\"o-icon  c-features-grid_icon\">\n        <svg class=\"svg-arrow-external\" focusable=\"false\" aria-hidden=\"true\">\n            <use xlink:href=\"assets/images/sprite.svg?v=1768510647719#arrow-external\"></use>\n        </svg>\n    </span>\n                                \n\n\n\n\n    <span class=\"o-icon  c-features-grid_icon\">\n        <svg class=\"svg-arrow-external\" focusable=\"false\" aria-hidden=\"true\">\n            <use xlink:href=\"assets/images/sprite.svg?v=1768510647719#arrow-external\"></use>\n        </svg>\n    </span>\n                            </span>\n                        </a>\n                        <div class=\"c-features-grid_cell_inner -logo\">\n                            <span class=\"c-features-grid_title || c-text -body-regular\" aria-hidden=\"true\">\n                                <span class=\"c-features-grid_title_label\">Lenis</span>\n                                <span class=\"c-features-grid_title_label\">Lenis</span>\n                            </span>\n                            \n\n\n\n\n    <span class=\"o-icon  c-features-grid_logo\">\n        <svg class=\"svg-logo-lenis\" focusable=\"false\" aria-hidden=\"true\">\n            <use xlink:href=\"assets/images/sprite.svg?v=1768510647719#logo-lenis\"></use>\n        </svg>\n    </span>\n                        </div>\n                    </div>\n                </div>\n\n                <div class=\"c-features-grid_cell -locomotive -link\">\n                    <div class=\"c-features-grid_cell_ratio\">\n                        <a href=\"https://locomotive.ca/\" class=\"c-features-grid_link\" target=\"_blank\">\n                            <span class=\"u-screen-reader-text\">Visit Locomotive website</span>\n                            <span class=\"c-features-grid_icon-container\">\n                                \n\n\n\n\n    <span class=\"o-icon  c-features-grid_icon\">\n        <svg class=\"svg-arrow-external\" focusable=\"false\" aria-hidden=\"true\">\n            <use xlink:href=\"assets/images/sprite.svg?v=1768510647719#arrow-external\"></use>\n        </svg>\n    </span>\n                                \n\n\n\n\n    <span class=\"o-icon  c-features-grid_icon\">\n        <svg class=\"svg-arrow-external\" focusable=\"false\" aria-hidden=\"true\">\n            <use xlink:href=\"assets/images/sprite.svg?v=1768510647719#arrow-external\"></use>\n        </svg>\n    </span>\n                            </span>\n                        </a>\n                        <div class=\"c-features-grid_cell_inner -logo\">\n                            <span class=\"c-features-grid_title || c-text -body-regular\" aria-hidden=\"true\">\n                                <span class=\"c-features-grid_title_label\">Locomotive</span>\n                                <span class=\"c-features-grid_title_label\">Locomotive</span>\n                            </span>\n                            \n\n\n\n\n    <span class=\"o-icon  c-features-grid_logo\">\n        <svg class=\"svg-logo-locomotive\" focusable=\"false\" aria-hidden=\"true\">\n            <use xlink:href=\"assets/images/sprite.svg?v=1768510647719#logo-locomotive\"></use>\n        </svg>\n    </span>\n                        </div>\n                    </div>\n                </div>\n\n                <div class=\"c-features-grid_cell -scrollbar\">\n                    <div class=\"c-features-grid_cell_ratio\">\n                        <div class=\"c-features-grid_cell_inner\">\n                            <span class=\"c-features-grid_index || c-text -label-small\">01</span>\n                            <h3 class=\"c-features-grid_title || c-heading -h3\">Native scrollbar</h3>\n                            <p class=\"c-features-grid_desc || c-text -body-regular\">Real browser scrollbar. No fake alternatives. Accessible, performant, and familiar to users.</p>\n                        </div>\n                    </div>\n                </div>\n\n                <div class=\"c-features-grid_cell -normalized\">\n                    <div class=\"c-features-grid_cell_ratio\">\n                        <div class=\"c-features-grid_cell_inner\">\n                            <span class=\"c-features-grid_index || c-text -label-small\">02</span>\n                            <h3 class=\"c-features-grid_title || c-heading -h3\">Smooth easing</h3>\n                            <p class=\"c-features-grid_desc || c-text -body-regular\">Configurable lerp, duration, and custom easing functions thanks to Lenis options.</p>\n                        </div>\n                    </div>\n                </div>\n\n                <div class=\"c-features-grid_cell -sticky\">\n                    <div class=\"c-features-grid_cell_ratio\">\n                        <div class=\"c-features-grid_cell_inner\">\n                            <span class=\"c-features-grid_index || c-text -label-small\">03</span>\n                            <h3 class=\"c-features-grid_title || c-heading -h3\">CSS sticky</h3>\n                            <p class=\"c-features-grid_desc || c-text -body-regular\">Works perfectly with position: sticky. No conflicts, no workarounds.</p>\n                        </div>\n                    </div>\n                </div>\n\n                <div class=\"c-features-grid_cell -io\" data-scroll data-scroll-offset=\"60%\" data-scroll-repeat>\n                    <div class=\"c-features-grid_cell_ratio\">\n                        <div class=\"c-features-grid_cell_inner\">\n                            <span class=\"c-features-grid_index || c-text -label-small\">04</span>\n                            <h3 class=\"c-features-grid_title || c-heading -h3\">Intersection Observer API</h3>\n                            <p class=\"c-features-grid_desc || c-text -body-regular\">Browser-native detection. No polling, no performance hits, just efficient viewport tracking.</p>\n                        </div>\n                    </div>\n                </div>\n\n                <div data-scroll class=\"c-features-grid_cell -scroll-to\">\n                    <span class=\"c-features-grid_cell_ratio\">\n                        <span class=\"c-features-grid_cell_inner\">\n                            <span class=\"c-features-grid_index || c-text -label-small\">05</span>\n                            <span class=\"c-features-grid_title || c-heading -h3\">Scroll to</span>\n                            <span class=\"c-features-grid_desc || c-text -body-regular\">Programmatic scrolling to any element, selector, or pixel value via Lenis. Supports offset, duration, and custom easing.</span>\n                        </span>\n                    </span>\n                </div>\n\n                <div class=\"c-features-grid_cell -direction\">\n                    <div class=\"c-features-grid_cell_ratio\">\n                        <div class=\"c-features-grid_cell_inner\">\n                            <span class=\"c-features-grid_index || c-text -label-small\">06</span>\n                            <div class=\"c-features_direction_title\">\n                                <h3 class=\"c-features-grid_title || c-heading -h3\">Scroll direction</h3>\n                                <div class=\"c-heading -h3 || c-features_direction_arrows\">\n                                    <span>↓</span>\n                                    <span>↑</span>\n                                </div>\n                            </div>\n                            <p class=\"c-features-grid_desc || c-text -body-regular\">Track direction changes in real-time thanks to Lenis. Perfect for hiding/showing headers or reversing animations.</p>\n                        </div>\n                    </div>\n                </div>\n\n                <div class=\"c-features-grid_cell -custom-easing\">\n                    <div class=\"c-features-grid_cell_ratio\">\n                        <div class=\"c-features-grid_cell_inner\">\n                            <span class=\"c-features-grid_index || c-text -label-small\">07</span>\n                            <h3 class=\"c-features-grid_title || c-heading -h3\">No layout shifts</h3>\n                            <p class=\"c-features-grid_desc || c-text -body-regular\">No more greedy CSS transforms breaking your layouts. Plays nice with position: sticky, fixed headers, and existing CSS.</p>\n                        </div>\n                    </div>\n                </div>\n\n            </div>\n        </div>\n    </div>\n</section>\n    <section class=\"u-relative || u-padding-bottom-2xl\" data-theme=\"white\" id=\"showcase\">\n\n    <div\n        class=\"c-header-theme-toggler\"\n        data-scroll\n        data-scroll-repeat\n        data-scroll-call=\"changeHeaderTheme\"\n        data-scroll-offset=\"100%\"\n    ></div>\n\n    <div class=\"c-sticky-heading\" data-scroll data-scroll-offset=\"100%, 100%\" data-scroll-css-progress>\n        <div class=\"c-sticky-heading_inner || o-container\">\n            <div class=\"c-sticky-heading_text\">\n                <div class=\"c-sticky-heading_description || fadeInText -white\">\n                    <div class=\"c-text -body-medium\">\n                        <span class=\"u-glyph\" aria-hidden=\"true\">⛵</span>\n                        <div class=\"u-margin-top-2xs\" role=\"group\" data-module-fade-in-text data-scroll data-scroll-offset=\"0, 25%\"  data-scroll-event-progress=\"fadeinTextProgress\">\n                            Real projects built with Locomotive Scroll by leading studios and developers.\n                        </div>\n                    </div>\n                </div>\n                <h2 class=\"c-sticky-heading_title\">\n                    Showcase\n                </h2>\n            </div>\n        </div>\n    </div>\n\n    <div class=\"o-container || u-margin-top-sm\">\n        \n\n<div class=\"c-list -showcase \" data-scroll>\n    <ul class=\"c-list_inner\">\n                    <li class=\"c-list_item | c-text -body-regular\" style=\"--index: 0\">\n                                    <a class=\"c-list_item_inner u-hover-underline\" href=https://locomotive.ca target=\"_blank\" data-module-hover-shuffle data-hover-shuffle=\"children\">\n                        <span class=\"c-list_title || c-text -body-regular\" data-hover-shuffle-child>Locomotive</span>\n                        <span class=\"c-list_description || c-text -body-regular\" data-hover-shuffle-child>https://locomotive.ca</span>\n                        <span class=\"c-list-anchor\">↗</span>\n                    </a>\n                            </li>\n                    <li class=\"c-list_item | c-text -body-regular\" style=\"--index: 1\">\n                                    <a class=\"c-list_item_inner u-hover-underline\" href=https://2024.destigmatize.ca/ target=\"_blank\" data-module-hover-shuffle data-hover-shuffle=\"children\">\n                        <span class=\"c-list_title || c-text -body-regular\" data-hover-shuffle-child>Destigmatize</span>\n                        <span class=\"c-list_description || c-text -body-regular\" data-hover-shuffle-child>https://2024.destigmatize.ca/</span>\n                        <span class=\"c-list-anchor\">↗</span>\n                    </a>\n                            </li>\n                    <li class=\"c-list_item | c-text -body-regular\" style=\"--index: 2\">\n                                    <a class=\"c-list_item_inner u-hover-underline\" href=https://scoutmotors.com/ target=\"_blank\" data-module-hover-shuffle data-hover-shuffle=\"children\">\n                        <span class=\"c-list_title || c-text -body-regular\" data-hover-shuffle-child>Scout Motors</span>\n                        <span class=\"c-list_description || c-text -body-regular\" data-hover-shuffle-child>https://scoutmotors.com/</span>\n                        <span class=\"c-list-anchor\">↗</span>\n                    </a>\n                            </li>\n                    <li class=\"c-list_item | c-text -body-regular\" style=\"--index: 3\">\n                                    <a class=\"c-list_item_inner u-hover-underline\" href=https://lightshiprv.com/ target=\"_blank\" data-module-hover-shuffle data-hover-shuffle=\"children\">\n                        <span class=\"c-list_title || c-text -body-regular\" data-hover-shuffle-child>Lightship</span>\n                        <span class=\"c-list_description || c-text -body-regular\" data-hover-shuffle-child>https://lightshiprv.com/</span>\n                        <span class=\"c-list-anchor\">↗</span>\n                    </a>\n                            </li>\n                    <li class=\"c-list_item | c-text -body-regular\" style=\"--index: 4\">\n                                    <a class=\"c-list_item_inner u-hover-underline\" href=https://vooban.com/ target=\"_blank\" data-module-hover-shuffle data-hover-shuffle=\"children\">\n                        <span class=\"c-list_title || c-text -body-regular\" data-hover-shuffle-child>Vooban</span>\n                        <span class=\"c-list_description || c-text -body-regular\" data-hover-shuffle-child>https://vooban.com/</span>\n                        <span class=\"c-list-anchor\">↗</span>\n                    </a>\n                            </li>\n                    <li class=\"c-list_item | c-text -body-regular\" style=\"--index: 5\">\n                                    <a class=\"c-list_item_inner u-hover-underline\" href=https://constructiondesourdy.com/ target=\"_blank\" data-module-hover-shuffle data-hover-shuffle=\"children\">\n                        <span class=\"c-list_title || c-text -body-regular\" data-hover-shuffle-child>Construction Desourdy</span>\n                        <span class=\"c-list_description || c-text -body-regular\" data-hover-shuffle-child>https://constructiondesourdy.com/</span>\n                        <span class=\"c-list-anchor\">↗</span>\n                    </a>\n                            </li>\n                    <li class=\"c-list_item | c-text -body-regular\" style=\"--index: 6\">\n                                    <a class=\"c-list_item_inner u-hover-underline\" href=https://gkc.ca/ target=\"_blank\" data-module-hover-shuffle data-hover-shuffle=\"children\">\n                        <span class=\"c-list_title || c-text -body-regular\" data-hover-shuffle-child>GKC</span>\n                        <span class=\"c-list_description || c-text -body-regular\" data-hover-shuffle-child>https://gkc.ca/</span>\n                        <span class=\"c-list-anchor\">↗</span>\n                    </a>\n                            </li>\n                    <li class=\"c-list_item | c-text -body-regular\" style=\"--index: 7\">\n                                    <a class=\"c-list_item_inner u-hover-underline\" href=https://www.troa.fr/ target=\"_blank\" data-module-hover-shuffle data-hover-shuffle=\"children\">\n                        <span class=\"c-list_title || c-text -body-regular\" data-hover-shuffle-child>Troa</span>\n                        <span class=\"c-list_description || c-text -body-regular\" data-hover-shuffle-child>https://www.troa.fr/</span>\n                        <span class=\"c-list-anchor\">↗</span>\n                    </a>\n                            </li>\n                    <li class=\"c-list_item | c-text -body-regular\" style=\"--index: 8\">\n                                    <a class=\"c-list_item_inner u-hover-underline\" href=https://vazzi.fun/ target=\"_blank\" data-module-hover-shuffle data-hover-shuffle=\"children\">\n                        <span class=\"c-list_title || c-text -body-regular\" data-hover-shuffle-child>Vazzi</span>\n                        <span class=\"c-list_description || c-text -body-regular\" data-hover-shuffle-child>https://vazzi.fun/</span>\n                        <span class=\"c-list-anchor\">↗</span>\n                    </a>\n                            </li>\n                    <li class=\"c-list_item | c-text -body-regular\" style=\"--index: 9\">\n                                    <a class=\"c-list_item_inner u-hover-underline\" href=https://21tsi.com/ target=\"_blank\" data-module-hover-shuffle data-hover-shuffle=\"children\">\n                        <span class=\"c-list_title || c-text -body-regular\" data-hover-shuffle-child>21TSI</span>\n                        <span class=\"c-list_description || c-text -body-regular\" data-hover-shuffle-child>https://21tsi.com/</span>\n                        <span class=\"c-list-anchor\">↗</span>\n                    </a>\n                            </li>\n                    <li class=\"c-list_item | c-text -body-regular\" style=\"--index: 10\">\n                                    <a class=\"c-list_item_inner u-hover-underline\" href=https://www.eduardbodak.com/ target=\"_blank\" data-module-hover-shuffle data-hover-shuffle=\"children\">\n                        <span class=\"c-list_title || c-text -body-regular\" data-hover-shuffle-child>Eduard Bodak</span>\n                        <span class=\"c-list_description || c-text -body-regular\" data-hover-shuffle-child>https://www.eduardbodak.com/</span>\n                        <span class=\"c-list-anchor\">↗</span>\n                    </a>\n                            </li>\n                    <li class=\"c-list_item | c-text -body-regular\" style=\"--index: 11\">\n                                    <a class=\"c-list_item_inner u-hover-underline\" href=https://mindmarket.com/ target=\"_blank\" data-module-hover-shuffle data-hover-shuffle=\"children\">\n                        <span class=\"c-list_title || c-text -body-regular\" data-hover-shuffle-child>Mindmarket</span>\n                        <span class=\"c-list_description || c-text -body-regular\" data-hover-shuffle-child>https://mindmarket.com/</span>\n                        <span class=\"c-list-anchor\">↗</span>\n                    </a>\n                            </li>\n            </ul>\n</div>    </div>\n</section>\n\n\n                                                            <footer class=\"u-relative || c-footer || o-container || u-padding-top-sm\" data-theme=\"blue\">\n\n    <div\n        class=\"c-header-theme-toggler\"\n        data-scroll\n        data-scroll-repeat\n        data-scroll-call=\"changeHeaderTheme\"\n        data-scroll-offset=\"100%\"\n    ></div>\n\n    <div aria-hidden data-module-randomize class=\"c-footer_attributes || o-grid -cols\">\n        <div data-scroll data-scroll-position=\"end\" data-scroll-call=\"randomize\">\n            <p>npm</p>\n            <p>npm install</p>\n            <p>npm install locomotive-scroll</p>\n            <p>npm install</p>\n            <p>npm</p>\n        </div>\n        <div data-scroll data-scroll-position=\"end\" data-scroll-call=\"randomize\">\n            <p>locomotive</p>\n            <p>locomotive-scroll</p>\n            <p>locomotive-scroll v5.x</p>\n            <p>locomotive-scroll v5.x</p>\n            <p>locomotive-scroll</p>\n            <p>locomotive</p>\n        </div>\n        <div data-scroll data-scroll-position=\"end\" data-scroll-call=\"randomize\">\n            <p>data</p>\n            <p>data-scroll</p>\n            <p>data-scroll-speed</p>\n            <p>data-scroll-class</p>\n            <p>data-scroll-repeat</p>\n        </div>\n        <div data-scroll data-scroll-position=\"end\" data-scroll-call=\"randomize\">\n            <p>data</p>\n            <p>data-scroll</p>\n            <p>data-scroll-position</p>\n            <p>data-scroll-call</p>\n            <p>data-scroll-event-progress</p>\n        </div>\n    </div>\n\n    <div class=\"o-grid -cols u-padding-top-lg\">\n        <h2\n            data-module-mask-lines\n            data-scroll\n            data-scroll-event-progress=\"progressEvent\"\n            data-scroll-position=\"start, end\"\n            data-scroll-offset=\"100px, 75%\"\n            class=\"c-footer_thanks || c-hero_title || c-heading -h1\">\n            We hope that you enjoy our library.\n        </h2>\n    </div>\n\n\n    <div class=\"c-hero_main || -footer || u-padding-bottom-lg\">\n        <div class=\"c-hero_heading\">\n            <p class=\"c-hero_title || c-heading -h1\" data-scroll data-scroll-position=\"end\" data-scroll-repeat>\n                <span class=\"c-hero_line\" style=\"--index: 0\">\n                    <span class=\"u-glyph || c-hero_word || -footer\" aria-hidden=\"true\">🟦🔁</span>\n                </span>\n                <span class=\"c-hero_line\" style=\"--index: 1\">\n                    <span class=\"c-hero_word || -footer\">Locomotive®</span>\n                </span>\n                <span class=\"c-hero_line\" style=\"--index: 2\">\n                    <span class=\"c-hero_word || -footer\">Scroll</span>\n                </span>\n            </p>\n\n            <p class=\"c-text -body-regular || c-footer_website\" data-scroll data-scroll-position=\"end\" data-scroll-repeat>\n                Made by <a class=\"u-hover-underline\" href=\"https://locomotive.ca\" target=\"_blank\" data-module-hover-shuffle>Locomotive</a>\n            </p>\n        </div>\n        <nav class=\"c-hero_nav\">\n            <ul class=\"c-hero_links\">\n                <li class=\"c-hero_links_item\">\n                    \n\n\n\n\n    \n\n\n\n\n\n\n<a\n    class=\"c-button\"\n    href=\"https://github.com/locomotivemtl/locomotive-scroll\"        data-load=\"false\"    >\n                    <span\n                class=\"c-button_wrap\"\n                            >\n                <span class=\"c-button_inner\">\n                                            \n\n\n\n\n    <span class=\"o-icon  c-button_icon\">\n        <svg class=\"svg-github\" focusable=\"false\" aria-hidden=\"true\">\n            <use xlink:href=\"assets/images/sprite.svg?v=1768510647719#github\"></use>\n        </svg>\n    </span>\n                    \n                                            <span class=\"c-button_label\">\n                            View on Github\n                        </span>\n                                    </span>\n            </span>\n                    <span\n                class=\"c-button_wrap\"\n                                    aria-hidden=\"true\"\n                            >\n                <span class=\"c-button_inner\">\n                                            \n\n\n\n\n    <span class=\"o-icon  c-button_icon\">\n        <svg class=\"svg-github\" focusable=\"false\" aria-hidden=\"true\">\n            <use xlink:href=\"assets/images/sprite.svg?v=1768510647719#github\"></use>\n        </svg>\n    </span>\n                    \n                                            <span class=\"c-button_label\">\n                            View on Github\n                        </span>\n                                    </span>\n            </span>\n        </a>\n                </li>\n                <li class=\"c-hero_links_item\">\n                    \n\n\n\n\n    \n\n    \n\n\n\n\n<a\n    class=\"c-button -stroke\"\n    href=\"https://scroll.locomotive.ca/docs\"        data-load=\"false\"    >\n                    <span\n                class=\"c-button_wrap\"\n                            >\n                <span class=\"c-button_inner\">\n                                            \n\n\n\n\n    <span class=\"o-icon  c-button_icon\">\n        <svg class=\"svg-doc\" focusable=\"false\" aria-hidden=\"true\">\n            <use xlink:href=\"assets/images/sprite.svg?v=1768510647719#doc\"></use>\n        </svg>\n    </span>\n                    \n                                            <span class=\"c-button_label\">\n                            Read documentation\n                        </span>\n                                    </span>\n            </span>\n                    <span\n                class=\"c-button_wrap\"\n                                    aria-hidden=\"true\"\n                            >\n                <span class=\"c-button_inner\">\n                                            \n\n\n\n\n    <span class=\"o-icon  c-button_icon\">\n        <svg class=\"svg-doc\" focusable=\"false\" aria-hidden=\"true\">\n            <use xlink:href=\"assets/images/sprite.svg?v=1768510647719#doc\"></use>\n        </svg>\n    </span>\n                    \n                                            <span class=\"c-button_label\">\n                            Read documentation\n                        </span>\n                                    </span>\n            </span>\n        </a>\n                </li>\n            </ul>\n        </nav>\n    </div>\n\n\n</footer>\n                                                    </main>\n\n                                    </div>\n                    </div>\n\n        <script nomodule src=\"https://cdnjs.cloudflare.com/ajax/libs/babel-polyfill/7.6.0/polyfill.min.js\" crossorigin=\"anonymous\"></script>\n        <script nomodule src=\"https://polyfill.io/v3/polyfill.min.js?features=Element.prototype.remove%2CElement.prototype.append%2Cfetch%2CCustomEvent%2CElement.prototype.matches%2CNodeList.prototype.forEach%2CAbortController\" crossorigin=\"anonymous\"></script>\n\n        <script src=\"assets/scripts/vendors.js?v=1768510647719\" defer></script>\n        <script src=\"assets/scripts/app.js?v=1768510647719\" defer></script>\n    </body>\n</html>\n"
  }
]