├── .env ├── .eslintignore ├── .eslintrc.json ├── .gitignore ├── README.md ├── babel.config.js ├── next-env.d.ts ├── next.config.js ├── package.json ├── prettier.config.js ├── public ├── apple-icon.png ├── favicon.png ├── images │ ├── Higher.png │ ├── HigherMobile.png │ ├── banner.svg │ ├── cover.png │ ├── daniele-evangelista.jpeg │ ├── diego-fernandes.jpg │ ├── polygon-mobile.svg │ ├── polygon.png │ ├── rafael-camarda.png │ ├── spoiler.svg │ └── template.png ├── logo-full.svg ├── manifest.json ├── sw.js ├── sw.js.map ├── workbox-d6d90c3a.js └── workbox-d6d90c3a.js.map ├── repo.config.json ├── src ├── @types │ ├── modules.d.ts │ └── styled.d.ts ├── assets │ ├── animations │ │ └── intro.json │ ├── icons │ │ ├── arrow.svg │ │ ├── attention.svg │ │ ├── check.svg │ │ ├── elixir.svg │ │ ├── higher.svg │ │ ├── node.svg │ │ ├── quotationMarks.svg │ │ ├── react.svg │ │ └── warning.svg │ └── images │ │ ├── logo.svg │ │ └── spoiler.svg ├── components │ ├── Cursor │ │ ├── index.tsx │ │ ├── onTouch.ts │ │ └── styles.ts │ ├── GlobalAnimations │ │ ├── index.tsx │ │ └── styles.ts │ ├── PageTransition │ │ └── index.tsx │ ├── SEO.tsx │ ├── Swiper.tsx │ └── TestimoniesSlide │ │ ├── index.tsx │ │ └── styles.ts ├── contexts │ ├── Global.tsx │ └── index.tsx ├── data.ts ├── hooks │ ├── useResize.tsx │ └── useRouter.tsx ├── lib │ ├── createOgImage.ts │ └── react-smooth-scrolling │ │ ├── index.d.ts │ │ ├── index.ts │ │ └── useWindowSize.ts ├── pages │ ├── _app.tsx │ ├── _document.tsx │ └── index.tsx └── styles │ ├── GlobalStyle.ts │ ├── pages │ └── Home.ts │ └── theme.ts ├── tsconfig.json └── yarn.lock /.env: -------------------------------------------------------------------------------- 1 | NEXTAUTH_URL=http://localhost:3000 2 | 3 | GITHUB_ID=Iv1.5e91aae12b466542 4 | GITHUB_SECRET=91937ace76086a5bfba0655eb4b4f6bdd72e1f65 5 | 6 | DATABASE_URL=sqlite://localhost/:memory:?synchronize=true -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .next 3 | /*.js -------------------------------------------------------------------------------- /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "browser": true, 4 | "es2020": true, 5 | "node": true, 6 | "jest": true 7 | }, 8 | "extends": [ 9 | "plugin:react/recommended", 10 | "standard", 11 | "plugin:@typescript-eslint/recommended", 12 | "prettier/@typescript-eslint", 13 | "prettier/standard", 14 | "prettier/react" 15 | ], 16 | "parser": "@typescript-eslint/parser", 17 | "parserOptions": { 18 | "ecmaFeatures": { 19 | "jsx": true 20 | }, 21 | "ecmaVersion": 12, 22 | "sourceType": "module" 23 | }, 24 | "plugins": [ 25 | "react", 26 | "@typescript-eslint", 27 | "prettier" 28 | ], 29 | "rules": { 30 | // suppress errors for missing 'import React' in files 31 | "react/react-in-jsx-scope": "off", 32 | // allow jsx syntax in js files (for next.js project) 33 | "react/jsx-filename-extension": [1, { "extensions": [".js", ".jsx", ".tsx"] }], //should add ".ts" if typescript project 34 | "prettier/prettier": "error", 35 | "space-before-function-paren": "off", 36 | "react/prop-types": "off" 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # next.js 12 | /.next/ 13 | /out/ 14 | 15 | # production 16 | /build 17 | /public/images/og/*.png 18 | 19 | # misc 20 | .DS_Store 21 | *.pem 22 | 23 | # debug 24 | npm-debug.log* 25 | yarn-debug.log* 26 | yarn-error.log* 27 | 28 | # local env files 29 | .env.local 30 | .env.development.local 31 | .env.test.local 32 | .env.production.local 33 | 34 | # vercel 35 | .vercel 36 | 37 | .vercel 38 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |

5 | 6 | Landing page template Logo 7 | 8 | 9 |

10 | 11 | 12 | Banner 13 |

A clone of the landing page interface of the rocketseat sales page, with nice things like animations and user interactions and smooth scrolling! Veja funcionando 14 | aqui. 15 |

16 | 17 |

18 | 19 | Made by Carlos Miguel 20 | 21 | 22 | Carlos Miguel 23 | 24 | 25 | 26 | 27 | Repository size 28 | 29 | GitHub last commit 30 | 31 | License 32 |
33 | 34 | Stargazers 35 | 36 |

37 |

38 | landing-page-template_3 Logo 39 |

40 | 41 | --- 42 | 43 | 44 | ## 🚀 Getting Started 45 | 46 | ### Prerequisites 47 | 48 | - To run any ReactJS application you need to configure the environment on your machine. 49 | 50 | - Setting the environment is a simple process, so it's recommended to follow the Rocketseat guide which is currently the most complete and detailed to make the settings: 51 | 52 | #### [**Rocketseat Guide**](https://www.notion.so/Configura-es-do-ambiente-React-76f2963a042f45b9b9b567a2795945b8) 53 | 54 | ### Clone 55 | 56 | - Clone this repo to your local machine using: 57 | 58 | ``` 59 | https://github.com/solrachix/landing-page-template_3 60 | ``` 61 | 62 | ### Setup 63 | 64 | - Install project dependencies; 65 | - ```javascript 66 | yarn install 67 | // or 68 | npm install 69 | ``` 70 | - Run project in development mode; 71 | 72 | - ```javascript 73 | yarn dev 74 | // or 75 | npm run dev 76 | ``` 77 | - Be Happy! 😆 78 | 79 | --- 80 | 81 | ## 📋 Features 82 | 83 | 84 | ### Build with 85 | 86 | - [ReactJS](https://reactjs.org/) - A JavaScript library for building user interfaces 87 | - [Typescript](https://www.typescriptlang.org/) - TypeScript is an open-source language which builds on JavaScript, one of the world’s most used tools, by adding static type definitions. 88 | - [Next.JS](https://nextjs.org/) - Next.js gives you the best developer experience with all the features you need for production: hybrid static & server rendering, TypeScript support, smart bundling, route pre-fetching, and more. No config needed. 89 | 90 | --- 91 | 92 | ## 🤔 Contributing 93 | 94 | > To get started... 95 | 96 | ### Step 1 97 | 98 | - 🍴 Fork this repo! 99 | 100 | ### Step 2 101 | 102 | - 👯 Clone this repo to your local machine using `https://github.com/solrachix/landing-page-template_3` 103 | 104 | ### Step 3 105 | 106 | - 🎋 Create your feature branch using `git checkout -b my-feature` 107 | 108 | ### Step 4 109 | 110 | - ✅ Commit your changes using `git commit -m 'feat: My new feature'`; 111 | 112 | ### Step 5 113 | 114 | - 📌 Push to the branch using `git push origin my-feature`; 115 | 116 | ### Step 6 117 | 118 | - 🔃 Create a new pull request 119 | 120 | After your Pull Request is merged, can you delete your feature branch. 121 | 122 | --- 123 | 124 | ## 📌 Support 125 | 126 | Reach out to me at one of the following places! 127 | 128 | - Linkedin at [Carlos Miguel](https://www.linkedin.com/in/carlos-miguel-380413197) 129 | - Instagram [Solrachix](https://www.instagram.com/solrachix) 130 | 131 | --- 132 | 133 | ## 📝 License 134 | 135 | License 136 | 137 | This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details. 138 | 139 | --- 140 | 141 | Made by Carlos Miguel with 💙 Enjoy it! 142 | -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: ['next/babel'], 3 | plugins: [['styled-components', { ssr: true }]] 4 | } 5 | -------------------------------------------------------------------------------- /next-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | -------------------------------------------------------------------------------- /next.config.js: -------------------------------------------------------------------------------- 1 | const withPlugins = require('next-compose-plugins') 2 | const withSvgr = require('next-svgr') 3 | const withPWA = require('next-pwa') 4 | 5 | module.exports = withPlugins([ 6 | { 7 | distDir: 'build', 8 | future: { webpack5: true }, 9 | typescript: { 10 | // !! WARN !! 11 | ignoreBuildErrors: true, 12 | }, 13 | env: { 14 | NEXTAUTH_URL: 'http://localhost:3000' 15 | } 16 | }, 17 | [withPWA, { 18 | pwa: { 19 | dest: 'public' 20 | } 21 | }], 22 | withSvgr 23 | // your other plugins here 24 | ]) 25 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "moveit-next", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "dev": "next dev", 7 | "build": "next build", 8 | "start": "next start", 9 | "export": "next export" 10 | }, 11 | "dependencies": { 12 | "axios": "^0.21.1", 13 | "dotenv": "^8.2.0", 14 | "js-cookie": "^2.2.1", 15 | "next": "10.0.7", 16 | "next-compose-plugins": "^2.2.1", 17 | "next-pwa": "^5.0.5", 18 | "next-svgr": "^0.0.2", 19 | "polished": "^4.1.1", 20 | "puppeteer": "^8.0.0", 21 | "react": "17.0.1", 22 | "react-dom": "17.0.1", 23 | "react-icons": "^4.2.0", 24 | "react-lottie": "^1.2.3", 25 | "react-spring": "^8.0.27", 26 | "sqlite3": "^5.0.2", 27 | "styled-components": "^5.2.1", 28 | "swiper": "^6.5.2", 29 | "webpack": "^5.24.2" 30 | }, 31 | "devDependencies": { 32 | "@types/js-cookie": "^2.2.6", 33 | "@types/next-auth": "^3.1.24", 34 | "@types/node": "^14.11.2", 35 | "@types/react": "^16.9.49", 36 | "@types/react-lottie": "^1.2.5", 37 | "@types/styled-components": "^5.1.3", 38 | "@typescript-eslint/eslint-plugin": "^3.9.1", 39 | "@typescript-eslint/parser": "^3.9.1", 40 | "babel-plugin-styled-components": "^1.11.1", 41 | "eslint": "^7.7.0", 42 | "eslint-config-prettier": "^6.11.0", 43 | "eslint-config-standard": "^14.1.1", 44 | "eslint-plugin-import": "^2.22.0", 45 | "eslint-plugin-node": "^11.1.0", 46 | "eslint-plugin-prettier": "^3.1.4", 47 | "eslint-plugin-promise": "^4.2.1", 48 | "eslint-plugin-react": "^7.20.6", 49 | "eslint-plugin-standard": "^4.0.1", 50 | "prettier": "^2.1.0", 51 | "typescript": "^4.0.3" 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /prettier.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | semi: false, 3 | singleQuote: true, 4 | arrowParens: 'avoid', 5 | trailingComma: 'none', 6 | endOfLine: 'auto' 7 | }; -------------------------------------------------------------------------------- /public/apple-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/solrachix/landing-page-template_3/c42c9dc4f74430b8e8a18c1834cc88adf9a18dcb/public/apple-icon.png -------------------------------------------------------------------------------- /public/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/solrachix/landing-page-template_3/c42c9dc4f74430b8e8a18c1834cc88adf9a18dcb/public/favicon.png -------------------------------------------------------------------------------- /public/images/Higher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/solrachix/landing-page-template_3/c42c9dc4f74430b8e8a18c1834cc88adf9a18dcb/public/images/Higher.png -------------------------------------------------------------------------------- /public/images/HigherMobile.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/solrachix/landing-page-template_3/c42c9dc4f74430b8e8a18c1834cc88adf9a18dcb/public/images/HigherMobile.png -------------------------------------------------------------------------------- /public/images/banner.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /public/images/cover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/solrachix/landing-page-template_3/c42c9dc4f74430b8e8a18c1834cc88adf9a18dcb/public/images/cover.png -------------------------------------------------------------------------------- /public/images/daniele-evangelista.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/solrachix/landing-page-template_3/c42c9dc4f74430b8e8a18c1834cc88adf9a18dcb/public/images/daniele-evangelista.jpeg -------------------------------------------------------------------------------- /public/images/diego-fernandes.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/solrachix/landing-page-template_3/c42c9dc4f74430b8e8a18c1834cc88adf9a18dcb/public/images/diego-fernandes.jpg -------------------------------------------------------------------------------- /public/images/polygon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/solrachix/landing-page-template_3/c42c9dc4f74430b8e8a18c1834cc88adf9a18dcb/public/images/polygon.png -------------------------------------------------------------------------------- /public/images/rafael-camarda.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/solrachix/landing-page-template_3/c42c9dc4f74430b8e8a18c1834cc88adf9a18dcb/public/images/rafael-camarda.png -------------------------------------------------------------------------------- /public/images/spoiler.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | -------------------------------------------------------------------------------- /public/images/template.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/solrachix/landing-page-template_3/c42c9dc4f74430b8e8a18c1834cc88adf9a18dcb/public/images/template.png -------------------------------------------------------------------------------- /public/logo-full.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Rocketseat-lading-page", 3 | "short_name": "Moveit", 4 | "theme_color": "#5965e0", 5 | "background_color": "#f2f3f5", 6 | "display": "browser", 7 | "scope": "/", 8 | "start_url": "/" 9 | } -------------------------------------------------------------------------------- /public/sw.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2018 Google Inc. All Rights Reserved. 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * Unless required by applicable law or agreed to in writing, software 8 | * distributed under the License is distributed on an "AS IS" BASIS, 9 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 | * See the License for the specific language governing permissions and 11 | * limitations under the License. 12 | */ 13 | 14 | // If the loader is already loaded, just stop. 15 | if (!self.define) { 16 | const singleRequire = name => { 17 | if (name !== 'require') { 18 | name = name + '.js'; 19 | } 20 | let promise = Promise.resolve(); 21 | if (!registry[name]) { 22 | 23 | promise = new Promise(async resolve => { 24 | if ("document" in self) { 25 | const script = document.createElement("script"); 26 | script.src = name; 27 | document.head.appendChild(script); 28 | script.onload = resolve; 29 | } else { 30 | importScripts(name); 31 | resolve(); 32 | } 33 | }); 34 | 35 | } 36 | return promise.then(() => { 37 | if (!registry[name]) { 38 | throw new Error(`Module ${name} didn’t register its module`); 39 | } 40 | return registry[name]; 41 | }); 42 | }; 43 | 44 | const require = (names, resolve) => { 45 | Promise.all(names.map(singleRequire)) 46 | .then(modules => resolve(modules.length === 1 ? modules[0] : modules)); 47 | }; 48 | 49 | const registry = { 50 | require: Promise.resolve(require) 51 | }; 52 | 53 | self.define = (moduleName, depsNames, factory) => { 54 | if (registry[moduleName]) { 55 | // Module is already loading or loaded. 56 | return; 57 | } 58 | registry[moduleName] = Promise.resolve().then(() => { 59 | let exports = {}; 60 | const module = { 61 | uri: location.origin + moduleName.slice(1) 62 | }; 63 | return Promise.all( 64 | depsNames.map(depName => { 65 | switch(depName) { 66 | case "exports": 67 | return exports; 68 | case "module": 69 | return module; 70 | default: 71 | return singleRequire(depName); 72 | } 73 | }) 74 | ).then(deps => { 75 | const facValue = factory(...deps); 76 | if(!exports.default) { 77 | exports.default = facValue; 78 | } 79 | return exports; 80 | }); 81 | }); 82 | }; 83 | } 84 | define("./sw.js",['./workbox-d6d90c3a'], function (workbox) { 'use strict'; 85 | 86 | /** 87 | * Welcome to your Workbox-powered service worker! 88 | * 89 | * You'll need to register this file in your web app. 90 | * See https://goo.gl/nhQhGp 91 | * 92 | * The rest of the code is auto-generated. Please don't update this file 93 | * directly; instead, make changes to your Workbox build configuration 94 | * and re-run your build process. 95 | * See https://goo.gl/2aRDsh 96 | */ 97 | 98 | importScripts(); 99 | self.skipWaiting(); 100 | workbox.clientsClaim(); 101 | workbox.registerRoute(/.*/i, new workbox.NetworkOnly({ 102 | "cacheName": "dev", 103 | plugins: [] 104 | }), 'GET'); 105 | 106 | }); 107 | //# sourceMappingURL=sw.js.map 108 | -------------------------------------------------------------------------------- /public/sw.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"sw.js","sources":["../../../../../Acer/AppData/Local/Temp/9e36a7f33700638bc2083dbc236bbc0d/sw.js"],"sourcesContent":["import {registerRoute as workbox_routing_registerRoute} from 'C:/Users/Public/Documents/Projetos-miguel/Projetos_para_instagram/rocketseat-landing-page/node_modules/workbox-routing/registerRoute.mjs';\nimport {NetworkOnly as workbox_strategies_NetworkOnly} from 'C:/Users/Public/Documents/Projetos-miguel/Projetos_para_instagram/rocketseat-landing-page/node_modules/workbox-strategies/NetworkOnly.mjs';\nimport {clientsClaim as workbox_core_clientsClaim} from 'C:/Users/Public/Documents/Projetos-miguel/Projetos_para_instagram/rocketseat-landing-page/node_modules/workbox-core/clientsClaim.mjs';/**\n * Welcome to your Workbox-powered service worker!\n *\n * You'll need to register this file in your web app.\n * See https://goo.gl/nhQhGp\n *\n * The rest of the code is auto-generated. Please don't update this file\n * directly; instead, make changes to your Workbox build configuration\n * and re-run your build process.\n * See https://goo.gl/2aRDsh\n */\n\n\nimportScripts(\n \n);\n\n\n\n\n\n\n\nself.skipWaiting();\n\nworkbox_core_clientsClaim();\n\n\n\nworkbox_routing_registerRoute(/.*/i, new workbox_strategies_NetworkOnly({ \"cacheName\":\"dev\", plugins: [] }), 'GET');\n\n\n\n\n"],"names":["importScripts","self","skipWaiting","workbox_core_clientsClaim","workbox_routing_registerRoute","workbox_strategies_NetworkOnly","plugins"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAE+L;EAC/L;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;EAGAA,aAAa;EAUbC,IAAI,CAACC,WAAL;AAEAC,sBAAyB;AAIzBC,uBAA6B,CAAC,KAAD,EAAQ,IAAIC,mBAAJ,CAAmC;EAAE,eAAY,KAAd;EAAqBC,EAAAA,OAAO,EAAE;EAA9B,CAAnC,CAAR,EAAgF,KAAhF,CAA7B;;"} -------------------------------------------------------------------------------- /repo.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "project_name": "Rocketseat Landing Page", 3 | "type": "web", 4 | 5 | "template_url": "./public/images/cover.png", 6 | "logo_url": "./src/assets/logo.svg", 7 | 8 | "web": "./" 9 | } 10 | -------------------------------------------------------------------------------- /src/@types/modules.d.ts: -------------------------------------------------------------------------------- 1 | declare module '*.svg' 2 | -------------------------------------------------------------------------------- /src/@types/styled.d.ts: -------------------------------------------------------------------------------- 1 | import 'styled-components' 2 | 3 | import { DarkTheme } from '../styles/theme' 4 | 5 | export type Theme = typeof DarkTheme 6 | 7 | declare module 'styled-components' { 8 | export interface DefaultTheme extends Theme {} 9 | } 10 | -------------------------------------------------------------------------------- /src/assets/animations/intro.json: -------------------------------------------------------------------------------- 1 | {"v":"5.5.7","meta":{"g":"LottieFiles AE 0.1.14","a":"","k":"","d":"","tc":"#f00"},"fr":60,"ip":0,"op":300,"w":800,"h":600,"nm":"Rocketseat-launch","ddd":0,"assets":[{"id":"image_0","w":139,"h":180,"u":"","p":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIsAAAC0CAYAAACkNd+HAAAJ40lEQVR4Xu2dgZXUNhCGZyogqQCoAFIBpAKgAqCCXCqAVABUAFdBoIJABeEqACoIV8Hkza5212tJtrQe7crS7/fu3Xt39tgaf56R55dkJmyr9YCIPCaiF0R0zzXiOxG9Zmb9bb6xuUUYLOoBEfmFiJ4qFER0N3CyWyJ6WAIYwFL01toZFxGNHlcuktyZsXzNzBpxTDfAYupOe2Mu1SgkTzKsf2FmTVGmG2AxdaeNsYRUM3ciwDLnobX/PzPVTDUXsKwdhtj1n5hqAEurQITaJSLaCY291SxxxTtm1n6O6YY+i6k75425VKOQ6M2ce6uZNxje4y9mVghNN8Bi6s64sUEB7fkZTglYzuBk81O4VKNR5IG58bjBl8z8wfp8iCzWHiUi9+qrgJRMNVNX/jszf7ZuGmAx9qiIPCQifarPGUnGrQAsxvfV3JyLKPpEXxIUbRdgMb+7xgZFRN9AXhmbzTbHzEUyRhGj2a1r5AAR+VnwdTjZS4Al2VWX2dH1Vf69zNmPzwpYargLE9fg6ij/VHCZN8ysnWzzDWnIyKUVwVJERFQ3ARY7WLSE/97I3BIzgGWJ985xbC1vQkT0iZl12KX5hshi5NKKYCmiCyENGYGiZgCLoTNbNyUiWrl9VEE7EVkquAmTl1ARLEVK/UhDhgQCFkNntm5KRHQWYGjS17mbjshybo/nnk9EJPeYQvvfLzEbEWnI8G7VAkspXQiwAJYsD6Aol+Wu8M4V6UK3zKwT50/aXDs2x4aGZQKWk9x6fFBFsGTrQhOzIHU1hqvhwG/A0iksGbMgnzHzR/RZDEBRE266R/WK84kT7n8w82axIEQWA2Aq0oWC01YNJtxvajeApS1YbojoMTPrWGCNeLpGS+7aLiGPbPQmwNIWLNoaBUbnLSkkVhVlwGLAycZERbqQVZPGdgCLlWcBi5UnO7ADWDq4yVZNrEhxtmrS2M5mVQZ0cA3cW4uIaNCUmAm8Ols5F7BYebIDOx2kIUQWK45FROsa51j+y+qSs+zsxsigz5LltvDOrpz+zcBUlSYAi/FtERGtmL4xNluFOcBS4DZUJChatg6qs6U3h7ZcStIVoHS+cal1bktdfsjufkAV+iyF3O7Gjuj0kLUDA1gKMaKioi6ko/2XVt6OAIs1LG60nK7RUsN8Z8vm7edOIw0tcOtgcWSFxGrsyIIrKnIoYFni1gZTzZQ7AMspsDScaqbcgdH9qbB0kmqm3LGfaI8+S8RNg3pJK281qc/HeD/AMuU5EXlLRH+c6t3GjvuNmb9qmxBZRne2dQU5F+ThqgyAZeC9lsXAXEh2+wOWgOcaKs+fykXwOMAShqWWFbJNb/ZCY0ffAUAact5EpzaI1dESHoDlAEst69guDAamhwOWkDs7mCh2CkVH3wFAZEFkSdKFUGc5fm2u4pN1pzz+BY85WtodkeUQWWpZx7bgvc82DVgifRbA4jtmrzgjDR2iii4H+l/2c9f+AUdLuyMNHZbTquFjmLXhB1jGd6SidWxrg2WvOCMNHdKQLtSHyDJCdfwdAKShbRpqdurpklAFWMIios4gfLXEsS0eC1gASyrX3pfnkYa2aQjDKH2EvI9GAJY+1rFNjSbD/QALFOdkbq6ZWQeE7TdEFkSWGD3e96EByxYWKM4+MoAFImJyGgIsgCUZFu/70N2nITcFBIqzzxBggYiIyJLsAcCS7Crvy/NIQ9tPw0FxnlGcMUQBinM0zIxFRMCyhQWKcwAZwALFObXDEvzyPPosUJxDAAEWiIipgYUAC2BJhsVTnNHBheKcrDgDFijOgCU52G5hwbTVhOEJiCyAJfZceSJi97BAcY7GYMACETE5QQMWwJIMy6/MrENNj7auK7iYEB+GJ6QLoc+COc5BWgALRMTUHHTLzLq4kbf1noYwPMFnIqgLIQ1BcQ4FEMACETE1C4UVZ0QWESzB7jP0jpl1cSP0WYYewBLswWjjzUTc7dV7BxdznH1eAEukzwLF2XfMn8ysixshDY3SEGDxmQjqQl13cKE4R9+OAMvYNdCFAEtyMQGwRF0VVJx7T0OY4xzqxDJH35C7fXXGqtrhyBJTnHuPLBARfV6iijNgwRLsY1yiImLvsGBVbT+yAJZI9RYiImBJe3uGiJgnIvaehhBZMkTE3mGB4gxYktMQRETfVS+Z+UPMgz0X5QBLhuLcbRqC4pwvIvYMC3ShMC/R4QmAJa17081eU7oQYOkGg7SGApaAn6A45yvOPUcWKM4+Lz+Y+d5UDOry1RlLsAeRmBQRe44sUJwzRcSeYYEuBFjSev0i8pWIHqTt3c1e0ZmIOw9012cREdU+nneDQFpDb4jocWgdueHhWbC46RNpp5/f6yERBVcYmj80eY/xOfR8NUeUayLSqKc/ltt3Zv6+1OAsLCKir1P6qomncam348d/IqIrixta7hKJJmEREX0ytTN4p+RFdG47+AWOGn0ShcUpsxoO79Z44Y1c0w0z6wO5im0KlhdE9H4VrVjvRU6qvLU1awqWj0T0pLYLbuh6ZiumtbV1ChYUrsrerVVFFXUFIktZIGLWVxdV5mBBn6UcSKuLKnOwaAELb0P2wHxi5qf2ZstbRJ2lvI/HZ7hfe/Et5pLUCq7qKY/O79fmzriaAlzI87Ow7A5yZf/dSCr9rWNCUNnN43m1UWWyzzLnA1fhVXEKwMw5a/v/ydl+aSYuu1dyZAldpuCrGil379aJhNFpoSlGathnKSyajr7V0JAKr+GHE2Ffr7VDO/bpIljUGAYTkQ4cUmlEK94/mdl6LEo1z4EFLL1OBf1CRC9aiRopRC6GxUWX3sa0zo5XTXH+2vaxgqUnaWDVtZIlgJrA4qJLDysprWqw0hIwFhXlpk7c0Tr4qxQAraBJ0Ya0A6uiov7EhgDq31svzq1yWIEVKNEKrohoH0RH9GP87cHbq6/ALgXnKLK4Er7WDCAaHnt2ck37pTdhLcfvYXGgaGGp5klYl/Jr9PO1l7qgS5x3CEtvtZIcf69aLc5p6NS+G1iwXsmkO7utqwS1IRHpoUZy6gOGqOI8xyKi40H/PtWTjR+HvsrgBissWAUpTLyOQ7k3twxF4w/LUfMUFkwmC9/xZ8ysZQRsgzQEWHwckH4Cjwgii++U7sv6sVCqsGAC/ME7Sctl9ZqXFJYrInrTqwMG7QYoMxAoLBh0TaRDJJ/izWeall0Ft+cVHNGZTUwrO1g0uqg21PqYlKFbdKqGDrjWt0FsCR4YCom9jKPVYpsWIt8i7SQQMqzgDnd3g55aXUdOI4mmW0CSx8h+b29YpRtPq05tYZScRhEtDXxENfZEQmKRJRBl9LV6LYOhNHLoRH3te+nvzy3PDlx+6/MtJE0FcYsnl146ffbq0RmddVHRHf4HahWp4vSnGowAAAAASUVORK5CYII=","e":1},{"id":"image_1","w":77,"h":38,"u":"","p":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAE0AAAAmCAYAAACBOhYpAAACTUlEQVRoQ+2a0VHDMBBEdyuADggVQAmhAkIFQAWECggVABUAFQAVQAeQCkgqgFQg5jxyxjG2I+M7WyS+r2RGluXnXel0FgHAOfcMYFd+91FJYETym865MYCbHlYQgWuSE4E2BPAadEnfaJ/kjN6eDwBOeyaVBB5JnkmLFNoAwGcPrZJAorIlNK+2CYCrHlwhgTuSMvcnkSgtDedcb9PfzJa2LITmFSe+FdXtbbnqpgDGJN/yHFaUllPdtsKbi2hIiusKoxRaxrLbAm8trFJ7ltF1zm0qvGBYtaFtoPJqw/oztA2A92dYjaFl4I0AyKS58w9W22Tv2HScaxeCkBs45w4BvIe07bDNSoLaZBwq0Hx+F/OOYgFgIGWdJrDU7Jmxacz71xeSMo2ohJrSvNo+AByojEy3k/OqZLXurbShxWrRZYWiLqCi9trQYlwQpiRlXGqhCs1bVGpOMW321VZN9YUgsyDcArhQe63NOzoqqlQ06dZCaTFZdEFS/SubOrTILKqaapjZ00OLpQKsmmpYQ5NE8qnJvKF0rWqqYQrNq022LF1u4tVTjTagdW1R9VSjDWhdW/SEpJxRUQ+T1TOTszn1EQd2SNLs2cw69vOavOnjwOfUbGaSapjb00OTjzH3mjQC+7okKTsTk7BWmmTjXyYjr+7UJNVoRWkdWXROUgqiZmGqtI4sapZqtKk0eetS0W0r0VWvauQla640rzapfEiya1kKl48nQ5LygkyjFWiZvE2OqkrIApGtpub/lz10/gRP+n+WHrgzpeU7/wEqb8cn1kvLhwAAAABJRU5ErkJggg==","e":1},{"id":"image_2","w":40,"h":79,"u":"","p":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAABPCAYAAACZD4ePAAADNUlEQVRoQ+2a3XkWIRCFORUYK1AriFagVqBWYKxArUCtQK3ApAK1A63ApAJjBWoF+MwKPLssP8Mw7O5FvssEhrNngHdgF6bws9aeGGOeGmPuJpp9K/V1/6P+92ftKI6PdW2MOQdQjIPcINZaCkydbzGE9DS5AHCWC5AUuKE4rysrciXQpfXSGHOnxxZB33cA3sb9UgK/GGOeCAbQ6PI4npMLgdZaWhCfNUYSxrgCMF9UJhZIK2vr1MbP8gLAuf9jEHgA97ymXwDCtjYXuOfci118BoD0/E+xW7m/hfNmRLew7XiBey+O+CH/AiAKBQdp/3kzwoqOmPcAXHsHCWkPO4KN6DrtiUcWOJHlRmBH7m8c7DBv6voawAc/B4+4zSxWMVW0n3ofWbn/bQB/vIME55/KA/SEC2XXvFigKvq0J6pi348AXgXUuYLhSPNwWc04gVTJ/lB0QRwKQMjsESvq7wAerSpq5yKV2s/Fj67Tcdr/cgKPUBc+AEALdvqljp1WxwhRlFColgTueTZZ3TCkHNyTKosjZy7Fe1JlKvPnkyN3ebQHVVa3CkkHd6RKwBvHwT2oEvBWFehc3PSeZo43rsAtqbLAG1fgllRZ4I0l0KV5K6os8NYicAuqrPDWInALqrTf8vsnsNZuQZUV3tgOunk4miorvLUKHHlWWVz3pgq07JumWZpHUiWJtyYHB1MliTeJwFFUmW4PSrV3NcXOwRFUyeKt2cFBVEm+m4vdZDnoBGpTJYs3qYOaVCniTSpQkypfAdC8rv7YKVamShFvIgedQC2qFPHWI1CDKlW8iQUqUaWKt16BvVSp4q1XYC9VqnjrEthJFRbeNARKqcLCm4ZAKVVYeNMQKKEKG2/dAoVUYeNNS2ArVdh40xLYShU23lQENlKlCW+aArlUKd4edJ9JcgEaPqdqwpuagw1UacKbtsAaVZKX49VS2jVoqqhTQa219F73fWHAZrxpO1ijyuqrSq571K7bwQpVRHhTddAJpNenLxPOiPA2QmCOKtnLcW6aVVLsXKRLoPijcBHe1B10AmOqiPE2SmB8VhHjbYjA2WKh+UjpPqvd/XHmodoc5AwmafMPilKHX5E7OAUAAAAASUVORK5CYII=","e":1},{"id":"comp_0","layers":[{"ddd":0,"ind":1,"ty":4,"nm":"speed-line 2","sr":1,"ks":{"o":{"a":0,"k":35,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[401.84,362.291,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-1.786,-399.253],[-1.893,474.672]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":3,"ix":5},"lc":2,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tm","s":{"a":0,"k":0,"ix":1},"e":{"a":0,"k":25,"ix":2},"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":40,"s":[0]},{"t":99,"s":[720]}],"ix":3},"m":1,"ix":3,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":40,"op":101,"st":40,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"speed-line","sr":1,"ks":{"o":{"a":0,"k":35,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[401.84,362.291,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-1.786,-399.253],[-1.893,474.672]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":3,"ix":5},"lc":2,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tm","s":{"a":0,"k":0,"ix":1},"e":{"a":0,"k":25,"ix":2},"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[0]},{"t":59,"s":[720]}],"ix":3},"m":1,"ix":3,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":61,"st":0,"bm":0}]}],"layers":[{"ddd":0,"ind":1,"ty":3,"nm":"speed-lines-anchor","sr":1,"ks":{"o":{"a":0,"k":0,"ix":11},"r":{"a":0,"k":0,"ix":10,"x":"var $bm_rt;\n$bm_rt = thisComp.layer('seat').transform.rotation;"},"p":{"a":0,"k":[400,300,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ip":0,"op":300,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":0,"nm":"speed-line","parent":1,"refId":"comp_0","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.562],"y":[1]},"o":{"x":[0.827],"y":[0]},"t":27,"s":[0]},{"i":{"x":[0.65],"y":[1]},"o":{"x":[0.396],"y":[0]},"t":69,"s":[100]},{"i":{"x":[0.744],"y":[1]},"o":{"x":[1],"y":[0]},"t":237,"s":[100]},{"t":265,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[149.153,-80.114,0],"ix":2},"a":{"a":0,"k":[400,400,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"tm":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":-17.449,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":73.527,"s":[1]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":74.402,"s":[0.017]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":126.1,"s":[1]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":126.977,"s":[0.017]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":178.674,"s":[1]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":179.549,"s":[0.017]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":231.246,"s":[1]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":232.123,"s":[0.017]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":278.123,"s":[1]},{"t":279,"s":[0.017]}],"ix":2},"w":800,"h":800,"ip":0,"op":300,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":0,"nm":"speed-line","parent":1,"refId":"comp_0","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.562],"y":[1]},"o":{"x":[0.827],"y":[0]},"t":27,"s":[0]},{"i":{"x":[0.65],"y":[1]},"o":{"x":[0.396],"y":[0]},"t":69,"s":[100]},{"i":{"x":[0.744],"y":[1]},"o":{"x":[1],"y":[0]},"t":237,"s":[100]},{"t":265,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[251.268,-77.965,0],"ix":2},"a":{"a":0,"k":[400,400,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"tm":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":38,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":98,"s":[1]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":99,"s":[0.017]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[1]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":159,"s":[0.017]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":218,"s":[1]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":219,"s":[0.017]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":278,"s":[1]},{"t":279,"s":[0.017]}],"ix":2},"w":800,"h":800,"ip":0,"op":300,"st":0,"bm":0},{"ddd":0,"ind":4,"ty":0,"nm":"speed-line","parent":1,"refId":"comp_0","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.562],"y":[1]},"o":{"x":[0.827],"y":[0]},"t":27,"s":[0]},{"i":{"x":[0.65],"y":[1]},"o":{"x":[0.396],"y":[0]},"t":69,"s":[100]},{"i":{"x":[0.744],"y":[1]},"o":{"x":[1],"y":[0]},"t":237,"s":[100]},{"t":265,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-258.354,81,0],"ix":2},"a":{"a":0,"k":[400,400,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"tm":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":-17.449,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":74.527,"s":[1]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":75.402,"s":[0.017]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":127.1,"s":[1]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":127.977,"s":[0.017]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":179.674,"s":[1]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":180.549,"s":[0.017]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":232.246,"s":[1]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":233.123,"s":[0.017]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":279.123,"s":[1]},{"t":280,"s":[0.017]}],"ix":2},"w":800,"h":800,"ip":0,"op":300,"st":0,"bm":0},{"ddd":0,"ind":5,"ty":0,"nm":"speed-line","parent":1,"refId":"comp_0","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.562],"y":[1]},"o":{"x":[0.827],"y":[0]},"t":27,"s":[0]},{"i":{"x":[0.65],"y":[1]},"o":{"x":[0.396],"y":[0]},"t":69,"s":[100]},{"i":{"x":[0.744],"y":[1]},"o":{"x":[1],"y":[0]},"t":237,"s":[100]},{"t":265,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-158.354,81,0],"ix":2},"a":{"a":0,"k":[400,400,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"tm":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":40,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":100,"s":[1]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":101,"s":[0.017]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":160,"s":[1]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":161,"s":[0.017]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":220,"s":[1]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":221,"s":[0.017]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":280,"s":[1]},{"t":281,"s":[0.017]}],"ix":2},"w":800,"h":800,"ip":0,"op":300,"st":0,"bm":0},{"ddd":0,"ind":6,"ty":2,"nm":"seat","refId":"image_0","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.6],"y":[0.711]},"o":{"x":[0.705],"y":[0]},"t":102,"s":[0]},{"i":{"x":[0],"y":[1]},"o":{"x":[0.118],"y":[-0.341]},"t":141,"s":[42]},{"t":178,"s":[32]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.865},"o":{"x":0.637,"y":0},"t":21,"s":[377.403,358.2,0],"to":[0,-12,0],"ti":[0,10.667,0]},{"i":{"x":0.207,"y":1},"o":{"x":0.167,"y":0.32},"t":76,"s":[377.403,286.2,0],"to":[0,-10.667,0],"ti":[0,-1.333,0]},{"t":103,"s":[377.403,294.2,0]}],"ix":2},"a":{"a":0,"k":[69.117,142.094,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.833,0.833,0.833],"y":[1.155,1.155,1.426]},"o":{"x":[0.795,0.795,0.167],"y":[-0.033,-0.033,0]},"t":210,"s":[100,100,100]},{"i":{"x":[0.323,0.323,0.667],"y":[0.989,0.989,1]},"o":{"x":[0.177,0.177,0.167],"y":[0.065,0.065,-0.593]},"t":233,"s":[80,80,100]},{"i":{"x":[0.375,0.375,0.667],"y":[1.045,1.045,1]},"o":{"x":[0.333,0.333,0.333],"y":[-0.078,-0.078,0]},"t":265,"s":[150,150,100]},{"t":285,"s":[140,140,100]}],"ix":6}},"ao":0,"ip":0,"op":300,"st":0,"bm":0},{"ddd":0,"ind":7,"ty":2,"nm":"seat-base","parent":6,"refId":"image_1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.39],"y":[1]},"o":{"x":[0.615],"y":[0.002]},"t":92,"s":[0]},{"i":{"x":[0.473],"y":[0.951]},"o":{"x":[0.576],"y":[-0.001]},"t":125,"s":[-18]},{"i":{"x":[0.279],"y":[0.998]},"o":{"x":[0.448],"y":[-0.093]},"t":157,"s":[14]},{"t":187,"s":[0]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.409,"y":1},"o":{"x":0.637,"y":0},"t":22,"s":[70.279,187.057,0],"to":[0,-0.667,0],"ti":[0,0.667,0]},{"i":{"x":0.667,"y":0.667},"o":{"x":0.333,"y":0.333},"t":32,"s":[70.279,183.057,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.422,"y":1},"o":{"x":0.68,"y":0},"t":68,"s":[70.279,183.057,0],"to":[0,0.667,0],"ti":[0,-0.667,0]},{"t":80,"s":[70.279,187.057,0]}],"ix":2},"a":{"a":0,"k":[38.764,2.677,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ip":0,"op":300,"st":0,"bm":0},{"ddd":0,"ind":8,"ty":2,"nm":"fire","parent":7,"refId":"image_2","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.733],"y":[0.936]},"o":{"x":[0.406],"y":[0]},"t":24,"s":[0]},{"i":{"x":[0.278],"y":[1]},"o":{"x":[0.468],"y":[2.733]},"t":27,"s":[48.966]},{"t":103,"s":[100]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[38.768,42.034,0],"ix":2},"a":{"a":0,"k":[19.819,0.222,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.217,0.211,0.667],"y":[1,1,1]},"o":{"x":[0.648,0.648,0.333],"y":[0,0,0]},"t":15,"s":[118,10,100]},{"i":{"x":[0.28,0.211,0.667],"y":[1,1,1]},"o":{"x":[0.502,0.521,0.333],"y":[0,0,0]},"t":62,"s":[65,165,100]},{"i":{"x":[0.322,0.322,0.667],"y":[1,1,1]},"o":{"x":[0.98,0.9,0.333],"y":[3.11,0,0]},"t":79,"s":[80,120,100]},{"i":{"x":[0.322,0.322,0.667],"y":[1,1,1]},"o":{"x":[0.98,0.9,0.333],"y":[0,0,0]},"t":199,"s":[75,120,100]},{"t":235,"s":[100,100,100]}],"ix":6}},"ao":0,"ip":0,"op":300,"st":0,"bm":0},{"ddd":0,"ind":9,"ty":4,"nm":"ground-smoke 2","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":16,"s":[0]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.651],"y":[0]},"t":24,"s":[100]},{"i":{"x":[0.173],"y":[1]},"o":{"x":[0.651],"y":[0]},"t":45,"s":[100]},{"t":60,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.252,"y":1},"o":{"x":0.598,"y":0},"t":16,"s":[378.311,438.117,0],"to":[0,21.208,0],"ti":[0,-21.208,0]},{"t":60,"s":[378.311,565.367,0]}],"ix":2},"a":{"a":0,"k":[-278.689,21.867,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.656,0.656,0.667],"y":[1,1,1]},"o":{"x":[1,1,0.167],"y":[0,0,0]},"t":16,"s":[10,8.029,100]},{"t":60,"s":[232.383,186.578,100]}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-38.513,2.828],[0.307,-12.302],[-50.202,1.642],[0.222,11.595]],"o":[[-36.913,-0.36],[-0.389,15.589],[-38.364,-1.147],[-0.152,-7.941]],"v":[[-293.045,2.893],[-371.482,19.62],[-273.357,36.755],[-359.295,19.629]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[30.424,0.427],[-0.252,-12.361],[41.184,-0.369],[0,11.677]],"o":[[56.98,-1.166],[0.211,10.358],[27.106,-2.361],[0,-10.898]],"v":[[-280.076,2.105],[-177.412,19.277],[-251.482,35.976],[-191.482,18.462]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":-1,"op":61,"st":25,"bm":0}],"markers":[]} -------------------------------------------------------------------------------- /src/assets/icons/arrow.svg: -------------------------------------------------------------------------------- 1 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /src/assets/icons/attention.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/assets/icons/check.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/assets/icons/elixir.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/assets/icons/higher.svg: -------------------------------------------------------------------------------- 1 | 8 | 13 | 14 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /src/assets/icons/node.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/assets/icons/quotationMarks.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/assets/icons/react.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/assets/icons/warning.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/assets/images/logo.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/assets/images/spoiler.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | -------------------------------------------------------------------------------- /src/components/Cursor/index.tsx: -------------------------------------------------------------------------------- 1 | import { ReactElement, useEffect, useState } from 'react' 2 | 3 | import { useTrail } from 'react-spring' 4 | import onTouch from './onTouch' 5 | 6 | import { Cursor, CursorSphere } from './styles' 7 | 8 | interface CursorProps { 9 | color?: string 10 | } 11 | 12 | interface Event extends MouseEvent { 13 | path: HTMLElement[] 14 | } 15 | // const fast = { tension: 1200, friction: 40 } 16 | // const slow = { mass: 10, tension: 200, friction: 40 } 17 | const trans = (x: number, y: number) => 18 | `translate3d(${x}px,${y}px,0) translate3d(-50%,-50%,0)` 19 | 20 | const disable = ['button', 'input'] 21 | 22 | function CursorComponent({ color }: CursorProps): ReactElement { 23 | const [disabled, setDisabled] = useState(false) 24 | const [trail, set] = useTrail<{ xy: number[] }>(2, () => ({ 25 | xy: [0, 0] 26 | // config: i => (Number(i) === 0 ? fast : slow) 27 | })) 28 | 29 | const style = { 30 | color 31 | } 32 | 33 | useEffect(() => { 34 | // window.addEventListener('touchmove', onTouch) 35 | 36 | window.addEventListener('mousemove', (event: Event) => { 37 | window.document.body.style.cursor = 'none' 38 | 39 | const { pageX, clientY } = event 40 | const elem = event.path[0] 41 | setDisabled(disable.includes(elem.tagName.toLocaleLowerCase())) 42 | 43 | set({ xy: [pageX, clientY] }) 44 | }) 45 | }, []) 46 | 47 | return ( 48 | !disabled && ( 49 | <> 50 | 54 | 58 | 59 | ) 60 | ) 61 | } 62 | 63 | CursorComponent.prototype = { 64 | color: '#000' 65 | } 66 | 67 | export default CursorComponent 68 | -------------------------------------------------------------------------------- /src/components/Cursor/onTouch.ts: -------------------------------------------------------------------------------- 1 | export default function onTouch(event: TouchEvent): void { 2 | // event.preventDefault() 3 | if ( 4 | event.touches.length > 1 || 5 | (event.type === 'touchend' && event.touches.length > 0) 6 | ) { 7 | return 8 | } 9 | 10 | const newEvent = document.createEvent('MouseEvents') 11 | let type = null 12 | let touch: Touch = null 13 | 14 | switch (event.type) { 15 | case 'touchstart': 16 | type = 'mousedown' 17 | touch = event.changedTouches[0] 18 | break 19 | case 'touchmove': 20 | type = 'mousemove' 21 | touch = event.changedTouches[0] 22 | break 23 | case 'touchend': 24 | type = 'mouseup' 25 | touch = event.changedTouches[0] 26 | break 27 | } 28 | 29 | newEvent.initMouseEvent( 30 | type, 31 | true, 32 | true, 33 | event.target.ownerDocument.defaultView, 34 | 0, 35 | touch.screenX, 36 | touch.screenY, 37 | touch.clientX, 38 | touch.clientY, 39 | event.ctrlKey, 40 | event.altKey, 41 | event.shiftKey, 42 | event.metaKey, 43 | 0, 44 | null 45 | ) 46 | event.target.dispatchEvent(newEvent) 47 | } 48 | -------------------------------------------------------------------------------- /src/components/Cursor/styles.ts: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components' 2 | 3 | import { animated } from 'react-spring' 4 | 5 | interface Props { 6 | color?: string 7 | } 8 | const CursorDefault = styled(animated.div)` 9 | @media (any-pointer: fine) { 10 | display: block; 11 | position: fixed; 12 | top: 0; 13 | left: 0; 14 | pointer-events: none; 15 | transition: none !important; 16 | } 17 | 18 | z-index: 9999999; 19 | ` 20 | export const Cursor = styled(CursorDefault)` 21 | width: 6px; 22 | height: 6px; 23 | 24 | background: ${({ color = 'red' }) => color}; 25 | border-radius: 500px; 26 | ` 27 | 28 | export const CursorSphere = styled(CursorDefault)` 29 | width: 30px; 30 | height: 30px; 31 | 32 | border: 3px solid ${({ color = 'red' }) => color}; 33 | border-radius: 500px; 34 | 35 | transform: translate(-50%, -50%); 36 | ` 37 | -------------------------------------------------------------------------------- /src/components/GlobalAnimations/index.tsx: -------------------------------------------------------------------------------- 1 | import { ReactNode } from 'react' 2 | 3 | import SmoothScroll from '@/lib/react-smooth-scrolling' 4 | import Swiper, { SwiperSlide } from '@/components/Swiper' 5 | import Cursor from '@/components/Cursor' 6 | 7 | import { Container } from './styles' 8 | 9 | interface GlobalAnimationsProps { 10 | children: ReactNode 11 | } 12 | 13 | function GlobalAnimations({ children }: GlobalAnimationsProps) { 14 | return ( 15 | 16 | 17 | 18 | 19 | {children} 20 | {/* 27 | {children} 28 | */} 29 | 30 | 31 | ) 32 | } 33 | 34 | export default GlobalAnimations 35 | -------------------------------------------------------------------------------- /src/components/GlobalAnimations/styles.ts: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components' 2 | 3 | export const Container = styled.div` 4 | width: 100%; 5 | height: 100%; 6 | 7 | .swiper-container { 8 | width: 100%; 9 | height: 100%; 10 | 11 | max-height: 100vh; 12 | 13 | transition: all 2s; 14 | * { 15 | transition: all 2s; 16 | } 17 | } 18 | 19 | .swiper-slide { 20 | display: flex; 21 | flex-direction: column; 22 | justify-content: center; 23 | align-items: center; 24 | } 25 | 26 | & > .container { 27 | width: 100%; 28 | min-height: 100%; 29 | } 30 | ` 31 | -------------------------------------------------------------------------------- /src/components/PageTransition/index.tsx: -------------------------------------------------------------------------------- 1 | import React, { useEffect, useState } from 'react' 2 | 3 | import styled from 'styled-components' 4 | import Lottie from 'react-lottie' 5 | import { useTransition, animated, config, useSpring } from 'react-spring' 6 | 7 | import animation from '@/assets/animations/intro.json' 8 | import { useRouter } from '../../hooks/useRouter' 9 | 10 | export const PageTransition = ({ children, ...props }) => { 11 | const router = useRouter() 12 | const [finishing, setFinishing] = useState(false) 13 | const [spring, set] = useSpring<{ opacity: number; scale: number }>(() => ({ 14 | opacity: 0, 15 | scale: 0, 16 | config: { mass: 10, tension: 200, friction: 40 } 17 | })) 18 | 19 | const transitions = useTransition(router, router => router.pathname, { 20 | from: { opacity: 0 }, 21 | enter: { opacity: 1 }, 22 | leave: { opacity: 0 }, 23 | config: config.wobbly 24 | 25 | // from: { transform: 'translateY(-2000px)' }, 26 | // enter: { transform: 'translateY(0)' }, 27 | // leave: { transform: 'translateY(200px)' }, 28 | // config: config.stiff 29 | }) 30 | const defaultAnimationOptions = { 31 | loop: false, 32 | autoplay: true, 33 | animationData: animation, 34 | rendererSettings: { 35 | preserveAspectRatio: 'xMidYMid slice' 36 | } 37 | } 38 | 39 | useEffect(() => { 40 | if (finishing) { 41 | set({ opacity: 1, scale: 1 }) 42 | } 43 | }, [finishing]) 44 | return ( 45 | <> 46 | {transitions.map(({ item, props: style, key }) => { 47 | if (!item.components) { 48 | return null 49 | } 50 | 51 | const { Component, props } = item.components[item.pathname] 52 | 53 | return ( 54 | 55 | {!finishing && ( 56 | 57 | setFinishing(true) 63 | } 64 | ]} 65 | width="50%" 66 | height="auto" 67 | /> 68 | 69 | )} 70 | 71 | {finishing && ( 72 | 78 | {children( 79 | item ? { Component, pageProps: props && props.pageProps } : {} 80 | )} 81 | 82 | )} 83 | 84 | ) 85 | })} 86 | 87 | ) 88 | } 89 | 90 | const Page = styled(animated.div)` 91 | min-height: 100%; 92 | height: 100vh; 93 | 94 | & > div { 95 | height: inherit; 96 | } 97 | ` 98 | const LottieContainer = styled(animated.div)` 99 | position: fixed; 100 | top: 0; 101 | left: 0; 102 | width: 100vw; 103 | height: 100vh; 104 | 105 | background: #04d361; 106 | 107 | z-index: 10; 108 | 109 | display: flex; 110 | justify-content: center; 111 | align-items: center; 112 | ` 113 | -------------------------------------------------------------------------------- /src/components/SEO.tsx: -------------------------------------------------------------------------------- 1 | import Head from 'next/head' 2 | 3 | interface SEOProps { 4 | title: string 5 | description?: string 6 | keywords?: string[] 7 | image?: string 8 | shouldExcludeTitleSuffix?: boolean 9 | shouldIndexPage?: boolean 10 | } 11 | 12 | export default function SEO({ 13 | title, 14 | description, 15 | keywords, 16 | image, 17 | shouldExcludeTitleSuffix = false, 18 | shouldIndexPage = true 19 | }: SEOProps) { 20 | const pageTitle = `${title} ${ 21 | !shouldExcludeTitleSuffix && '| Acelere sua carreira' 22 | }` 23 | const pageImage = image 24 | ? image.startsWith('/') 25 | ? `${process.env.NEXT_PUBLIC_SITE_URL}${image}` 26 | : image 27 | : null 28 | 29 | return ( 30 | 31 | {pageTitle} 32 | {description && } 33 | {pageImage && } 34 | {keywords && ( 35 | 36 | )} 37 | 38 | {!shouldIndexPage && } 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 80 | 81 | ) 82 | } 83 | -------------------------------------------------------------------------------- /src/components/Swiper.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | // import Swiper core and required modules 3 | import SwiperCore, { 4 | Navigation, 5 | Pagination, 6 | Scrollbar, 7 | A11y, 8 | SwiperOptions 9 | } from 'swiper' 10 | 11 | import { Swiper as SwiperComponent, SwiperSlide } from 'swiper/react' 12 | import 'swiper/swiper.min.css' 13 | 14 | // install Swiper modules 15 | SwiperCore.use([Navigation, Pagination, Scrollbar, A11y]) 16 | 17 | interface SwiperProps extends SwiperOptions { 18 | children?: React.ReactNode 19 | } 20 | 21 | export { SwiperSlide } 22 | 23 | export default function Swiper({ 24 | children, 25 | ...props 26 | }: SwiperProps): React.ReactElement { 27 | return ( 28 | console.log(swiper)} 39 | // onSlideChange={() => console.log('slide change')} 40 | > 41 | {children} 42 | 43 | ) 44 | } 45 | -------------------------------------------------------------------------------- /src/components/TestimoniesSlide/index.tsx: -------------------------------------------------------------------------------- 1 | import QuotationMarks from '@/assets/icons/quotationMarks.svg' 2 | import Arrow from '@/assets/icons/arrow.svg' 3 | 4 | import Swiper, { SwiperSlide } from '@/components/Swiper' 5 | import { Container, Comment } from './styles' 6 | 7 | interface TestimoniesSlideProps { 8 | testimonies: { 9 | name: string 10 | testimony: string 11 | }[][] 12 | } 13 | 14 | function TestimoniesSlide({ testimonies }: TestimoniesSlideProps) { 15 | return ( 16 | 17 | 24 | {testimonies.map((testimonyArray, index) => ( 25 | 26 | {testimonyArray.map((testimony, testimonyIndex) => ( 27 | 28 | 29 | 30 |
31 |

{testimony.testimony}

32 |
33 | {testimony.name} 34 |
35 |
36 |
37 | ))} 38 |
39 | ))} 40 |
41 | 42 |
43 | 51 | 54 |
55 |
56 | ) 57 | } 58 | 59 | export default TestimoniesSlide 60 | -------------------------------------------------------------------------------- /src/components/TestimoniesSlide/styles.ts: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components' 2 | 3 | export const Container = styled.div` 4 | overflow: hidden; 5 | 6 | cursor: grab; 7 | 8 | &:active { 9 | cursor: grabbing; 10 | } 11 | 12 | .testimonyOptionsArrow { 13 | width: 100%; 14 | margin-top: 8px; 15 | padding-bottom: 2px; 16 | 17 | display: flex; 18 | justify-content: space-between; 19 | align-items: flex-end; 20 | 21 | z-index: 5; 22 | 23 | button { 24 | margin-left: 64px; 25 | padding: 6px; 26 | 27 | display: flex; 28 | align-items: center; 29 | 30 | font-size: 16px; 31 | font-weight: 700; 32 | line-height: 26px; 33 | text-transform: uppercase; 34 | 35 | background-color: transparent; 36 | color: ${props => props.theme.colors.primary.normal}; 37 | border: 0; 38 | 39 | cursor: pointer; 40 | 41 | &:disabled { 42 | color: ${props => props.theme.colors.icons}; 43 | } 44 | 45 | svg { 46 | margin-left: 16px; 47 | } 48 | } 49 | } 50 | 51 | @media (max-width: 960px) { 52 | .testimonyOptionsArrow button { 53 | margin-left: 0; 54 | } 55 | } 56 | ` 57 | 58 | export const Comment = styled.div` 59 | display: flex; 60 | 61 | & > svg { 62 | margin-right: 32px; 63 | } 64 | &:nth-of-type(2) .testimonyContent > div { 65 | border-bottom: 1px solid ${props => props.theme.colors.background.lighter}; 66 | } 67 | 68 | .testimonyContent { 69 | p { 70 | max-width: 576px; 71 | } 72 | & > div { 73 | display: flex; 74 | 75 | margin-top: 24px; 76 | padding-bottom: 64px; 77 | 78 | strong { 79 | margin-right: 24px; 80 | 81 | font-size: 18px; 82 | font-weight: 700; 83 | line-height: 21px; 84 | 85 | color: ${props => props.theme.colors.secondary}; 86 | } 87 | } 88 | } 89 | 90 | .swiper-container { 91 | width: 100%; 92 | height: 100%; 93 | 94 | .swiper-wrapper { 95 | display: flex; 96 | } 97 | } 98 | 99 | @media (max-width: 960px) { 100 | & > svg { 101 | margin-right: 0px; 102 | } 103 | } 104 | ` 105 | -------------------------------------------------------------------------------- /src/contexts/Global.tsx: -------------------------------------------------------------------------------- 1 | import React, { createContext, useState, useContext, useEffect } from 'react' 2 | 3 | import { ThemeProvider } from 'styled-components' 4 | 5 | import GlobalStyle from '@/styles/GlobalStyle' 6 | import { DarkTheme, LightTheme } from '@/styles/theme' 7 | 8 | interface GlobalContextData { 9 | handleThemeChanges(): void 10 | } 11 | 12 | const GlobalContext = createContext({} as GlobalContextData) 13 | 14 | export const GlobalProvider: React.FC = ({ children }) => { 15 | const [theme, setTheme] = useState(DarkTheme) 16 | 17 | function handleThemeChanges() { 18 | setTheme(theme.title === 'Light' ? DarkTheme : LightTheme) 19 | } 20 | 21 | return ( 22 | 23 | 24 | 25 | {children} 26 | 27 | 28 | ) 29 | } 30 | 31 | // Hook próprio 32 | export function useGlobal(): GlobalContextData { 33 | const context = useContext(GlobalContext) 34 | 35 | return context 36 | } 37 | -------------------------------------------------------------------------------- /src/contexts/index.tsx: -------------------------------------------------------------------------------- 1 | import { ReactNode } from 'react' 2 | 3 | import { RouterContextProvider } from '@/hooks/useRouter' 4 | import { GlobalProvider } from './Global' 5 | 6 | interface Props { 7 | children: ReactNode 8 | } 9 | function AppProvider({ children }: Props) { 10 | return ( 11 | 12 | {children} 13 | 14 | ) 15 | } 16 | 17 | export default AppProvider 18 | -------------------------------------------------------------------------------- /src/data.ts: -------------------------------------------------------------------------------- 1 | import React from '@/assets/icons/react.svg' 2 | import Node from '@/assets/icons/node.svg' 3 | import Elixir from '@/assets/icons/elixir.svg' 4 | 5 | export default { 6 | trails: [ 7 | { 8 | Icon: React, 9 | title: 'Ignite *ReactJS*', 10 | stack: 'Front End', 11 | descriptions: `Se o seu objetivo está alinhado com o front-end, e você deseja 12 | construir interfaces modernas e reativas na web utilizando uma 13 | biblioteca modular e escalável, essa trilha é para você.`, 14 | teacher: 'Diego Fernandes', 15 | teacherDescription: `Responsável pela área de tecnologia na Rocketseat - onde 16 | utilizamos principalmente Node.js e ReactJS para atender 17 | quase meio milhão de usuários na nossa plataforma - é o 18 | educador que vai te guiar no Ignite ReactJS.`, 19 | teacherAvatar: '/images/diego-fernandes.jpg' 20 | }, 21 | { 22 | Icon: Node, 23 | title: 'Ignite *NodeJS*', 24 | stack: 'Back End', 25 | descriptions: 26 | 'Se o seu objetivo está alinhado com o back-end, e você deseja construir arquiteturas escaláveis e simples para a web utilizando uma linguagem flexível e popular, essa trilha é para você.', 27 | teacher: 'Daniele Evangelista', 28 | teacherDescription: 29 | 'Formada em Sistemas de Informação e há 11 anos atuando no mercado como programadora, foi responsável pelo time de educação aqui na Rocketseat e é a educadora que vai te guiar no Ignite Node.js.', 30 | teacherAvatar: '/images/daniele-evangelista.jpeg' 31 | }, 32 | { 33 | Icon: Elixir, 34 | title: 'Ignite *Elixir*', 35 | stack: 'Back End', 36 | descriptions: 37 | 'SSe o seu objetivo está alinhado com o back-end, e você deseja construir aplicações distribuídas, escaláveis e tolerantes a falhas utilizando programação funcional, essa trilha é para você.', 38 | teacher: 'Rafael Camarda', 39 | teacherDescription: 40 | 'Formado em Engenharia de Computação pela Universidade Federal de Ouro Preto, iniciou sua jornada de ensino ainda na universidade. Há 6 anos no mercado como programador, é o educador que vai te guiar Ignite Elixir.', 41 | teacherAvatar: '/images/rafael-camarda.png' 42 | } 43 | ], 44 | testimonies: [ 45 | [ 46 | { 47 | name: 'Aleixa Caroline', 48 | testimony: 49 | 'Em menos de um ano, saí de estudante de engenharia da computação que não sabia quase nada de programação, para CTO de uma startup em BH. Isso mostra a suma importancia que o GoStack teve pra minha carreira e pra minha vida. Jamais imaginaria estar onde estou com apenas 23 anos de idade. Que a Rocketseat continue levando conhecimento para as pessoas da mesma forma que proporcionou para mim. Obrigada.' 50 | }, 51 | { 52 | name: 'Bruno Henrique', 53 | testimony: 54 | 'Além de mudar de carreira e ter de volta um propósito, hoje eu tenho uma remuneração que nunca tive mesmo tendo anos de experiência na minha antiga área. Outro ponto importante é que com a comunidade do GoStack eu aprendi a aprender, inclusive a ter esse senso de comunidade, de compartilhar conhecimento e isso me faz ser um desenvolvedor melhor a cada dia.' 55 | } 56 | ], 57 | [ 58 | { 59 | name: 'Mellisa Fernandes', 60 | testimony: 61 | 'Eu já era programadora quando conheci a Rocketseat e gostei muito de como o conteúdo era apresentado. Resolvi investir no curso para aprender a stack que vcs ensinavam e foi um ótimo investimento! Aprendi muito e de maneira bem rápida, consegui um novo emprego em uma empresa incrivel e trabalho com o que eu amo nas tecnologias que eu mais gosto no momento. Só tenho a agradecer a toda a equipe por tornar isso possível!' 62 | }, 63 | { 64 | name: 'Eduardo Diniz', 65 | testimony: 66 | 'Em 2018 meu adblock parou de funcionar, e nesse dia apareceu o diego falando "fala dev" pra mim, e esse anuncio, esse dia mudou minha vida por completo, eu dupliquei meu salario, virei remoto, aconteceu tudo que o Diego havia falado que acontecia com os alunos... Foi simplesmente a melhor decisão da minha vida, e o maior investimento profissional pra mim.' 67 | } 68 | ], 69 | [ 70 | { 71 | name: 'Daniel Moreira', 72 | testimony: 73 | 'Com a ajuda do Rocketseat consegui dobrar meu salário em apenas 4 meses, conseguindo uma oportunidade melhor e tudo graças aos conhecimentos em typescript e Javascript.' 74 | }, 75 | { 76 | name: 'Caroline da Cunha', 77 | testimony: 78 | 'Trabalhava como analista de suporte e em plena pandemia perdi o emprego e decidi que era o momento de ir atrás de um velho sonho que era trabalhar com desenvolvimento. Conheci a rocketseat através do instagram, participei do NLW e me apaixonei pela didática e conteúdo, adquiri o GoStack e já consegui uma oportunidade na área de desenvolvimento, só tenho a agradecer a rocketseat por abrir a minha mente e me oferecer uma experiência enriquecedora.' 79 | } 80 | ], 81 | [ 82 | { 83 | name: 'Eder Rodrigo', 84 | testimony: 85 | 'Depois de ficar 1 ano desempregado, resolvi fazer minha transição profissional, mudando da construção civil para a área de tecnologia. E depois de 6 meses de empresa, fiz o GoStack, e agora com 1 ano e meio de carreira, já ganho 60% mais do que ganhava na minha área de formação!' 86 | }, 87 | { 88 | name: 'Allan Mendes', 89 | testimony: 90 | 'O curso da RocketSeat me levou para o próximo nível. Me sinto 100% confortável para criar um sistema inteiro sozinho e também escalá-lo com as melhores práticas. Impactou bastante na minha carreira como Product Manager, pois me atualizou em relação as tecnologias que eu conhecia e usava e pude ter uma dinâmica muito mais produtiva com o time de desenvolvimento.' 91 | } 92 | ] 93 | ], 94 | 95 | testimonyVideos: [ 96 | { 97 | videoUrl: 98 | 'https://www.youtube.com/embed/d5j-d3tg_nQ?showinfo=0&rel=0&modestbranding=0', 99 | testimonyName: 'Camila Jesus' 100 | }, 101 | { 102 | videoUrl: 'https://www.youtube.com/embed/zvtShzuXQvE', 103 | testimonyName: 'Aryclenio Xavier' 104 | }, 105 | { 106 | videoUrl: 107 | 'https://www.youtube.com/embed/RPT0i1QQK90?showinfo=0&rel=0&modestbranding=0', 108 | testimonyName: 'Alexia karoline' 109 | }, 110 | { 111 | videoUrl: 112 | 'https://www.youtube.com/embed/ncGFtSRRqIQ?showinfo=0&rel=0&modestbranding=0', 113 | testimonyName: 'Jose Luiz' 114 | }, 115 | { 116 | videoUrl: 117 | 'https://www.youtube.com/embed/znKkfDqrXII?showinfo=0&rel=0&modestbranding=0', 118 | testimonyName: 'Breno Rios' 119 | }, 120 | { 121 | videoUrl: 122 | 'https://www.youtube.com/embed/PYxZTKJPOuM?showinfo=0&rel=0&modestbranding=0', 123 | testimonyName: 'Melissa Fernandes' 124 | }, 125 | { 126 | videoUrl: 127 | 'https://www.youtube.com/embed/vgl5CofxvGA?showinfo=0&rel=0&modestbranding=0', 128 | testimonyName: 'Jonas da Silva' 129 | } 130 | ] 131 | } 132 | -------------------------------------------------------------------------------- /src/hooks/useResize.tsx: -------------------------------------------------------------------------------- 1 | import { useState, useEffect, useCallback } from 'react' 2 | 3 | const useResize = (myRef: React.RefObject) => { 4 | const getWidth = useCallback(() => myRef?.current?.offsetWidth, [myRef]) 5 | 6 | const [width, setWidth] = useState(undefined) 7 | 8 | useEffect(() => { 9 | const handleResize = () => { 10 | setWidth(getWidth()) 11 | } 12 | 13 | if (myRef.current) { 14 | setWidth(getWidth()) 15 | } 16 | 17 | window.addEventListener('resize', handleResize) 18 | 19 | return () => { 20 | window.removeEventListener('resize', handleResize) 21 | } 22 | }, [myRef, getWidth]) 23 | 24 | return width && width > 25 ? width - 25 : width 25 | } 26 | 27 | export default useResize 28 | -------------------------------------------------------------------------------- /src/hooks/useRouter.tsx: -------------------------------------------------------------------------------- 1 | /* eslint-disable @typescript-eslint/ban-ts-comment */ 2 | // @ts-ignore 3 | 4 | import React, { useContext } from 'react' 5 | import { withRouter } from 'next/router' 6 | 7 | import Home from '@/pages' 8 | 9 | const Context = React.createContext({ 10 | asPath: '/', 11 | basePath: '', 12 | components: { 13 | '/': Home 14 | }, 15 | isFallback: false, 16 | isReady: true, 17 | pathname: '/', 18 | route: '/' 19 | }) 20 | 21 | interface Route { 22 | asPath: string 23 | back(): void 24 | basePath: string 25 | beforePopState(): void 26 | components: unknown 27 | defaultLocale: undefined 28 | events: { on(): void; off(): void; emit(): void } 29 | isFallback: false 30 | isReady: boolean 31 | locale: undefined 32 | locales: undefined 33 | pathname: string 34 | prefetch(): void 35 | push(): void 36 | query: unknown 37 | reload(): void 38 | replace(): void 39 | route: string 40 | } 41 | 42 | const Provider = ({ router, children }) => ( 43 | {children} 44 | ) 45 | 46 | export const useRouter = (): Route => useContext(Context) 47 | export const RouterContextProvider = withRouter(Provider) 48 | -------------------------------------------------------------------------------- /src/lib/createOgImage.ts: -------------------------------------------------------------------------------- 1 | import { createHash } from 'crypto' 2 | import fs from 'fs' 3 | import api from '@/services/api' 4 | 5 | interface createOgImageProps { 6 | path: string 7 | baseUrl?: string 8 | } 9 | 10 | const isDev = process.env.NODE_ENV === 'development' 11 | async function createOgImage({ 12 | path, 13 | baseUrl = process.env.NEXT_PUBLIC_SITE_URL 14 | }: createOgImageProps): Promise { 15 | const url = `${baseUrl}${path}` 16 | const hash = createHash('md5').update(url).digest('hex') + 'OG-Template' 17 | 18 | const ogImageDir = './public/images/og' 19 | const imagePath = `${ogImageDir}/${hash}.png` 20 | let publicPath = `${baseUrl}/images/og/${hash}.png` 21 | publicPath = publicPath.includes('http') 22 | ? publicPath 23 | : `https://${publicPath}` 24 | 25 | try { 26 | fs.statSync(imagePath) 27 | return publicPath 28 | } catch (error) { 29 | // file does not exists, so we create it 30 | } 31 | 32 | const ogImage = await api.post('ogImage', { 33 | frontendUrl: String(url).replace(/\n/g, '').replace(/ /g, '') 34 | }) 35 | 36 | fs.mkdirSync(ogImageDir, { recursive: true }) 37 | fs.writeFileSync(imagePath, ogImage.data.binaryData, 'binary') 38 | 39 | return publicPath 40 | } 41 | 42 | export default createOgImage 43 | -------------------------------------------------------------------------------- /src/lib/react-smooth-scrolling/index.d.ts: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | interface SmoothProviderProps { 3 | /** 4 | * Default ease is `0.1`. More ease means more stiffness. 5 | */ 6 | ease?: number 7 | /** 8 | * Enable distortion 9 | */ 10 | skew: boolean 11 | } 12 | export declare const SmoothProvider: React.FC 13 | export {} 14 | -------------------------------------------------------------------------------- /src/lib/react-smooth-scrolling/index.ts: -------------------------------------------------------------------------------- 1 | // Credits to Akram Khalid 2 | import React, { useEffect, useRef, useCallback } from 'react' 3 | import useWindowSize from './useWindowSize' 4 | let __assign = 5 | (this && this.__assign) || 6 | function () { 7 | __assign = 8 | Object.assign || 9 | function (t) { 10 | for (let s, i = 1, n = arguments.length; i < n; i++) { 11 | s = arguments[i] 12 | for (const p in s) { 13 | if (Object.prototype.hasOwnProperty.call(s, p)) { 14 | t[p] = s[p] 15 | } 16 | } 17 | } 18 | return t 19 | } 20 | return __assign.apply(this, arguments) 21 | } 22 | const __rest = 23 | (this && this.__rest) || 24 | function (s, e) { 25 | const t = {} 26 | for (const p in s) { 27 | if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) { 28 | t[p] = s[p] 29 | } 30 | } 31 | if (s != null && typeof Object.getOwnPropertySymbols === 'function') { 32 | for (let i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { 33 | if ( 34 | e.indexOf(p[i]) < 0 && 35 | Object.prototype.propertyIsEnumerable.call(s, p[i]) 36 | ) { 37 | t[p[i]] = s[p[i]] 38 | } 39 | } 40 | } 41 | return t 42 | } 43 | 44 | export default function SmoothProvider(_a) { 45 | const ease = _a.ease 46 | const skew = _a.skew 47 | const children = _a.children 48 | const props = __rest(_a, ['ease', 'skew', 'children']) 49 | // Hook to grab window size 50 | const size = useWindowSize() 51 | useRef() 52 | // Ref for parent div and scrolling div 53 | const scrollContainer = useRef(null) 54 | // Configs 55 | const data = { 56 | ease: Math.max( 57 | 0, 58 | Math.min(1, ease !== null && ease !== undefined ? ease : 0.1) 59 | ), 60 | current: 0, 61 | previous: 0, 62 | rounded: 0 63 | } 64 | // Scrolling 65 | const skewScrolling = useCallback( 66 | function () { 67 | let _a 68 | // Set Current to the scroll position amount 69 | data.current = window.scrollY 70 | // Set Previous to the scroll previous position 71 | data.previous += (data.current - data.previous) * data.ease 72 | // Set rounded to 73 | data.rounded = Math.round(data.previous * 100) / 100 74 | // Difference between 75 | const difference = data.current - data.rounded 76 | const acceleration = difference / size.width 77 | const velocity = +acceleration 78 | const graus = velocity * (isMobile() ? 0.5 : 7.5) 79 | const skewing = skew ? velocity * graus : 0 80 | // Assign skew and smooth scrolling to the scroll container 81 | if ( 82 | (_a = scrollContainer.current) === null || _a === undefined 83 | ? undefined 84 | : _a.style 85 | ) { 86 | const translate3d = 'translate3d(0, -' + data.rounded + 'px, 0)' 87 | const skewY = 'skewY(' + skewing + 'deg)' 88 | scrollContainer.current.style.transform = translate3d + ' ' + skewY 89 | } 90 | // loop vai raf 91 | requestAnimationFrame(skewScrolling) 92 | }, 93 | [data, size.width] 94 | ) 95 | // Run scrollrender once page is loaded. 96 | useEffect( 97 | function () { 98 | requestAnimationFrame(skewScrolling) 99 | }, 100 | [skewScrolling] 101 | ) 102 | // Set the height of the body to the height of the scrolling div 103 | const setBodyHeight = function () { 104 | let _a 105 | document.body.style.height = 106 | ((_a = scrollContainer.current) === null || _a === undefined 107 | ? undefined 108 | : _a.getBoundingClientRect().height) + 'px' 109 | } 110 | // set the height of the body. 111 | useEffect( 112 | function () { 113 | setBodyHeight() 114 | }, 115 | [size.height] 116 | ) 117 | 118 | return React.createElement('div', { ref: scrollContainer }, children) 119 | } 120 | 121 | function isMobile() { 122 | let check = false 123 | ;(function (a) { 124 | if ( 125 | /(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test( 126 | a 127 | ) || 128 | /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test( 129 | a.substr(0, 4) 130 | ) 131 | ) { 132 | check = true 133 | } 134 | })(navigator.userAgent || navigator.vendor || window.opera) 135 | return check 136 | } 137 | -------------------------------------------------------------------------------- /src/lib/react-smooth-scrolling/useWindowSize.ts: -------------------------------------------------------------------------------- 1 | import { useState, useEffect } from 'react' 2 | 3 | interface UseWindowSize { 4 | width: number 5 | height: number 6 | } 7 | 8 | export default function useWindowSize(): UseWindowSize { 9 | const [windowSize, setWindowSize] = useState({ 10 | width: 0, 11 | height: 0 12 | }) 13 | 14 | function getSize() { 15 | const window = document.querySelector('#__next') as HTMLDivElement 16 | return { 17 | width: window.offsetWidth, 18 | height: window.offsetHeight 19 | } 20 | } 21 | 22 | useEffect(() => { 23 | const window = document.querySelector('#__next') as HTMLDivElement 24 | 25 | function handleResize() { 26 | console.log(getSize()) 27 | setWindowSize(getSize()) 28 | } 29 | handleResize() 30 | 31 | window.addEventListener('resize', handleResize) 32 | return () => window.removeEventListener('resize', handleResize) 33 | }, []) 34 | return windowSize 35 | } 36 | -------------------------------------------------------------------------------- /src/pages/_app.tsx: -------------------------------------------------------------------------------- 1 | import { AppProps } from 'next/app' 2 | 3 | import { PageTransition } from '@/components/PageTransition' 4 | import GlobalAnimations from '@/components/GlobalAnimations' 5 | 6 | import Context from '@/contexts' 7 | 8 | export default function App({ 9 | Component: SsrComponent, 10 | pageProps: ssrPageProps 11 | }: AppProps) { 12 | return ( 13 | 14 | 15 | {({ Component, pageProps }) => ( 16 | 17 | {Component ? ( 18 | 19 | ) : ( 20 | 21 | )} 22 | 23 | )} 24 | 25 | 26 | {/* 27 | 28 | */} 29 | 30 | ) 31 | } 32 | -------------------------------------------------------------------------------- /src/pages/_document.tsx: -------------------------------------------------------------------------------- 1 | import Document, { 2 | DocumentContext, 3 | Html, 4 | Head, 5 | Main, 6 | NextScript 7 | } from 'next/document' 8 | import { ServerStyleSheet } from 'styled-components' 9 | 10 | export default class MyDocument extends Document { 11 | static async getInitialProps(ctx: DocumentContext) { 12 | const sheet = new ServerStyleSheet() 13 | const originalRenderPage = ctx.renderPage 14 | 15 | try { 16 | ctx.renderPage = () => 17 | originalRenderPage({ 18 | enhanceApp: App => props => sheet.collectStyles() 19 | }) 20 | 21 | const initialProps = await Document.getInitialProps(ctx) 22 | 23 | return { 24 | ...initialProps, 25 | styles: ( 26 | <> 27 | {initialProps.styles} 28 | {sheet.getStyleElement()} 29 | 30 | ) 31 | } 32 | } finally { 33 | sheet.seal() 34 | } 35 | } 36 | 37 | render(): JSX.Element { 38 | return ( 39 | 40 | 41 | 42 | 47 | 51 | 55 | 56 | 57 |
58 | 59 | 60 | 61 | ) 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/pages/index.tsx: -------------------------------------------------------------------------------- 1 | import Logo from '@/assets/images/logo.svg' 2 | import AttentionIcon from '@/assets/icons/attention.svg' 3 | import Higher from '@/assets/icons/higher.svg' 4 | import Warning from '@/assets/icons/warning.svg' 5 | import Check from '@/assets/icons/check.svg' 6 | 7 | import SEO from '@/components/SEO' 8 | import { Container } from '@/styles/pages/Home' 9 | 10 | import TestimoniesSlide from '@/components/TestimoniesSlide' 11 | 12 | import Data from '@/data' 13 | 14 | const App = () => { 15 | return ( 16 | 17 | 21 | 22 |
23 |
24 |
25 |

26 | Acelere 27 |
28 | sua carreira. 29 |

30 |

31 | Currículo alinhado com o mercado e as atitudes que vão te ajudar a 32 | acelerar na direção dos seus objetivos como dev. 33 |

34 | 35 | 52 |
53 |
54 |
55 | 56 |

57 | As matrículas serão
abertas em breve. 58 |

59 |
60 |
61 | 62 |
63 |
64 |
65 |
66 | 67 |
68 |
69 |
70 |
71 |
72 | Currículo 73 | 74 | Profissional, atualizado, 75 |
pragmático 76 |
77 |
78 |
79 | Metodologia 80 | Foco, prática, grupo 81 |
82 |
83 | Atitude 84 | 85 | Clareza, disciplina,
paixão 86 |
87 |
88 |
89 | 90 | 91 | 92 |
93 |
94 |

Como você vai aprender

95 |

96 | O objetivo do Ignite é desenvolver habilidades que vão acelerar a 97 | sua carreira. 98 |

99 |
100 |
101 |
102 | 103 |
104 |
105 |
106 |

Por que escolher o Ignite

107 |
108 |
    109 |
  • 110 | 117 | 124 | 125 | 132 | 133 | 140 | 141 | 148 | 149 |
    150 |

    Boas práticas

    151 |

    152 | Chega de aprender por aprender, conhecimento precisa estar 153 | alinhado com as necessidades do mercado. 154 |

    155 |
    156 |
  • 157 |
  • 158 | 165 | 172 | 173 | 180 | 181 |
    182 |

    Certificado

    183 |

    184 | Receba a certificação de desempenho da Rocketseat reconhecida 185 | por grandes empresas. 186 |

    187 |
    188 |
  • 189 |
  • 190 | 197 | 204 | 205 | 212 | 213 |
    214 |

    Conteúdo prático

    215 |

    216 | Aulas gravadas em vídeo pra você ir a fundo e dominar na 217 | prática a tecnologia que você escolheu. 218 |

    219 |
    220 |
  • 221 |
  • 222 | 229 | 236 | 237 | 244 | 245 |
    246 |

    Conteúdo de soft skills

    247 |

    248 | Desenvolva as habilidades não técnicas que vão ser essenciais 249 | pra você se destacar como profissional. 250 |

    251 |
    252 |
  • 253 |
  • 254 | 261 | 268 | 269 | 276 | 277 |
    278 |

    Seja desafiado

    279 |

    280 | A cada módulo você terá que pôr à prova seus estudos através 281 | de atividades e desafios. 282 |

    283 |
    284 |
  • 285 |
  • 286 | 293 | 300 | 308 | 316 | 317 |
    318 |

    Fórum

    319 |

    320 | Um fórum exclusivo para você tirar todas as suas dúvidas 321 | técnicas com o nosso suporte e outros alunos. 322 |

    323 |
    324 |
  • 325 |
326 |
327 |
328 | 329 |
330 |
331 |
332 |

Confira as tecnologias

333 |
334 |
    335 | {Data.trails.map((trail, index) => ( 336 |
  • 337 |
    338 | {trail.Icon({})} 339 |

    ') 344 | .replace('*', '') 345 | }} 346 | >

    347 | Front End 348 |

    {trail.descriptions}

    349 | 350 |
    351 | Educador: 352 |
    353 | {trail.teacher} 354 |

    {trail.teacher}

    355 |
    356 |

    {trail.teacherDescription}

    357 |
    358 | 377 |
    378 |
  • 379 | ))} 380 |
381 |
382 |
383 | 384 |
385 |
386 |
387 |

388 | Programação vai muito além do código 389 |

390 |

391 | Durante o Ignite desenvolvemos habilidades e atitudes que vão além 392 | do código, para te ajudar a se destacar como profissional. 393 |

394 |

395 | Conteúdos de soft skills são disponibilizados semanalmente, 396 | trazendo desafios práticos para o desenvolvimento da aluna ou 397 | aluno em conseguir evoluir nas habilidades de comunicação, 398 | organização, criatividade, foco e produtividade. 399 |

400 |
401 |
402 | Higher 403 |
404 |
405 |
406 | 407 |
408 |
409 |
410 | 411 |
412 |
413 |
414 |

415 | Nosso compromisso é com seu resultado 416 |

417 |

418 | Os depoimentos a seguir são de alunos do GoStack. 419 |

420 |
421 |
422 | 423 |
424 |
425 |
426 | 427 |
428 |
429 |
    430 | {Data.testimonyVideos.map((props, index) => ( 431 |
  • 432 |
    433 | 439 |
    440 |

    {props.testimonyName}

    441 |
  • 442 | ))} 443 |
444 |
445 |
446 | 447 |
448 |
449 | 450 |
451 |

Esse não é um programa para iniciantes.

452 |

453 | Se você ainda não domina os fundamentos do desenvolvimento web, 454 | comece de graça pelo Discover 455 |

456 |
457 |
458 |
459 | 460 |
461 |
462 |
463 |

Benefícios do Ignite

464 |
465 |
    466 |
  • 467 | 468 |
    Conteúdo super atualizado
    469 |
  • 470 |
  • 471 | 472 |
    Certificado reconhecido
    473 |
  • 474 |
  • 475 |
    476 | Conteúdo de 477 |
    soft skills 478 |
    479 |
  • 480 |
  • 481 | 482 |
    Currículo alinhado com o mercado
    483 |
  • 484 |
  • 485 | 486 |
    Grupo exclusivo
    487 |
  • 488 |
  • 489 | 490 |
    Conteúdo prático
    491 |
  • 492 |
  • 493 | 494 |
    Direto ao ponto e do jeito certo
    495 |
  • 496 |
  • 497 | 498 |
    Suporte exclusivo no fórum
    499 |
  • 500 |
  • 501 | 502 |
    Desafios práticos
    503 |
  • 504 |
505 |
506 |
507 |
508 | ) 509 | } 510 | export default App 511 | -------------------------------------------------------------------------------- /src/styles/GlobalStyle.ts: -------------------------------------------------------------------------------- 1 | import { createGlobalStyle } from 'styled-components' 2 | import { rgba } from 'polished' 3 | 4 | export default createGlobalStyle` 5 | * { 6 | margin: 0; 7 | padding: 0; 8 | box-sizing: border-box; 9 | transition: background-color 0.2s linear; 10 | } 11 | html, body, #__next { 12 | /* scroll-behavior: smooth; */ 13 | 14 | max-height: 100vh; 15 | /* overflow: hidden; */ 16 | 17 | background: ${props => props.theme.colors.background.normal}; 18 | color: ${props => props.theme.colors.text.normal}; 19 | 20 | font-family: Roboto, sans-serif !important; 21 | } 22 | 23 | @media (max-width: 1080px){ 24 | html { 25 | font-size: 93.75%; 26 | } 27 | } 28 | 29 | @media (max-width: 720px){ 30 | html { 31 | font-size: 87.5%; 32 | } 33 | } 34 | 35 | 36 | body, input, textarea, button, select, a { 37 | color: inherit; 38 | outline: none; 39 | 40 | text-decoration: none; 41 | font: 400 1rem Roboto, sans-serif; 42 | } 43 | h1, h2, h3, h4, h5, h6 { 44 | color: ${({ theme }) => theme.colors.text.normal}; 45 | } 46 | button { 47 | cursor: pointer; 48 | } 49 | 50 | input[type=search] { 51 | -webkit-appearance: textfield; 52 | -webkit-box-sizing: content-box; 53 | font-family: inherit; 54 | font-size: 100%; 55 | } 56 | input::-webkit-search-decoration, 57 | input::-webkit-search-cancel-button { 58 | display: none; 59 | } 60 | 61 | ::-webkit-scrollbar { 62 | width: 6px; 63 | background: transparent; 64 | } 65 | ::-webkit-scrollbar-track { 66 | background-color: transparent; 67 | } 68 | ::-webkit-scrollbar-thumb { 69 | background: #4d4d57; 70 | border-radius: 50px; 71 | } 72 | ` 73 | -------------------------------------------------------------------------------- /src/styles/pages/Home.ts: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components' 2 | import { rgba } from 'polished' 3 | 4 | export const Container = styled.div` 5 | width: 100%; 6 | 7 | img, 8 | video { 9 | height: auto; 10 | max-width: 100%; 11 | width: 100%; 12 | } 13 | 14 | section { 15 | .container { 16 | width: 1120px; 17 | 18 | display: flex; 19 | justify-content: space-between; 20 | } 21 | .title { 22 | font-size: 64px; 23 | font-style: normal; 24 | font-weight: 700; 25 | line-height: 67px; 26 | color: ${props => props.theme.colors.secondary}; 27 | } 28 | .titleSection { 29 | font-size: 54px; 30 | font-weight: 700; 31 | line-height: 60px; 32 | color: ${props => props.theme.colors.secondary}; 33 | } 34 | .subTitleSection { 35 | font-size: 24px; 36 | font-weight: 700; 37 | line-height: 34px; 38 | color: ${props => props.theme.colors.secondary}; 39 | } 40 | .subtitle { 41 | font-size: 20px; 42 | font-weight: 400; 43 | line-height: 30px; 44 | color: ${props => props.theme.colors.text.normal}; 45 | } 46 | .paragraph { 47 | font-size: ${props => props.theme.colors.text.size}; 48 | font-weight: 400; 49 | line-height: 28px; 50 | color: ${props => props.theme.colors.text.normal}; 51 | } 52 | 53 | &.capture { 54 | min-height: 100vh; 55 | padding-top: 56px; 56 | padding-bottom: 130px; 57 | 58 | background-color: ${props => props.theme.colors.background.normal}; 59 | 60 | display: flex; 61 | justify-content: center; 62 | 63 | & > div { 64 | position: relative; 65 | } 66 | 67 | .captureContent { 68 | h1 { 69 | margin-top: 200px; 70 | font-size: 96px; 71 | margin-bottom: 24px; 72 | } 73 | h2 { 74 | margin-top: 48px; 75 | max-width: 485px; 76 | margin-bottom: 32px; 77 | } 78 | b { 79 | color: ${props => props.theme.colors.green}; 80 | } 81 | button { 82 | max-width: 140px; 83 | margin-top: 96px; 84 | 85 | font-weight: bold; 86 | font-size: 14px; 87 | line-height: 28px; 88 | 89 | background: none; 90 | border: none; 91 | color: #e1e1e6; 92 | 93 | display: flex; 94 | align-items: center; 95 | 96 | svg { 97 | width: 22px; 98 | height: 22px; 99 | margin-left: 16px; 100 | 101 | color: ${props => props.theme.colors.green}; 102 | 103 | transition: all 0.2s; 104 | } 105 | } 106 | } 107 | 108 | .captureAction { 109 | position: absolute; 110 | top: -15%; 111 | right: 0; 112 | 113 | min-width: 448px; 114 | min-height: 100vh; 115 | padding: 0 76px; 116 | 117 | background-color: red; 118 | border-bottom-left-radius: 5px; 119 | border-bottom-right-radius: 5px; 120 | background: ${props => props.theme.colors.linearGradient.normal}; 121 | 122 | display: flex; 123 | align-items: center; 124 | justify-content: center; 125 | flex-direction: column; 126 | 127 | .bgt { 128 | display: flex; 129 | flex-direction: column; 130 | align-items: center; 131 | 132 | .icon-attention { 133 | width: 56px; 134 | height: 56px; 135 | margin-bottom: 16px; 136 | 137 | color: #fd951f; 138 | } 139 | 140 | h3 { 141 | width: 100%; 142 | 143 | color: #fd951f; 144 | 145 | font-size: 24px; 146 | text-align: center; 147 | line-height: 34px; 148 | font-weight: 400; 149 | } 150 | } 151 | 152 | .logo { 153 | margin: 40px 0; 154 | } 155 | } 156 | } 157 | 158 | &.methodology { 159 | padding-top: 130px; 160 | padding-bottom: 64px; 161 | 162 | display: flex; 163 | justify-content: center; 164 | 165 | background: linear-gradient( 166 | 180deg, 167 | #0b0b0d -72.08%, 168 | rgba(9, 9, 10, 0.5) 56.98%, 169 | rgba(9, 9, 10, 0) 170 | ); 171 | 172 | .methodologyPolygon { 173 | width: 100%; 174 | max-width: 535px; 175 | 176 | .methodologyPolygonGrid { 177 | position: relative; 178 | height: 398px; 179 | 180 | display: grid; 181 | grid-template-areas: 182 | 'ItemMethodology ItemMethodology' 183 | 'ItemAttitude ItemResume'; 184 | 185 | text-align: center; 186 | 187 | background-size: cover; 188 | background: url('/images/polygon.png') 50% no-repeat; 189 | 190 | strong { 191 | font-size: 36px; 192 | font-weight: 700; 193 | line-height: 28px; 194 | margin-bottom: 12px; 195 | color: ${props => props.theme.colors.secondary}; 196 | } 197 | span { 198 | font-size: 16px; 199 | font-weight: 400; 200 | line-height: 24px; 201 | color: ${props => props.theme.colors.green}; 202 | } 203 | 204 | .ItemAttitude, 205 | .ItemMethodology, 206 | .ItemResume { 207 | display: flex; 208 | position: absolute; 209 | flex-direction: column; 210 | } 211 | 212 | .ItemMethodology { 213 | grid-area: ItemMethodology; 214 | top: -5px; 215 | right: 0; 216 | left: 0; 217 | 218 | margin-bottom: 234px; 219 | } 220 | .ItemAttitude { 221 | grid-area: ItemAttitude; 222 | left: 0; 223 | bottom: 0; 224 | } 225 | .ItemResume { 226 | grid-area: ItemResume; 227 | right: 0; 228 | bottom: -28px; 229 | } 230 | } 231 | 232 | .polygonMobile { 233 | display: none; 234 | } 235 | } 236 | .methodologyContent { 237 | h2 { 238 | max-width: 302px; 239 | margin-bottom: 32px; 240 | } 241 | h3 { 242 | max-width: 384px; 243 | margin-bottom: 32px; 244 | 245 | font-weight: 400; 246 | color: ${props => props.theme.colors.green}; 247 | } 248 | p { 249 | max-width: 384px; 250 | } 251 | } 252 | } 253 | 254 | &.whyIgnite { 255 | padding-top: 188px; 256 | padding-bottom: 240px; 257 | 258 | display: flex; 259 | justify-content: center; 260 | 261 | background-color: ${props => props.theme.colors.background.normal}; 262 | 263 | & > div { 264 | flex-direction: column; 265 | } 266 | 267 | .whyIgniteTop h2 { 268 | margin-bottom: 64px; 269 | } 270 | .whyIgniteDown { 271 | list-style: none; 272 | 273 | display: grid; 274 | grid-gap: 40px 64px; 275 | gap: 40px 64px; 276 | grid-template-columns: repeat(3, 1fr); 277 | 278 | li { 279 | padding-bottom: 40px; 280 | 281 | &:first-child, 282 | &:nth-child(2), 283 | &:nth-child(3) { 284 | border-bottom: 1px solid #29292e; 285 | } 286 | } 287 | } 288 | } 289 | 290 | &.trails { 291 | display: flex; 292 | justify-content: center; 293 | padding-bottom: 260px; 294 | background-color: ${props => props.theme.colors.background.normal}; 295 | 296 | & > div { 297 | align-items: center; 298 | flex-direction: column; 299 | } 300 | 301 | .trailsTop { 302 | .titleSection { 303 | font-size: 48px; 304 | line-height: 56px; 305 | margin-bottom: 62px; 306 | } 307 | } 308 | .trailsDown { 309 | grid-gap: 32px; 310 | gap: 32px; 311 | display: grid; 312 | grid-template-columns: repeat(3, 1fr); 313 | 314 | li { 315 | list-style: none; 316 | transition: all 0.3s ease; 317 | 318 | background-color: ${props => props.theme.colors.background.light}; 319 | border-radius: 5px; 320 | 321 | button { 322 | border: 0; 323 | width: 100%; 324 | height: 64px; 325 | margin-bottom: 16px; 326 | 327 | display: flex; 328 | align-items: center; 329 | justify-content: space-between; 330 | 331 | font-size: 16px; 332 | font-weight: 700; 333 | line-height: 26px; 334 | padding: 20px 32px; 335 | text-transform: uppercase; 336 | 337 | border-radius: 5px; 338 | } 339 | 340 | &:first-child { 341 | button { 342 | color: ${props => props.theme.colors.background.normal}; 343 | background-color: ${props => 344 | props.theme.colors.react}; /* react */ 345 | } 346 | 347 | .teacher span, 348 | strong { 349 | color: ${props => props.theme.colors.react}; /* react */ 350 | } 351 | 352 | &:hover { 353 | box-shadow: 0 0 0 2px ${props => props.theme.colors.react}; /* react */ 354 | } 355 | } 356 | &:nth-child(2) { 357 | button { 358 | color: ${props => props.theme.colors.background.normal}; 359 | background-color: #8cc84b; 360 | } 361 | 362 | .teacher span, 363 | strong { 364 | color: #8cc84b; 365 | } 366 | 367 | &:hover { 368 | box-shadow: 0 0 0 2px #8cc84b; 369 | } 370 | } 371 | &:nth-child(3) { 372 | button { 373 | color: ${props => props.theme.colors.background.normal}; 374 | background-color: #a32ddf; 375 | } 376 | 377 | .teacher span, 378 | strong { 379 | color: #a32ddf; 380 | } 381 | 382 | &:hover { 383 | box-shadow: 0 0 0 2px #a32ddf; 384 | } 385 | } 386 | 387 | .trail { 388 | padding: 32px; 389 | 390 | & > svg { 391 | margin-bottom: 32px; 392 | } 393 | h3 { 394 | font-size: 30px; 395 | font-weight: 400; 396 | line-height: 41px; 397 | color: ${props => props.theme.colors.text.normal}; 398 | } 399 | span { 400 | font-size: 20px; 401 | font-weight: 400; 402 | line-height: 30px; 403 | color: ${props => props.theme.colors.text.normal}; 404 | } 405 | & > .paragraph { 406 | margin-top: 24px; 407 | padding-bottom: 32px; 408 | border-bottom: 1px solid 409 | ${props => props.theme.colors.background.lighter}; 410 | } 411 | .teacher { 412 | padding-top: 32px; 413 | padding-bottom: 80px; 414 | 415 | span { 416 | font-size: 20px; 417 | font-weight: 500; 418 | line-height: 23px; 419 | } 420 | p { 421 | font-size: 16px; 422 | font-weight: 400; 423 | line-height: 26px; 424 | } 425 | 426 | & > div { 427 | display: flex; 428 | align-items: center; 429 | margin-top: 24px; 430 | margin-bottom: 16px; 431 | 432 | img { 433 | width: 80px; 434 | height: 80px; 435 | border-radius: 50%; 436 | margin-right: 24px; 437 | } 438 | h3 { 439 | font-size: 24px; 440 | font-weight: 700; 441 | line-height: 30px; 442 | color: ${props => props.theme.colors.secondary}; 443 | } 444 | } 445 | } 446 | } 447 | } 448 | } 449 | } 450 | 451 | &.advance { 452 | display: flex; 453 | justify-content: center; 454 | padding-bottom: 288px; 455 | background-color: ${props => props.theme.colors.background.normal}; 456 | 457 | & > div { 458 | position: relative; 459 | 460 | .advanceLeft { 461 | z-index: 5; 462 | h2 { 463 | max-width: 525px; 464 | margin-bottom: 32px; 465 | } 466 | p { 467 | max-width: 543px; 468 | margin-bottom: 32px; 469 | } 470 | .higher { 471 | width: 704px; 472 | height: 178px; 473 | margin-top: 32px; 474 | position: relative; 475 | 476 | &:before { 477 | content: ''; 478 | width: 100%; 479 | height: 100%; 480 | position: absolute; 481 | top: 0; 482 | left: 0; 483 | right: 0; 484 | bottom: 0; 485 | z-index: 1; 486 | background: url('/images/Higher.png') 100% no-repeat; 487 | background-size: cover; 488 | } 489 | } 490 | .mobile { 491 | display: none; 492 | } 493 | } 494 | 495 | .advanceRight { 496 | right: 0; 497 | position: absolute; 498 | 499 | z-index: 0; 500 | } 501 | } 502 | } 503 | 504 | &.testimony { 505 | display: flex; 506 | align-items: center; 507 | justify-content: center; 508 | padding-bottom: 120px; 509 | background-color: ${props => props.theme.colors.background.normal}; 510 | 511 | .testimonyLeft { 512 | max-width: 333px; 513 | h2 { 514 | max-width: 322px; 515 | margin-bottom: 32px; 516 | } 517 | strong { 518 | color: ${props => props.theme.colors.green}; 519 | } 520 | } 521 | 522 | .testimonyRight { 523 | display: flex; 524 | justify-content: space-between; 525 | max-width: 640px; 526 | } 527 | } 528 | 529 | &.testimonyVideo { 530 | display: flex; 531 | justify-content: center; 532 | 533 | padding-bottom: 288px; 534 | 535 | background-color: ${props => props.theme.colors.background.normal}; 536 | 537 | .testimonyVideoContent { 538 | flex: 1 1; 539 | display: grid; 540 | grid-template-columns: repeat(3, 1fr); 541 | 542 | grid-gap: 80px 32px; 543 | gap: 80px 32px; 544 | 545 | list-style: none; 546 | 547 | li { 548 | height: 192px; 549 | border-radius: 5px; 550 | background: ${props => props.theme.colors.black}; 551 | 552 | div { 553 | border-radius: 5px; 554 | } 555 | 556 | .video { 557 | width: 100%; 558 | height: 100%; 559 | border-radius: 5px; 560 | 561 | iframe { 562 | width: 100%; 563 | height: 100%; 564 | border-radius: 5px; 565 | } 566 | } 567 | 568 | h3 { 569 | font-size: 20px; 570 | font-weight: 700; 571 | line-height: 30px; 572 | margin-top: 16px; 573 | } 574 | } 575 | } 576 | } 577 | 578 | &.warning { 579 | display: flex; 580 | justify-content: center; 581 | padding-top: 130px; 582 | padding-bottom: 260px; 583 | 584 | & > div { 585 | position: relative; 586 | align-items: center; 587 | flex-direction: column; 588 | 589 | svg { 590 | top: -22%; 591 | position: absolute; 592 | 593 | path { 594 | fill: ${props => props.theme.colors.orange}; 595 | } 596 | } 597 | 598 | .warningBackground { 599 | width: 100%; 600 | height: 231px; 601 | 602 | display: flex; 603 | align-items: center; 604 | flex-direction: column; 605 | 606 | background-color: red; 607 | background-size: cover; 608 | background: url('/images/spoiler.svg') 50% no-repeat; 609 | 610 | h2 { 611 | padding-top: 67px; 612 | max-width: 400px; 613 | margin-bottom: 16px; 614 | 615 | font-size: 36px; 616 | font-weight: 700; 617 | line-height: 46px; 618 | text-align: center; 619 | 620 | color: ${props => props.theme.colors.secondary}; 621 | } 622 | p { 623 | max-width: 460px; 624 | text-align: center; 625 | } 626 | } 627 | } 628 | } 629 | 630 | &.summary { 631 | display: flex; 632 | justify-content: center; 633 | padding-bottom: 260px; 634 | background-color: ${props => props.theme.colors.background.normal}; 635 | 636 | .summaryLeft { 637 | h2 { 638 | margin-bottom: 54px; 639 | } 640 | } 641 | 642 | .summaryRight { 643 | display: grid; 644 | grid-gap: 40px 20px; 645 | gap: 40px 20px; 646 | grid-template-columns: repeat(3, 1fr); 647 | 648 | list-style: none; 649 | 650 | li { 651 | display: flex; 652 | align-items: center; 653 | 654 | svg { 655 | width: 48px; 656 | height: 48px; 657 | min-width: 48px; 658 | min-height: 48px; 659 | margin-right: 24px; 660 | } 661 | 662 | div { 663 | display: flex; 664 | align-items: center; 665 | font-size: 20px; 666 | font-weight: 500; 667 | line-height: 30px; 668 | color: ${props => props.theme.colors.secondary}; 669 | } 670 | } 671 | } 672 | } 673 | } 674 | 675 | @media (max-width: 1100px) { 676 | section { 677 | &.capture { 678 | .captureContent { 679 | } 680 | 681 | .captureAction { 682 | top: -20%; 683 | min-width: 350px; 684 | padding: 40px 24px 32px; 685 | } 686 | } 687 | 688 | &.summary { 689 | .summaryRight div { 690 | font-size: 16px; 691 | line-height: auto; 692 | } 693 | } 694 | } 695 | } 696 | 697 | @media (max-width: 1160px) { 698 | section { 699 | .container { 700 | margin: 0 24px; 701 | } 702 | } 703 | } 704 | 705 | @media (max-width: 960px) { 706 | section { 707 | .container { 708 | width: 100%; 709 | } 710 | .titleSection { 711 | font-size: 40px; 712 | } 713 | 714 | &.capture { 715 | min-height: unset; 716 | 717 | & > div { 718 | flex-direction: column; 719 | } 720 | .captureContent { 721 | h1 { 722 | margin-top: 48px; 723 | } 724 | h2 { 725 | margin-bottom: 40px; 726 | } 727 | button { 728 | display: none; 729 | } 730 | } 731 | 732 | .captureAction { 733 | flex: 1 1; 734 | position: unset; 735 | min-height: unset; 736 | max-width: none; 737 | min-width: none; 738 | border-radius: 5px; 739 | min-width: 100px; 740 | 741 | .bgt { 742 | flex-direction: row; 743 | justify-content: flex-start; 744 | } 745 | .logo { 746 | margin: 32px 0; 747 | svg { 748 | max-height: 200px; 749 | } 750 | } 751 | } 752 | } 753 | 754 | &.methodology { 755 | padding-top: 120px; 756 | 757 | & > div { 758 | flex-direction: column-reverse; 759 | 760 | .methodologyPolygon { 761 | margin-top: 40px; 762 | } 763 | .methodologyContent { 764 | h2, 765 | h3, 766 | p { 767 | max-width: none; 768 | } 769 | } 770 | } 771 | } 772 | 773 | &.whyIgnite { 774 | padding: 120px 0; 775 | 776 | .whyIgniteDown { 777 | grid-template-columns: repeat(2, 1fr); 778 | } 779 | } 780 | 781 | &.trails { 782 | padding-bottom: 120px; 783 | 784 | .trailsDown { 785 | grid-template-columns: repeat(1, 1fr); 786 | } 787 | } 788 | 789 | &.advance { 790 | padding-bottom: 120px; 791 | 792 | .advanceRight { 793 | /* display: none; */ 794 | } 795 | .advanceLeft { 796 | width: 100%; 797 | } 798 | } 799 | 800 | &.testimony { 801 | padding-bottom: 80px; 802 | 803 | & > div { 804 | flex-direction: column; 805 | 806 | .testimonyLeft, 807 | .testimonyLeft h2 { 808 | max-width: none; 809 | } 810 | 811 | .testimonyLeft p { 812 | max-width: 800px; 813 | margin-bottom: 64px; 814 | } 815 | } 816 | } 817 | 818 | &.testimonyVideo { 819 | padding-bottom: 120px; 820 | 821 | .testimonyVideoContent { 822 | grid-template-columns: repeat(2, 1fr); 823 | } 824 | } 825 | 826 | &.warning { 827 | padding-top: 90px; 828 | padding-bottom: 120px; 829 | background-size: cover; 830 | background: url('/images/spoiler.svg') 50% no-repeat; 831 | 832 | & > div { 833 | position: relative; 834 | align-items: center; 835 | flex-direction: column; 836 | svg { 837 | top: -12%; 838 | width: 88px; 839 | height: 88px; 840 | } 841 | 842 | .warningBackground { 843 | background: none; 844 | } 845 | } 846 | } 847 | 848 | &.summary { 849 | padding-bottom: 120px; 850 | 851 | & > div { 852 | flex-direction: column; 853 | 854 | .summaryRight { 855 | grid-gap: 24px; 856 | gap: 24px; 857 | grid-template-columns: repeat(2, 1fr); 858 | } 859 | } 860 | } 861 | } 862 | } 863 | 864 | @media (max-width: 550px) { 865 | section { 866 | .titleSection { 867 | font-size: 30px; 868 | font-weight: 700; 869 | line-height: 35px; 870 | } 871 | 872 | &.capture { 873 | padding-bottom: 120px; 874 | 875 | .captureContent { 876 | h1 { 877 | font-size: 50px; 878 | font-weight: 700; 879 | line-height: 50px; 880 | margin-bottom: 19px; 881 | } 882 | h2 { 883 | max-width: 290px; 884 | font-size: 15px; 885 | line-height: 25px; 886 | margin-bottom: 44px; 887 | } 888 | button { 889 | display: none; 890 | } 891 | } 892 | 893 | .captureAction { 894 | .logo svg { 895 | max-height: 200px; 896 | } 897 | } 898 | } 899 | 900 | &.methodology { 901 | padding-top: 120px 0; 902 | 903 | & > div { 904 | flex-direction: column-reverse; 905 | 906 | .methodologyPolygon { 907 | margin-top: 40px; 908 | 909 | .methodologyPolygonGrid { 910 | display: none; 911 | } 912 | .polygonMobile { 913 | display: block; 914 | } 915 | } 916 | .methodologyContent { 917 | h2 { 918 | max-width: 198px; 919 | margin-bottom: 16px; 920 | } 921 | h3 { 922 | max-width: 327px; 923 | margin-bottom: 16px; 924 | } 925 | p { 926 | max-width: 290px; 927 | } 928 | } 929 | } 930 | } 931 | 932 | &.whyIgnite { 933 | padding-top: 0; 934 | padding-bottom: 120px; 935 | 936 | .whyIgniteDown { 937 | grid-template-columns: repeat(1, 1fr); 938 | } 939 | } 940 | 941 | &.trails { 942 | padding-bottom: 120px; 943 | 944 | .trailsDown { 945 | grid-template-columns: repeat(1, 1fr); 946 | } 947 | } 948 | 949 | &.advance { 950 | padding-bottom: 120px; 951 | 952 | & > div { 953 | .advanceLeft { 954 | p { 955 | max-width: 327px; 956 | margin-bottom: 24px; 957 | } 958 | .higher { 959 | display: none; 960 | } 961 | .mobile { 962 | display: block; 963 | } 964 | } 965 | .advanceRight { 966 | display: block; 967 | } 968 | } 969 | } 970 | 971 | &.testimony { 972 | & > div { 973 | .testimonyLeft p { 974 | font-size: 16px; 975 | margin-bottom: 32px; 976 | } 977 | .testimonyRight { 978 | max-width: 300px; 979 | 980 | margin: auto; 981 | 982 | .testimonyOptionsArrow button { 983 | margin-left: 0; 984 | } 985 | } 986 | } 987 | } 988 | 989 | &.testimonyVideo { 990 | .testimonyVideoContent { 991 | grid-template-columns: repeat(1, 1fr); 992 | } 993 | } 994 | 995 | &.warning { 996 | } 997 | 998 | &.summary { 999 | & > div { 1000 | .summaryRight { 1001 | grid-gap: 24px; 1002 | gap: 24px; 1003 | grid-template-columns: repeat(1, 1fr); 1004 | } 1005 | } 1006 | } 1007 | } 1008 | } 1009 | ` 1010 | -------------------------------------------------------------------------------- /src/styles/theme.ts: -------------------------------------------------------------------------------- 1 | // import { shade } from 'polished' 2 | 3 | export const LightTheme = { 4 | title: 'Light', 5 | colors: { 6 | primary: { 7 | lighter: '#2aa9e0', 8 | light: '#615df0', 9 | normal: '#5965e0', 10 | dark: '#4953b8', 11 | darker: '#3846D4' 12 | }, 13 | secondary: '#E02041', 14 | 15 | background: { 16 | light: '#fff', 17 | normal: '#f2f3f5', 18 | dark: '#dcdde0' 19 | }, 20 | text: { 21 | highlight: '#b3b9ff', 22 | normal: '#666666', 23 | title: '#2e384d' 24 | }, 25 | 26 | white: '#f7f7f7', 27 | grey: 'aeaeb0', 28 | opaque: '#41414D', 29 | purple: '#6633cc', 30 | purpleDark: '#5A4B81', 31 | green: '#51B56D', 32 | orange: '#E89E64', 33 | pink: '#FF79C6', 34 | blue: '#2436e8' /** #5659eb */, 35 | red: '#e83f5b', 36 | yellow: '#e7de79' 37 | } 38 | } 39 | 40 | export const DarkTheme = { 41 | title: 'Dark', 42 | colors: { 43 | primary: { 44 | light: '#9466ff', 45 | normal: '#8257e5', 46 | dark: '#734bd1', 47 | darker: '#6833e4' 48 | }, 49 | secondary: '#e1e1e6', 50 | icons: '#41414d', // #323238 51 | 52 | background: { 53 | lighter: '#323238', 54 | light: '#181818', 55 | normal: '#121214', 56 | dark: '#0D0D0D' 57 | }, 58 | text: { 59 | size: '18px', 60 | highlight: '#b3b9ff', 61 | normal: '#a8a8b3', 62 | title: '#555' 63 | }, 64 | linearGradient: { 65 | light: 'linear-gradient(155.49deg,#11251c,rgba(17,37,28,0.6))', 66 | normal: 'linear-gradient(155.49deg,#064523,#0f2c1d 39.06%,#11251c)', 67 | dark: 68 | 'radial-gradient(31.12% 84.59% at 26.38% 50%,#04d361 0%,rgba(8,60,32,0.25) 71.35%,rgba(9,9,10,0) 100%),#09090a' 69 | }, 70 | 71 | react: '#2ac7e3', 72 | white: '#fff', 73 | black: '#09090a', 74 | grey: 'aeaeb0', 75 | opaque: '#41414D', 76 | purple: '#6633cc', 77 | purpleDark: '#5A4B81', 78 | green: '#04d361', 79 | orange: '#fd951f', 80 | pink: '#FF79C6', 81 | blue: '#2436e8' /** #5659eb */, 82 | red: '#ce4a4a', 83 | yellow: '#ffcd1e' 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es2020", 4 | "lib": [ 5 | "dom", 6 | "dom.iterable", 7 | "esnext" 8 | ], 9 | "allowJs": true, 10 | "allowSyntheticDefaultImports": true, 11 | "skipLibCheck": true, 12 | "strict": false, 13 | "forceConsistentCasingInFileNames": true, 14 | "noEmit": true, 15 | "esModuleInterop": true, 16 | "module": "esnext", 17 | "moduleResolution": "node", 18 | "resolveJsonModule": true, 19 | "isolatedModules": true, 20 | "jsx": "preserve", 21 | "baseUrl": "./src", 22 | "paths": { 23 | "@/*": [ 24 | "./*" 25 | ] 26 | } 27 | }, 28 | "include": [ 29 | "next-env.d.ts", 30 | "**/*.ts", 31 | "**/*.tsx" 32 | ], 33 | "exclude": [ 34 | "node_modules" 35 | ] 36 | } 37 | --------------------------------------------------------------------------------