diff --git a/.eslintrc.cjs b/.eslintrc.cjs index 4dcb439..7b48102 100644 --- a/.eslintrc.cjs +++ b/.eslintrc.cjs @@ -7,7 +7,7 @@ module.exports = { 'plugin:react/jsx-runtime', 'plugin:react-hooks/recommended', ], - ignorePatterns: ['dist', '.eslintrc.cjs'], + ignorePatterns: ['dist', '.eslintrc.cjs', 'Dockerfile', 'docker-compose.yml'], parserOptions: { ecmaVersion: 'latest', sourceType: 'module' }, settings: { react: { version: '18.2' } }, plugins: ['react-refresh'], diff --git a/.github/workflows/CIDocker.yml b/.github/workflows/CIDocker.yml new file mode 100644 index 0000000..e73bb3a --- /dev/null +++ b/.github/workflows/CIDocker.yml @@ -0,0 +1,20 @@ +name: Docker Image CI + +on: + push: + branches: + - main + - develop + pull_request: + branches: + - main + - develop + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v3 + - name: Build the Docker image + run: docker build . --file Dockerfile --tag ecommece-compass:$(date +%s) \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..ecdcfa6 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,37 @@ +# Estágio de desenvolvimento +FROM node:14 AS development + +WORKDIR /app + +# Copia apenas os arquivos necessários para aproveitar o cache de camadas do Docker +COPY package*.json ./ +RUN npm install + +# Instala o pacote "vite" globalmente no contêiner +RUN npm install -g vite + +# Copia todos os arquivos do projeto +COPY . . + +# Executa o comando para iniciar o servidor de desenvolvimento do Vite +CMD ["npm", "run", "dev"] + +# Estágio de produção +FROM development AS production + +# Executa o comando para fazer o build da aplicação usando o Vite +RUN npm run build + +# Estágio final para servir os arquivos com o Nginx +FROM nginx:alpine AS final + +# Remove a configuração padrão do Nginx +RUN rm -rf /usr/share/nginx/html/* + +# Copia todos os arquivos do projeto da etapa de produção para o diretório padrão do Nginx +COPY --from=production /app/dist /usr/share/nginx/html + +EXPOSE 80 + +# Comando para iniciar o servidor Nginx em modo daemon +CMD ["nginx", "-g", "daemon off;"] \ No newline at end of file diff --git a/README.md b/README.md index 336a1c2..baf17e2 100644 --- a/README.md +++ b/README.md @@ -1,15 +1,138 @@ -# React + Vite +# E-commece Compass.uol -## Links Demo -Produção: https://ecommece-compass.vercel.app/ +![Logo](https://i.ibb.co/chJPk3G/Home.png) -Desenvolvimento: https://ecommece-compass.pages.dev/ +O site de Ecommerce para o programa de bolsa da @compass.uol composto por três telas principais: Página Inicial, Detalhes do Produto e Carrinho. O design e a funcionalidade de cada tela foi implementado conforme especificado no protótipo do Figma. +## Funcionalidades Principais🔥 +### Tela de Página Inicial +1. **Lista de Produtos**: Exibir uma lista de produtos incluindo nome, preço e, em alguns casos, uma descrição de avaliação. +2. **Contador de Tempo para Ofertas Finais**: Para alguns produtos, mostrar um contador de tempo indicando quanto tempo resta para o fim da oferta. +3. **Marcadores de Oferta e Novos Produtos**: Alguns produtos serão marcados com a porcentagem de desconto como "Oferta", enquanto outros serão marcados como "Novo". +4. **Funcionalidade de Favoritos**: Os cards de produtos terão um botão para marcar produtos como favoritos. +5. **Funcionalidade de Adicionar ao Carrinho**: Os cards de produtos também incluirão um botão para adicionar o produto ao carrinho. Isso deve atualizar o estado global do sistema. +6. **Seção de Novos Produtos**: Uma seção permitindo navegação para novos produtos. +7. **Botão de Retorno**: Um botão para voltar à tela anterior. +8. **Cabeçalho e Rodapé Globais**: O site deve ter um cabeçalho e rodapé consistentes em todas as páginas. +9. **Banners Estáticos**: Os banners na página inicial serão estáticos e não terão funcionalidade interativa. +10. **Responsividade**: A tela de Página Inicial deve ser adequadamente projetada para dispositivos móveis. -This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules. +### Tela de Detalhes do Produto -Currently, two official plugins are available: +1. **Detalhes do Produto**: Exibir informações detalhadas sobre um produto específico, incluindo nome, preço, descrição, etc. +2. **Funcionalidade de Adicionar ao Carrinho**: Botão para adicionar o produto ao carrinho. Isso também deve atualizar o estado global do carrinho. +3. **Funcionalidade de Compra**: Opção para comprar o produto, com a capacidade de escolher a quantidade desejada. +4. **Contador de Quantidade**: Um contador que permite ajustar a quantidade de produtos a serem adicionados. -- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/README.md) uses [Babel](https://babeljs.io/) for Fast Refresh -- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh +### Tela de Carrinho + +1. **Informações de Compra**: Exibir os produtos selecionados, suas quantidades e preços individuais. +2. **Total de Itens e Valor Total**: Mostrar o número total de itens no carrinho e o valor total da compra. +3. **Contadores de Adicionar/Remover Produtos**: Para cada produto no carrinho, fornecer um contador que permite ajustar a quantidade. + +## Link do demo 🚀 + +Produção: [https://ecommece-compass.vercel.app/](https://ecommece-compass.vercel.app/) + +Desenvolvimento: [https://ecommece-compass.pages.dev/](https://ecommece-compass.pages.dev/) + +## Rodando localmente 💻 + +Siga os passos abaixo para rodar o projeto em sua máquina local: + +1. Clone o repositório ⬇️ + +```bash +git clone https://github.com/ecsistem/blog-compass +``` + +2. Acesse o diretório do projeto 📂 + +```bash +cd blog-compass +``` + +3. Instale as dependências usando NPM 📦 + +```bash +npm install +``` + +ou usando PNPM 📦 + +```bash +pnpm install +``` + +ou usando Yarn 📦 + +```bash +yarn install +``` + +4. Inicie o servidor local 🚀 + +```bash +npm run start +``` + +## Build 🛠️ + +Para fazer o build do projeto, execute o seguinte comando: + +```bash +npm run build +``` + +## 🧱Ambiente de Desenvolvimento - Docker +Para iniciar o servidor de desenvolvimento do Vite com docker, execute o seguinte comando: + +```bash +docker-compose up development +``` +Isso iniciará o servidor de desenvolvimento do Vite, e você poderá acessá-lo em http://localhost:3000 no seu navegador. + +## 🧱Ambiente de Produção - Docker +Para realizar o build da aplicação usando o Vite e executar o ambiente de produção com o Nginx, execute o seguinte comando: + +```bash +docker-compose up production +``` +Isso executará o build da aplicação usando o Vite e, em seguida, iniciará o servidor Nginx para servir os arquivos estáticos. Você poderá acessar a aplicação em http://localhost no seu navegador. + +## Requisitos Técnicos + +- A aplicação deve ser desenvolvida usando o framework ReactJS. +- O design e a funcionalidade devem ser implementados de acordo com o protótipo fornecido no Figma. +- O estado global da aplicação deve ser gerenciado usando ferramentas como Context API ou Redux. +- A aplicação deve ser responsiva e devidamente otimizada para dispositivos móveis. + +## Autores 👤 +- [@Edson Costa](https://www.github.com/ecsistem) +- [@Eduardo Kuritza](https://www.github.com/eduardokuritza) +- [@Cristopher Kovalski Saporiti](https://www.github.com/cristopherkovalski) + + +## Contato📱 + +Se tiver alguma dúvida ou precisar entrar em contato, você pode me encontrar em: + +//Edson Costa +- E-mail: edson.costa.pb@compasso.com.br +- GitHub: [ecsistem](https://github.com/ecsistem) +- LinkedIn: [https://www.linkedin.com/in/edsoncostadev/](https://www.linkedin.com/in/edsoncostadev/) + +//Eduardo Kuritza +- E-mail: eduardo.kuritza.pb@compasso.com.br +- GitHub: [eduardokuritza](https://github.com/eduardokuritza) +- LinkedIn: [https://www.linkedin.com/in/eduardokuritza/] + +//Cristopher Kovalski Saporit +- E-mail: cristopher.sapori.pb@compasso.com.br +- GitHub: [Cristopher Kovalski Saporiti](https://www.github.com/cristopherkovalski) +- LinkedIn: [https://www.linkedin.com/in/cristopher-kovalski-saporiti-a09526146/] + +## Suporte ✉️ + +Para suporte, entre em contato enviando um e-mail para edson.costa.pb@compasso.com.br, eduardo.kuritza.pb@compasso.com.br ou cristopher.sapori.pb@compasso.com.br. Estamos à disposição para ajudar com qualquer dúvida ou problema relacionado ao projeto. \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..acfc0f9 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,22 @@ +version: "3" + +project_name: ecommece-compass + +services: + # Serviço para o ambiente de desenvolvimento com o Vite + development: + build: + context: . + target: development + ports: + - "3000:3000" # Porta para acesso ao servidor de desenvolvimento do Vite + volumes: + - .:/app # Monta o diretório local como volume para refletir as alterações no contêiner em tempo real + + # Serviço para o ambiente de produção com o Nginx + production: + build: + context: . + target: final + ports: + - "80:80" # Porta para acesso ao servidor Nginx em modo de produção \ No newline at end of file diff --git a/index.html b/index.html index 0c589ec..a212940 100644 --- a/index.html +++ b/index.html @@ -1,10 +1,10 @@ - + - + - Vite + React + Ecommerce Compass
diff --git a/package-lock.json b/package-lock.json index e68ca53..c118da5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,8 +8,13 @@ "name": "ecommece-compass", "version": "0.0.0", "dependencies": { + "@reduxjs/toolkit": "^1.9.5", + "axios": "^1.4.0", "react": "^18.2.0", - "react-dom": "^18.2.0" + "react-dom": "^18.2.0", + "react-redux": "^8.1.2", + "react-router-dom": "^6.15.0", + "react-toastify": "^9.1.3" }, "devDependencies": { "@types/react": "^18.2.15", @@ -322,6 +327,17 @@ "@babel/core": "^7.0.0-0" } }, + "node_modules/@babel/runtime": { + "version": "7.22.11", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.22.11.tgz", + "integrity": "sha512-ee7jVNlWN09+KftVOu9n7S8gQzD/Z6hN/I8VBRXW4P1+Xe7kJGXMwu8vds4aGIMHZnNbdpSWCfZZtinytpcAvA==", + "dependencies": { + "regenerator-runtime": "^0.14.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@babel/template": { "version": "7.22.5", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.5.tgz", @@ -910,17 +926,55 @@ "node": ">= 8" } }, + "node_modules/@reduxjs/toolkit": { + "version": "1.9.5", + "resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-1.9.5.tgz", + "integrity": "sha512-Rt97jHmfTeaxL4swLRNPD/zV4OxTes4la07Xc4hetpUW/vc75t5m1ANyxG6ymnEQ2FsLQsoMlYB2vV1sO3m8tQ==", + "dependencies": { + "immer": "^9.0.21", + "redux": "^4.2.1", + "redux-thunk": "^2.4.2", + "reselect": "^4.1.8" + }, + "peerDependencies": { + "react": "^16.9.0 || ^17.0.0 || ^18", + "react-redux": "^7.2.1 || ^8.0.2" + }, + "peerDependenciesMeta": { + "react": { + "optional": true + }, + "react-redux": { + "optional": true + } + } + }, + "node_modules/@remix-run/router": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.8.0.tgz", + "integrity": "sha512-mrfKqIHnSZRyIzBcanNJmVQELTnX+qagEDlcKO90RgRBVOZGSGvZKeDihTRfWcqoDn5N/NkUcwWTccnpN18Tfg==", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@types/hoist-non-react-statics": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz", + "integrity": "sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA==", + "dependencies": { + "@types/react": "*", + "hoist-non-react-statics": "^3.3.0" + } + }, "node_modules/@types/prop-types": { "version": "15.7.5", "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz", - "integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==", - "dev": true + "integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==" }, "node_modules/@types/react": { "version": "18.2.20", "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.20.tgz", "integrity": "sha512-WKNtmsLWJM/3D5mG4U84cysVY31ivmyw85dE84fOCk5Hx78wezB/XEjVPWl2JTZ5FkEeaTJf+VgUAUn3PE7Isw==", - "dev": true, "dependencies": { "@types/prop-types": "*", "@types/scheduler": "*", @@ -931,7 +985,7 @@ "version": "18.2.7", "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.2.7.tgz", "integrity": "sha512-GRaAEriuT4zp9N4p1i8BDBYmEyfo+xQ3yHjJU4eiK5NDa1RmUZG+unZABUTK4/Ox/M+GaHwb6Ow8rUITrtjszA==", - "dev": true, + "devOptional": true, "dependencies": { "@types/react": "*" } @@ -939,8 +993,12 @@ "node_modules/@types/scheduler": { "version": "0.16.3", "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.3.tgz", - "integrity": "sha512-5cJ8CB4yAx7BH1oMvdU0Jh9lrEXyPkar6F9G/ERswkCuvP4KQZfZkSjcMbAICCpQTN4OuZn8tz0HiKv9TGZgrQ==", - "dev": true + "integrity": "sha512-5cJ8CB4yAx7BH1oMvdU0Jh9lrEXyPkar6F9G/ERswkCuvP4KQZfZkSjcMbAICCpQTN4OuZn8tz0HiKv9TGZgrQ==" + }, + "node_modules/@types/use-sync-external-store": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/@types/use-sync-external-store/-/use-sync-external-store-0.0.3.tgz", + "integrity": "sha512-EwmlvuaxPNej9+T4v5AuBPJa2x2UOJVdjCtDHgcDqitUeOtjnJKJ+apYjVcAoBEMjKW1VVFGZLUb5+qqa09XFA==" }, "node_modules/@vitejs/plugin-react": { "version": "4.0.4", @@ -1134,6 +1192,11 @@ "has-symbols": "^1.0.3" } }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + }, "node_modules/available-typed-arrays": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", @@ -1146,6 +1209,16 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/axios": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.4.0.tgz", + "integrity": "sha512-S4XCWMEmzvo64T9GfvQDOXgYRDJ/wsSZc7Jvdgx5u1sd0JwsuPLqb3SYmusag+edF6ziyMensPVqLTSc1PiSEA==", + "dependencies": { + "follow-redirects": "^1.15.0", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + } + }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", @@ -1250,6 +1323,14 @@ "node": ">=4" } }, + "node_modules/clsx": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-1.2.1.tgz", + "integrity": "sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==", + "engines": { + "node": ">=6" + } + }, "node_modules/color-convert": { "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", @@ -1265,6 +1346,17 @@ "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", "dev": true }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -1294,8 +1386,7 @@ "node_modules/csstype": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz", - "integrity": "sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==", - "dev": true + "integrity": "sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==" }, "node_modules/debug": { "version": "4.3.4", @@ -1336,6 +1427,14 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/doctrine": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", @@ -1899,6 +1998,25 @@ "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==", "dev": true }, + "node_modules/follow-redirects": { + "version": "1.15.2", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", + "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, "node_modules/for-each": { "version": "0.3.3", "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", @@ -1908,6 +2026,19 @@ "is-callable": "^1.1.3" } }, + "node_modules/form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -2156,6 +2287,14 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/hoist-non-react-statics": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", + "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", + "dependencies": { + "react-is": "^16.7.0" + } + }, "node_modules/ignore": { "version": "5.2.4", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", @@ -2165,6 +2304,15 @@ "node": ">= 4" } }, + "node_modules/immer": { + "version": "9.0.21", + "resolved": "https://registry.npmjs.org/immer/-/immer-9.0.21.tgz", + "integrity": "sha512-bc4NBHqOqSfRW7POMkHd51LvClaeMXpm8dx0e8oE2GORbq5aRK7Bxl4FyzVLdGtLmvLKL7BTDBG5ACQm4HWjTA==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/immer" + } + }, "node_modules/import-fresh": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", @@ -2672,6 +2820,25 @@ "yallist": "^3.0.2" } }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, "node_modules/minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", @@ -2981,6 +3148,11 @@ "react-is": "^16.13.1" } }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" + }, "node_modules/punycode": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", @@ -3036,8 +3208,50 @@ "node_modules/react-is": { "version": "16.13.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", - "dev": true + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + }, + "node_modules/react-redux": { + "version": "8.1.2", + "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-8.1.2.tgz", + "integrity": "sha512-xJKYI189VwfsFc4CJvHqHlDrzyFTY/3vZACbE+rr/zQ34Xx1wQfB4OTOSeOSNrF6BDVe8OOdxIrAnMGXA3ggfw==", + "dependencies": { + "@babel/runtime": "^7.12.1", + "@types/hoist-non-react-statics": "^3.3.1", + "@types/use-sync-external-store": "^0.0.3", + "hoist-non-react-statics": "^3.3.2", + "react-is": "^18.0.0", + "use-sync-external-store": "^1.0.0" + }, + "peerDependencies": { + "@types/react": "^16.8 || ^17.0 || ^18.0", + "@types/react-dom": "^16.8 || ^17.0 || ^18.0", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0", + "react-native": ">=0.59", + "redux": "^4 || ^5.0.0-beta.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + }, + "react-dom": { + "optional": true + }, + "react-native": { + "optional": true + }, + "redux": { + "optional": true + } + } + }, + "node_modules/react-redux/node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==" }, "node_modules/react-refresh": { "version": "0.14.0", @@ -3048,6 +3262,64 @@ "node": ">=0.10.0" } }, + "node_modules/react-router": { + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.15.0.tgz", + "integrity": "sha512-NIytlzvzLwJkCQj2HLefmeakxxWHWAP+02EGqWEZy+DgfHHKQMUoBBjUQLOtFInBMhWtb3hiUy6MfFgwLjXhqg==", + "dependencies": { + "@remix-run/router": "1.8.0" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "react": ">=16.8" + } + }, + "node_modules/react-router-dom": { + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.15.0.tgz", + "integrity": "sha512-aR42t0fs7brintwBGAv2+mGlCtgtFQeOzK0BM1/OiqEzRejOZtpMZepvgkscpMUnKb8YO84G7s3LsHnnDNonbQ==", + "dependencies": { + "@remix-run/router": "1.8.0", + "react-router": "6.15.0" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "react": ">=16.8", + "react-dom": ">=16.8" + } + }, + "node_modules/react-toastify": { + "version": "9.1.3", + "resolved": "https://registry.npmjs.org/react-toastify/-/react-toastify-9.1.3.tgz", + "integrity": "sha512-fPfb8ghtn/XMxw3LkxQBk3IyagNpF/LIKjOBflbexr2AWxAH1MJgvnESwEwBn9liLFXgTKWgBSdZpw9m4OTHTg==", + "dependencies": { + "clsx": "^1.1.1" + }, + "peerDependencies": { + "react": ">=16", + "react-dom": ">=16" + } + }, + "node_modules/redux": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/redux/-/redux-4.2.1.tgz", + "integrity": "sha512-LAUYz4lc+Do8/g7aeRa8JkyDErK6ekstQaqWQrNRW//MY1TvCEpMtpTWvlQ+FPbWCx+Xixu/6SHt5N0HR+SB4w==", + "dependencies": { + "@babel/runtime": "^7.9.2" + } + }, + "node_modules/redux-thunk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/redux-thunk/-/redux-thunk-2.4.2.tgz", + "integrity": "sha512-+P3TjtnP0k/FEjcBL5FZpoovtvrTNT/UXd4/sluaSyrURlSlhLSzEdfsTBW7WsKB6yPvgd7q/iZPICFjW4o57Q==", + "peerDependencies": { + "redux": "^4" + } + }, "node_modules/reflect.getprototypeof": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.3.tgz", @@ -3068,6 +3340,11 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/regenerator-runtime": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz", + "integrity": "sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA==" + }, "node_modules/regexp.prototype.flags": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.0.tgz", @@ -3085,6 +3362,11 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/reselect": { + "version": "4.1.8", + "resolved": "https://registry.npmjs.org/reselect/-/reselect-4.1.8.tgz", + "integrity": "sha512-ab9EmR80F/zQTMNeneUr4cv+jSwPJgIlvEmVwLerwrWVbpLlBuls9XHzIeTFy4cegU2NHBp3va0LKOzU5qFEYQ==" + }, "node_modules/resolve": { "version": "2.0.0-next.4", "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.4.tgz", @@ -3538,6 +3820,14 @@ "punycode": "^2.1.0" } }, + "node_modules/use-sync-external-store": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz", + "integrity": "sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, "node_modules/vite": { "version": "4.4.9", "resolved": "https://registry.npmjs.org/vite/-/vite-4.4.9.tgz", diff --git a/package.json b/package.json index 80bb043..cf76a62 100644 --- a/package.json +++ b/package.json @@ -7,11 +7,18 @@ "dev": "vite", "build": "vite build", "lint": "eslint . --ext js,jsx --report-unused-disable-directives --max-warnings 0", - "preview": "vite preview" + "preview": "vite preview", + "build-docker": "docker build -t ecommece-compass .", + "deploy-s3": "aws s3 sync dist/ s3://seu-bucket-s3" }, "dependencies": { + "@reduxjs/toolkit": "^1.9.5", + "axios": "^1.4.0", "react": "^18.2.0", - "react-dom": "^18.2.0" + "react-dom": "^18.2.0", + "react-redux": "^8.1.2", + "react-router-dom": "^6.15.0", + "react-toastify": "^9.1.3" }, "devDependencies": { "@types/react": "^18.2.15", diff --git a/src/assets/css/colors.css b/src/assets/css/colors.css new file mode 100644 index 0000000..89ca045 --- /dev/null +++ b/src/assets/css/colors.css @@ -0,0 +1,12 @@ +:root { + --primary: #FFFFFF; + --bg-primary: #FFFFFF; + --secondary: #62D0B6; + --title: #333333; + --price-off: #F55157; + --bg-red: #F55157; + --description: #666666; + --card-time-bg: #F8F8F8; + --border-product: #EEEEEE; + --border-love: #EEEEEE; +} \ No newline at end of file diff --git a/src/assets/css/font.css b/src/assets/css/font.css new file mode 100644 index 0000000..876c5c8 --- /dev/null +++ b/src/assets/css/font.css @@ -0,0 +1,2558 @@ +@import url("https://fonts.googleapis.com/css2?family=Roboto+Flex:opsz,wght@8..144,100;8..144,200;8..144,300;8..144,400;8..144,500;8..144,600;8..144,700;8..144,800;8..144,900;8..144,1000&family=Roboto+Mono:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;1,100;1,200;1,300;1,400;1,500;1,600;1,700&family=Roboto:ital,wght@0,100;0,300;0,400;0,500;0,700;0,900;1,100;1,300;1,400;1,500;1,700;1,900&display=swap"); + +/* cyrillic-ext */ +@font-face { + font-family: "Roboto"; + font-style: italic; + font-weight: 100; + font-display: swap; + src: url(https://fonts.gstatic.com/s/roboto/v30/KFOiCnqEu92Fr1Mu51QrEz0dL_nz.woff2) + format("woff2"); + unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, + U+FE2E-FE2F; +} +/* cyrillic */ +@font-face { + font-family: "Roboto"; + font-style: italic; + font-weight: 100; + font-display: swap; + src: url(https://fonts.gstatic.com/s/roboto/v30/KFOiCnqEu92Fr1Mu51QrEzQdL_nz.woff2) + format("woff2"); + unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; +} +/* greek-ext */ +@font-face { + font-family: "Roboto"; + font-style: italic; + font-weight: 100; + font-display: swap; + src: url(https://fonts.gstatic.com/s/roboto/v30/KFOiCnqEu92Fr1Mu51QrEzwdL_nz.woff2) + format("woff2"); + unicode-range: U+1F00-1FFF; +} +/* greek */ +@font-face { + font-family: "Roboto"; + font-style: italic; + font-weight: 100; + font-display: swap; + src: url(https://fonts.gstatic.com/s/roboto/v30/KFOiCnqEu92Fr1Mu51QrEzMdL_nz.woff2) + format("woff2"); + unicode-range: U+0370-03FF; +} +/* vietnamese */ +@font-face { + font-family: "Roboto"; + font-style: italic; + font-weight: 100; + font-display: swap; + src: url(https://fonts.gstatic.com/s/roboto/v30/KFOiCnqEu92Fr1Mu51QrEz8dL_nz.woff2) + format("woff2"); + unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, + U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, + U+1EA0-1EF9, U+20AB; +} +/* latin-ext */ +@font-face { + font-family: "Roboto"; + font-style: italic; + font-weight: 100; + font-display: swap; + src: url(https://fonts.gstatic.com/s/roboto/v30/KFOiCnqEu92Fr1Mu51QrEz4dL_nz.woff2) + format("woff2"); + unicode-range: U+0100-02AF, U+0304, U+0308, U+0329, U+1E00-1E9F, U+1EF2-1EFF, + U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF; +} +/* latin */ +@font-face { + font-family: "Roboto"; + font-style: italic; + font-weight: 100; + font-display: swap; + src: url(https://fonts.gstatic.com/s/roboto/v30/KFOiCnqEu92Fr1Mu51QrEzAdLw.woff2) + format("woff2"); + unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, + U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, + U+2193, U+2212, U+2215, U+FEFF, U+FFFD; +} +/* cyrillic-ext */ +@font-face { + font-family: "Roboto"; + font-style: italic; + font-weight: 300; + font-display: swap; + src: url(https://fonts.gstatic.com/s/roboto/v30/KFOjCnqEu92Fr1Mu51TjASc3CsTKlA.woff2) + format("woff2"); + unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, + U+FE2E-FE2F; +} +/* cyrillic */ +@font-face { + font-family: "Roboto"; + font-style: italic; + font-weight: 300; + font-display: swap; + src: url(https://fonts.gstatic.com/s/roboto/v30/KFOjCnqEu92Fr1Mu51TjASc-CsTKlA.woff2) + format("woff2"); + unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; +} +/* greek-ext */ +@font-face { + font-family: "Roboto"; + font-style: italic; + font-weight: 300; + font-display: swap; + src: url(https://fonts.gstatic.com/s/roboto/v30/KFOjCnqEu92Fr1Mu51TjASc2CsTKlA.woff2) + format("woff2"); + unicode-range: U+1F00-1FFF; +} +/* greek */ +@font-face { + font-family: "Roboto"; + font-style: italic; + font-weight: 300; + font-display: swap; + src: url(https://fonts.gstatic.com/s/roboto/v30/KFOjCnqEu92Fr1Mu51TjASc5CsTKlA.woff2) + format("woff2"); + unicode-range: U+0370-03FF; +} +/* vietnamese */ +@font-face { + font-family: "Roboto"; + font-style: italic; + font-weight: 300; + font-display: swap; + src: url(https://fonts.gstatic.com/s/roboto/v30/KFOjCnqEu92Fr1Mu51TjASc1CsTKlA.woff2) + format("woff2"); + unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, + U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, + U+1EA0-1EF9, U+20AB; +} +/* latin-ext */ +@font-face { + font-family: "Roboto"; + font-style: italic; + font-weight: 300; + font-display: swap; + src: url(https://fonts.gstatic.com/s/roboto/v30/KFOjCnqEu92Fr1Mu51TjASc0CsTKlA.woff2) + format("woff2"); + unicode-range: U+0100-02AF, U+0304, U+0308, U+0329, U+1E00-1E9F, U+1EF2-1EFF, + U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF; +} +/* latin */ +@font-face { + font-family: "Roboto"; + font-style: italic; + font-weight: 300; + font-display: swap; + src: url(https://fonts.gstatic.com/s/roboto/v30/KFOjCnqEu92Fr1Mu51TjASc6CsQ.woff2) + format("woff2"); + unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, + U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, + U+2193, U+2212, U+2215, U+FEFF, U+FFFD; +} +/* cyrillic-ext */ +@font-face { + font-family: "Roboto"; + font-style: italic; + font-weight: 400; + font-display: swap; + src: url(https://fonts.gstatic.com/s/roboto/v30/KFOkCnqEu92Fr1Mu51xFIzIFKw.woff2) + format("woff2"); + unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, + U+FE2E-FE2F; +} +/* cyrillic */ +@font-face { + font-family: "Roboto"; + font-style: italic; + font-weight: 400; + font-display: swap; + src: url(https://fonts.gstatic.com/s/roboto/v30/KFOkCnqEu92Fr1Mu51xMIzIFKw.woff2) + format("woff2"); + unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; +} +/* greek-ext */ +@font-face { + font-family: "Roboto"; + font-style: italic; + font-weight: 400; + font-display: swap; + src: url(https://fonts.gstatic.com/s/roboto/v30/KFOkCnqEu92Fr1Mu51xEIzIFKw.woff2) + format("woff2"); + unicode-range: U+1F00-1FFF; +} +/* greek */ +@font-face { + font-family: "Roboto"; + font-style: italic; + font-weight: 400; + font-display: swap; + src: url(https://fonts.gstatic.com/s/roboto/v30/KFOkCnqEu92Fr1Mu51xLIzIFKw.woff2) + format("woff2"); + unicode-range: U+0370-03FF; +} +/* vietnamese */ +@font-face { + font-family: "Roboto"; + font-style: italic; + font-weight: 400; + font-display: swap; + src: url(https://fonts.gstatic.com/s/roboto/v30/KFOkCnqEu92Fr1Mu51xHIzIFKw.woff2) + format("woff2"); + unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, + U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, + U+1EA0-1EF9, U+20AB; +} +/* latin-ext */ +@font-face { + font-family: "Roboto"; + font-style: italic; + font-weight: 400; + font-display: swap; + src: url(https://fonts.gstatic.com/s/roboto/v30/KFOkCnqEu92Fr1Mu51xGIzIFKw.woff2) + format("woff2"); + unicode-range: U+0100-02AF, U+0304, U+0308, U+0329, U+1E00-1E9F, U+1EF2-1EFF, + U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF; +} +/* latin */ +@font-face { + font-family: "Roboto"; + font-style: italic; + font-weight: 400; + font-display: swap; + src: url(https://fonts.gstatic.com/s/roboto/v30/KFOkCnqEu92Fr1Mu51xIIzI.woff2) + format("woff2"); + unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, + U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, + U+2193, U+2212, U+2215, U+FEFF, U+FFFD; +} +/* cyrillic-ext */ +@font-face { + font-family: "Roboto"; + font-style: italic; + font-weight: 500; + font-display: swap; + src: url(https://fonts.gstatic.com/s/roboto/v30/KFOjCnqEu92Fr1Mu51S7ACc3CsTKlA.woff2) + format("woff2"); + unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, + U+FE2E-FE2F; +} +/* cyrillic */ +@font-face { + font-family: "Roboto"; + font-style: italic; + font-weight: 500; + font-display: swap; + src: url(https://fonts.gstatic.com/s/roboto/v30/KFOjCnqEu92Fr1Mu51S7ACc-CsTKlA.woff2) + format("woff2"); + unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; +} +/* greek-ext */ +@font-face { + font-family: "Roboto"; + font-style: italic; + font-weight: 500; + font-display: swap; + src: url(https://fonts.gstatic.com/s/roboto/v30/KFOjCnqEu92Fr1Mu51S7ACc2CsTKlA.woff2) + format("woff2"); + unicode-range: U+1F00-1FFF; +} +/* greek */ +@font-face { + font-family: "Roboto"; + font-style: italic; + font-weight: 500; + font-display: swap; + src: url(https://fonts.gstatic.com/s/roboto/v30/KFOjCnqEu92Fr1Mu51S7ACc5CsTKlA.woff2) + format("woff2"); + unicode-range: U+0370-03FF; +} +/* vietnamese */ +@font-face { + font-family: "Roboto"; + font-style: italic; + font-weight: 500; + font-display: swap; + src: url(https://fonts.gstatic.com/s/roboto/v30/KFOjCnqEu92Fr1Mu51S7ACc1CsTKlA.woff2) + format("woff2"); + unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, + U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, + U+1EA0-1EF9, U+20AB; +} +/* latin-ext */ +@font-face { + font-family: "Roboto"; + font-style: italic; + font-weight: 500; + font-display: swap; + src: url(https://fonts.gstatic.com/s/roboto/v30/KFOjCnqEu92Fr1Mu51S7ACc0CsTKlA.woff2) + format("woff2"); + unicode-range: U+0100-02AF, U+0304, U+0308, U+0329, U+1E00-1E9F, U+1EF2-1EFF, + U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF; +} +/* latin */ +@font-face { + font-family: "Roboto"; + font-style: italic; + font-weight: 500; + font-display: swap; + src: url(https://fonts.gstatic.com/s/roboto/v30/KFOjCnqEu92Fr1Mu51S7ACc6CsQ.woff2) + format("woff2"); + unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, + U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, + U+2193, U+2212, U+2215, U+FEFF, U+FFFD; +} +/* cyrillic-ext */ +@font-face { + font-family: "Roboto"; + font-style: italic; + font-weight: 700; + font-display: swap; + src: url(https://fonts.gstatic.com/s/roboto/v30/KFOjCnqEu92Fr1Mu51TzBic3CsTKlA.woff2) + format("woff2"); + unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, + U+FE2E-FE2F; +} +/* cyrillic */ +@font-face { + font-family: "Roboto"; + font-style: italic; + font-weight: 700; + font-display: swap; + src: url(https://fonts.gstatic.com/s/roboto/v30/KFOjCnqEu92Fr1Mu51TzBic-CsTKlA.woff2) + format("woff2"); + unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; +} +/* greek-ext */ +@font-face { + font-family: "Roboto"; + font-style: italic; + font-weight: 700; + font-display: swap; + src: url(https://fonts.gstatic.com/s/roboto/v30/KFOjCnqEu92Fr1Mu51TzBic2CsTKlA.woff2) + format("woff2"); + unicode-range: U+1F00-1FFF; +} +/* greek */ +@font-face { + font-family: "Roboto"; + font-style: italic; + font-weight: 700; + font-display: swap; + src: url(https://fonts.gstatic.com/s/roboto/v30/KFOjCnqEu92Fr1Mu51TzBic5CsTKlA.woff2) + format("woff2"); + unicode-range: U+0370-03FF; +} +/* vietnamese */ +@font-face { + font-family: "Roboto"; + font-style: italic; + font-weight: 700; + font-display: swap; + src: url(https://fonts.gstatic.com/s/roboto/v30/KFOjCnqEu92Fr1Mu51TzBic1CsTKlA.woff2) + format("woff2"); + unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, + U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, + U+1EA0-1EF9, U+20AB; +} +/* latin-ext */ +@font-face { + font-family: "Roboto"; + font-style: italic; + font-weight: 700; + font-display: swap; + src: url(https://fonts.gstatic.com/s/roboto/v30/KFOjCnqEu92Fr1Mu51TzBic0CsTKlA.woff2) + format("woff2"); + unicode-range: U+0100-02AF, U+0304, U+0308, U+0329, U+1E00-1E9F, U+1EF2-1EFF, + U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF; +} +/* latin */ +@font-face { + font-family: "Roboto"; + font-style: italic; + font-weight: 700; + font-display: swap; + src: url(https://fonts.gstatic.com/s/roboto/v30/KFOjCnqEu92Fr1Mu51TzBic6CsQ.woff2) + format("woff2"); + unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, + U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, + U+2193, U+2212, U+2215, U+FEFF, U+FFFD; +} +/* cyrillic-ext */ +@font-face { + font-family: "Roboto"; + font-style: italic; + font-weight: 900; + font-display: swap; + src: url(https://fonts.gstatic.com/s/roboto/v30/KFOjCnqEu92Fr1Mu51TLBCc3CsTKlA.woff2) + format("woff2"); + unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, + U+FE2E-FE2F; +} +/* cyrillic */ +@font-face { + font-family: "Roboto"; + font-style: italic; + font-weight: 900; + font-display: swap; + src: url(https://fonts.gstatic.com/s/roboto/v30/KFOjCnqEu92Fr1Mu51TLBCc-CsTKlA.woff2) + format("woff2"); + unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; +} +/* greek-ext */ +@font-face { + font-family: "Roboto"; + font-style: italic; + font-weight: 900; + font-display: swap; + src: url(https://fonts.gstatic.com/s/roboto/v30/KFOjCnqEu92Fr1Mu51TLBCc2CsTKlA.woff2) + format("woff2"); + unicode-range: U+1F00-1FFF; +} +/* greek */ +@font-face { + font-family: "Roboto"; + font-style: italic; + font-weight: 900; + font-display: swap; + src: url(https://fonts.gstatic.com/s/roboto/v30/KFOjCnqEu92Fr1Mu51TLBCc5CsTKlA.woff2) + format("woff2"); + unicode-range: U+0370-03FF; +} +/* vietnamese */ +@font-face { + font-family: "Roboto"; + font-style: italic; + font-weight: 900; + font-display: swap; + src: url(https://fonts.gstatic.com/s/roboto/v30/KFOjCnqEu92Fr1Mu51TLBCc1CsTKlA.woff2) + format("woff2"); + unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, + U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, + U+1EA0-1EF9, U+20AB; +} +/* latin-ext */ +@font-face { + font-family: "Roboto"; + font-style: italic; + font-weight: 900; + font-display: swap; + src: url(https://fonts.gstatic.com/s/roboto/v30/KFOjCnqEu92Fr1Mu51TLBCc0CsTKlA.woff2) + format("woff2"); + unicode-range: U+0100-02AF, U+0304, U+0308, U+0329, U+1E00-1E9F, U+1EF2-1EFF, + U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF; +} +/* latin */ +@font-face { + font-family: "Roboto"; + font-style: italic; + font-weight: 900; + font-display: swap; + src: url(https://fonts.gstatic.com/s/roboto/v30/KFOjCnqEu92Fr1Mu51TLBCc6CsQ.woff2) + format("woff2"); + unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, + U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, + U+2193, U+2212, U+2215, U+FEFF, U+FFFD; +} +/* cyrillic-ext */ +@font-face { + font-family: "Roboto"; + font-style: normal; + font-weight: 100; + font-display: swap; + src: url(https://fonts.gstatic.com/s/roboto/v30/KFOkCnqEu92Fr1MmgVxFIzIFKw.woff2) + format("woff2"); + unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, + U+FE2E-FE2F; +} +/* cyrillic */ +@font-face { + font-family: "Roboto"; + font-style: normal; + font-weight: 100; + font-display: swap; + src: url(https://fonts.gstatic.com/s/roboto/v30/KFOkCnqEu92Fr1MmgVxMIzIFKw.woff2) + format("woff2"); + unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; +} +/* greek-ext */ +@font-face { + font-family: "Roboto"; + font-style: normal; + font-weight: 100; + font-display: swap; + src: url(https://fonts.gstatic.com/s/roboto/v30/KFOkCnqEu92Fr1MmgVxEIzIFKw.woff2) + format("woff2"); + unicode-range: U+1F00-1FFF; +} +/* greek */ +@font-face { + font-family: "Roboto"; + font-style: normal; + font-weight: 100; + font-display: swap; + src: url(https://fonts.gstatic.com/s/roboto/v30/KFOkCnqEu92Fr1MmgVxLIzIFKw.woff2) + format("woff2"); + unicode-range: U+0370-03FF; +} +/* vietnamese */ +@font-face { + font-family: "Roboto"; + font-style: normal; + font-weight: 100; + font-display: swap; + src: url(https://fonts.gstatic.com/s/roboto/v30/KFOkCnqEu92Fr1MmgVxHIzIFKw.woff2) + format("woff2"); + unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, + U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, + U+1EA0-1EF9, U+20AB; +} +/* latin-ext */ +@font-face { + font-family: "Roboto"; + font-style: normal; + font-weight: 100; + font-display: swap; + src: url(https://fonts.gstatic.com/s/roboto/v30/KFOkCnqEu92Fr1MmgVxGIzIFKw.woff2) + format("woff2"); + unicode-range: U+0100-02AF, U+0304, U+0308, U+0329, U+1E00-1E9F, U+1EF2-1EFF, + U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF; +} +/* latin */ +@font-face { + font-family: "Roboto"; + font-style: normal; + font-weight: 100; + font-display: swap; + src: url(https://fonts.gstatic.com/s/roboto/v30/KFOkCnqEu92Fr1MmgVxIIzI.woff2) + format("woff2"); + unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, + U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, + U+2193, U+2212, U+2215, U+FEFF, U+FFFD; +} +/* cyrillic-ext */ +@font-face { + font-family: "Roboto"; + font-style: normal; + font-weight: 300; + font-display: swap; + src: url(https://fonts.gstatic.com/s/roboto/v30/KFOlCnqEu92Fr1MmSU5fCRc4EsA.woff2) + format("woff2"); + unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, + U+FE2E-FE2F; +} +/* cyrillic */ +@font-face { + font-family: "Roboto"; + font-style: normal; + font-weight: 300; + font-display: swap; + src: url(https://fonts.gstatic.com/s/roboto/v30/KFOlCnqEu92Fr1MmSU5fABc4EsA.woff2) + format("woff2"); + unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; +} +/* greek-ext */ +@font-face { + font-family: "Roboto"; + font-style: normal; + font-weight: 300; + font-display: swap; + src: url(https://fonts.gstatic.com/s/roboto/v30/KFOlCnqEu92Fr1MmSU5fCBc4EsA.woff2) + format("woff2"); + unicode-range: U+1F00-1FFF; +} +/* greek */ +@font-face { + font-family: "Roboto"; + font-style: normal; + font-weight: 300; + font-display: swap; + src: url(https://fonts.gstatic.com/s/roboto/v30/KFOlCnqEu92Fr1MmSU5fBxc4EsA.woff2) + format("woff2"); + unicode-range: U+0370-03FF; +} +/* vietnamese */ +@font-face { + font-family: "Roboto"; + font-style: normal; + font-weight: 300; + font-display: swap; + src: url(https://fonts.gstatic.com/s/roboto/v30/KFOlCnqEu92Fr1MmSU5fCxc4EsA.woff2) + format("woff2"); + unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, + U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, + U+1EA0-1EF9, U+20AB; +} +/* latin-ext */ +@font-face { + font-family: "Roboto"; + font-style: normal; + font-weight: 300; + font-display: swap; + src: url(https://fonts.gstatic.com/s/roboto/v30/KFOlCnqEu92Fr1MmSU5fChc4EsA.woff2) + format("woff2"); + unicode-range: U+0100-02AF, U+0304, U+0308, U+0329, U+1E00-1E9F, U+1EF2-1EFF, + U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF; +} +/* latin */ +@font-face { + font-family: "Roboto"; + font-style: normal; + font-weight: 300; + font-display: swap; + src: url(https://fonts.gstatic.com/s/roboto/v30/KFOlCnqEu92Fr1MmSU5fBBc4.woff2) + format("woff2"); + unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, + U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, + U+2193, U+2212, U+2215, U+FEFF, U+FFFD; +} +/* cyrillic-ext */ +@font-face { + font-family: "Roboto"; + font-style: normal; + font-weight: 400; + font-display: swap; + src: url(https://fonts.gstatic.com/s/roboto/v30/KFOmCnqEu92Fr1Mu72xKOzY.woff2) + format("woff2"); + unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, + U+FE2E-FE2F; +} +/* cyrillic */ +@font-face { + font-family: "Roboto"; + font-style: normal; + font-weight: 400; + font-display: swap; + src: url(https://fonts.gstatic.com/s/roboto/v30/KFOmCnqEu92Fr1Mu5mxKOzY.woff2) + format("woff2"); + unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; +} +/* greek-ext */ +@font-face { + font-family: "Roboto"; + font-style: normal; + font-weight: 400; + font-display: swap; + src: url(https://fonts.gstatic.com/s/roboto/v30/KFOmCnqEu92Fr1Mu7mxKOzY.woff2) + format("woff2"); + unicode-range: U+1F00-1FFF; +} +/* greek */ +@font-face { + font-family: "Roboto"; + font-style: normal; + font-weight: 400; + font-display: swap; + src: url(https://fonts.gstatic.com/s/roboto/v30/KFOmCnqEu92Fr1Mu4WxKOzY.woff2) + format("woff2"); + unicode-range: U+0370-03FF; +} +/* vietnamese */ +@font-face { + font-family: "Roboto"; + font-style: normal; + font-weight: 400; + font-display: swap; + src: url(https://fonts.gstatic.com/s/roboto/v30/KFOmCnqEu92Fr1Mu7WxKOzY.woff2) + format("woff2"); + unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, + U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, + U+1EA0-1EF9, U+20AB; +} +/* latin-ext */ +@font-face { + font-family: "Roboto"; + font-style: normal; + font-weight: 400; + font-display: swap; + src: url(https://fonts.gstatic.com/s/roboto/v30/KFOmCnqEu92Fr1Mu7GxKOzY.woff2) + format("woff2"); + unicode-range: U+0100-02AF, U+0304, U+0308, U+0329, U+1E00-1E9F, U+1EF2-1EFF, + U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF; +} +/* latin */ +@font-face { + font-family: "Roboto"; + font-style: normal; + font-weight: 400; + font-display: swap; + src: url(https://fonts.gstatic.com/s/roboto/v30/KFOmCnqEu92Fr1Mu4mxK.woff2) + format("woff2"); + unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, + U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, + U+2193, U+2212, U+2215, U+FEFF, U+FFFD; +} +/* cyrillic-ext */ +@font-face { + font-family: "Roboto"; + font-style: normal; + font-weight: 500; + font-display: swap; + src: url(https://fonts.gstatic.com/s/roboto/v30/KFOlCnqEu92Fr1MmEU9fCRc4EsA.woff2) + format("woff2"); + unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, + U+FE2E-FE2F; +} +/* cyrillic */ +@font-face { + font-family: "Roboto"; + font-style: normal; + font-weight: 500; + font-display: swap; + src: url(https://fonts.gstatic.com/s/roboto/v30/KFOlCnqEu92Fr1MmEU9fABc4EsA.woff2) + format("woff2"); + unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; +} +/* greek-ext */ +@font-face { + font-family: "Roboto"; + font-style: normal; + font-weight: 500; + font-display: swap; + src: url(https://fonts.gstatic.com/s/roboto/v30/KFOlCnqEu92Fr1MmEU9fCBc4EsA.woff2) + format("woff2"); + unicode-range: U+1F00-1FFF; +} +/* greek */ +@font-face { + font-family: "Roboto"; + font-style: normal; + font-weight: 500; + font-display: swap; + src: url(https://fonts.gstatic.com/s/roboto/v30/KFOlCnqEu92Fr1MmEU9fBxc4EsA.woff2) + format("woff2"); + unicode-range: U+0370-03FF; +} +/* vietnamese */ +@font-face { + font-family: "Roboto"; + font-style: normal; + font-weight: 500; + font-display: swap; + src: url(https://fonts.gstatic.com/s/roboto/v30/KFOlCnqEu92Fr1MmEU9fCxc4EsA.woff2) + format("woff2"); + unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, + U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, + U+1EA0-1EF9, U+20AB; +} +/* latin-ext */ +@font-face { + font-family: "Roboto"; + font-style: normal; + font-weight: 500; + font-display: swap; + src: url(https://fonts.gstatic.com/s/roboto/v30/KFOlCnqEu92Fr1MmEU9fChc4EsA.woff2) + format("woff2"); + unicode-range: U+0100-02AF, U+0304, U+0308, U+0329, U+1E00-1E9F, U+1EF2-1EFF, + U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF; +} +/* latin */ +@font-face { + font-family: "Roboto"; + font-style: normal; + font-weight: 500; + font-display: swap; + src: url(https://fonts.gstatic.com/s/roboto/v30/KFOlCnqEu92Fr1MmEU9fBBc4.woff2) + format("woff2"); + unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, + U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, + U+2193, U+2212, U+2215, U+FEFF, U+FFFD; +} +/* cyrillic-ext */ +@font-face { + font-family: "Roboto"; + font-style: normal; + font-weight: 700; + font-display: swap; + src: url(https://fonts.gstatic.com/s/roboto/v30/KFOlCnqEu92Fr1MmWUlfCRc4EsA.woff2) + format("woff2"); + unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, + U+FE2E-FE2F; +} +/* cyrillic */ +@font-face { + font-family: "Roboto"; + font-style: normal; + font-weight: 700; + font-display: swap; + src: url(https://fonts.gstatic.com/s/roboto/v30/KFOlCnqEu92Fr1MmWUlfABc4EsA.woff2) + format("woff2"); + unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; +} +/* greek-ext */ +@font-face { + font-family: "Roboto"; + font-style: normal; + font-weight: 700; + font-display: swap; + src: url(https://fonts.gstatic.com/s/roboto/v30/KFOlCnqEu92Fr1MmWUlfCBc4EsA.woff2) + format("woff2"); + unicode-range: U+1F00-1FFF; +} +/* greek */ +@font-face { + font-family: "Roboto"; + font-style: normal; + font-weight: 700; + font-display: swap; + src: url(https://fonts.gstatic.com/s/roboto/v30/KFOlCnqEu92Fr1MmWUlfBxc4EsA.woff2) + format("woff2"); + unicode-range: U+0370-03FF; +} +/* vietnamese */ +@font-face { + font-family: "Roboto"; + font-style: normal; + font-weight: 700; + font-display: swap; + src: url(https://fonts.gstatic.com/s/roboto/v30/KFOlCnqEu92Fr1MmWUlfCxc4EsA.woff2) + format("woff2"); + unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, + U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, + U+1EA0-1EF9, U+20AB; +} +/* latin-ext */ +@font-face { + font-family: "Roboto"; + font-style: normal; + font-weight: 700; + font-display: swap; + src: url(https://fonts.gstatic.com/s/roboto/v30/KFOlCnqEu92Fr1MmWUlfChc4EsA.woff2) + format("woff2"); + unicode-range: U+0100-02AF, U+0304, U+0308, U+0329, U+1E00-1E9F, U+1EF2-1EFF, + U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF; +} +/* latin */ +@font-face { + font-family: "Roboto"; + font-style: normal; + font-weight: 700; + font-display: swap; + src: url(https://fonts.gstatic.com/s/roboto/v30/KFOlCnqEu92Fr1MmWUlfBBc4.woff2) + format("woff2"); + unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, + U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, + U+2193, U+2212, U+2215, U+FEFF, U+FFFD; +} +/* cyrillic-ext */ +@font-face { + font-family: "Roboto"; + font-style: normal; + font-weight: 900; + font-display: swap; + src: url(https://fonts.gstatic.com/s/roboto/v30/KFOlCnqEu92Fr1MmYUtfCRc4EsA.woff2) + format("woff2"); + unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, + U+FE2E-FE2F; +} +/* cyrillic */ +@font-face { + font-family: "Roboto"; + font-style: normal; + font-weight: 900; + font-display: swap; + src: url(https://fonts.gstatic.com/s/roboto/v30/KFOlCnqEu92Fr1MmYUtfABc4EsA.woff2) + format("woff2"); + unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; +} +/* greek-ext */ +@font-face { + font-family: "Roboto"; + font-style: normal; + font-weight: 900; + font-display: swap; + src: url(https://fonts.gstatic.com/s/roboto/v30/KFOlCnqEu92Fr1MmYUtfCBc4EsA.woff2) + format("woff2"); + unicode-range: U+1F00-1FFF; +} +/* greek */ +@font-face { + font-family: "Roboto"; + font-style: normal; + font-weight: 900; + font-display: swap; + src: url(https://fonts.gstatic.com/s/roboto/v30/KFOlCnqEu92Fr1MmYUtfBxc4EsA.woff2) + format("woff2"); + unicode-range: U+0370-03FF; +} +/* vietnamese */ +@font-face { + font-family: "Roboto"; + font-style: normal; + font-weight: 900; + font-display: swap; + src: url(https://fonts.gstatic.com/s/roboto/v30/KFOlCnqEu92Fr1MmYUtfCxc4EsA.woff2) + format("woff2"); + unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, + U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, + U+1EA0-1EF9, U+20AB; +} +/* latin-ext */ +@font-face { + font-family: "Roboto"; + font-style: normal; + font-weight: 900; + font-display: swap; + src: url(https://fonts.gstatic.com/s/roboto/v30/KFOlCnqEu92Fr1MmYUtfChc4EsA.woff2) + format("woff2"); + unicode-range: U+0100-02AF, U+0304, U+0308, U+0329, U+1E00-1E9F, U+1EF2-1EFF, + U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF; +} +/* latin */ +@font-face { + font-family: "Roboto"; + font-style: normal; + font-weight: 900; + font-display: swap; + src: url(https://fonts.gstatic.com/s/roboto/v30/KFOlCnqEu92Fr1MmYUtfBBc4.woff2) + format("woff2"); + unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, + U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, + U+2193, U+2212, U+2215, U+FEFF, U+FFFD; +} +/* cyrillic-ext */ +@font-face { + font-family: "Roboto Flex"; + font-style: normal; + font-weight: 100; + font-stretch: 100%; + font-display: swap; + src: url(https://fonts.gstatic.com/s/robotoflex/v9/NaNeepOXO_NexZs0b5QrzlOHb8wCikXpYqmZsWI-__OGfttPZktqc2VdZ80KvCLZaPcSBZtOx2MifRuWR28sPJtUMbsFEK6cRrleUx9Xgbm3WLHa_F4Ep4Fm0PN19Ik5Dntczx0wZGzhPlL1YNMYKbv9_1IQXOw7AiUJVXRrV8cWW4O8LJCoXjCnwSRSaLshNP1d9-wmF9lp.woff2) + format("woff2"); + unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, + U+FE2E-FE2F; +} +/* cyrillic */ +@font-face { + font-family: "Roboto Flex"; + font-style: normal; + font-weight: 100; + font-stretch: 100%; + font-display: swap; + src: url(https://fonts.gstatic.com/s/robotoflex/v9/NaNeepOXO_NexZs0b5QrzlOHb8wCikXpYqmZsWI-__OGfttPZktqc2VdZ80KvCLZaPcSBZtOx2MifRuWR28sPJtUMbsFEK6cRrleUx9Xgbm3WLHa_F4Ep4Fm0PN19Ik5Dntczx0wZGzhPlL1YNMYKbv9_1IQXOw7AiUJVXRrV8cWW4O8LJCoXjCnwSRSaLshNP1d9-UmF9lp.woff2) + format("woff2"); + unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; +} +/* greek */ +@font-face { + font-family: "Roboto Flex"; + font-style: normal; + font-weight: 100; + font-stretch: 100%; + font-display: swap; + src: url(https://fonts.gstatic.com/s/robotoflex/v9/NaNeepOXO_NexZs0b5QrzlOHb8wCikXpYqmZsWI-__OGfttPZktqc2VdZ80KvCLZaPcSBZtOx2MifRuWR28sPJtUMbsFEK6cRrleUx9Xgbm3WLHa_F4Ep4Fm0PN19Ik5Dntczx0wZGzhPlL1YNMYKbv9_1IQXOw7AiUJVXRrV8cWW4O8LJCoXjCnwSRSaLshNP1d9-ImF9lp.woff2) + format("woff2"); + unicode-range: U+0370-03FF; +} +/* vietnamese */ +@font-face { + font-family: "Roboto Flex"; + font-style: normal; + font-weight: 100; + font-stretch: 100%; + font-display: swap; + src: url(https://fonts.gstatic.com/s/robotoflex/v9/NaNeepOXO_NexZs0b5QrzlOHb8wCikXpYqmZsWI-__OGfttPZktqc2VdZ80KvCLZaPcSBZtOx2MifRuWR28sPJtUMbsFEK6cRrleUx9Xgbm3WLHa_F4Ep4Fm0PN19Ik5Dntczx0wZGzhPlL1YNMYKbv9_1IQXOw7AiUJVXRrV8cWW4O8LJCoXjCnwSRSaLshNP1d9-4mF9lp.woff2) + format("woff2"); + unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, + U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, + U+1EA0-1EF9, U+20AB; +} +/* latin-ext */ +@font-face { + font-family: "Roboto Flex"; + font-style: normal; + font-weight: 100; + font-stretch: 100%; + font-display: swap; + src: url(https://fonts.gstatic.com/s/robotoflex/v9/NaNeepOXO_NexZs0b5QrzlOHb8wCikXpYqmZsWI-__OGfttPZktqc2VdZ80KvCLZaPcSBZtOx2MifRuWR28sPJtUMbsFEK6cRrleUx9Xgbm3WLHa_F4Ep4Fm0PN19Ik5Dntczx0wZGzhPlL1YNMYKbv9_1IQXOw7AiUJVXRrV8cWW4O8LJCoXjCnwSRSaLshNP1d9-8mF9lp.woff2) + format("woff2"); + unicode-range: U+0100-02AF, U+0304, U+0308, U+0329, U+1E00-1E9F, U+1EF2-1EFF, + U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF; +} +/* latin */ +@font-face { + font-family: "Roboto Flex"; + font-style: normal; + font-weight: 100; + font-stretch: 100%; + font-display: swap; + src: url(https://fonts.gstatic.com/s/robotoflex/v9/NaNeepOXO_NexZs0b5QrzlOHb8wCikXpYqmZsWI-__OGfttPZktqc2VdZ80KvCLZaPcSBZtOx2MifRuWR28sPJtUMbsFEK6cRrleUx9Xgbm3WLHa_F4Ep4Fm0PN19Ik5Dntczx0wZGzhPlL1YNMYKbv9_1IQXOw7AiUJVXRrV8cWW4O8LJCoXjCnwSRSaLshNP1d9-EmFw.woff2) + format("woff2"); + unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, + U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, + U+2193, U+2212, U+2215, U+FEFF, U+FFFD; +} +/* cyrillic-ext */ +@font-face { + font-family: "Roboto Flex"; + font-style: normal; + font-weight: 200; + font-stretch: 100%; + font-display: swap; + src: url(https://fonts.gstatic.com/s/robotoflex/v9/NaNeepOXO_NexZs0b5QrzlOHb8wCikXpYqmZsWI-__OGfttPZktqc2VdZ80KvCLZaPcSBZtOx2MifRuWR28sPJtUMbsFEK6cRrleUx9Xgbm3WLHa_F4Ep4Fm0PN19Ik5Dntczx0wZGzhPlL1YNMYKbv9_1IQXOw7AiUJVXRrV8cWW4O8LJCoXjCnwSRSaLshNP1d9-wmF9lp.woff2) + format("woff2"); + unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, + U+FE2E-FE2F; +} +/* cyrillic */ +@font-face { + font-family: "Roboto Flex"; + font-style: normal; + font-weight: 200; + font-stretch: 100%; + font-display: swap; + src: url(https://fonts.gstatic.com/s/robotoflex/v9/NaNeepOXO_NexZs0b5QrzlOHb8wCikXpYqmZsWI-__OGfttPZktqc2VdZ80KvCLZaPcSBZtOx2MifRuWR28sPJtUMbsFEK6cRrleUx9Xgbm3WLHa_F4Ep4Fm0PN19Ik5Dntczx0wZGzhPlL1YNMYKbv9_1IQXOw7AiUJVXRrV8cWW4O8LJCoXjCnwSRSaLshNP1d9-UmF9lp.woff2) + format("woff2"); + unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; +} +/* greek */ +@font-face { + font-family: "Roboto Flex"; + font-style: normal; + font-weight: 200; + font-stretch: 100%; + font-display: swap; + src: url(https://fonts.gstatic.com/s/robotoflex/v9/NaNeepOXO_NexZs0b5QrzlOHb8wCikXpYqmZsWI-__OGfttPZktqc2VdZ80KvCLZaPcSBZtOx2MifRuWR28sPJtUMbsFEK6cRrleUx9Xgbm3WLHa_F4Ep4Fm0PN19Ik5Dntczx0wZGzhPlL1YNMYKbv9_1IQXOw7AiUJVXRrV8cWW4O8LJCoXjCnwSRSaLshNP1d9-ImF9lp.woff2) + format("woff2"); + unicode-range: U+0370-03FF; +} +/* vietnamese */ +@font-face { + font-family: "Roboto Flex"; + font-style: normal; + font-weight: 200; + font-stretch: 100%; + font-display: swap; + src: url(https://fonts.gstatic.com/s/robotoflex/v9/NaNeepOXO_NexZs0b5QrzlOHb8wCikXpYqmZsWI-__OGfttPZktqc2VdZ80KvCLZaPcSBZtOx2MifRuWR28sPJtUMbsFEK6cRrleUx9Xgbm3WLHa_F4Ep4Fm0PN19Ik5Dntczx0wZGzhPlL1YNMYKbv9_1IQXOw7AiUJVXRrV8cWW4O8LJCoXjCnwSRSaLshNP1d9-4mF9lp.woff2) + format("woff2"); + unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, + U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, + U+1EA0-1EF9, U+20AB; +} +/* latin-ext */ +@font-face { + font-family: "Roboto Flex"; + font-style: normal; + font-weight: 200; + font-stretch: 100%; + font-display: swap; + src: url(https://fonts.gstatic.com/s/robotoflex/v9/NaNeepOXO_NexZs0b5QrzlOHb8wCikXpYqmZsWI-__OGfttPZktqc2VdZ80KvCLZaPcSBZtOx2MifRuWR28sPJtUMbsFEK6cRrleUx9Xgbm3WLHa_F4Ep4Fm0PN19Ik5Dntczx0wZGzhPlL1YNMYKbv9_1IQXOw7AiUJVXRrV8cWW4O8LJCoXjCnwSRSaLshNP1d9-8mF9lp.woff2) + format("woff2"); + unicode-range: U+0100-02AF, U+0304, U+0308, U+0329, U+1E00-1E9F, U+1EF2-1EFF, + U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF; +} +/* latin */ +@font-face { + font-family: "Roboto Flex"; + font-style: normal; + font-weight: 200; + font-stretch: 100%; + font-display: swap; + src: url(https://fonts.gstatic.com/s/robotoflex/v9/NaNeepOXO_NexZs0b5QrzlOHb8wCikXpYqmZsWI-__OGfttPZktqc2VdZ80KvCLZaPcSBZtOx2MifRuWR28sPJtUMbsFEK6cRrleUx9Xgbm3WLHa_F4Ep4Fm0PN19Ik5Dntczx0wZGzhPlL1YNMYKbv9_1IQXOw7AiUJVXRrV8cWW4O8LJCoXjCnwSRSaLshNP1d9-EmFw.woff2) + format("woff2"); + unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, + U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, + U+2193, U+2212, U+2215, U+FEFF, U+FFFD; +} +/* cyrillic-ext */ +@font-face { + font-family: "Roboto Flex"; + font-style: normal; + font-weight: 300; + font-stretch: 100%; + font-display: swap; + src: url(https://fonts.gstatic.com/s/robotoflex/v9/NaNeepOXO_NexZs0b5QrzlOHb8wCikXpYqmZsWI-__OGfttPZktqc2VdZ80KvCLZaPcSBZtOx2MifRuWR28sPJtUMbsFEK6cRrleUx9Xgbm3WLHa_F4Ep4Fm0PN19Ik5Dntczx0wZGzhPlL1YNMYKbv9_1IQXOw7AiUJVXRrV8cWW4O8LJCoXjCnwSRSaLshNP1d9-wmF9lp.woff2) + format("woff2"); + unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, + U+FE2E-FE2F; +} +/* cyrillic */ +@font-face { + font-family: "Roboto Flex"; + font-style: normal; + font-weight: 300; + font-stretch: 100%; + font-display: swap; + src: url(https://fonts.gstatic.com/s/robotoflex/v9/NaNeepOXO_NexZs0b5QrzlOHb8wCikXpYqmZsWI-__OGfttPZktqc2VdZ80KvCLZaPcSBZtOx2MifRuWR28sPJtUMbsFEK6cRrleUx9Xgbm3WLHa_F4Ep4Fm0PN19Ik5Dntczx0wZGzhPlL1YNMYKbv9_1IQXOw7AiUJVXRrV8cWW4O8LJCoXjCnwSRSaLshNP1d9-UmF9lp.woff2) + format("woff2"); + unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; +} +/* greek */ +@font-face { + font-family: "Roboto Flex"; + font-style: normal; + font-weight: 300; + font-stretch: 100%; + font-display: swap; + src: url(https://fonts.gstatic.com/s/robotoflex/v9/NaNeepOXO_NexZs0b5QrzlOHb8wCikXpYqmZsWI-__OGfttPZktqc2VdZ80KvCLZaPcSBZtOx2MifRuWR28sPJtUMbsFEK6cRrleUx9Xgbm3WLHa_F4Ep4Fm0PN19Ik5Dntczx0wZGzhPlL1YNMYKbv9_1IQXOw7AiUJVXRrV8cWW4O8LJCoXjCnwSRSaLshNP1d9-ImF9lp.woff2) + format("woff2"); + unicode-range: U+0370-03FF; +} +/* vietnamese */ +@font-face { + font-family: "Roboto Flex"; + font-style: normal; + font-weight: 300; + font-stretch: 100%; + font-display: swap; + src: url(https://fonts.gstatic.com/s/robotoflex/v9/NaNeepOXO_NexZs0b5QrzlOHb8wCikXpYqmZsWI-__OGfttPZktqc2VdZ80KvCLZaPcSBZtOx2MifRuWR28sPJtUMbsFEK6cRrleUx9Xgbm3WLHa_F4Ep4Fm0PN19Ik5Dntczx0wZGzhPlL1YNMYKbv9_1IQXOw7AiUJVXRrV8cWW4O8LJCoXjCnwSRSaLshNP1d9-4mF9lp.woff2) + format("woff2"); + unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, + U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, + U+1EA0-1EF9, U+20AB; +} +/* latin-ext */ +@font-face { + font-family: "Roboto Flex"; + font-style: normal; + font-weight: 300; + font-stretch: 100%; + font-display: swap; + src: url(https://fonts.gstatic.com/s/robotoflex/v9/NaNeepOXO_NexZs0b5QrzlOHb8wCikXpYqmZsWI-__OGfttPZktqc2VdZ80KvCLZaPcSBZtOx2MifRuWR28sPJtUMbsFEK6cRrleUx9Xgbm3WLHa_F4Ep4Fm0PN19Ik5Dntczx0wZGzhPlL1YNMYKbv9_1IQXOw7AiUJVXRrV8cWW4O8LJCoXjCnwSRSaLshNP1d9-8mF9lp.woff2) + format("woff2"); + unicode-range: U+0100-02AF, U+0304, U+0308, U+0329, U+1E00-1E9F, U+1EF2-1EFF, + U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF; +} +/* latin */ +@font-face { + font-family: "Roboto Flex"; + font-style: normal; + font-weight: 300; + font-stretch: 100%; + font-display: swap; + src: url(https://fonts.gstatic.com/s/robotoflex/v9/NaNeepOXO_NexZs0b5QrzlOHb8wCikXpYqmZsWI-__OGfttPZktqc2VdZ80KvCLZaPcSBZtOx2MifRuWR28sPJtUMbsFEK6cRrleUx9Xgbm3WLHa_F4Ep4Fm0PN19Ik5Dntczx0wZGzhPlL1YNMYKbv9_1IQXOw7AiUJVXRrV8cWW4O8LJCoXjCnwSRSaLshNP1d9-EmFw.woff2) + format("woff2"); + unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, + U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, + U+2193, U+2212, U+2215, U+FEFF, U+FFFD; +} +/* cyrillic-ext */ +@font-face { + font-family: "Roboto Flex"; + font-style: normal; + font-weight: 400; + font-stretch: 100%; + font-display: swap; + src: url(https://fonts.gstatic.com/s/robotoflex/v9/NaNeepOXO_NexZs0b5QrzlOHb8wCikXpYqmZsWI-__OGfttPZktqc2VdZ80KvCLZaPcSBZtOx2MifRuWR28sPJtUMbsFEK6cRrleUx9Xgbm3WLHa_F4Ep4Fm0PN19Ik5Dntczx0wZGzhPlL1YNMYKbv9_1IQXOw7AiUJVXRrV8cWW4O8LJCoXjCnwSRSaLshNP1d9-wmF9lp.woff2) + format("woff2"); + unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, + U+FE2E-FE2F; +} +/* cyrillic */ +@font-face { + font-family: "Roboto Flex"; + font-style: normal; + font-weight: 400; + font-stretch: 100%; + font-display: swap; + src: url(https://fonts.gstatic.com/s/robotoflex/v9/NaNeepOXO_NexZs0b5QrzlOHb8wCikXpYqmZsWI-__OGfttPZktqc2VdZ80KvCLZaPcSBZtOx2MifRuWR28sPJtUMbsFEK6cRrleUx9Xgbm3WLHa_F4Ep4Fm0PN19Ik5Dntczx0wZGzhPlL1YNMYKbv9_1IQXOw7AiUJVXRrV8cWW4O8LJCoXjCnwSRSaLshNP1d9-UmF9lp.woff2) + format("woff2"); + unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; +} +/* greek */ +@font-face { + font-family: "Roboto Flex"; + font-style: normal; + font-weight: 400; + font-stretch: 100%; + font-display: swap; + src: url(https://fonts.gstatic.com/s/robotoflex/v9/NaNeepOXO_NexZs0b5QrzlOHb8wCikXpYqmZsWI-__OGfttPZktqc2VdZ80KvCLZaPcSBZtOx2MifRuWR28sPJtUMbsFEK6cRrleUx9Xgbm3WLHa_F4Ep4Fm0PN19Ik5Dntczx0wZGzhPlL1YNMYKbv9_1IQXOw7AiUJVXRrV8cWW4O8LJCoXjCnwSRSaLshNP1d9-ImF9lp.woff2) + format("woff2"); + unicode-range: U+0370-03FF; +} +/* vietnamese */ +@font-face { + font-family: "Roboto Flex"; + font-style: normal; + font-weight: 400; + font-stretch: 100%; + font-display: swap; + src: url(https://fonts.gstatic.com/s/robotoflex/v9/NaNeepOXO_NexZs0b5QrzlOHb8wCikXpYqmZsWI-__OGfttPZktqc2VdZ80KvCLZaPcSBZtOx2MifRuWR28sPJtUMbsFEK6cRrleUx9Xgbm3WLHa_F4Ep4Fm0PN19Ik5Dntczx0wZGzhPlL1YNMYKbv9_1IQXOw7AiUJVXRrV8cWW4O8LJCoXjCnwSRSaLshNP1d9-4mF9lp.woff2) + format("woff2"); + unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, + U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, + U+1EA0-1EF9, U+20AB; +} +/* latin-ext */ +@font-face { + font-family: "Roboto Flex"; + font-style: normal; + font-weight: 400; + font-stretch: 100%; + font-display: swap; + src: url(https://fonts.gstatic.com/s/robotoflex/v9/NaNeepOXO_NexZs0b5QrzlOHb8wCikXpYqmZsWI-__OGfttPZktqc2VdZ80KvCLZaPcSBZtOx2MifRuWR28sPJtUMbsFEK6cRrleUx9Xgbm3WLHa_F4Ep4Fm0PN19Ik5Dntczx0wZGzhPlL1YNMYKbv9_1IQXOw7AiUJVXRrV8cWW4O8LJCoXjCnwSRSaLshNP1d9-8mF9lp.woff2) + format("woff2"); + unicode-range: U+0100-02AF, U+0304, U+0308, U+0329, U+1E00-1E9F, U+1EF2-1EFF, + U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF; +} +/* latin */ +@font-face { + font-family: "Roboto Flex"; + font-style: normal; + font-weight: 400; + font-stretch: 100%; + font-display: swap; + src: url(https://fonts.gstatic.com/s/robotoflex/v9/NaNeepOXO_NexZs0b5QrzlOHb8wCikXpYqmZsWI-__OGfttPZktqc2VdZ80KvCLZaPcSBZtOx2MifRuWR28sPJtUMbsFEK6cRrleUx9Xgbm3WLHa_F4Ep4Fm0PN19Ik5Dntczx0wZGzhPlL1YNMYKbv9_1IQXOw7AiUJVXRrV8cWW4O8LJCoXjCnwSRSaLshNP1d9-EmFw.woff2) + format("woff2"); + unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, + U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, + U+2193, U+2212, U+2215, U+FEFF, U+FFFD; +} +/* cyrillic-ext */ +@font-face { + font-family: "Roboto Flex"; + font-style: normal; + font-weight: 500; + font-stretch: 100%; + font-display: swap; + src: url(https://fonts.gstatic.com/s/robotoflex/v9/NaNeepOXO_NexZs0b5QrzlOHb8wCikXpYqmZsWI-__OGfttPZktqc2VdZ80KvCLZaPcSBZtOx2MifRuWR28sPJtUMbsFEK6cRrleUx9Xgbm3WLHa_F4Ep4Fm0PN19Ik5Dntczx0wZGzhPlL1YNMYKbv9_1IQXOw7AiUJVXRrV8cWW4O8LJCoXjCnwSRSaLshNP1d9-wmF9lp.woff2) + format("woff2"); + unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, + U+FE2E-FE2F; +} +/* cyrillic */ +@font-face { + font-family: "Roboto Flex"; + font-style: normal; + font-weight: 500; + font-stretch: 100%; + font-display: swap; + src: url(https://fonts.gstatic.com/s/robotoflex/v9/NaNeepOXO_NexZs0b5QrzlOHb8wCikXpYqmZsWI-__OGfttPZktqc2VdZ80KvCLZaPcSBZtOx2MifRuWR28sPJtUMbsFEK6cRrleUx9Xgbm3WLHa_F4Ep4Fm0PN19Ik5Dntczx0wZGzhPlL1YNMYKbv9_1IQXOw7AiUJVXRrV8cWW4O8LJCoXjCnwSRSaLshNP1d9-UmF9lp.woff2) + format("woff2"); + unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; +} +/* greek */ +@font-face { + font-family: "Roboto Flex"; + font-style: normal; + font-weight: 500; + font-stretch: 100%; + font-display: swap; + src: url(https://fonts.gstatic.com/s/robotoflex/v9/NaNeepOXO_NexZs0b5QrzlOHb8wCikXpYqmZsWI-__OGfttPZktqc2VdZ80KvCLZaPcSBZtOx2MifRuWR28sPJtUMbsFEK6cRrleUx9Xgbm3WLHa_F4Ep4Fm0PN19Ik5Dntczx0wZGzhPlL1YNMYKbv9_1IQXOw7AiUJVXRrV8cWW4O8LJCoXjCnwSRSaLshNP1d9-ImF9lp.woff2) + format("woff2"); + unicode-range: U+0370-03FF; +} +/* vietnamese */ +@font-face { + font-family: "Roboto Flex"; + font-style: normal; + font-weight: 500; + font-stretch: 100%; + font-display: swap; + src: url(https://fonts.gstatic.com/s/robotoflex/v9/NaNeepOXO_NexZs0b5QrzlOHb8wCikXpYqmZsWI-__OGfttPZktqc2VdZ80KvCLZaPcSBZtOx2MifRuWR28sPJtUMbsFEK6cRrleUx9Xgbm3WLHa_F4Ep4Fm0PN19Ik5Dntczx0wZGzhPlL1YNMYKbv9_1IQXOw7AiUJVXRrV8cWW4O8LJCoXjCnwSRSaLshNP1d9-4mF9lp.woff2) + format("woff2"); + unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, + U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, + U+1EA0-1EF9, U+20AB; +} +/* latin-ext */ +@font-face { + font-family: "Roboto Flex"; + font-style: normal; + font-weight: 500; + font-stretch: 100%; + font-display: swap; + src: url(https://fonts.gstatic.com/s/robotoflex/v9/NaNeepOXO_NexZs0b5QrzlOHb8wCikXpYqmZsWI-__OGfttPZktqc2VdZ80KvCLZaPcSBZtOx2MifRuWR28sPJtUMbsFEK6cRrleUx9Xgbm3WLHa_F4Ep4Fm0PN19Ik5Dntczx0wZGzhPlL1YNMYKbv9_1IQXOw7AiUJVXRrV8cWW4O8LJCoXjCnwSRSaLshNP1d9-8mF9lp.woff2) + format("woff2"); + unicode-range: U+0100-02AF, U+0304, U+0308, U+0329, U+1E00-1E9F, U+1EF2-1EFF, + U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF; +} +/* latin */ +@font-face { + font-family: "Roboto Flex"; + font-style: normal; + font-weight: 500; + font-stretch: 100%; + font-display: swap; + src: url(https://fonts.gstatic.com/s/robotoflex/v9/NaNeepOXO_NexZs0b5QrzlOHb8wCikXpYqmZsWI-__OGfttPZktqc2VdZ80KvCLZaPcSBZtOx2MifRuWR28sPJtUMbsFEK6cRrleUx9Xgbm3WLHa_F4Ep4Fm0PN19Ik5Dntczx0wZGzhPlL1YNMYKbv9_1IQXOw7AiUJVXRrV8cWW4O8LJCoXjCnwSRSaLshNP1d9-EmFw.woff2) + format("woff2"); + unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, + U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, + U+2193, U+2212, U+2215, U+FEFF, U+FFFD; +} +/* cyrillic-ext */ +@font-face { + font-family: "Roboto Flex"; + font-style: normal; + font-weight: 600; + font-stretch: 100%; + font-display: swap; + src: url(https://fonts.gstatic.com/s/robotoflex/v9/NaNeepOXO_NexZs0b5QrzlOHb8wCikXpYqmZsWI-__OGfttPZktqc2VdZ80KvCLZaPcSBZtOx2MifRuWR28sPJtUMbsFEK6cRrleUx9Xgbm3WLHa_F4Ep4Fm0PN19Ik5Dntczx0wZGzhPlL1YNMYKbv9_1IQXOw7AiUJVXRrV8cWW4O8LJCoXjCnwSRSaLshNP1d9-wmF9lp.woff2) + format("woff2"); + unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, + U+FE2E-FE2F; +} +/* cyrillic */ +@font-face { + font-family: "Roboto Flex"; + font-style: normal; + font-weight: 600; + font-stretch: 100%; + font-display: swap; + src: url(https://fonts.gstatic.com/s/robotoflex/v9/NaNeepOXO_NexZs0b5QrzlOHb8wCikXpYqmZsWI-__OGfttPZktqc2VdZ80KvCLZaPcSBZtOx2MifRuWR28sPJtUMbsFEK6cRrleUx9Xgbm3WLHa_F4Ep4Fm0PN19Ik5Dntczx0wZGzhPlL1YNMYKbv9_1IQXOw7AiUJVXRrV8cWW4O8LJCoXjCnwSRSaLshNP1d9-UmF9lp.woff2) + format("woff2"); + unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; +} +/* greek */ +@font-face { + font-family: "Roboto Flex"; + font-style: normal; + font-weight: 600; + font-stretch: 100%; + font-display: swap; + src: url(https://fonts.gstatic.com/s/robotoflex/v9/NaNeepOXO_NexZs0b5QrzlOHb8wCikXpYqmZsWI-__OGfttPZktqc2VdZ80KvCLZaPcSBZtOx2MifRuWR28sPJtUMbsFEK6cRrleUx9Xgbm3WLHa_F4Ep4Fm0PN19Ik5Dntczx0wZGzhPlL1YNMYKbv9_1IQXOw7AiUJVXRrV8cWW4O8LJCoXjCnwSRSaLshNP1d9-ImF9lp.woff2) + format("woff2"); + unicode-range: U+0370-03FF; +} +/* vietnamese */ +@font-face { + font-family: "Roboto Flex"; + font-style: normal; + font-weight: 600; + font-stretch: 100%; + font-display: swap; + src: url(https://fonts.gstatic.com/s/robotoflex/v9/NaNeepOXO_NexZs0b5QrzlOHb8wCikXpYqmZsWI-__OGfttPZktqc2VdZ80KvCLZaPcSBZtOx2MifRuWR28sPJtUMbsFEK6cRrleUx9Xgbm3WLHa_F4Ep4Fm0PN19Ik5Dntczx0wZGzhPlL1YNMYKbv9_1IQXOw7AiUJVXRrV8cWW4O8LJCoXjCnwSRSaLshNP1d9-4mF9lp.woff2) + format("woff2"); + unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, + U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, + U+1EA0-1EF9, U+20AB; +} +/* latin-ext */ +@font-face { + font-family: "Roboto Flex"; + font-style: normal; + font-weight: 600; + font-stretch: 100%; + font-display: swap; + src: url(https://fonts.gstatic.com/s/robotoflex/v9/NaNeepOXO_NexZs0b5QrzlOHb8wCikXpYqmZsWI-__OGfttPZktqc2VdZ80KvCLZaPcSBZtOx2MifRuWR28sPJtUMbsFEK6cRrleUx9Xgbm3WLHa_F4Ep4Fm0PN19Ik5Dntczx0wZGzhPlL1YNMYKbv9_1IQXOw7AiUJVXRrV8cWW4O8LJCoXjCnwSRSaLshNP1d9-8mF9lp.woff2) + format("woff2"); + unicode-range: U+0100-02AF, U+0304, U+0308, U+0329, U+1E00-1E9F, U+1EF2-1EFF, + U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF; +} +/* latin */ +@font-face { + font-family: "Roboto Flex"; + font-style: normal; + font-weight: 600; + font-stretch: 100%; + font-display: swap; + src: url(https://fonts.gstatic.com/s/robotoflex/v9/NaNeepOXO_NexZs0b5QrzlOHb8wCikXpYqmZsWI-__OGfttPZktqc2VdZ80KvCLZaPcSBZtOx2MifRuWR28sPJtUMbsFEK6cRrleUx9Xgbm3WLHa_F4Ep4Fm0PN19Ik5Dntczx0wZGzhPlL1YNMYKbv9_1IQXOw7AiUJVXRrV8cWW4O8LJCoXjCnwSRSaLshNP1d9-EmFw.woff2) + format("woff2"); + unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, + U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, + U+2193, U+2212, U+2215, U+FEFF, U+FFFD; +} +/* cyrillic-ext */ +@font-face { + font-family: "Roboto Flex"; + font-style: normal; + font-weight: 700; + font-stretch: 100%; + font-display: swap; + src: url(https://fonts.gstatic.com/s/robotoflex/v9/NaNeepOXO_NexZs0b5QrzlOHb8wCikXpYqmZsWI-__OGfttPZktqc2VdZ80KvCLZaPcSBZtOx2MifRuWR28sPJtUMbsFEK6cRrleUx9Xgbm3WLHa_F4Ep4Fm0PN19Ik5Dntczx0wZGzhPlL1YNMYKbv9_1IQXOw7AiUJVXRrV8cWW4O8LJCoXjCnwSRSaLshNP1d9-wmF9lp.woff2) + format("woff2"); + unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, + U+FE2E-FE2F; +} +/* cyrillic */ +@font-face { + font-family: "Roboto Flex"; + font-style: normal; + font-weight: 700; + font-stretch: 100%; + font-display: swap; + src: url(https://fonts.gstatic.com/s/robotoflex/v9/NaNeepOXO_NexZs0b5QrzlOHb8wCikXpYqmZsWI-__OGfttPZktqc2VdZ80KvCLZaPcSBZtOx2MifRuWR28sPJtUMbsFEK6cRrleUx9Xgbm3WLHa_F4Ep4Fm0PN19Ik5Dntczx0wZGzhPlL1YNMYKbv9_1IQXOw7AiUJVXRrV8cWW4O8LJCoXjCnwSRSaLshNP1d9-UmF9lp.woff2) + format("woff2"); + unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; +} +/* greek */ +@font-face { + font-family: "Roboto Flex"; + font-style: normal; + font-weight: 700; + font-stretch: 100%; + font-display: swap; + src: url(https://fonts.gstatic.com/s/robotoflex/v9/NaNeepOXO_NexZs0b5QrzlOHb8wCikXpYqmZsWI-__OGfttPZktqc2VdZ80KvCLZaPcSBZtOx2MifRuWR28sPJtUMbsFEK6cRrleUx9Xgbm3WLHa_F4Ep4Fm0PN19Ik5Dntczx0wZGzhPlL1YNMYKbv9_1IQXOw7AiUJVXRrV8cWW4O8LJCoXjCnwSRSaLshNP1d9-ImF9lp.woff2) + format("woff2"); + unicode-range: U+0370-03FF; +} +/* vietnamese */ +@font-face { + font-family: "Roboto Flex"; + font-style: normal; + font-weight: 700; + font-stretch: 100%; + font-display: swap; + src: url(https://fonts.gstatic.com/s/robotoflex/v9/NaNeepOXO_NexZs0b5QrzlOHb8wCikXpYqmZsWI-__OGfttPZktqc2VdZ80KvCLZaPcSBZtOx2MifRuWR28sPJtUMbsFEK6cRrleUx9Xgbm3WLHa_F4Ep4Fm0PN19Ik5Dntczx0wZGzhPlL1YNMYKbv9_1IQXOw7AiUJVXRrV8cWW4O8LJCoXjCnwSRSaLshNP1d9-4mF9lp.woff2) + format("woff2"); + unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, + U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, + U+1EA0-1EF9, U+20AB; +} +/* latin-ext */ +@font-face { + font-family: "Roboto Flex"; + font-style: normal; + font-weight: 700; + font-stretch: 100%; + font-display: swap; + src: url(https://fonts.gstatic.com/s/robotoflex/v9/NaNeepOXO_NexZs0b5QrzlOHb8wCikXpYqmZsWI-__OGfttPZktqc2VdZ80KvCLZaPcSBZtOx2MifRuWR28sPJtUMbsFEK6cRrleUx9Xgbm3WLHa_F4Ep4Fm0PN19Ik5Dntczx0wZGzhPlL1YNMYKbv9_1IQXOw7AiUJVXRrV8cWW4O8LJCoXjCnwSRSaLshNP1d9-8mF9lp.woff2) + format("woff2"); + unicode-range: U+0100-02AF, U+0304, U+0308, U+0329, U+1E00-1E9F, U+1EF2-1EFF, + U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF; +} +/* latin */ +@font-face { + font-family: "Roboto Flex"; + font-style: normal; + font-weight: 700; + font-stretch: 100%; + font-display: swap; + src: url(https://fonts.gstatic.com/s/robotoflex/v9/NaNeepOXO_NexZs0b5QrzlOHb8wCikXpYqmZsWI-__OGfttPZktqc2VdZ80KvCLZaPcSBZtOx2MifRuWR28sPJtUMbsFEK6cRrleUx9Xgbm3WLHa_F4Ep4Fm0PN19Ik5Dntczx0wZGzhPlL1YNMYKbv9_1IQXOw7AiUJVXRrV8cWW4O8LJCoXjCnwSRSaLshNP1d9-EmFw.woff2) + format("woff2"); + unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, + U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, + U+2193, U+2212, U+2215, U+FEFF, U+FFFD; +} +/* cyrillic-ext */ +@font-face { + font-family: "Roboto Flex"; + font-style: normal; + font-weight: 800; + font-stretch: 100%; + font-display: swap; + src: url(https://fonts.gstatic.com/s/robotoflex/v9/NaNeepOXO_NexZs0b5QrzlOHb8wCikXpYqmZsWI-__OGfttPZktqc2VdZ80KvCLZaPcSBZtOx2MifRuWR28sPJtUMbsFEK6cRrleUx9Xgbm3WLHa_F4Ep4Fm0PN19Ik5Dntczx0wZGzhPlL1YNMYKbv9_1IQXOw7AiUJVXRrV8cWW4O8LJCoXjCnwSRSaLshNP1d9-wmF9lp.woff2) + format("woff2"); + unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, + U+FE2E-FE2F; +} +/* cyrillic */ +@font-face { + font-family: "Roboto Flex"; + font-style: normal; + font-weight: 800; + font-stretch: 100%; + font-display: swap; + src: url(https://fonts.gstatic.com/s/robotoflex/v9/NaNeepOXO_NexZs0b5QrzlOHb8wCikXpYqmZsWI-__OGfttPZktqc2VdZ80KvCLZaPcSBZtOx2MifRuWR28sPJtUMbsFEK6cRrleUx9Xgbm3WLHa_F4Ep4Fm0PN19Ik5Dntczx0wZGzhPlL1YNMYKbv9_1IQXOw7AiUJVXRrV8cWW4O8LJCoXjCnwSRSaLshNP1d9-UmF9lp.woff2) + format("woff2"); + unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; +} +/* greek */ +@font-face { + font-family: "Roboto Flex"; + font-style: normal; + font-weight: 800; + font-stretch: 100%; + font-display: swap; + src: url(https://fonts.gstatic.com/s/robotoflex/v9/NaNeepOXO_NexZs0b5QrzlOHb8wCikXpYqmZsWI-__OGfttPZktqc2VdZ80KvCLZaPcSBZtOx2MifRuWR28sPJtUMbsFEK6cRrleUx9Xgbm3WLHa_F4Ep4Fm0PN19Ik5Dntczx0wZGzhPlL1YNMYKbv9_1IQXOw7AiUJVXRrV8cWW4O8LJCoXjCnwSRSaLshNP1d9-ImF9lp.woff2) + format("woff2"); + unicode-range: U+0370-03FF; +} +/* vietnamese */ +@font-face { + font-family: "Roboto Flex"; + font-style: normal; + font-weight: 800; + font-stretch: 100%; + font-display: swap; + src: url(https://fonts.gstatic.com/s/robotoflex/v9/NaNeepOXO_NexZs0b5QrzlOHb8wCikXpYqmZsWI-__OGfttPZktqc2VdZ80KvCLZaPcSBZtOx2MifRuWR28sPJtUMbsFEK6cRrleUx9Xgbm3WLHa_F4Ep4Fm0PN19Ik5Dntczx0wZGzhPlL1YNMYKbv9_1IQXOw7AiUJVXRrV8cWW4O8LJCoXjCnwSRSaLshNP1d9-4mF9lp.woff2) + format("woff2"); + unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, + U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, + U+1EA0-1EF9, U+20AB; +} +/* latin-ext */ +@font-face { + font-family: "Roboto Flex"; + font-style: normal; + font-weight: 800; + font-stretch: 100%; + font-display: swap; + src: url(https://fonts.gstatic.com/s/robotoflex/v9/NaNeepOXO_NexZs0b5QrzlOHb8wCikXpYqmZsWI-__OGfttPZktqc2VdZ80KvCLZaPcSBZtOx2MifRuWR28sPJtUMbsFEK6cRrleUx9Xgbm3WLHa_F4Ep4Fm0PN19Ik5Dntczx0wZGzhPlL1YNMYKbv9_1IQXOw7AiUJVXRrV8cWW4O8LJCoXjCnwSRSaLshNP1d9-8mF9lp.woff2) + format("woff2"); + unicode-range: U+0100-02AF, U+0304, U+0308, U+0329, U+1E00-1E9F, U+1EF2-1EFF, + U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF; +} +/* latin */ +@font-face { + font-family: "Roboto Flex"; + font-style: normal; + font-weight: 800; + font-stretch: 100%; + font-display: swap; + src: url(https://fonts.gstatic.com/s/robotoflex/v9/NaNeepOXO_NexZs0b5QrzlOHb8wCikXpYqmZsWI-__OGfttPZktqc2VdZ80KvCLZaPcSBZtOx2MifRuWR28sPJtUMbsFEK6cRrleUx9Xgbm3WLHa_F4Ep4Fm0PN19Ik5Dntczx0wZGzhPlL1YNMYKbv9_1IQXOw7AiUJVXRrV8cWW4O8LJCoXjCnwSRSaLshNP1d9-EmFw.woff2) + format("woff2"); + unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, + U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, + U+2193, U+2212, U+2215, U+FEFF, U+FFFD; +} +/* cyrillic-ext */ +@font-face { + font-family: "Roboto Flex"; + font-style: normal; + font-weight: 900; + font-stretch: 100%; + font-display: swap; + src: url(https://fonts.gstatic.com/s/robotoflex/v9/NaNeepOXO_NexZs0b5QrzlOHb8wCikXpYqmZsWI-__OGfttPZktqc2VdZ80KvCLZaPcSBZtOx2MifRuWR28sPJtUMbsFEK6cRrleUx9Xgbm3WLHa_F4Ep4Fm0PN19Ik5Dntczx0wZGzhPlL1YNMYKbv9_1IQXOw7AiUJVXRrV8cWW4O8LJCoXjCnwSRSaLshNP1d9-wmF9lp.woff2) + format("woff2"); + unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, + U+FE2E-FE2F; +} +/* cyrillic */ +@font-face { + font-family: "Roboto Flex"; + font-style: normal; + font-weight: 900; + font-stretch: 100%; + font-display: swap; + src: url(https://fonts.gstatic.com/s/robotoflex/v9/NaNeepOXO_NexZs0b5QrzlOHb8wCikXpYqmZsWI-__OGfttPZktqc2VdZ80KvCLZaPcSBZtOx2MifRuWR28sPJtUMbsFEK6cRrleUx9Xgbm3WLHa_F4Ep4Fm0PN19Ik5Dntczx0wZGzhPlL1YNMYKbv9_1IQXOw7AiUJVXRrV8cWW4O8LJCoXjCnwSRSaLshNP1d9-UmF9lp.woff2) + format("woff2"); + unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; +} +/* greek */ +@font-face { + font-family: "Roboto Flex"; + font-style: normal; + font-weight: 900; + font-stretch: 100%; + font-display: swap; + src: url(https://fonts.gstatic.com/s/robotoflex/v9/NaNeepOXO_NexZs0b5QrzlOHb8wCikXpYqmZsWI-__OGfttPZktqc2VdZ80KvCLZaPcSBZtOx2MifRuWR28sPJtUMbsFEK6cRrleUx9Xgbm3WLHa_F4Ep4Fm0PN19Ik5Dntczx0wZGzhPlL1YNMYKbv9_1IQXOw7AiUJVXRrV8cWW4O8LJCoXjCnwSRSaLshNP1d9-ImF9lp.woff2) + format("woff2"); + unicode-range: U+0370-03FF; +} +/* vietnamese */ +@font-face { + font-family: "Roboto Flex"; + font-style: normal; + font-weight: 900; + font-stretch: 100%; + font-display: swap; + src: url(https://fonts.gstatic.com/s/robotoflex/v9/NaNeepOXO_NexZs0b5QrzlOHb8wCikXpYqmZsWI-__OGfttPZktqc2VdZ80KvCLZaPcSBZtOx2MifRuWR28sPJtUMbsFEK6cRrleUx9Xgbm3WLHa_F4Ep4Fm0PN19Ik5Dntczx0wZGzhPlL1YNMYKbv9_1IQXOw7AiUJVXRrV8cWW4O8LJCoXjCnwSRSaLshNP1d9-4mF9lp.woff2) + format("woff2"); + unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, + U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, + U+1EA0-1EF9, U+20AB; +} +/* latin-ext */ +@font-face { + font-family: "Roboto Flex"; + font-style: normal; + font-weight: 900; + font-stretch: 100%; + font-display: swap; + src: url(https://fonts.gstatic.com/s/robotoflex/v9/NaNeepOXO_NexZs0b5QrzlOHb8wCikXpYqmZsWI-__OGfttPZktqc2VdZ80KvCLZaPcSBZtOx2MifRuWR28sPJtUMbsFEK6cRrleUx9Xgbm3WLHa_F4Ep4Fm0PN19Ik5Dntczx0wZGzhPlL1YNMYKbv9_1IQXOw7AiUJVXRrV8cWW4O8LJCoXjCnwSRSaLshNP1d9-8mF9lp.woff2) + format("woff2"); + unicode-range: U+0100-02AF, U+0304, U+0308, U+0329, U+1E00-1E9F, U+1EF2-1EFF, + U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF; +} +/* latin */ +@font-face { + font-family: "Roboto Flex"; + font-style: normal; + font-weight: 900; + font-stretch: 100%; + font-display: swap; + src: url(https://fonts.gstatic.com/s/robotoflex/v9/NaNeepOXO_NexZs0b5QrzlOHb8wCikXpYqmZsWI-__OGfttPZktqc2VdZ80KvCLZaPcSBZtOx2MifRuWR28sPJtUMbsFEK6cRrleUx9Xgbm3WLHa_F4Ep4Fm0PN19Ik5Dntczx0wZGzhPlL1YNMYKbv9_1IQXOw7AiUJVXRrV8cWW4O8LJCoXjCnwSRSaLshNP1d9-EmFw.woff2) + format("woff2"); + unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, + U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, + U+2193, U+2212, U+2215, U+FEFF, U+FFFD; +} +/* cyrillic-ext */ +@font-face { + font-family: "Roboto Flex"; + font-style: normal; + font-weight: 1000; + font-stretch: 100%; + font-display: swap; + src: url(https://fonts.gstatic.com/s/robotoflex/v9/NaNeepOXO_NexZs0b5QrzlOHb8wCikXpYqmZsWI-__OGfttPZktqc2VdZ80KvCLZaPcSBZtOx2MifRuWR28sPJtUMbsFEK6cRrleUx9Xgbm3WLHa_F4Ep4Fm0PN19Ik5Dntczx0wZGzhPlL1YNMYKbv9_1IQXOw7AiUJVXRrV8cWW4O8LJCoXjCnwSRSaLshNP1d9-wmF9lp.woff2) + format("woff2"); + unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, + U+FE2E-FE2F; +} +/* cyrillic */ +@font-face { + font-family: "Roboto Flex"; + font-style: normal; + font-weight: 1000; + font-stretch: 100%; + font-display: swap; + src: url(https://fonts.gstatic.com/s/robotoflex/v9/NaNeepOXO_NexZs0b5QrzlOHb8wCikXpYqmZsWI-__OGfttPZktqc2VdZ80KvCLZaPcSBZtOx2MifRuWR28sPJtUMbsFEK6cRrleUx9Xgbm3WLHa_F4Ep4Fm0PN19Ik5Dntczx0wZGzhPlL1YNMYKbv9_1IQXOw7AiUJVXRrV8cWW4O8LJCoXjCnwSRSaLshNP1d9-UmF9lp.woff2) + format("woff2"); + unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; +} +/* greek */ +@font-face { + font-family: "Roboto Flex"; + font-style: normal; + font-weight: 1000; + font-stretch: 100%; + font-display: swap; + src: url(https://fonts.gstatic.com/s/robotoflex/v9/NaNeepOXO_NexZs0b5QrzlOHb8wCikXpYqmZsWI-__OGfttPZktqc2VdZ80KvCLZaPcSBZtOx2MifRuWR28sPJtUMbsFEK6cRrleUx9Xgbm3WLHa_F4Ep4Fm0PN19Ik5Dntczx0wZGzhPlL1YNMYKbv9_1IQXOw7AiUJVXRrV8cWW4O8LJCoXjCnwSRSaLshNP1d9-ImF9lp.woff2) + format("woff2"); + unicode-range: U+0370-03FF; +} +/* vietnamese */ +@font-face { + font-family: "Roboto Flex"; + font-style: normal; + font-weight: 1000; + font-stretch: 100%; + font-display: swap; + src: url(https://fonts.gstatic.com/s/robotoflex/v9/NaNeepOXO_NexZs0b5QrzlOHb8wCikXpYqmZsWI-__OGfttPZktqc2VdZ80KvCLZaPcSBZtOx2MifRuWR28sPJtUMbsFEK6cRrleUx9Xgbm3WLHa_F4Ep4Fm0PN19Ik5Dntczx0wZGzhPlL1YNMYKbv9_1IQXOw7AiUJVXRrV8cWW4O8LJCoXjCnwSRSaLshNP1d9-4mF9lp.woff2) + format("woff2"); + unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, + U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, + U+1EA0-1EF9, U+20AB; +} +/* latin-ext */ +@font-face { + font-family: "Roboto Flex"; + font-style: normal; + font-weight: 1000; + font-stretch: 100%; + font-display: swap; + src: url(https://fonts.gstatic.com/s/robotoflex/v9/NaNeepOXO_NexZs0b5QrzlOHb8wCikXpYqmZsWI-__OGfttPZktqc2VdZ80KvCLZaPcSBZtOx2MifRuWR28sPJtUMbsFEK6cRrleUx9Xgbm3WLHa_F4Ep4Fm0PN19Ik5Dntczx0wZGzhPlL1YNMYKbv9_1IQXOw7AiUJVXRrV8cWW4O8LJCoXjCnwSRSaLshNP1d9-8mF9lp.woff2) + format("woff2"); + unicode-range: U+0100-02AF, U+0304, U+0308, U+0329, U+1E00-1E9F, U+1EF2-1EFF, + U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF; +} +/* latin */ +@font-face { + font-family: "Roboto Flex"; + font-style: normal; + font-weight: 1000; + font-stretch: 100%; + font-display: swap; + src: url(https://fonts.gstatic.com/s/robotoflex/v9/NaNeepOXO_NexZs0b5QrzlOHb8wCikXpYqmZsWI-__OGfttPZktqc2VdZ80KvCLZaPcSBZtOx2MifRuWR28sPJtUMbsFEK6cRrleUx9Xgbm3WLHa_F4Ep4Fm0PN19Ik5Dntczx0wZGzhPlL1YNMYKbv9_1IQXOw7AiUJVXRrV8cWW4O8LJCoXjCnwSRSaLshNP1d9-EmFw.woff2) + format("woff2"); + unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, + U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, + U+2193, U+2212, U+2215, U+FEFF, U+FFFD; +} +/* cyrillic-ext */ +@font-face { + font-family: "Roboto Mono"; + font-style: italic; + font-weight: 100; + font-display: swap; + src: url(https://fonts.gstatic.com/s/robotomono/v22/L0x7DF4xlVMF-BfR8bXMIjhOm3CWWoKC.woff2) + format("woff2"); + unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, + U+FE2E-FE2F; +} +/* cyrillic */ +@font-face { + font-family: "Roboto Mono"; + font-style: italic; + font-weight: 100; + font-display: swap; + src: url(https://fonts.gstatic.com/s/robotomono/v22/L0x7DF4xlVMF-BfR8bXMIjhOm3mWWoKC.woff2) + format("woff2"); + unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; +} +/* greek */ +@font-face { + font-family: "Roboto Mono"; + font-style: italic; + font-weight: 100; + font-display: swap; + src: url(https://fonts.gstatic.com/s/robotomono/v22/L0x7DF4xlVMF-BfR8bXMIjhOm36WWoKC.woff2) + format("woff2"); + unicode-range: U+0370-03FF; +} +/* vietnamese */ +@font-face { + font-family: "Roboto Mono"; + font-style: italic; + font-weight: 100; + font-display: swap; + src: url(https://fonts.gstatic.com/s/robotomono/v22/L0x7DF4xlVMF-BfR8bXMIjhOm3KWWoKC.woff2) + format("woff2"); + unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, + U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, + U+1EA0-1EF9, U+20AB; +} +/* latin-ext */ +@font-face { + font-family: "Roboto Mono"; + font-style: italic; + font-weight: 100; + font-display: swap; + src: url(https://fonts.gstatic.com/s/robotomono/v22/L0x7DF4xlVMF-BfR8bXMIjhOm3OWWoKC.woff2) + format("woff2"); + unicode-range: U+0100-02AF, U+0304, U+0308, U+0329, U+1E00-1E9F, U+1EF2-1EFF, + U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF; +} +/* latin */ +@font-face { + font-family: "Roboto Mono"; + font-style: italic; + font-weight: 100; + font-display: swap; + src: url(https://fonts.gstatic.com/s/robotomono/v22/L0x7DF4xlVMF-BfR8bXMIjhOm32WWg.woff2) + format("woff2"); + unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, + U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, + U+2193, U+2212, U+2215, U+FEFF, U+FFFD; +} +/* cyrillic-ext */ +@font-face { + font-family: "Roboto Mono"; + font-style: italic; + font-weight: 200; + font-display: swap; + src: url(https://fonts.gstatic.com/s/robotomono/v22/L0x7DF4xlVMF-BfR8bXMIjhOm3CWWoKC.woff2) + format("woff2"); + unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, + U+FE2E-FE2F; +} +/* cyrillic */ +@font-face { + font-family: "Roboto Mono"; + font-style: italic; + font-weight: 200; + font-display: swap; + src: url(https://fonts.gstatic.com/s/robotomono/v22/L0x7DF4xlVMF-BfR8bXMIjhOm3mWWoKC.woff2) + format("woff2"); + unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; +} +/* greek */ +@font-face { + font-family: "Roboto Mono"; + font-style: italic; + font-weight: 200; + font-display: swap; + src: url(https://fonts.gstatic.com/s/robotomono/v22/L0x7DF4xlVMF-BfR8bXMIjhOm36WWoKC.woff2) + format("woff2"); + unicode-range: U+0370-03FF; +} +/* vietnamese */ +@font-face { + font-family: "Roboto Mono"; + font-style: italic; + font-weight: 200; + font-display: swap; + src: url(https://fonts.gstatic.com/s/robotomono/v22/L0x7DF4xlVMF-BfR8bXMIjhOm3KWWoKC.woff2) + format("woff2"); + unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, + U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, + U+1EA0-1EF9, U+20AB; +} +/* latin-ext */ +@font-face { + font-family: "Roboto Mono"; + font-style: italic; + font-weight: 200; + font-display: swap; + src: url(https://fonts.gstatic.com/s/robotomono/v22/L0x7DF4xlVMF-BfR8bXMIjhOm3OWWoKC.woff2) + format("woff2"); + unicode-range: U+0100-02AF, U+0304, U+0308, U+0329, U+1E00-1E9F, U+1EF2-1EFF, + U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF; +} +/* latin */ +@font-face { + font-family: "Roboto Mono"; + font-style: italic; + font-weight: 200; + font-display: swap; + src: url(https://fonts.gstatic.com/s/robotomono/v22/L0x7DF4xlVMF-BfR8bXMIjhOm32WWg.woff2) + format("woff2"); + unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, + U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, + U+2193, U+2212, U+2215, U+FEFF, U+FFFD; +} +/* cyrillic-ext */ +@font-face { + font-family: "Roboto Mono"; + font-style: italic; + font-weight: 300; + font-display: swap; + src: url(https://fonts.gstatic.com/s/robotomono/v22/L0x7DF4xlVMF-BfR8bXMIjhOm3CWWoKC.woff2) + format("woff2"); + unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, + U+FE2E-FE2F; +} +/* cyrillic */ +@font-face { + font-family: "Roboto Mono"; + font-style: italic; + font-weight: 300; + font-display: swap; + src: url(https://fonts.gstatic.com/s/robotomono/v22/L0x7DF4xlVMF-BfR8bXMIjhOm3mWWoKC.woff2) + format("woff2"); + unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; +} +/* greek */ +@font-face { + font-family: "Roboto Mono"; + font-style: italic; + font-weight: 300; + font-display: swap; + src: url(https://fonts.gstatic.com/s/robotomono/v22/L0x7DF4xlVMF-BfR8bXMIjhOm36WWoKC.woff2) + format("woff2"); + unicode-range: U+0370-03FF; +} +/* vietnamese */ +@font-face { + font-family: "Roboto Mono"; + font-style: italic; + font-weight: 300; + font-display: swap; + src: url(https://fonts.gstatic.com/s/robotomono/v22/L0x7DF4xlVMF-BfR8bXMIjhOm3KWWoKC.woff2) + format("woff2"); + unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, + U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, + U+1EA0-1EF9, U+20AB; +} +/* latin-ext */ +@font-face { + font-family: "Roboto Mono"; + font-style: italic; + font-weight: 300; + font-display: swap; + src: url(https://fonts.gstatic.com/s/robotomono/v22/L0x7DF4xlVMF-BfR8bXMIjhOm3OWWoKC.woff2) + format("woff2"); + unicode-range: U+0100-02AF, U+0304, U+0308, U+0329, U+1E00-1E9F, U+1EF2-1EFF, + U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF; +} +/* latin */ +@font-face { + font-family: "Roboto Mono"; + font-style: italic; + font-weight: 300; + font-display: swap; + src: url(https://fonts.gstatic.com/s/robotomono/v22/L0x7DF4xlVMF-BfR8bXMIjhOm32WWg.woff2) + format("woff2"); + unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, + U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, + U+2193, U+2212, U+2215, U+FEFF, U+FFFD; +} +/* cyrillic-ext */ +@font-face { + font-family: "Roboto Mono"; + font-style: italic; + font-weight: 400; + font-display: swap; + src: url(https://fonts.gstatic.com/s/robotomono/v22/L0x7DF4xlVMF-BfR8bXMIjhOm3CWWoKC.woff2) + format("woff2"); + unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, + U+FE2E-FE2F; +} +/* cyrillic */ +@font-face { + font-family: "Roboto Mono"; + font-style: italic; + font-weight: 400; + font-display: swap; + src: url(https://fonts.gstatic.com/s/robotomono/v22/L0x7DF4xlVMF-BfR8bXMIjhOm3mWWoKC.woff2) + format("woff2"); + unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; +} +/* greek */ +@font-face { + font-family: "Roboto Mono"; + font-style: italic; + font-weight: 400; + font-display: swap; + src: url(https://fonts.gstatic.com/s/robotomono/v22/L0x7DF4xlVMF-BfR8bXMIjhOm36WWoKC.woff2) + format("woff2"); + unicode-range: U+0370-03FF; +} +/* vietnamese */ +@font-face { + font-family: "Roboto Mono"; + font-style: italic; + font-weight: 400; + font-display: swap; + src: url(https://fonts.gstatic.com/s/robotomono/v22/L0x7DF4xlVMF-BfR8bXMIjhOm3KWWoKC.woff2) + format("woff2"); + unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, + U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, + U+1EA0-1EF9, U+20AB; +} +/* latin-ext */ +@font-face { + font-family: "Roboto Mono"; + font-style: italic; + font-weight: 400; + font-display: swap; + src: url(https://fonts.gstatic.com/s/robotomono/v22/L0x7DF4xlVMF-BfR8bXMIjhOm3OWWoKC.woff2) + format("woff2"); + unicode-range: U+0100-02AF, U+0304, U+0308, U+0329, U+1E00-1E9F, U+1EF2-1EFF, + U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF; +} +/* latin */ +@font-face { + font-family: "Roboto Mono"; + font-style: italic; + font-weight: 400; + font-display: swap; + src: url(https://fonts.gstatic.com/s/robotomono/v22/L0x7DF4xlVMF-BfR8bXMIjhOm32WWg.woff2) + format("woff2"); + unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, + U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, + U+2193, U+2212, U+2215, U+FEFF, U+FFFD; +} +/* cyrillic-ext */ +@font-face { + font-family: "Roboto Mono"; + font-style: italic; + font-weight: 500; + font-display: swap; + src: url(https://fonts.gstatic.com/s/robotomono/v22/L0x7DF4xlVMF-BfR8bXMIjhOm3CWWoKC.woff2) + format("woff2"); + unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, + U+FE2E-FE2F; +} +/* cyrillic */ +@font-face { + font-family: "Roboto Mono"; + font-style: italic; + font-weight: 500; + font-display: swap; + src: url(https://fonts.gstatic.com/s/robotomono/v22/L0x7DF4xlVMF-BfR8bXMIjhOm3mWWoKC.woff2) + format("woff2"); + unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; +} +/* greek */ +@font-face { + font-family: "Roboto Mono"; + font-style: italic; + font-weight: 500; + font-display: swap; + src: url(https://fonts.gstatic.com/s/robotomono/v22/L0x7DF4xlVMF-BfR8bXMIjhOm36WWoKC.woff2) + format("woff2"); + unicode-range: U+0370-03FF; +} +/* vietnamese */ +@font-face { + font-family: "Roboto Mono"; + font-style: italic; + font-weight: 500; + font-display: swap; + src: url(https://fonts.gstatic.com/s/robotomono/v22/L0x7DF4xlVMF-BfR8bXMIjhOm3KWWoKC.woff2) + format("woff2"); + unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, + U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, + U+1EA0-1EF9, U+20AB; +} +/* latin-ext */ +@font-face { + font-family: "Roboto Mono"; + font-style: italic; + font-weight: 500; + font-display: swap; + src: url(https://fonts.gstatic.com/s/robotomono/v22/L0x7DF4xlVMF-BfR8bXMIjhOm3OWWoKC.woff2) + format("woff2"); + unicode-range: U+0100-02AF, U+0304, U+0308, U+0329, U+1E00-1E9F, U+1EF2-1EFF, + U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF; +} +/* latin */ +@font-face { + font-family: "Roboto Mono"; + font-style: italic; + font-weight: 500; + font-display: swap; + src: url(https://fonts.gstatic.com/s/robotomono/v22/L0x7DF4xlVMF-BfR8bXMIjhOm32WWg.woff2) + format("woff2"); + unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, + U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, + U+2193, U+2212, U+2215, U+FEFF, U+FFFD; +} +/* cyrillic-ext */ +@font-face { + font-family: "Roboto Mono"; + font-style: italic; + font-weight: 600; + font-display: swap; + src: url(https://fonts.gstatic.com/s/robotomono/v22/L0x7DF4xlVMF-BfR8bXMIjhOm3CWWoKC.woff2) + format("woff2"); + unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, + U+FE2E-FE2F; +} +/* cyrillic */ +@font-face { + font-family: "Roboto Mono"; + font-style: italic; + font-weight: 600; + font-display: swap; + src: url(https://fonts.gstatic.com/s/robotomono/v22/L0x7DF4xlVMF-BfR8bXMIjhOm3mWWoKC.woff2) + format("woff2"); + unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; +} +/* greek */ +@font-face { + font-family: "Roboto Mono"; + font-style: italic; + font-weight: 600; + font-display: swap; + src: url(https://fonts.gstatic.com/s/robotomono/v22/L0x7DF4xlVMF-BfR8bXMIjhOm36WWoKC.woff2) + format("woff2"); + unicode-range: U+0370-03FF; +} +/* vietnamese */ +@font-face { + font-family: "Roboto Mono"; + font-style: italic; + font-weight: 600; + font-display: swap; + src: url(https://fonts.gstatic.com/s/robotomono/v22/L0x7DF4xlVMF-BfR8bXMIjhOm3KWWoKC.woff2) + format("woff2"); + unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, + U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, + U+1EA0-1EF9, U+20AB; +} +/* latin-ext */ +@font-face { + font-family: "Roboto Mono"; + font-style: italic; + font-weight: 600; + font-display: swap; + src: url(https://fonts.gstatic.com/s/robotomono/v22/L0x7DF4xlVMF-BfR8bXMIjhOm3OWWoKC.woff2) + format("woff2"); + unicode-range: U+0100-02AF, U+0304, U+0308, U+0329, U+1E00-1E9F, U+1EF2-1EFF, + U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF; +} +/* latin */ +@font-face { + font-family: "Roboto Mono"; + font-style: italic; + font-weight: 600; + font-display: swap; + src: url(https://fonts.gstatic.com/s/robotomono/v22/L0x7DF4xlVMF-BfR8bXMIjhOm32WWg.woff2) + format("woff2"); + unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, + U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, + U+2193, U+2212, U+2215, U+FEFF, U+FFFD; +} +/* cyrillic-ext */ +@font-face { + font-family: "Roboto Mono"; + font-style: italic; + font-weight: 700; + font-display: swap; + src: url(https://fonts.gstatic.com/s/robotomono/v22/L0x7DF4xlVMF-BfR8bXMIjhOm3CWWoKC.woff2) + format("woff2"); + unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, + U+FE2E-FE2F; +} +/* cyrillic */ +@font-face { + font-family: "Roboto Mono"; + font-style: italic; + font-weight: 700; + font-display: swap; + src: url(https://fonts.gstatic.com/s/robotomono/v22/L0x7DF4xlVMF-BfR8bXMIjhOm3mWWoKC.woff2) + format("woff2"); + unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; +} +/* greek */ +@font-face { + font-family: "Roboto Mono"; + font-style: italic; + font-weight: 700; + font-display: swap; + src: url(https://fonts.gstatic.com/s/robotomono/v22/L0x7DF4xlVMF-BfR8bXMIjhOm36WWoKC.woff2) + format("woff2"); + unicode-range: U+0370-03FF; +} +/* vietnamese */ +@font-face { + font-family: "Roboto Mono"; + font-style: italic; + font-weight: 700; + font-display: swap; + src: url(https://fonts.gstatic.com/s/robotomono/v22/L0x7DF4xlVMF-BfR8bXMIjhOm3KWWoKC.woff2) + format("woff2"); + unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, + U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, + U+1EA0-1EF9, U+20AB; +} +/* latin-ext */ +@font-face { + font-family: "Roboto Mono"; + font-style: italic; + font-weight: 700; + font-display: swap; + src: url(https://fonts.gstatic.com/s/robotomono/v22/L0x7DF4xlVMF-BfR8bXMIjhOm3OWWoKC.woff2) + format("woff2"); + unicode-range: U+0100-02AF, U+0304, U+0308, U+0329, U+1E00-1E9F, U+1EF2-1EFF, + U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF; +} +/* latin */ +@font-face { + font-family: "Roboto Mono"; + font-style: italic; + font-weight: 700; + font-display: swap; + src: url(https://fonts.gstatic.com/s/robotomono/v22/L0x7DF4xlVMF-BfR8bXMIjhOm32WWg.woff2) + format("woff2"); + unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, + U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, + U+2193, U+2212, U+2215, U+FEFF, U+FFFD; +} +/* cyrillic-ext */ +@font-face { + font-family: "Roboto Mono"; + font-style: normal; + font-weight: 100; + font-display: swap; + src: url(https://fonts.gstatic.com/s/robotomono/v22/L0x5DF4xlVMF-BfR8bXMIjhGq3-OXg.woff2) + format("woff2"); + unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, + U+FE2E-FE2F; +} +/* cyrillic */ +@font-face { + font-family: "Roboto Mono"; + font-style: normal; + font-weight: 100; + font-display: swap; + src: url(https://fonts.gstatic.com/s/robotomono/v22/L0x5DF4xlVMF-BfR8bXMIjhPq3-OXg.woff2) + format("woff2"); + unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; +} +/* greek */ +@font-face { + font-family: "Roboto Mono"; + font-style: normal; + font-weight: 100; + font-display: swap; + src: url(https://fonts.gstatic.com/s/robotomono/v22/L0x5DF4xlVMF-BfR8bXMIjhIq3-OXg.woff2) + format("woff2"); + unicode-range: U+0370-03FF; +} +/* vietnamese */ +@font-face { + font-family: "Roboto Mono"; + font-style: normal; + font-weight: 100; + font-display: swap; + src: url(https://fonts.gstatic.com/s/robotomono/v22/L0x5DF4xlVMF-BfR8bXMIjhEq3-OXg.woff2) + format("woff2"); + unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, + U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, + U+1EA0-1EF9, U+20AB; +} +/* latin-ext */ +@font-face { + font-family: "Roboto Mono"; + font-style: normal; + font-weight: 100; + font-display: swap; + src: url(https://fonts.gstatic.com/s/robotomono/v22/L0x5DF4xlVMF-BfR8bXMIjhFq3-OXg.woff2) + format("woff2"); + unicode-range: U+0100-02AF, U+0304, U+0308, U+0329, U+1E00-1E9F, U+1EF2-1EFF, + U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF; +} +/* latin */ +@font-face { + font-family: "Roboto Mono"; + font-style: normal; + font-weight: 100; + font-display: swap; + src: url(https://fonts.gstatic.com/s/robotomono/v22/L0x5DF4xlVMF-BfR8bXMIjhLq38.woff2) + format("woff2"); + unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, + U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, + U+2193, U+2212, U+2215, U+FEFF, U+FFFD; +} +/* cyrillic-ext */ +@font-face { + font-family: "Roboto Mono"; + font-style: normal; + font-weight: 200; + font-display: swap; + src: url(https://fonts.gstatic.com/s/robotomono/v22/L0x5DF4xlVMF-BfR8bXMIjhGq3-OXg.woff2) + format("woff2"); + unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, + U+FE2E-FE2F; +} +/* cyrillic */ +@font-face { + font-family: "Roboto Mono"; + font-style: normal; + font-weight: 200; + font-display: swap; + src: url(https://fonts.gstatic.com/s/robotomono/v22/L0x5DF4xlVMF-BfR8bXMIjhPq3-OXg.woff2) + format("woff2"); + unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; +} +/* greek */ +@font-face { + font-family: "Roboto Mono"; + font-style: normal; + font-weight: 200; + font-display: swap; + src: url(https://fonts.gstatic.com/s/robotomono/v22/L0x5DF4xlVMF-BfR8bXMIjhIq3-OXg.woff2) + format("woff2"); + unicode-range: U+0370-03FF; +} +/* vietnamese */ +@font-face { + font-family: "Roboto Mono"; + font-style: normal; + font-weight: 200; + font-display: swap; + src: url(https://fonts.gstatic.com/s/robotomono/v22/L0x5DF4xlVMF-BfR8bXMIjhEq3-OXg.woff2) + format("woff2"); + unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, + U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, + U+1EA0-1EF9, U+20AB; +} +/* latin-ext */ +@font-face { + font-family: "Roboto Mono"; + font-style: normal; + font-weight: 200; + font-display: swap; + src: url(https://fonts.gstatic.com/s/robotomono/v22/L0x5DF4xlVMF-BfR8bXMIjhFq3-OXg.woff2) + format("woff2"); + unicode-range: U+0100-02AF, U+0304, U+0308, U+0329, U+1E00-1E9F, U+1EF2-1EFF, + U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF; +} +/* latin */ +@font-face { + font-family: "Roboto Mono"; + font-style: normal; + font-weight: 200; + font-display: swap; + src: url(https://fonts.gstatic.com/s/robotomono/v22/L0x5DF4xlVMF-BfR8bXMIjhLq38.woff2) + format("woff2"); + unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, + U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, + U+2193, U+2212, U+2215, U+FEFF, U+FFFD; +} +/* cyrillic-ext */ +@font-face { + font-family: "Roboto Mono"; + font-style: normal; + font-weight: 300; + font-display: swap; + src: url(https://fonts.gstatic.com/s/robotomono/v22/L0x5DF4xlVMF-BfR8bXMIjhGq3-OXg.woff2) + format("woff2"); + unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, + U+FE2E-FE2F; +} +/* cyrillic */ +@font-face { + font-family: "Roboto Mono"; + font-style: normal; + font-weight: 300; + font-display: swap; + src: url(https://fonts.gstatic.com/s/robotomono/v22/L0x5DF4xlVMF-BfR8bXMIjhPq3-OXg.woff2) + format("woff2"); + unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; +} +/* greek */ +@font-face { + font-family: "Roboto Mono"; + font-style: normal; + font-weight: 300; + font-display: swap; + src: url(https://fonts.gstatic.com/s/robotomono/v22/L0x5DF4xlVMF-BfR8bXMIjhIq3-OXg.woff2) + format("woff2"); + unicode-range: U+0370-03FF; +} +/* vietnamese */ +@font-face { + font-family: "Roboto Mono"; + font-style: normal; + font-weight: 300; + font-display: swap; + src: url(https://fonts.gstatic.com/s/robotomono/v22/L0x5DF4xlVMF-BfR8bXMIjhEq3-OXg.woff2) + format("woff2"); + unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, + U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, + U+1EA0-1EF9, U+20AB; +} +/* latin-ext */ +@font-face { + font-family: "Roboto Mono"; + font-style: normal; + font-weight: 300; + font-display: swap; + src: url(https://fonts.gstatic.com/s/robotomono/v22/L0x5DF4xlVMF-BfR8bXMIjhFq3-OXg.woff2) + format("woff2"); + unicode-range: U+0100-02AF, U+0304, U+0308, U+0329, U+1E00-1E9F, U+1EF2-1EFF, + U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF; +} +/* latin */ +@font-face { + font-family: "Roboto Mono"; + font-style: normal; + font-weight: 300; + font-display: swap; + src: url(https://fonts.gstatic.com/s/robotomono/v22/L0x5DF4xlVMF-BfR8bXMIjhLq38.woff2) + format("woff2"); + unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, + U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, + U+2193, U+2212, U+2215, U+FEFF, U+FFFD; +} +/* cyrillic-ext */ +@font-face { + font-family: "Roboto Mono"; + font-style: normal; + font-weight: 400; + font-display: swap; + src: url(https://fonts.gstatic.com/s/robotomono/v22/L0x5DF4xlVMF-BfR8bXMIjhGq3-OXg.woff2) + format("woff2"); + unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, + U+FE2E-FE2F; +} +/* cyrillic */ +@font-face { + font-family: "Roboto Mono"; + font-style: normal; + font-weight: 400; + font-display: swap; + src: url(https://fonts.gstatic.com/s/robotomono/v22/L0x5DF4xlVMF-BfR8bXMIjhPq3-OXg.woff2) + format("woff2"); + unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; +} +/* greek */ +@font-face { + font-family: "Roboto Mono"; + font-style: normal; + font-weight: 400; + font-display: swap; + src: url(https://fonts.gstatic.com/s/robotomono/v22/L0x5DF4xlVMF-BfR8bXMIjhIq3-OXg.woff2) + format("woff2"); + unicode-range: U+0370-03FF; +} +/* vietnamese */ +@font-face { + font-family: "Roboto Mono"; + font-style: normal; + font-weight: 400; + font-display: swap; + src: url(https://fonts.gstatic.com/s/robotomono/v22/L0x5DF4xlVMF-BfR8bXMIjhEq3-OXg.woff2) + format("woff2"); + unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, + U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, + U+1EA0-1EF9, U+20AB; +} +/* latin-ext */ +@font-face { + font-family: "Roboto Mono"; + font-style: normal; + font-weight: 400; + font-display: swap; + src: url(https://fonts.gstatic.com/s/robotomono/v22/L0x5DF4xlVMF-BfR8bXMIjhFq3-OXg.woff2) + format("woff2"); + unicode-range: U+0100-02AF, U+0304, U+0308, U+0329, U+1E00-1E9F, U+1EF2-1EFF, + U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF; +} +/* latin */ +@font-face { + font-family: "Roboto Mono"; + font-style: normal; + font-weight: 400; + font-display: swap; + src: url(https://fonts.gstatic.com/s/robotomono/v22/L0x5DF4xlVMF-BfR8bXMIjhLq38.woff2) + format("woff2"); + unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, + U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, + U+2193, U+2212, U+2215, U+FEFF, U+FFFD; +} +/* cyrillic-ext */ +@font-face { + font-family: "Roboto Mono"; + font-style: normal; + font-weight: 500; + font-display: swap; + src: url(https://fonts.gstatic.com/s/robotomono/v22/L0x5DF4xlVMF-BfR8bXMIjhGq3-OXg.woff2) + format("woff2"); + unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, + U+FE2E-FE2F; +} +/* cyrillic */ +@font-face { + font-family: "Roboto Mono"; + font-style: normal; + font-weight: 500; + font-display: swap; + src: url(https://fonts.gstatic.com/s/robotomono/v22/L0x5DF4xlVMF-BfR8bXMIjhPq3-OXg.woff2) + format("woff2"); + unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; +} +/* greek */ +@font-face { + font-family: "Roboto Mono"; + font-style: normal; + font-weight: 500; + font-display: swap; + src: url(https://fonts.gstatic.com/s/robotomono/v22/L0x5DF4xlVMF-BfR8bXMIjhIq3-OXg.woff2) + format("woff2"); + unicode-range: U+0370-03FF; +} +/* vietnamese */ +@font-face { + font-family: "Roboto Mono"; + font-style: normal; + font-weight: 500; + font-display: swap; + src: url(https://fonts.gstatic.com/s/robotomono/v22/L0x5DF4xlVMF-BfR8bXMIjhEq3-OXg.woff2) + format("woff2"); + unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, + U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, + U+1EA0-1EF9, U+20AB; +} +/* latin-ext */ +@font-face { + font-family: "Roboto Mono"; + font-style: normal; + font-weight: 500; + font-display: swap; + src: url(https://fonts.gstatic.com/s/robotomono/v22/L0x5DF4xlVMF-BfR8bXMIjhFq3-OXg.woff2) + format("woff2"); + unicode-range: U+0100-02AF, U+0304, U+0308, U+0329, U+1E00-1E9F, U+1EF2-1EFF, + U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF; +} +/* latin */ +@font-face { + font-family: "Roboto Mono"; + font-style: normal; + font-weight: 500; + font-display: swap; + src: url(https://fonts.gstatic.com/s/robotomono/v22/L0x5DF4xlVMF-BfR8bXMIjhLq38.woff2) + format("woff2"); + unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, + U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, + U+2193, U+2212, U+2215, U+FEFF, U+FFFD; +} +/* cyrillic-ext */ +@font-face { + font-family: "Roboto Mono"; + font-style: normal; + font-weight: 600; + font-display: swap; + src: url(https://fonts.gstatic.com/s/robotomono/v22/L0x5DF4xlVMF-BfR8bXMIjhGq3-OXg.woff2) + format("woff2"); + unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, + U+FE2E-FE2F; +} +/* cyrillic */ +@font-face { + font-family: "Roboto Mono"; + font-style: normal; + font-weight: 600; + font-display: swap; + src: url(https://fonts.gstatic.com/s/robotomono/v22/L0x5DF4xlVMF-BfR8bXMIjhPq3-OXg.woff2) + format("woff2"); + unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; +} +/* greek */ +@font-face { + font-family: "Roboto Mono"; + font-style: normal; + font-weight: 600; + font-display: swap; + src: url(https://fonts.gstatic.com/s/robotomono/v22/L0x5DF4xlVMF-BfR8bXMIjhIq3-OXg.woff2) + format("woff2"); + unicode-range: U+0370-03FF; +} +/* vietnamese */ +@font-face { + font-family: "Roboto Mono"; + font-style: normal; + font-weight: 600; + font-display: swap; + src: url(https://fonts.gstatic.com/s/robotomono/v22/L0x5DF4xlVMF-BfR8bXMIjhEq3-OXg.woff2) + format("woff2"); + unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, + U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, + U+1EA0-1EF9, U+20AB; +} +/* latin-ext */ +@font-face { + font-family: "Roboto Mono"; + font-style: normal; + font-weight: 600; + font-display: swap; + src: url(https://fonts.gstatic.com/s/robotomono/v22/L0x5DF4xlVMF-BfR8bXMIjhFq3-OXg.woff2) + format("woff2"); + unicode-range: U+0100-02AF, U+0304, U+0308, U+0329, U+1E00-1E9F, U+1EF2-1EFF, + U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF; +} +/* latin */ +@font-face { + font-family: "Roboto Mono"; + font-style: normal; + font-weight: 600; + font-display: swap; + src: url(https://fonts.gstatic.com/s/robotomono/v22/L0x5DF4xlVMF-BfR8bXMIjhLq38.woff2) + format("woff2"); + unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, + U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, + U+2193, U+2212, U+2215, U+FEFF, U+FFFD; +} +/* cyrillic-ext */ +@font-face { + font-family: "Roboto Mono"; + font-style: normal; + font-weight: 700; + font-display: swap; + src: url(https://fonts.gstatic.com/s/robotomono/v22/L0x5DF4xlVMF-BfR8bXMIjhGq3-OXg.woff2) + format("woff2"); + unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, + U+FE2E-FE2F; +} +/* cyrillic */ +@font-face { + font-family: "Roboto Mono"; + font-style: normal; + font-weight: 700; + font-display: swap; + src: url(https://fonts.gstatic.com/s/robotomono/v22/L0x5DF4xlVMF-BfR8bXMIjhPq3-OXg.woff2) + format("woff2"); + unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; +} +/* greek */ +@font-face { + font-family: "Roboto Mono"; + font-style: normal; + font-weight: 700; + font-display: swap; + src: url(https://fonts.gstatic.com/s/robotomono/v22/L0x5DF4xlVMF-BfR8bXMIjhIq3-OXg.woff2) + format("woff2"); + unicode-range: U+0370-03FF; +} +/* vietnamese */ +@font-face { + font-family: "Roboto Mono"; + font-style: normal; + font-weight: 700; + font-display: swap; + src: url(https://fonts.gstatic.com/s/robotomono/v22/L0x5DF4xlVMF-BfR8bXMIjhEq3-OXg.woff2) + format("woff2"); + unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, + U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, + U+1EA0-1EF9, U+20AB; +} +/* latin-ext */ +@font-face { + font-family: "Roboto Mono"; + font-style: normal; + font-weight: 700; + font-display: swap; + src: url(https://fonts.gstatic.com/s/robotomono/v22/L0x5DF4xlVMF-BfR8bXMIjhFq3-OXg.woff2) + format("woff2"); + unicode-range: U+0100-02AF, U+0304, U+0308, U+0329, U+1E00-1E9F, U+1EF2-1EFF, + U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF; +} +/* latin */ +@font-face { + font-family: "Roboto Mono"; + font-style: normal; + font-weight: 700; + font-display: swap; + src: url(https://fonts.gstatic.com/s/robotomono/v22/L0x5DF4xlVMF-BfR8bXMIjhLq38.woff2) + format("woff2"); + unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, + U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, + U+2193, U+2212, U+2215, U+FEFF, U+FFFD; +} diff --git a/src/assets/css/global.css b/src/assets/css/global.css index e69de29..c81ff16 100644 --- a/src/assets/css/global.css +++ b/src/assets/css/global.css @@ -0,0 +1,136 @@ +@import "./colors.css"; + +@import "./font.css"; + +/* Reset CSS */ + +/* Remove a margem padrão e o preenchimento */ +body { + font-family: "Roboto"; + line-height: 1.5; + -webkit-font-smoothing: antialiased; + background-color: var(--bg-primary); + margin: 0; + padding: 0; +} +.distance { + display: flex; + width: 100%; + margin: 0 auto; + max-width: 80%; + padding: 8px; +} + +h1, +h2, +h3, +h4, +h5, +h6, +p, +ul, +ol, +li, +blockquote, +dl, +dd { + margin: 0; + padding: 0; +} + +/* Quebra de texto caso o conteúdo seja muito grande para o container */ + +p, +h1, +h2, +h3, +h4, +h5, +h6 { + overflow-wrap: break-word; +} + +/* Remove estilos padrão da lista */ + +ul, +ol { + list-style: none; +} + +/* Remove a decoração do link */ + +a { + text-decoration: none; +} + +/* Define a cor do texto para o title */ + +body { + color: var(--color-title); +} + +/* Define a cor do texto do paragrafo para cinza */ + +p { + color: var(--color-gray); +} + +/* O conteúdo da página ocupará a largura total */ + +/* body, +html { + width: 100%; + + box-sizing: border-box; +} */ + +/* Corrige o box-sizing para incluir padding e border no tamanho total do elemento */ + +*, +*::before, +*::after { + box-sizing: inherit; +} + +/* Garante que os elementos de foco sejam visíveis e acessíveis */ + +a, +button, +input, +textarea, +select { + outline: none; +} + +/* Remova os estilos padrão da tag de botão */ + +/* button { + width: Fill (302px); + height: Hug (56px); + padding: 16px; + border-radius: 4px; + border: 1px; + border-color: var(--border-love); + gap: 8px; + background: var(--bg-primary); +} */ + +/* Define a família de fontes padrão e o tamanho do texto para uma melhor legibilidade */ + +/* body { + font-family: "Inter", sans-serif; + + font-size: 16px; + + line-height: 1.5; + + -webkit-font-smoothing: antialiased; +} */ + +/* O conteúdo se ajustará ao tamanho da tela */ + +img, +video { + max-width: auto; + height: auto; +} diff --git a/src/assets/css/index.css b/src/assets/css/index.css deleted file mode 100644 index 2c3fac6..0000000 --- a/src/assets/css/index.css +++ /dev/null @@ -1,69 +0,0 @@ -:root { - font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif; - line-height: 1.5; - font-weight: 400; - - color-scheme: light dark; - color: rgba(255, 255, 255, 0.87); - background-color: #242424; - - font-synthesis: none; - text-rendering: optimizeLegibility; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; - -webkit-text-size-adjust: 100%; -} - -a { - font-weight: 500; - color: #646cff; - text-decoration: inherit; -} -a:hover { - color: #535bf2; -} - -body { - margin: 0; - display: flex; - place-items: center; - min-width: 320px; - min-height: 100vh; -} - -h1 { - font-size: 3.2em; - line-height: 1.1; -} - -button { - border-radius: 8px; - border: 1px solid transparent; - padding: 0.6em 1.2em; - font-size: 1em; - font-weight: 500; - font-family: inherit; - background-color: #1a1a1a; - cursor: pointer; - transition: border-color 0.25s; -} -button:hover { - border-color: #646cff; -} -button:focus, -button:focus-visible { - outline: 4px auto -webkit-focus-ring-color; -} - -@media (prefers-color-scheme: light) { - :root { - color: #213547; - background-color: #ffffff; - } - a:hover { - color: #747bff; - } - button { - background-color: #f9f9f9; - } -} diff --git a/src/assets/images/Icons/ArrowIcon.svg b/src/assets/images/Icons/ArrowIcon.svg new file mode 100644 index 0000000..0437747 --- /dev/null +++ b/src/assets/images/Icons/ArrowIcon.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/src/assets/images/Icons/Cancel.svg b/src/assets/images/Icons/Cancel.svg new file mode 100644 index 0000000..55bf4b3 --- /dev/null +++ b/src/assets/images/Icons/Cancel.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/src/assets/images/Icons/IconArrow.svg b/src/assets/images/Icons/IconArrow.svg new file mode 100644 index 0000000..486b14d --- /dev/null +++ b/src/assets/images/Icons/IconArrow.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/src/assets/images/Icons/Line.svg b/src/assets/images/Icons/Line.svg new file mode 100644 index 0000000..fc274e0 --- /dev/null +++ b/src/assets/images/Icons/Line.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/assets/images/Icons/Logo1.svg b/src/assets/images/Icons/Logo1.svg new file mode 100644 index 0000000..2b9c08a --- /dev/null +++ b/src/assets/images/Icons/Logo1.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/src/assets/images/Icons/Vector.svg b/src/assets/images/Icons/Vector.svg new file mode 100644 index 0000000..3b20f44 --- /dev/null +++ b/src/assets/images/Icons/Vector.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/assets/images/Icons/apple.svg b/src/assets/images/Icons/apple.svg new file mode 100644 index 0000000..cb22a17 --- /dev/null +++ b/src/assets/images/Icons/apple.svg @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/src/assets/images/Icons/arrow_left.svg b/src/assets/images/Icons/arrow_left.svg new file mode 100644 index 0000000..4acb247 --- /dev/null +++ b/src/assets/images/Icons/arrow_left.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/assets/images/Icons/arrow_right.svg b/src/assets/images/Icons/arrow_right.svg new file mode 100644 index 0000000..50fd217 --- /dev/null +++ b/src/assets/images/Icons/arrow_right.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/assets/images/Icons/car.svg b/src/assets/images/Icons/car.svg new file mode 100644 index 0000000..79dce17 --- /dev/null +++ b/src/assets/images/Icons/car.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/src/assets/images/Icons/card.svg b/src/assets/images/Icons/card.svg new file mode 100644 index 0000000..12b5187 --- /dev/null +++ b/src/assets/images/Icons/card.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/src/assets/images/Icons/cart.svg b/src/assets/images/Icons/cart.svg new file mode 100644 index 0000000..7f8f543 --- /dev/null +++ b/src/assets/images/Icons/cart.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/src/assets/images/Icons/cartlogoGreen.svg b/src/assets/images/Icons/cartlogoGreen.svg new file mode 100644 index 0000000..8c7ee9f --- /dev/null +++ b/src/assets/images/Icons/cartlogoGreen.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/assets/images/Icons/email.svg b/src/assets/images/Icons/email.svg new file mode 100644 index 0000000..a70026a --- /dev/null +++ b/src/assets/images/Icons/email.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/src/assets/images/Icons/googleplay.svg b/src/assets/images/Icons/googleplay.svg new file mode 100644 index 0000000..b38c103 --- /dev/null +++ b/src/assets/images/Icons/googleplay.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/src/assets/images/Icons/like.svg b/src/assets/images/Icons/like.svg new file mode 100644 index 0000000..ed85fed --- /dev/null +++ b/src/assets/images/Icons/like.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/src/assets/images/Icons/loading.svg b/src/assets/images/Icons/loading.svg new file mode 100644 index 0000000..8e0379e --- /dev/null +++ b/src/assets/images/Icons/loading.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/src/assets/images/Icons/mastercard.png b/src/assets/images/Icons/mastercard.png new file mode 100644 index 0000000..6991e79 Binary files /dev/null and b/src/assets/images/Icons/mastercard.png differ diff --git a/src/assets/images/Icons/minoricon.svg b/src/assets/images/Icons/minoricon.svg new file mode 100644 index 0000000..180ea6b --- /dev/null +++ b/src/assets/images/Icons/minoricon.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/src/assets/images/Icons/paypal.png b/src/assets/images/Icons/paypal.png new file mode 100644 index 0000000..0315c9b Binary files /dev/null and b/src/assets/images/Icons/paypal.png differ diff --git a/src/assets/images/Icons/plusicon.svg b/src/assets/images/Icons/plusicon.svg new file mode 100644 index 0000000..fe513b8 --- /dev/null +++ b/src/assets/images/Icons/plusicon.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/src/assets/images/Icons/visa.png b/src/assets/images/Icons/visa.png new file mode 100644 index 0000000..0b2031b Binary files /dev/null and b/src/assets/images/Icons/visa.png differ diff --git a/src/assets/images/IphonePage.svg b/src/assets/images/IphonePage.svg new file mode 100644 index 0000000..2c1dc30 --- /dev/null +++ b/src/assets/images/IphonePage.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/src/assets/images/banner/banner.png b/src/assets/images/banner/banner.png new file mode 100644 index 0000000..d1e3ad1 Binary files /dev/null and b/src/assets/images/banner/banner.png differ diff --git a/src/assets/images/banners/BannerMobile.png b/src/assets/images/banners/BannerMobile.png new file mode 100644 index 0000000..afd9bec Binary files /dev/null and b/src/assets/images/banners/BannerMobile.png differ diff --git a/src/assets/images/banners/bannerContainer.png b/src/assets/images/banners/bannerContainer.png new file mode 100644 index 0000000..a56b99f Binary files /dev/null and b/src/assets/images/banners/bannerContainer.png differ diff --git a/src/assets/images/banners/lap.png b/src/assets/images/banners/lap.png new file mode 100644 index 0000000..8ebe05e Binary files /dev/null and b/src/assets/images/banners/lap.png differ diff --git a/src/assets/images/containerImage.svg b/src/assets/images/containerImage.svg new file mode 100644 index 0000000..433d97e --- /dev/null +++ b/src/assets/images/containerImage.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/src/components/App/store.js b/src/components/App/store.js new file mode 100644 index 0000000..f5f52a0 --- /dev/null +++ b/src/components/App/store.js @@ -0,0 +1,9 @@ +import { configureStore } from '@reduxjs/toolkit' +import cartReducer from '../Slices/CartSlice' + + +export const store = configureStore({ + reducer: { + cart: cartReducer, + }, +}) \ No newline at end of file diff --git a/src/components/Badge/index.jsx b/src/components/Badge/index.jsx new file mode 100644 index 0000000..c2e51eb --- /dev/null +++ b/src/components/Badge/index.jsx @@ -0,0 +1,27 @@ +import './styles.css'; +import {BadgePropTypes } from '../../types/BadgePropTypes'; + +export function Badge({price, priceDiscount}) { + const porcentagemDesconto = ((price - priceDiscount) / price) * 100; + const isDiscounted = porcentagemDesconto > 0; + return ( +
+ + + + {isDiscounted ? `${ Math.round(porcentagemDesconto)}% OFF` : 'Novo'} +
+ ); +} + +Badge.propTypes = BadgePropTypes; \ No newline at end of file diff --git a/src/components/Badge/styles.css b/src/components/Badge/styles.css new file mode 100644 index 0000000..c15bd9c --- /dev/null +++ b/src/components/Badge/styles.css @@ -0,0 +1,38 @@ +.banner-desconto{ + display: flex; + width: 67px; + height: 30px; + padding: 5px 10px; + justify-content: center; + align-items: center; + gap: 10px; + position: absolute; + left: 16px; + top: 16px; + border-radius: 2px; +} +.seta-banner-desconto { + width: 10px; + height: 20px; + position: absolute; + right: -6px; + top: 9px; +} +.percentage{ + color: #FFF; + text-align: right; + font-family: Roboto Flex; + font-size: 14px; + font-style: normal; + font-weight: 400; + line-height: normal; + text-wrap: nowrap; +} +.bg-red{ + background: #F55157; + fill: #F55157; +} +.bg-blue{ + background: #62D0B6; + fill: #62D0B6; +} \ No newline at end of file diff --git a/src/components/Banner/index.jsx b/src/components/Banner/index.jsx new file mode 100644 index 0000000..fdaef90 --- /dev/null +++ b/src/components/Banner/index.jsx @@ -0,0 +1,19 @@ +import NextButtonBanner from '../Buttons/NextButtonBanner'; +import ReturnButtonBanner from '../Buttons/ReturnButtonBanner'; +import './styles.css'; + +export function Banner() { + return ( +
+
+ +
+

Macbook PRO M2

+

Velocidade e performance

+ +
+ +
+
+ ); +} \ No newline at end of file diff --git a/src/components/Banner/styles.css b/src/components/Banner/styles.css new file mode 100644 index 0000000..9691f1d --- /dev/null +++ b/src/components/Banner/styles.css @@ -0,0 +1,65 @@ +.banner { + display: flex; + justify-content: space-between; + align-items: center; + background: url(./../../assets/images/banner/banner.png) center/cover + no-repeat; + padding: 0 20px; + height: 500px; /* Defina a altura do banner como aproximadamente 500px */ + margin-bottom: 60px; +} + +.banner-button-center { + width: 200px; + padding: var(--spacing-xl, 16px); + border-radius: var(--radius-sm, 4px); + border: 1px solid #62d0b6; + background: #62d0b6; + border: none; + cursor: pointer; + color: #fff; + text-align: center; + font-family: Roboto Mono; + font-size: 16px; + font-style: normal; + font-weight: 400; + line-height: 24px; + margin: 16px 0; +} + +.banner-button-center:hover { + background-color: #81D9C5; + color: var(--primary); +} + +.banner-content { + flex-grow: 1; + text-align: center; + margin: 0 20px; +} + +.banner-button-left { + order: -1; +} + +.banner-button-right { + order: 1; +} +.title-banner { + color: #fff; + text-align: center; + font-family: Roboto Mono; + font-size: 48px; + font-style: normal; + font-weight: 400; + line-height: 70px; /* 145.833% */ +} +.description-banner { + color: #f8f8f8; + text-align: center; + font-family: Roboto Mono; + font-size: 16px; + font-style: normal; + font-weight: 400; + line-height: 25px; /* 156.25% */ +} diff --git a/src/components/Buttons/Button.module.css b/src/components/Buttons/Button.module.css new file mode 100644 index 0000000..f7f0a51 --- /dev/null +++ b/src/components/Buttons/Button.module.css @@ -0,0 +1,112 @@ +@import "../../assets/css/font.css"; + +.favoriteButton { + display: flex; + padding: var(--spacing-xl, 16px); + justify-content: center; + align-items: center; + gap: var(--spacing-lg, 8px); + align-self: stretch; + background-color: white; + border-radius: var(--radius-sm, 4px); + border: 1px solid #eee; + transition: background-color 0.3s ease; + cursor: pointer; +} + +.cartButton { + color: #333; + text-align: right; + font-family: Roboto Flex; + font-size: 16px; + font-style: normal; + font-weight: 500; + line-height: 24px; /* 150% */ + + display: flex; + padding: var(--spacing-xl, 16px); + justify-content: center; + align-items: center; + gap: var(--spacing-lg, 8px); + flex: 1 0 0; + background-color: white; + border-radius: var(--radius-sm, 4px); + border: 1px solid #eee; + cursor: pointer; + + transition: background-color 0.3s ease; +} + +.cartButtonDestaque { + color: #333; + text-align: right; + font-family: Roboto Flex; + font-size: 16px; + font-style: normal; + font-weight: 500; + line-height: 24px; /* 150% */ + + display: flex; + padding: var(--spacing-xl, 16px); + justify-content: center; + align-items: center; + gap: var(--spacing-lg, 8px); + flex: 1 0 0; + border-radius: var(--radius-sm, 4px); + border: 1px solid #62d0b6; + background: #62d0b6; + color: #fff; + text-align: right; + font-family: Roboto Flex; + font-size: 16px; + font-style: normal; + font-weight: 500; + line-height: 24px; /* 150% */ + cursor: pointer; +} + +.favoriteButton img { + display: flex; + width: 18px; + height: 18px; + padding: 1.098px 0px 1.66px 0px; + justify-content: center; + align-items: center; +} + +.cartButton img, +.cartButtonDestaque img { + display: flex; + width: 16px; + height: 16px; + padding: 1.222px 1.229px 1.333px 1.193px; + justify-content: center; + align-items: center; +} + +.selected { + background-color: var(--secondary); + color: var(--primary); + transition-delay: 20ms; +} + +.favoriteButton:hover, +.cartButton:hover { + background-color: var(--secondary); + color: var(--primary); + transition: background-color 0.3s ease; +} + +.cartButtonDestaque:hover { + background-color: #81d9c5; + color: var(--primary); + transition: #81d9c5 0.3s ease; +} + +.favoriteButton.selected img[alt="icon"], +.favoriteButton:hover img[alt="icon"], +.cartButton.selected img[alt="icon"], +.cartButton:hover img[alt="icon"], +.cartButtonDestaque img[alt="icon"] { + filter: brightness(0) invert(1); +} diff --git a/src/components/Buttons/BuyButton.css b/src/components/Buttons/BuyButton.css new file mode 100644 index 0000000..c5cf973 --- /dev/null +++ b/src/components/Buttons/BuyButton.css @@ -0,0 +1,25 @@ +.buyButton { + display: flex; + padding: var(--spacing-xl, 16px); + justify-content: center; + align-items: center; + gap: var(--spacing-lg, 8px); + flex: 1 0 0; + border-radius: var(--radius-sm, 4px); + border: 1px solid #62d0b6; + background: #62d0b6; + color: #fff; + text-align: right; + font-family: Roboto Flex; + font-size: 16px; + font-style: normal; + font-weight: 500; + line-height: 24px; /* 150% */ + cursor: pointer; +} + +.buyButton:hover { + background-color: #81D9C5; + color: var(--primary); + transition: #81D9C5 0.3s ease; + } \ No newline at end of file diff --git a/src/components/Buttons/BuyButton.jsx b/src/components/Buttons/BuyButton.jsx new file mode 100644 index 0000000..199bac3 --- /dev/null +++ b/src/components/Buttons/BuyButton.jsx @@ -0,0 +1,11 @@ +import "./BuyButton.css" + +function BuyButton() { + return ( + <> + + + ); +} + +export default BuyButton; diff --git a/src/components/Buttons/CartButton.jsx b/src/components/Buttons/CartButton.jsx new file mode 100644 index 0000000..adaa0d2 --- /dev/null +++ b/src/components/Buttons/CartButton.jsx @@ -0,0 +1,42 @@ +import classes from "./Button.module.css"; +import { addToCart } from '../Slices/CartSlice' +import cartlogo from "../../assets/images/Icons/cart.svg"; +import { useDispatch } from "react-redux"; +import PropTypes from "prop-types"; +import { toast } from 'react-toastify'; + +function CartButton({ product }) { + const dispatch = useDispatch(); + const addItemToCartHandler = () => { + const item = { + id: product.id, + price: product.price, + image: product.image, + title: product.title, + amount: 1, + }; + dispatch(addToCart(item)); + toast.success(`${item.title} adicionado ao carrinho!`); + }; + return ( + + <> + + + ); +} + +export default CartButton; + +CartButton.propTypes = { + product: PropTypes.shape({ + id: PropTypes.number.isRequired, + price: PropTypes.number.isRequired, + image: PropTypes.string.isRequired, + title: PropTypes.string.isRequired, + // Add other required properties here + }).isRequired, +}; \ No newline at end of file diff --git a/src/components/Buttons/CartButtonDestaque.jsx b/src/components/Buttons/CartButtonDestaque.jsx new file mode 100644 index 0000000..f27554b --- /dev/null +++ b/src/components/Buttons/CartButtonDestaque.jsx @@ -0,0 +1,41 @@ +import classes from "./Button.module.css"; +import { addToCart } from "../Slices/CartSlice"; +import cartlogo from "../../assets/images/Icons/cart.svg"; +import { useDispatch } from "react-redux"; +import PropTypes from "prop-types"; +import { toast } from "react-toastify"; + +function CartButtonDestaque({ product }) { + const dispatch = useDispatch(); + const addItemToCartHandler = () => { + const item = { + id: product.id, + price: product.price, + image: product.image, + title: product.title, + amount: 1, + }; + dispatch(addToCart(item)); + toast.success(`${item.title} adicionado ao carrinho!`); + }; + return ( + <> + + + ); +} + +export default CartButtonDestaque; + +CartButtonDestaque.propTypes = { + product: PropTypes.shape({ + id: PropTypes.number.isRequired, + price: PropTypes.number.isRequired, + image: PropTypes.string.isRequired, + title: PropTypes.string.isRequired, + // Add other required properties here + }).isRequired, +}; diff --git a/src/components/Buttons/CartButtonProductPage.css b/src/components/Buttons/CartButtonProductPage.css new file mode 100644 index 0000000..bb42948 --- /dev/null +++ b/src/components/Buttons/CartButtonProductPage.css @@ -0,0 +1,39 @@ +.cartButtonPage { + display: flex; + padding: var(--spacing-xl, 16px); + justify-content: center; + align-items: center; + gap: var(--spacing-lg, 8px); + flex: 1 0 0; + border-radius: var(--radius-sm, 4px); + border: 1px solid #62d0b6; + background: #fff; + color: #62d0b6; + text-align: right; + font-family: Roboto Flex; + font-size: 16px; + font-style: normal; + font-weight: 500; + line-height: 24px; /* 150% */ + cursor: pointer; +} + +.cartButtonPage:hover { + background-color: var(--secondary); + color: var(--primary); + transition: background-color 0.3s ease; +} + +.cartButtonPage img { + display: flex; + width: 16px; + height: 16px; + padding: 1.222px 1.229px 1.333px 1.193px; + justify-content: center; + align-items: center; + fill: #62d0b6 +} + +.cartButtonPage:hover img[alt="icon"] { + filter: brightness(0) invert(1); + } \ No newline at end of file diff --git a/src/components/Buttons/CartButtonProductPage.jsx b/src/components/Buttons/CartButtonProductPage.jsx new file mode 100644 index 0000000..8552001 --- /dev/null +++ b/src/components/Buttons/CartButtonProductPage.jsx @@ -0,0 +1,43 @@ +import cartlogoGreen from "../../assets/images/Icons/cartlogoGreen.svg"; +import { useDispatch } from "react-redux"; +import { addToCart } from '../Slices/CartSlice' +import PropTypes from "prop-types"; +import { toast } from 'react-toastify'; +import "./CartButtonProductPage.css" + +function CartButtonProductPage({ product, amount }) { + const dispatch = useDispatch(); + const addItemToCartHandler = () => { + const item = { + id: product.id, + price: product.price, + image: product.image, + title: product.title, + amount: amount, + }; + dispatch(addToCart(item)); + toast.success(`${item.title} adicionado ao carrinho!`); + }; + return ( + <> + + + ); + } + CartButtonProductPage.propTypes = { + product: PropTypes.shape({ + id: PropTypes.number.isRequired, + price: PropTypes.number.isRequired, + image: PropTypes.string.isRequired, + title: PropTypes.string.isRequired, + // Add other required properties here + }).isRequired, + amount: PropTypes.number.isRequired, + }; + + + export default CartButtonProductPage; + \ No newline at end of file diff --git a/src/components/Buttons/FavoriteButton.jsx b/src/components/Buttons/FavoriteButton.jsx new file mode 100644 index 0000000..6694df6 --- /dev/null +++ b/src/components/Buttons/FavoriteButton.jsx @@ -0,0 +1,24 @@ +import { useState } from "react"; + +import classes from "./Button.module.css"; + +import heart from "../../assets/images/Icons/like.svg"; + +export function FavoriteButton() { + const [favorite, setFavorite] = useState(false); + + const favoriteHandler = () => { + setFavorite(!favorite); + }; + + return ( + + ); +} diff --git a/src/components/Buttons/IncrementButton.css b/src/components/Buttons/IncrementButton.css new file mode 100644 index 0000000..b62b95e --- /dev/null +++ b/src/components/Buttons/IncrementButton.css @@ -0,0 +1,42 @@ +.incrementButton { + display: flex; + height: 50px; + justify-content: center; + align-items: center; + gap: var(--spacing-2-xl, 24px); + border-radius: 4px; + border: 1px solid #eee; + background: #fff; +} + +.quantityButton { + display: flex; + height: 50px; + padding: 0px var(--spacing-xl, 16px); + justify-content: center; + align-items: center; + gap: var(--spacing-2-xl, 24px); + border-radius: 4px; + border: 1px solid #eee; + background: #fff; + cursor: pointer; +} + +.quantityButton:hover { + background-color: var(--secondary); + color: var(--primary); + transition: background-color 0.3s ease; +} + +.quantityInsert { + display: flex; + align-items: center; + gap: 30px; + color: #333; + text-align: center; + font-family: Roboto Flex; + font-size: 14px; + font-style: normal; + font-weight: 400; + line-height: 24px; /* 171.429% */ +} diff --git a/src/components/Buttons/IncrementButton.jsx b/src/components/Buttons/IncrementButton.jsx new file mode 100644 index 0000000..39d585c --- /dev/null +++ b/src/components/Buttons/IncrementButton.jsx @@ -0,0 +1,53 @@ +/*import { useReducer } from 'react';*/ +import "./IncrementButton.css"; +import PropTypes from 'prop-types'; + +/*const quantityReducer = (state, action) => { + switch (action.type) { + case 'INCREMENT': + return state + 1; + case 'DECREMENT': + return state > 0 ? state - 1 : 0; + default: + return state; + } +};*/ + +function IncrementButton({ quantity, setQuantity }) { + const decreaseQuantity = () => { + if (quantity > 0) { + setQuantity(quantity - 1); + } + }; + + const increaseQuantity = () => { + setQuantity(quantity + 1); + }; + + + return ( +
+ + {quantity} {/* não é uma tag válida, então substituí por */} + +
+ ); +} + +IncrementButton.propTypes = { + quantity: PropTypes.number.isRequired, + setQuantity: PropTypes.func.isRequired, +}; + +export default IncrementButton; \ No newline at end of file diff --git a/src/components/Buttons/NextButton..jsx b/src/components/Buttons/NextButton..jsx new file mode 100644 index 0000000..5604a8c --- /dev/null +++ b/src/components/Buttons/NextButton..jsx @@ -0,0 +1,16 @@ +import "./ReturnNextButton.css"; +import { ButtonPaginationTypes } from "../../types/ButtonPaginationTypes"; +import arrowRight from "../../assets/images/Icons/arrow_right.svg"; + +function NextButton({ onClick, disabled }) { + return ( + <> + + + ); +} + +export default NextButton; +NextButton.propTypes = ButtonPaginationTypes diff --git a/src/components/Buttons/NextButtonBanner.jsx b/src/components/Buttons/NextButtonBanner.jsx new file mode 100644 index 0000000..e45fdc1 --- /dev/null +++ b/src/components/Buttons/NextButtonBanner.jsx @@ -0,0 +1,15 @@ +import "./ReturnNextButtonBanner.css"; + +import arrowRight from "../../assets/images/Icons/arrow_right.svg"; + +function NextButtonBanner() { + return ( + <> + + + ); +} + +export default NextButtonBanner; diff --git a/src/components/Buttons/ReturnButton.jsx b/src/components/Buttons/ReturnButton.jsx new file mode 100644 index 0000000..f0cc3fc --- /dev/null +++ b/src/components/Buttons/ReturnButton.jsx @@ -0,0 +1,18 @@ +import "./ReturnNextButton.css"; + +import arrowLeft from "../../assets/images/Icons/arrow_left.svg"; + +import { ButtonPaginationTypes } from "../../types/ButtonPaginationTypes"; +function ReturnButton({ onClick, disabled }) { + return ( + <> + + + ); +} + +export default ReturnButton; + +ReturnButton.propTypes = ButtonPaginationTypes; diff --git a/src/components/Buttons/ReturnButtonBanner.jsx b/src/components/Buttons/ReturnButtonBanner.jsx new file mode 100644 index 0000000..e970135 --- /dev/null +++ b/src/components/Buttons/ReturnButtonBanner.jsx @@ -0,0 +1,15 @@ +import "./ReturnNextButtonBanner.css"; + +import arrowLeft from "../../assets/images/Icons/arrow_left.svg"; + +function ReturnButtonBanner() { + return ( + <> + + + ); +} + +export default ReturnButtonBanner; diff --git a/src/components/Buttons/ReturnNextButton.css b/src/components/Buttons/ReturnNextButton.css new file mode 100644 index 0000000..fd0e436 --- /dev/null +++ b/src/components/Buttons/ReturnNextButton.css @@ -0,0 +1,40 @@ +.arrowButton { + display: flex; + width: 46px; + height: 46px; + padding: var(--spacing-lg, 8px); + flex-direction: column; + justify-content: center; + align-items: center; + gap: 10px; + border-radius: 100%; + border: 1px solid #eee; + background: #fff; + cursor: pointer; +} + +.arrow { + display: flex; + width: 16px; + height: 16px; + padding: 2px 4.667px; + justify-content: center; + align-items: center; + flex-shrink: 0; + color: (102, 102, 102, 1); +} + +.arrowButton:hover { + background-color: var(--secondary); + color: var(--primary); + transition: background-color 0.3s ease; +} + +.arrowButton:hover img[alt="arrow"] { + filter: brightness(0) invert(1); +} + +.arrowButton:disabled { + display: none; + cursor: not-allowed; +} \ No newline at end of file diff --git a/src/components/Buttons/ReturnNextButtonBanner.css b/src/components/Buttons/ReturnNextButtonBanner.css new file mode 100644 index 0000000..1349dd9 --- /dev/null +++ b/src/components/Buttons/ReturnNextButtonBanner.css @@ -0,0 +1,45 @@ +.arrowButtonBanner { + display: flex; + width: 30px; + height: 30px; + padding: var(--spacing-lg, 8px); + margin: 0 auto; /* Centraliza horizontalmente usando margem automática */ + flex-direction: column; + justify-content: center; + align-items: center; + gap: 10px; + flex-shrink: 0; + border-radius: 50%; + border: 1px solid #EEE; + background: transparent; + cursor: pointer; +} + +/* Adicione as media queries conforme necessário */ +@media (max-width: 768px) { + .arrowButtonBanner { + margin: 0 5%; /* Margem de 5% nas laterais para telas maiores */ + display: none; + } +} + +.arrowBanner { + display: flex; + width: 16px; + height: 16px; + padding: 2px 4.667px; + justify-content: center; + align-items: center; + flex-shrink: 0; + color: #fff; +} + +.arrowButtonBanner:hover { + background-color: #62D0B6; + color: var(--primary); + transition: background-color 0.3s ease; +} + +.arrowButtonBanner img[alt="arrowBanner"] { + filter: brightness(0) invert(1); +} \ No newline at end of file diff --git a/src/components/CardDesconto/index.jsx b/src/components/CardDesconto/index.jsx new file mode 100644 index 0000000..0c96e39 --- /dev/null +++ b/src/components/CardDesconto/index.jsx @@ -0,0 +1,64 @@ +import { Rating } from "./../Rating"; +import { Countdown } from "../Contdown"; +import { FavoriteButton } from "../Buttons/FavoriteButton"; +import { Badge } from "../Badge"; +import { formatarPreco } from "../../utils/function/formatarPreco"; +import { CardDescontoPropTypes } from "../../types/CardDescontoPropTypes"; +import CartButtonDestaque from "../Buttons/CartButtonDestaque"; + +import "./styles.css"; +export function CardDesconto({ + title, + description, + price, + priceDiscount, + image, + stars, + date, +}) { + const product = { + id: Math.random(), // You can generate a unique ID here + title, + description, + price, + priceDiscount, + image, + stars, + date, + }; + return ( +
+
+
+
+
+

{title}

+

{description}

+
+
+

({stars})

+ +
+
+

de {formatarPreco(price)}

+

{formatarPreco(priceDiscount)}

+
+
+ +
+ + +
+
+
+ {title} + +
+
+
+ ); +} +CardDesconto.propTypes = CardDescontoPropTypes; diff --git a/src/components/CardDesconto/styles.css b/src/components/CardDesconto/styles.css new file mode 100644 index 0000000..38e38b3 --- /dev/null +++ b/src/components/CardDesconto/styles.css @@ -0,0 +1,191 @@ +.container-card-desconto { + display: flex; + flex-direction: column; + align-items: flex-start; + flex: 1 0 0; + border-radius: 4px; + border: 1px solid var(--secondary); + background: #fff; +} + +.card-desconto { + display: flex; + justify-content: center; + align-items: flex-start; + align-self: stretch; + flex-wrap: wrap; +} + +.card-list-desconto { + display: flex; + padding: var(--spacing-xl, 16px); + flex-direction: column; + align-items: flex-end; + gap: var(--spacing-xl, 16px); + flex: 1 0 0; + flex-wrap: wrap; + order: 2; +} + +.content-desconto { + display: flex; + flex-direction: column; + align-items: flex-start; + gap: var(--spacing-md, 4px); + align-self: stretch; +} + +.text-desconto { + display: flex; + flex-direction: column; + align-items: flex-end; + gap: var(--spacing-md, 4px); + align-self: stretch; +} + +.title-desconto { + color: #333; + text-align: right; + font-family: Roboto Flex; + font-size: 18px; + font-style: normal; + font-weight: 500; + line-height: 25px; +} + +.description-desconto { + color: #666; + text-align: right; + font-family: Roboto Flex; + font-size: 16px; + font-style: normal; + font-weight: 400; + line-height: 25px; +} + +.star-desconto { + display: flex; + justify-content: flex-end; + align-items: center; + gap: var(--spacing-lg, 8px); + align-self: stretch; +} + +.pstars { + color: #a5a5a5; + text-align: right; + font-family: Roboto Flex; + font-size: 14px; + font-style: normal; + font-weight: 400; + line-height: normal; +} + +.prices-desconto { + display: flex; + justify-content: flex-end; + align-items: center; + gap: var(--spacing-lg, 8px); + align-self: stretch; +} + +.price-nodiscont { + color: #a5a5a5; + text-align: right; + font-family: Roboto Flex; + font-size: 16px; + font-style: normal; + font-weight: 400; + line-height: 24px; + text-decoration-line: strikethrough; + text-decoration: line-through; +} + +.price-discont { + color: #f55157; + text-align: right; + font-family: Roboto Flex; + font-size: 18px; + font-style: normal; + font-weight: 500; + line-height: 25px; +} + +.buttons-desconto { + display: flex; + align-items: flex-start; + gap: var(--spacing-lg, 8px); + align-self: stretch; +} + +.button-like { + display: flex; + padding: var(--spacing-xl, 16px); + justify-content: center; + align-items: center; + gap: var(--spacing-lg, 8px); + align-self: stretch; + border-radius: var(--radius-sm, 4px); + border: 1px solid #62d0b6; + background: #62d0b6; +} + +.button-cart { + display: flex; + padding: var(--spacing-xl, 16px); + justify-content: center; + align-items: center; + gap: var(--spacing-lg, 8px); + flex: 1 0 0; + border-radius: var(--radius-sm, 4px); + border: 1px solid #62d0b6; + background: #62d0b6; +} + +.container-image-desconto { + display: flex; + justify-content: flex-end; + align-items: flex-start; + gap: 10px; + align-self: stretch; + position: relative; + order: 1; +} + +.image-desconto { + min-width: 196px; + align-self: center; + border-radius: 0px 4px 0px 0px; + padding-inline: 10px; +} + +/* Media query for mobile */ +@media (max-width: 767px) { + .card-list-desconto { + padding: var(--spacing-md, 12px); /* Adjusted padding for mobile */ + gap: var(--spacing-md, 12px); /* Adjusted gap for mobile */ + } + + .image-desconto { + width: 100%; /* Image spans full width on mobile */ + max-width: none; /* Remove max-width for mobile */ + border-radius: 4px; /* Keep rounded corners for the image on mobile */ + } +} +@media (min-width: 1199px) { + .card-list-desconto { + order: 1; + } + .container-image-desconto { + order: 2; + } +} +@media (min-width: 545px) and (max-width: 628px) { + .card-list-desconto { + order: 1; + } + + .container-image-desconto { + order: 2; + } +} diff --git a/src/components/CardDestaque/index.jsx b/src/components/CardDestaque/index.jsx new file mode 100644 index 0000000..0649926 --- /dev/null +++ b/src/components/CardDestaque/index.jsx @@ -0,0 +1,16 @@ +import {CardDestaquePropTypes } from '../../types/CardDestaquePropTypes'; +import './style.css'; +export function CardDestaque({title, description, iconImage}) { + return ( +
+
+

{title}

+

{description}

+
+
+ {title} +
+
+ ) +} +CardDestaque.propTypes =CardDestaquePropTypes \ No newline at end of file diff --git a/src/components/CardDestaque/style.css b/src/components/CardDestaque/style.css new file mode 100644 index 0000000..0c59fc5 --- /dev/null +++ b/src/components/CardDestaque/style.css @@ -0,0 +1,58 @@ +.card-destaque { + display: flex; + padding: var(--spacing-3-xl, 32px); + justify-content: flex-end; + align-items: center; + gap: var(--spacing-xl, 16px); + align-self: stretch; +} +.card-text-destaque { + display: flex; + flex-direction: column; + align-items: flex-end; + gap: var(--spacing-md, 4px); + flex: 1 0 0; +} +.card-icon-destaque{ + display: flex; + width: 40px; + height: 40px; + padding: 2.813px 0px; + justify-content: center; + align-items: center; +} +.title-destaque{ + color: #333; + text-align: right; + font-family: Roboto Mono; + font-size: 20px; + font-style: normal; + font-weight: 400; + line-height: 30px; /* 150% */ +} +.description-destaque{ + color: #666; + text-align: right; + font-family: Roboto Flex; + font-size: 16px; + font-style: normal; + font-weight: 400; + line-height: 25px; /* 156.25% */ +} +@media screen and (max-width: 768px) { + .card-destaque { + display: flex; + padding: var(--spacing-3-xl, 32px); + justify-content: flex-end; + align-items: center; + gap: var(--spacing-xl, 16px); + align-self: stretch; + } + .card-text-destaque { + display: flex; + flex-direction: column; + align-items: flex-end; + gap: var(--spacing-md, 4px); + flex: 1 0 0; + } +} \ No newline at end of file diff --git a/src/components/CartContainer/index.jsx b/src/components/CartContainer/index.jsx new file mode 100644 index 0000000..0616539 --- /dev/null +++ b/src/components/CartContainer/index.jsx @@ -0,0 +1,58 @@ +import './style.css' +import { CartItems } from '../CartItems' +import { useSelector } from 'react-redux'; +import { selectTotalAmount} from '../Slices/TotalAmount' + +import Line from '../../assets/images/Icons/Line.svg' + + +export function CartContainer() { + const cartItems = useSelector(state => state.cart.items); + const totalValue = useSelector (selectTotalAmount) + const displayTotalValue = Math.abs(totalValue) < 0.01 ? 0 : totalValue; + + if (!cartItems) { + return
Loading...
; + } + return ( + +
+
+
Resumo Pedido
+
+
+ R$ {displayTotalValue.toFixed(2)} +
+
Total
+
+
+
+ Possui um código de desconto? +
+
+ + +
+ + + +
+
+
+ + {cartItems.map((item) => ( + + ))} +
+
+ + ) + +} diff --git a/src/components/CartContainer/style.css b/src/components/CartContainer/style.css new file mode 100644 index 0000000..4b07ab0 --- /dev/null +++ b/src/components/CartContainer/style.css @@ -0,0 +1,178 @@ +.cart-content-container { + display: flex;; + height: auto; + align-items: flex-start; + gap: var(--spacing-2-xl, 24px); + flex-shrink: 0; + flex-wrap: wrap; +} + +.cart-product-options-card { + display: flex; + width: 282px; + height: 368px; + padding: var(--spacing-xl, 16px); + flex-direction: column; + align-items: flex-end; + gap: var(--spacing-xl, 16px); + flex-shrink: 0; + border-radius: 4px; + border: 1px solid #EEE; + background: #FFF; + +} + +.cart-product-text { + align-self: stretch; + color: #333; + text-align: right; + font-family: Roboto Flex; + font-size: 18px; + font-style: normal; + font-weight: 500; + line-height: 25px; +} + +.cart-product-value-wrapper { + display: flex; + align-items: flex-start; + gap: var(--spacing-2-xl, 24px); + align-self: stretch; +} + +.cart-product-value-text { + color: #666; + font-family: Roboto Flex; + font-size: 20px; + font-style: normal; + font-weight: 900; + line-height: 25px; +} + +.cart-product-total-text { + color: #666; + text-align: right; + font-family: Roboto Flex; + font-size: 16px; + font-style: normal; + font-weight: 400; + line-height: 25px; + flex: 1 0 0; +} + +.cart-coupon-container { + display: flex; + flex-direction: column; + justify-content: center; + align-items: flex-end; + gap: var(--spacing-lg, 8px); + align-self: stretch; + +} + +.cart-coupon-container-text { + color: #333; + text-align: right; + font-family: Roboto Flex; + font-size: 14px; + font-style: normal; + font-weight: 400; + line-height: normal; +} + +.cart-coupon-container-wrapper { + display: flex; + padding-right: 0px; + align-items: center; + gap: 10px; + align-self: stretch; + border-radius: 4px; + border: 1px solid #EEE; + background: #FFF; +} + +.coupon-text { + color: #A5A5A5; + text-align: right; + font-family: Roboto Flex; + font-size: 14px; + font-style: normal; + font-weight: 400; + line-height: normal; +} + +.cart-coupon-button { + display: flex; + padding: 10px var(--spacing-xl, 16px) 11px var(--spacing-xl, 16px); + justify-content: center; + align-items: flex-end; + gap: var(--spacing-lg, 8px); + border-radius: var(--radius-sm, 4px) 4px var(--radius-sm, 4px) var(--radius-sm, 4px); + border: 1px solid #62D0B6; + border-radius: 4px; + background: #FFF; +} + +.cart-coupon-input { + color: #A5A5A5; + text-align: right; + font-family: Roboto Flex; + font-size: 14px; + font-style: normal; + font-weight: 400; + line-height: normal; + border: 0; +} + +.cart-coupon-line { + /*width: 250px*/ + width: 350px; + height: 1px; + background: #EEE; +} + + + +.cart-coupon-submit-button { + display: flex; + padding: var(--spacing-xl, 16px); + justify-content: center; + align-items: center; + gap: var(--spacing-lg, 8px); + align-self: stretch; + border-radius: var(--radius-sm, 4px); + border: 1px solid #62D0B6; + background: #62D0B6; + color: #FFF; + text-align: right; + font-family: Roboto Flex; + font-size: 16px; + font-style: normal; + font-weight: 500; + line-height: 24px; + cursor: pointer; + transition: background-color 0.3s ease-in-out; + +} + +.cart-coupon-submit-button:hover { + background-color: #62D0B6; + opacity: 0.75; +} +@media screen and (max-width: 445px){ + .cart-item-wrapper{ + flex-direction: column; + } + .cart-cancel-button{ + order: 1; + } + .cart-item-description-card{ + order: 2; + } + .cart-item-value-text { + order: 3; + } + .cart-item-quantity-button{ + order: 4; + } + } diff --git a/src/components/CartItems/index.jsx b/src/components/CartItems/index.jsx new file mode 100644 index 0000000..9b3bba8 --- /dev/null +++ b/src/components/CartItems/index.jsx @@ -0,0 +1,77 @@ +import './style.css' +import CancelIcon from '../../assets/images/Icons/Cancel.svg' +import MinorIcon from '../../assets/images/Icons/minoricon.svg' +import PlusIcon from '../../assets/images/Icons/plusicon.svg' +import { CartItemTypes } from './../../types/CartItensTypes' +import { useDispatch } from 'react-redux'; +import { toast } from 'react-toastify'; +import { removeFromCart, addToCart, removeAllById } from '../Slices/CartSlice'; // Ajuste o caminho +import { formatarPreco } from '../../utils/function/formatarPreco' +import { Link } from 'react-router-dom' + + +export function CartItems(props) { + const dispatch = useDispatch(); + + const increaseQuantity = () => { + dispatch(addToCart({ id: props.id, amount: 1, price: props.value })); + toast.success(`${props.title} adicionado ao carrinho!`); + + }; + + const decreaseQuantity = () => { + if (props.quantity > 0) { + dispatch(removeFromCart(props.id)); + toast.error(`Um ${props.title} removido do carrinho!`); + } + }; + + const handleRemoveItem = () => { + dispatch(removeAllById(props.id)); + toast.error(`${props.title} foi removido do carrinho`); + }; + + const calculatedValue = props.value * props.quantity; + + return ( +
+ +

+ {formatarPreco(calculatedValue)} +

+
+ + + +
+ +
+
+

{props.title}

+

R$ {props.value.toFixed(2)}

+
+
+ Item + +
+ ); +} + +CartItems.propTypes = CartItemTypes + diff --git a/src/components/CartItems/style.css b/src/components/CartItems/style.css new file mode 100644 index 0000000..fdb8e19 --- /dev/null +++ b/src/components/CartItems/style.css @@ -0,0 +1,191 @@ +.cart-items-list-container { + display: flex; + flex-direction: column; + align-items: flex-start; + gap: var(--spacing-xl, 16px); + flex: 1 0 0; + overflow: auto; +} + +.cart-item-wrapper { + display: flex; + padding: var(--spacing-xl, 16px); + align-items: center; + gap: var(--spacing-3-xl, 32px); + align-self: stretch; + border-radius: var(--radius-sm, 4px); + border: 1px solid #EEE; + background: #FFF; + overflow: auto; +} + +.cart-cancel-button { + display: flex; + padding: var(--spacing-lg, 8px); + align-items: center; + gap: 10px; + border: 0; + border-radius: 50px; + background: #F8F8F8; + cursor: pointer; + transition: background-color 0.3s ease-in-out; +} + +.cart-cancel-button:hover { + background-color: #F55157; + opacity: 0.75; + } + + +.cart-cancel-icon { + width: 12px; + height: 12px; +} + +.cart-item-value-text { + color: #333; + font-family: Roboto Flex; + font-size: 18px; + font-style: normal; + font-weight: 500; + line-height: 25px; +} + +.cart-item-quantity-button { + display: flex; + /*height: 60px; + width: 174px;*/ + padding: var(--spacing-xl, 16px); + justify-content: flex-end; + align-items: center; + gap: var(--spacing-xl, 16px); + border-radius: 4px; + border: 1px solid #EEE; + background: #FFF; +} + + +.cart-minor-button { + display: flex; + width: 16px; + height: 16px; + padding: 0px 2.667px; + justify-content: center; + align-items: center; + border: 0; + border-radius: 25%; + background: #FFF; + cursor: pointer; + transition: background-color 0.3s ease-in-out; + +} + +.cart-minor-button:hover { + background-color: #62D0B6; + opacity:0.75; + +} + +.cart-minor-icon { + /*width: 10.667px; + height: 1px;*/ + width: 20.667px; + flex-shrink: 0; +} + +.cart-plus-button { + display: flex; + width: 16px; + height: 16px; + padding: 2.667px; + justify-content: center; + align-items: center; + border: 0; + border-radius: 25%; + background: #FFF; + cursor: pointer; + transition: background-color 0.3s ease-in-out; +} + +.cart-plus-button:Hover { + background-color: #62D0B6; + opacity: 0.75; + +} + +.cart-plus-icon { + width: 20.667px; + flex-shrink: 0; + + +} + +.cart-quantity-input { + flex: 1 0 0; + color: #666; + text-align: center; + font-family: Roboto Flex; + font-size: 16px; + font-style: normal; + font-weight: 400; + line-height: 25px; + border-top: 0px; + border-bottom: 0px; + border-left: solid #EEE; + border-right: solid #EEE; + +} + +.cart-item-description-card { + display: flex; + justify-content: flex-end; + align-items: center; + gap: var(--spacing-xl, 16px); + flex: 1 0 0; +} + +.cart-item-description-wrapper { + display: flex; + flex-direction: column; + align-items: flex-end; + gap: var(--spacing-md, 4px); + flex: 1 0 0; +} + +.cart-item-description-text-container { + display: flex; + flex-direction: column; + align-items: flex-start; + align-self: stretch; +} + +.cart-item-description-text { + color: #333; + text-align: right; + font-family: Roboto Flex; + font-size: 16px; + font-style: normal; + font-weight: 500; + line-height: normal; + align-self: stretch; +} + +.cart-item-description-value { + color: #666; + text-align: right; + font-family: Roboto Flex; + font-size: 14px; + font-style: normal; + font-weight: 400; + line-height: normal; + align-self: stretch; +} + +.cart-item-img { + width: 95px; + height: 80px; + border-radius: 4px; + border: 2px solid #EEE; + background: #FFF; + +} \ No newline at end of file diff --git a/src/components/ContainerList/ContainerList.css b/src/components/ContainerList/ContainerList.css new file mode 100644 index 0000000..6a44ee3 --- /dev/null +++ b/src/components/ContainerList/ContainerList.css @@ -0,0 +1,95 @@ +@import "../../assets/css/font.css"; + +.containerList { + display: flex; + width: 100%; + margin: 0 auto; + max-width: 80%; + + padding: var(--spacing-6-xl, 56px) 37px; + padding-inline: 0%; + flex-direction: column; + align-items: stretch; + gap: var(--spacing-3-xl, 32px); +} + +.containerHeader { + display: flex; + justify-content: flex-end; + align-items: flex-end; + gap: var(--spacing-md, 4px); +} + +.verTudoButton { + margin: 0; + display: flex; + padding: 10px var(--spacing-xl, 16px) 11px var(--spacing-xl, 16px); + justify-content: flex-end; + align-items: center; + gap: var(--spacing-lg, 8px); + background-color: white; + border-radius: var(--radius-sm, 4px); + border: 1px solid #d0f1e9; + color: #d0f1e9; + text-align: right; + font-family: Roboto Flex; + font-size: 14px; + font-style: normal; + font-weight: 400; + line-height: normal; +} + +.containerTitle { + display: flex; + flex-direction: column; + align-items: flex-start; + flex: 1 0 0; +} + +h1 { + align-self: stretch; + color: #333; + text-align: right; + font-family: Roboto Flex; + font-size: 24px; + font-style: normal; + font-weight: 500; + line-height: 35px; /* 145.833% */ +} + +h2 { + align-self: stretch; + color: #666; + text-align: right; + font-family: Roboto Flex; + font-size: 16px; + font-style: normal; + font-weight: 400; + line-height: 25px; /* 156.25% */ +} + +.productList { + display: flex; + flex-wrap: wrap; + align-items: flex-start; + gap: var(--spacing-2-xl, 24px); + align-self: stretch; +} + +.productList > * { + flex: 1 0 calc(25% - var(--spacing-2-xl, 24px)); +} + +.returnNextButton { + display: flex; + justify-content: center; + align-items: center; + gap: var(--spacing-md, 4px); + align-self: stretch; +} + +@media (max-width: 800px) { + .productList > * { + flex: 1 0 calc(50% - var(--spacing-2-xl, 24px)); + } +} diff --git a/src/components/ContainerList/ContainerList.jsx b/src/components/ContainerList/ContainerList.jsx new file mode 100644 index 0000000..6cb936b --- /dev/null +++ b/src/components/ContainerList/ContainerList.jsx @@ -0,0 +1,76 @@ +import { useState, useEffect, useMemo } from "react"; +import ProductsContainer from "../ProductsContainer/ProductsContainer"; +import arrowIcon from "../../assets/images/Icons/ArrowIcon.svg"; +import "./ContainerList.css"; +import ReturnButton from "../Buttons/ReturnButton"; +import NextButton from "../Buttons/NextButton."; +import { clienteAxios } from "../../utils/service/cliente-api"; + +function ContainerList() { + const [products, setProducts] = useState([]); + const [currentPage, setCurrentPage] = useState(1); + const productsPerPage = 8; + + useEffect(() => { + const fetchData = async () => { + try { + const response = await clienteAxios.get('/products'); + setProducts(response.data); + } catch (error) { + console.error('Error:', error); + } + }; + + fetchData(); + }, []); + + const priceAdditions = useMemo(() => { + return products.map(product => { + const min = -5; + const max = 10; + const randomPercentage = Math.floor(Math.random() * (max - min + 1)) + min; + return (randomPercentage * product.price) / 100 + product.price; + }); + }, [products]); + + const handleNextPage = () => { + setCurrentPage(currentPage + 1); + }; + + const handleReturnPage = () => { + setCurrentPage(currentPage - 1); + }; + + const indexOfLastProduct = currentPage * productsPerPage; + const indexOfFirstProduct = indexOfLastProduct - productsPerPage; + const currentProducts = products.slice(indexOfFirstProduct, indexOfLastProduct); + + return ( +
+
+ +
+

Produtos em destaque

+

Produtos em destaque mais recentes adicionados

+
+
+
+ {currentProducts.map((product, index) => ( + + ))} +
+
+ + = products.length} /> +
+
+ ); +} + +export default ContainerList; \ No newline at end of file diff --git a/src/components/Contdown/index.jsx b/src/components/Contdown/index.jsx new file mode 100644 index 0000000..a930a1a --- /dev/null +++ b/src/components/Contdown/index.jsx @@ -0,0 +1,38 @@ +import { useState, useEffect } from 'react'; +import './styles.css'; +import { CountdownPropTypes } from '../../types/CountownPropTypes'; + +export function Countdown ({date}) { + const targetDate = new Date(date).getTime(); + const [timeLeft, setTimeLeft] = useState(targetDate - new Date().getTime()); + + useEffect(() => { + const interval = setInterval(() => { + const updatedTimeLeft = targetDate - new Date().getTime(); + setTimeLeft(updatedTimeLeft); + + if (updatedTimeLeft <= 0) { + clearInterval(interval); + } + }, 1000); + + return () => { + clearInterval(interval); + }; + }, [targetDate]); + + const days = Math.floor(timeLeft / (1000 * 60 * 60 * 24)); + const hours = Math.floor((timeLeft % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60)); + const minutes = Math.floor((timeLeft % (1000 * 60 * 60)) / (1000 * 60)); + const seconds = Math.floor((timeLeft % (1000 * 60)) / 1000); + + return ( +
+
{days}

dias

+
{hours}

horas

+
{minutes}

minutos

+
{seconds}

segundos

+
+ ); +} +Countdown.propTypes = CountdownPropTypes; diff --git a/src/components/Contdown/styles.css b/src/components/Contdown/styles.css new file mode 100644 index 0000000..6c28b27 --- /dev/null +++ b/src/components/Contdown/styles.css @@ -0,0 +1,35 @@ +.card-time-countdown{ + display: flex; + align-items: flex-start; + gap: var(--spacing-lg, 8px); + align-self: stretch; +} +.day-time-countdown, .hour-time-countdown, .min-time-countdown, .sec-time-countdown{ + display: flex; + padding: 8px 0; + flex-direction: column; + justify-content: center; + align-items: center; + gap: -5px; + flex: 1 0 0; + border-radius: 4px; + background: #F8F8F8; +} +.span-countdown{ + color: #333; + text-align: right; + font-family: Roboto Flex; + font-size: 18px; + font-style: normal; + font-weight: 500; + line-height: 25px; /* 138.889% */ +} +.p-countdown{ + color: #A5A5A5; + text-align: right; + font-family: Roboto Flex; + font-size: 14px; + font-style: normal; + font-weight: 400; + line-height: normal; +} \ No newline at end of file diff --git a/src/components/ContentContainer/ContentContainer.css b/src/components/ContentContainer/ContentContainer.css new file mode 100644 index 0000000..5a7a2c3 --- /dev/null +++ b/src/components/ContentContainer/ContentContainer.css @@ -0,0 +1,175 @@ +.contentContainer { + width: 100%; + margin: 0 auto; + max-width: 80%; + padding: 8px; + + margin-top: 60px; + margin-bottom: 100px; + + display: flex; + align-items: flex-start; + justify-content: center; + flex-direction: row; + gap: 24px; + align-self: center; +} + +.leftContent { + display: flex; + height: 751px; + flex-direction: column; + justify-content: space-between; + align-items: flex-start; + +} + +.divContainer { + display: flex; + flex-direction: column; + align-items: flex-end; + gap: var(--spacing-xl, 16px); + align-self: stretch; +} + +.productTitle { + color: #333; + text-align: right; + font-family: Roboto Flex; + font-size: 24px; + font-style: normal; + font-weight: 700; + line-height: 147%; /* 35.28px */ + align-self: stretch; +} + +.ratingStars { + display: flex; + justify-content: flex-end; + align-items: center; + gap: var(--spacing-xl, 16px); + align-self: stretch; +} + +.ratingComments { + color: #666; + text-align: right; + font-family: Roboto Flex; + font-size: 14px; + font-style: normal; + font-weight: 400; + line-height: normal; +} + +.productDescription { + display: flex; + flex-direction: column; + gap: var(--spacing-lg, 8px); + align-self: stretch; + color: #666; + text-align: right; + font-family: Roboto Flex; + font-size: 16px; + font-style: normal; + font-weight: 400; + line-height: 25px; /* 156.25% */ +} + +.divBuy { + display: flex; + flex-direction: column; + align-items: flex-start; + gap: var(--spacing-2-xl, 24px); + align-self: stretch; +} + +.priceQuantity { + display: flex; + align-items: flex-start; + gap: var(--spacing-xl, 16px); + align-self: stretch; +} + +.buttonGroup { + display: flex; + align-items: flex-start; + gap: var(--spacing-xl, 16px); + align-self: stretch; +} + +.productPrice { + display: flex; + align-items: center; + gap: 6px; + flex: 1 0 0; + color: #333; + font-family: Roboto Flex; + font-size: 24px; + font-style: normal; + font-weight: 700; + line-height: 147%; /* 35.28px */ +} + +.quantityProduct { + display: flex; + justify-content: flex-end; + align-items: center; + gap: var(--spacing-xl, 16px); +} + +.rightContent { + display: flex; + align-self: center; + height: 651px; + position: relative; + border-radius: var(--radius-sm, 4px); + border: 1px solid #EEE; + padding: 50px; +} + +.productImage { + display: flex; + max-width: 590px; + max-height: 651px; + flex: 1 0 0; + align-self: center; + align-items: stretch; +} + +.enlargeImage { + display: flex; + width: 40px; + height: 40px; + padding: 10px; + align-items: center; + gap: 10px; + position: absolute; + left: 15px; + bottom: 15px; + border-radius: 2px; + border: 1px solid #eee; + background: #ffffff; + align-content: center; + justify-content: center; + cursor: pointer; + align-self: flex-end; +} +.enlargeImage:hover { + background: #62d0b6; + border: 1px solid #62d0b6; +} + +@media (max-width: 768px) { + .contentContainer { + flex-direction: column; + align-items: stretch; + } + + .rightContent { + margin-top: 24px; + } + + .productImage { + max-height: 80vw; + } +} diff --git a/src/components/ContentContainer/ContentContainer.jsx b/src/components/ContentContainer/ContentContainer.jsx new file mode 100644 index 0000000..eb4001a --- /dev/null +++ b/src/components/ContentContainer/ContentContainer.jsx @@ -0,0 +1,55 @@ +import BuyButton from "../Buttons/BuyButton"; +import CartButtonProductPage from "../Buttons/CartButtonProductPage"; +import IncrementButton from "../Buttons/IncrementButton"; +import { Rating } from "../Rating"; +import { formatarPreco } from "../../utils/function/formatarPreco"; +import { ProductPropTypes } from "../../types/ProductPropTypes"; +import { useState } from "react"; + + +import vectorImg from "../../assets/images/Icons/Vector.svg"; + +import "./ContentContainer.css"; + +function ContentContainer({ product }) { + const [quantity, setQuantity] = useState(1); + + return ( +
+
+
+

{product.title}

+
+

({product.rating.count}) avaliações

+ +
+

{product.description}

+
+
+
+

{formatarPreco(product.price)}

+
+ +
+
+
+ + +
+
+
+
+ + +
+
+ ); +} + +ContentContainer.propTypes = { + product: ProductPropTypes.isRequired, +}; + +export default ContentContainer; diff --git a/src/components/Desconto/index.jsx b/src/components/Desconto/index.jsx new file mode 100644 index 0000000..48ffebb --- /dev/null +++ b/src/components/Desconto/index.jsx @@ -0,0 +1,25 @@ +import { CardDesconto } from '../CardDesconto' +import { dataPromocao } from './../../data/dataPomocao'; +import './styles.css' +export function Desconto(){ + return( +
+

Ofertas terminando em breve

+
+ {dataPromocao.map((card, index) => ( + + ))} +
+ +
+ ) +} \ No newline at end of file diff --git a/src/components/Desconto/styles.css b/src/components/Desconto/styles.css new file mode 100644 index 0000000..a9638b9 --- /dev/null +++ b/src/components/Desconto/styles.css @@ -0,0 +1,26 @@ +.desconto-container{ + display: flex; + flex-direction: column; + align-items: flex-end; + gap: var(--spacing-3-xl, 32px); + width: 100%; + margin: 0 auto; + max-width: 80%; + padding: 56px 8px 8px 8px; +} +.list-card-desconto{ + display: flex; + align-items: flex-start; + gap: var(--spacing-2-xl, 24px); + align-self: stretch; + flex-wrap: wrap; +} +.title-section{ + color: #333; + text-align: right; + font-family: Roboto Flex; + font-size: 24px; + font-style: normal; + font-weight: 500; + line-height: 35px; /* 145.833% */ +} \ No newline at end of file diff --git a/src/components/Destaque/index.jsx b/src/components/Destaque/index.jsx new file mode 100644 index 0000000..0c6ad45 --- /dev/null +++ b/src/components/Destaque/index.jsx @@ -0,0 +1,18 @@ +import { CardDestaque } from "../CardDestaque"; +import { dadosDestaque } from "../../data/dataDestaque"; +import "./style.css"; + +export function Destaque() { + return ( +
+ {dadosDestaque.map((destaque, index) => ( + + ))} +
+ ); +} diff --git a/src/components/Destaque/style.css b/src/components/Destaque/style.css new file mode 100644 index 0000000..2867dcf --- /dev/null +++ b/src/components/Destaque/style.css @@ -0,0 +1,36 @@ +.container-card-destaque { + display: flex; + justify-content: center; + align-items: center; + justify-content: space-evenly; + gap: 1px; + border-radius: var(--radius-sm, 4px); + border: 1px solid var(--border-product, #eeeeee); + background: var(--bg-primary); +} + +@media screen and (min-width: 768px) { + .container-card-destaque > :first-child { + border-right: 1px solid var(--border-product, #eeeeee); + padding-inline: 5%; + } + + .container-card-destaque > :last-child { + border-left: 1px solid var(--border-product, #eeeeee); + padding-inline: 5%; + } +} + +@media screen and (max-width: 768px) { + .container-card-destaque { + display: flex; + flex-direction: column; + align-items: flex-start; + align-self: stretch; + } + + .container-card-destaque > :not(:last-child) { + border-right: none; + border-bottom: 1px solid var(--border-product, #eeeeee); + } +} diff --git a/src/components/Footer/index.jsx b/src/components/Footer/index.jsx new file mode 100644 index 0000000..995bcc0 --- /dev/null +++ b/src/components/Footer/index.jsx @@ -0,0 +1,54 @@ +import './style.css' +import AndroidIcon from '../../assets/images/Icons/googleplay.svg' +import AppleIcon from '../../assets/images/Icons/apple.svg' +import NewsLetterIcon from '../../assets/images/Icons/email.svg' +import MasterCardIcon from '../../assets/images/Icons/mastercard.png' +import PaypalIcon from '../../assets/images/Icons/paypal.png' +import VisaIcon from '../../assets/images/Icons/visa.png' + +export function Footer() { + return ( +
+
+
+

Baixe nosso App

+
+ googleplay icon + apple icon +
+
+
+
+

Você pode cancelar a inscrição a qualquer momento

+
+ + +
+
+
+
+

Assine a Newsletter

+

Cadastre-se agora e ganhe 10% de desconto na sua próxima compra

+
+ email icon +
+ +
+
+
+
+
+ +
+
+ +
+
+ +
+
+

2023 © Todos os direitos reservados

+
+
+ ) +} \ No newline at end of file diff --git a/src/components/Footer/style.css b/src/components/Footer/style.css new file mode 100644 index 0000000..762560c --- /dev/null +++ b/src/components/Footer/style.css @@ -0,0 +1,328 @@ +.footer-top { + display: flex; + /* width: 1600px; */ + /*height: 133px;*/ + padding: var(--spacing-2-xl, 24px) 200px; + justify-content: center; + align-items: center; + gap: var(--spacing-2-xl, 24px); + flex-shrink: 0; + border-radius: 2px; + background: #f8f8f8; +} + +.footer-top-card-apps { + display: flex; + padding: 1px 0px var(--spacing-sm, 2px) 0px; + flex-direction: column; + align-items: flex-end; + gap: var(--spacing-xl, 16px); +} + +.footer-title-apps { + color: #333; + text-align: right; + font-family: Roboto; + font-size: 16px; + font-style: normal; + font-weight: 500; + line-height: normal; +} + +.footer-apps-box { + display: flex; + height: 42px; + align-items: flex-start; + gap: var(--spacing-lg, 8px); + align-self: stretch; +} + +.footer-top-card-subscribe { + display: flex; + padding: 1px 0px var(--spacing-sm, 2px) 0px; + justify-content: flex-end; + align-items: center; + gap: var(--spacing-2-xl, 24px); + flex: 1 0 0; +} + +.footer-title-subscribe { + align-self: stretch; + color: #333; + text-align: right; + font-family: Roboto Flex; + font-size: 14px; + font-style: normal; + font-weight: 400; + line-height: normal; +} + +.footer-button-subscribe { + display: flex; + width: 90px; + padding: var(--spacing-lg, 8px) var(--spacing-xl, 16px); + justify-content: center; + align-items: center; + gap: var(--spacing-lg, 8px); + align-self: stretch; + border-radius: var(--radius-sm, 4px); + border: 1px solid #62d0b6; + background: #62d0b6; + color: #fff; + text-align: right; + font-family: Roboto; + font-size: 14px; + font-style: normal; + font-weight: 500; + line-height: normal; + cursor: pointer; +} + +.footer-button-subscribe:hover { + background-color: #81D9C5; + color: var(--primary); +} + +.footer-top-card-email { + display: flex; + flex-direction: column; + justify-content: center; + align-items: flex-end; + gap: var(--spacing-xl, 16px); + flex: 1 0 0; + align-self: stretch; +} + +.footer-top-card-input { + display: flex; + padding: 10px var(--spacing-xl, 16px) 12px var(--spacing-xl, 16px); + justify-content: flex-end; + align-items: center; + gap: 10px; + flex: 1 0 0; + align-self: stretch; + border-radius: var(--radius-sm, 4px); + border: 1px solid #eee; + background: #fff; +} + +.footer-email-box { + display: flex; + justify-content: flex-end; + align-items: center; + gap: var(--spacing-lg, 8px); + align-self: stretch; +} + +.footer-newsletter-cardbox { + display: flex; + justify-content: flex-end; + align-items: center; + gap: var(--spacing-xl, 16px); + align-self: stretch; +} + +.footer-newsletter-box { + display: flex; + flex-direction: column; + align-items: flex-end; + gap: var(--spacing-md, 4px); +} + +.footer-newsletter-title { + color: #333; + text-align: right; + font-family: Roboto Flex; + font-size: 20px; + font-style: normal; + font-weight: 400; + line-height: 30px; +} + +.footer-newsletter-desc { + color: #666; + text-align: right; + font-family: Roboto Flex; + font-size: 14px; + font-style: normal; + font-weight: 400; + line-height: normal; +} + +.footer-newsletter-icon { + display: flex; + padding: var(--spacing-xl, 16px); + justify-content: center; + align-items: center; + gap: 10px; + border-radius: 50px; + background: rgba(214, 248, 240, 0.5); +} + +.footer-top-card-input::placeholder { + color: #a5a5a5; + text-align: right; + font-family: Roboto Flex; + font-size: 14px; + font-style: normal; + font-weight: 400; + line-height: normal; +} + +.footer-down { + display: flex; + /*width: 1600px;*/ + height: 65.416px; + height: 40px; + padding: var(--spacing-xl, 16px) 200px; + justify-content: center; + align-items: center; + gap: var(--spacing-2-xl, 24px); + flex-shrink: 0; + background: #1d1f1f; +} + +.footer-down-payment { + display: flex; + justify-content: flex-end; + align-items: flex-start; + gap: var(--spacing-lg, 8px); +} + +.footer-down-payment-wrapper { + display: flex; + width: 60px; + height: 31px; + height: 15px; + padding: 10px; + flex-direction: column; + justify-content: center; + align-items: center; + gap: 10px; + border-radius: 2px; + background: #fff; +} + +.footer-down-copyright { + flex: 1 0 0; + color: #fff; + text-align: right; + font-family: Roboto Flex; + font-size: 14px; + font-style: normal; + font-weight: 400; + line-height: normal; +} + +@media screen and (max-width: 1244px) { + .footer-top { + display: flex; + padding: var(--spacing-3-xl, 32px) var(--spacing-xl, 16px); + flex-direction: column; + justify-content: center; + align-items: center; + gap: var(--spacing-2-xl, 24px); + align-self: stretch; + } + + .footer-top-card-subscribe { + display: flex; + flex-direction: column; + justify-content: center; + align-items: flex-end; + gap: var(--spacing-xl, 16px); + align-self: stretch; + } + + .footer-newsletter-cardbox { + display: flex; + order: 1; + align-items: center; + gap: var(--spacing-xl, 16px); + align-self: stretch; + } + + .footer-newsletter-box { + display: flex; + flex-direction: column; + align-items: flex-end; + gap: var(--spacing-md, 4px); + flex: 1 0 0; + } + + .footer-top-card-email { + display: flex; + flex-direction: column; + order: 2; + justify-content: center; + align-items: flex-end; + gap: var(--spacing-xl, 16px); + align-self: stretch; + } + + .footer-newsletter-title { + align-self: stretch; + text-align: right; + font-size: 16px; + } + + .footer-top-card-apps { + display: flex; + order: 3; + flex-direction: column; + justify-content: center; + align-items: flex-end; + gap: var(--spacing-lg, 8px); + align-self: stretch; + } + + .footer-apps-box { + display: flex; + justify-content: flex-end; + align-items: center; + gap: 10px; + } + + .footer-down { + display: flex; + padding: var(--spacing-xl, 16px); + flex-direction: column; + justify-content: center; + align-items: flex-end; + gap: var(--spacing-xl, 16px); + align-self: stretch; + background: #1d1f1f; + } + + .footer-down-payment { + flex-direction: row; + align-items: center; + justify-content: flex-end; + } + + .footer-down-payment-wrapper { + display: flex; + width: 60px; + height: 15px; + padding: 10px; + flex-direction: column; + justify-content: center; + align-items: center; + gap: 10px; + flex-shrink: 0; + border-radius: 2px; + background: #fff; + } + + .footer-down-payment-icon { + flex-shrink: 0; + } + + .footer-down-copyright { + display: flex; + justify-content: flex-end; + align-items: center; + gap: var(--spacing-lg, 8px); + align-self: stretch; + } +} diff --git a/src/components/Header/index.jsx b/src/components/Header/index.jsx index e69de29..f08776e 100644 --- a/src/components/Header/index.jsx +++ b/src/components/Header/index.jsx @@ -0,0 +1,63 @@ +import { Link } from "react-router-dom"; +import { SearchComponent } from '../SearchComponent'; +import { HeaderPropTypes } from '../../types/HeaderPropTypes'; + +import './styles.css' + +export function Header({ numberCart, username}) { + + return ( +
+
+
+
+ +
+ + + + +
+
+ {numberCart} +
+ +
+
+
+

Bem-vindo

+
+

{username||"Username"}

+
+
+
+
+ + + + +
+
+
+
+ +
+ + + + + + + + + + + + + +
+
+
+ ); +} +Header.propTypes = HeaderPropTypes; \ No newline at end of file diff --git a/src/components/Header/styles.css b/src/components/Header/styles.css new file mode 100644 index 0000000..4bddefa --- /dev/null +++ b/src/components/Header/styles.css @@ -0,0 +1,147 @@ +.header { + display: flex; + width: 100%; + flex-direction: column; + justify-content: center; + align-items: center; + background: var(--bg-primary); +} +.section-details { + display: flex; + padding: var(--spacing-3-xl, 32px) 0; + align-items: center; + gap: var(--spacing-5-xl, 48px); + align-self: stretch; + justify-content: space-between; + flex-wrap: wrap; +} +.section-cart-profile { + display: flex; + align-items: flex-start; + gap: var(--spacing-3-xl, 32px); +} +.section-cart { + display: flex; + align-items: center; + gap: var(--spacing-lg, 8px); +} +.section-profile { + display: flex; + align-items: center; + gap: var(--spacing-lg, 8px); +} +.section-content-profile { + display: flex; + flex-direction: column; + align-items: flex-end; +} +.welcome { + color: #a5a5a5; + text-align: center; + font-family: Roboto Flex; + font-size: 14px; + font-style: normal; + font-weight: 400; + line-height: normal; +} +.section-nameuser { + display: flex; + justify-content: flex-end; + align-items: flex-start; + gap: 4px; +} +.name-user { + color: #333; + font-family: Roboto Flex; + font-size: 16px; + font-style: normal; + font-weight: 400; + line-height: 25px; /* 156.25% */ +} +.section-icon-profile { + display: flex; + padding: var(--spacing-lg, 8px); + justify-content: center; + align-items: center; + gap: 10px; + border-radius: 50px; + background: #F8F8F8; +} +.section-icon { + display: flex; + width: 24px; + height: 24px; + justify-content: center; + align-items: center; +} +.section-logo { + display: flex; + justify-content: flex-end; + align-items: flex-end; + gap: 4px; + width: 44px; + height: 44px; +} +.section-icon-cart { + display: flex; + padding: var(--spacing-lg, 16px); + justify-content: center; + align-items: center; + gap: 10px; + position: relative; + border-radius: 50px; + background: #F8F8F8; +} +.icon-cart { + display: flex; + width: 24px; + height: 24px; + padding: 2px; + justify-content: center; + align-items: center; +} +.number-cart { + display: flex; + width: 18px; + height: 18px; + padding: 2px; + flex-direction: column; + justify-content: center; + align-items: center; + gap: 6px; + position: absolute; + right: 1px; + top: 8px; + border-radius: 50%; + border: 1px solid #fff; + background: #f55157; +} +.span-cart { + width: 100%; + height: 50%; + color: #fff; + font-family: "Roboto Flex", sans-serif; + font-size: 10px; + font-weight: 400; + display: flex; + align-items: center; + justify-content: center; +} +@media screen and (max-width: 795px) { + .section-details { + gap: var(--spacing-xl, 16px); + } + .section-content-profile{ + display: none; + } + .section-cart-profile{ + order: 1; + } + .search-container{ + order:3; + } + .section-logo{ + order: 2; + } + +} \ No newline at end of file diff --git a/src/components/LowerBanner/index.jsx b/src/components/LowerBanner/index.jsx new file mode 100644 index 0000000..152202d --- /dev/null +++ b/src/components/LowerBanner/index.jsx @@ -0,0 +1,60 @@ +import './style.css' +import { useState, useEffect } from 'react'; +import banner from './../../assets/images/banners/bannerContainer.png' +import bannerMobile from './../../assets/images/banners/BannerMobile.png'; +import itemImg from './../../assets/images/banners/lap.png' +import arrow from './../../assets/images/Icons/ArrowIcon.svg' + +export function LowerBanner() { + const [shouldRenderItemImg, setShouldRenderItemImg] = useState(true); + const [shouldRenderButton, setShouldRenderButton] = useState(true); + const [bannerImage, setBannerImage] = useState(banner); + + useEffect(() => { + const handleResize = () => { + const windowWidth = document.documentElement.clientWidth; + if (windowWidth <= 1630) { + setShouldRenderItemImg(false); + } else { + setShouldRenderItemImg(true); + } + + if (windowWidth <= 1200) { + setShouldRenderButton(false); + } else { + setShouldRenderButton(true); + } + + if (windowWidth <= 800) { + setBannerImage(bannerMobile); + } else { + setBannerImage(banner); + } + }; + + window.addEventListener('resize', handleResize); + handleResize(); + return () => { + window.removeEventListener('resize', handleResize); + }; + }, []); + + return ( +
+
+ banner + {shouldRenderItemImg && item} +
+
Home Office
+
+ A loja de cestos oferece-lhe todos os artigos de eletrónica ou artigos de decoração de que necessita, + para além dos melhores descontos em produtos. Compre agora e aproveite todos os descontos nos produtos.
+ {shouldRenderButton && } +
+
+
+ + + + ) +} diff --git a/src/components/LowerBanner/style.css b/src/components/LowerBanner/style.css new file mode 100644 index 0000000..70239d3 --- /dev/null +++ b/src/components/LowerBanner/style.css @@ -0,0 +1,152 @@ +.lower-banner-container { + display: flex; + position: relative; + width: 100%; + flex-direction: row; + align-items: center; + gap: var(--spacing-5-xl, 48px); + +} + +.lower-banner-img { + width: 100%; +} + + +.lower-banner-img-card { + position: absolute; + padding: 90px 200px; + width: 696px; + height: 320px; + flex-shrink: 0; + +} + +.lower-banner-text-card { + display: flex; + position: absolute; + padding: 90px 200px; + flex-direction: column; + justify-content: center; + align-items: flex-end; + gap: var(--spacing-3-xl, 32px); + flex: 1 0 0; +} + +.lower-banner-text-card-title { + align-self: stretch; + padding-left: 90px; + color: #FFF; + text-align: right; + font-family: Roboto Flex; + font-size: 48px; + font-style: normal; + font-weight: 400; + line-height: 70px; + +} + +.lower-banner-text-card-description { + align-self: stretch; + padding-left: 900px; + color: #FFF; + text-align: right; + font-family: Roboto Flex; + font-size: 14px; + font-style: normal; + font-weight: 400; + line-height: 25px; + word-wrap: break-word; + /* 156.25% */ +} + +.lower-banner-button { + display: flex; + width: 200px; + padding: var(--spacing-xl, 16px); + justify-content: center; + align-items: center; + gap: var(--spacing-lg, 8px); + border-radius: var(--radius-sm, 4px); + border: 1px solid #62D0B6; + background: #62D0B6; + color: #FFF; + text-align: right; + font-family: Roboto Flex; + font-size: 16px; + font-style: normal; + font-weight: 400; + line-height: 24px; + cursor: pointer; +} + +.lower-banner-button:hover { + background-color: #81D9C5; + color: var(--primary); + } + +@media screen and (max-width: 1646px) { + .lower-banner-text-card { + display: flex; + height: 432px; + position: absolute; + padding: 90px; + flex-direction: column; + justify-content: center; + align-items: center; + text-align: center; + gap: var(--spacing-3-xl, 32px); + flex: 1 0 0; + } + + .lower-banner-text-card-title { + align-self: stretch; + padding-left: 0; + color: #FFF; + text-align: center; + font-family: Roboto Flex; + font-size: 48px; + font-style: normal; + font-weight: 400; + line-height: 70px; + + } + + .lower-banner-text-card-description { + align-self: stretch; + padding-left: 0; + color: #FFF; + text-align: center; + align-items: center; + font-family: Roboto Flex; + font-size: 14px; + font-style: normal; + font-weight: 400; + line-height: 25px; + word-wrap: break-word; + /* 156.25% */ + } + + + + @media screen and (max-width: 428px) { + .lower-banner-container { + width: 100%; + flex-shrink: 0; + } + + .lower-banner-text-card { + display: flex; + max-width: 428px; + height: auto; + padding: 0px var(--spacing-2-xl, 24px); + flex-direction: column; + justify-content: center; + align-items: center; + gap: var(--spacing-2-xl, 24px); + flex-shrink: 0; + } + } + + +} \ No newline at end of file diff --git a/src/components/ProductsContainer/Container.css b/src/components/ProductsContainer/Container.css new file mode 100644 index 0000000..12d3b1b --- /dev/null +++ b/src/components/ProductsContainer/Container.css @@ -0,0 +1,107 @@ +@import "../../assets/css/font.css"; + +@import "../../assets/css/colors.css"; + +.container { + width: 282px; + height: auto; + display: flex; + flex-direction: column; + align-items: flex-start; + flex: 1 0 0; + border-radius: var(--radius-sm, 4px); + border: 1px solid #eee; + background: #fff; +} + +.containerContent { + display: flex; + flex-direction: column; + align-items: center; + align-self: stretch; + position: relative; + max-height: 480px; +} + +.productsImage { + display: flex; + flex: 1 0 0; + max-width: 282px; + height: 228px; + align-self: stretch; + border-radius: 4px 4px 0px 0px; + min-height: 250px; + padding-top: 20px; +} + +.listContainer { + display: flex; + padding: var(--spacing-xl, 16px); + flex-direction: column; + align-items: flex-end; + gap: var(--spacing-xl, 16px); + align-self: stretch; +} + +.title { + align-self: flex-end; + color: #333; + text-align: right; + font-family: Roboto Flex; + font-size: 16px; + font-style: normal; + font-weight: 500; + line-height: normal; + overflow: hidden; + text-overflow: ellipsis; +} + +.addition { + color: #a5a5a5; + font-family: Roboto Flex; + font-size: 14px; + font-style: normal; + font-weight: 400; + line-height: 24px; /* 171.429% */ + text-decoration-line: line-through; +} + +.discountPrice { + color: #f55157; + text-align: right; + font-family: Roboto Flex; + font-size: 18px; + font-style: normal; + font-weight: 500; + line-height: 25px; /* 138.889% */ +} + +.price { + display: flex; + justify-content: flex-end; + align-items: center; + gap: 6px; + align-self: stretch; +} + +.buttonSection { + display: flex; + align-items: flex-start; + gap: var(--spacing-lg, 8px); + align-self: stretch; +} + +.container:hover { + border: 1px solid var(--secondary); + transition: border-color 20ms ease; +} + +.PriceGray{ + color: #333; + text-align: right; + font-family: Roboto Flex; + font-size: 18px; + font-style: normal; + font-weight: 500; + line-height: 25px; +} diff --git a/src/components/ProductsContainer/ProductsContainer.jsx b/src/components/ProductsContainer/ProductsContainer.jsx new file mode 100644 index 0000000..cdcb0b2 --- /dev/null +++ b/src/components/ProductsContainer/ProductsContainer.jsx @@ -0,0 +1,42 @@ +import { Link } from "react-router-dom"; +import { Badge } from "../Badge"; +import CartButton from "../Buttons/CartButton"; +import { FavoriteButton } from "../Buttons/FavoriteButton"; +import { formatarPreco } from "../../utils/function/formatarPreco"; +import { isPriceLower } from "../../utils/function/pricelower"; +import { ProductsContainerPropTypes } from "../../types/ProductsContainerPropTypes"; + +import "./Container.css"; +function ProductsContainer({ product, priceAddition }) { + return ( +
+
+ + + + +
+

{product.title}

+
+ {isPriceLower(product.price, priceAddition) ? ( + <> +

de {formatarPreco(priceAddition)}

+

+ por {formatarPreco(product.price)} +

+ + ) : ( +

por {formatarPreco(product.price)}

+ )} +
+
+ + +
+
+
+
+ ); +} +ProductsContainer.propTypes = ProductsContainerPropTypes; +export default ProductsContainer; diff --git a/src/components/Rating/index.jsx b/src/components/Rating/index.jsx new file mode 100644 index 0000000..5562ca2 --- /dev/null +++ b/src/components/Rating/index.jsx @@ -0,0 +1,25 @@ +import { RatingPropTypes } from '../../types/RatingPropTypes'; +import './styles.css' + export const Rating = ({ rating, maxStars }) => { + const renderStars = () => { + const stars = []; + for (let i = 1; i <= maxStars; i++) { + stars.push( + + ★ + + ); + } + return stars; + }; + + return ( +
+ {renderStars()} +
+ ); + }; + Rating.propTypes = RatingPropTypes; diff --git a/src/components/Rating/styles.css b/src/components/Rating/styles.css new file mode 100644 index 0000000..3abfa95 --- /dev/null +++ b/src/components/Rating/styles.css @@ -0,0 +1,13 @@ +.rating-desconto { + font-size: 24px; + display: inline-block; + } + + .star { + color: #D6D6D6 + } + + .star.filled { + color: #FFC62A; + } + \ No newline at end of file diff --git a/src/components/SearchComponent/index.jsx b/src/components/SearchComponent/index.jsx new file mode 100644 index 0000000..1dd2564 --- /dev/null +++ b/src/components/SearchComponent/index.jsx @@ -0,0 +1,45 @@ +import { useState } from 'react'; +import './styles.css'; + +export function SearchComponent() { + const [searchTerm, setSearchTerm] = useState(''); + + const handleSearchChange = (event) => { + setSearchTerm(event.target.value); + }; + + const handleSearchSubmit = (event) => { + event.preventDefault(); + }; + + return ( +
+
+
+ + + + + + + + + + +
+ + +
+ +
+ ); + } + \ No newline at end of file diff --git a/src/components/SearchComponent/styles.css b/src/components/SearchComponent/styles.css new file mode 100644 index 0000000..8703f1c --- /dev/null +++ b/src/components/SearchComponent/styles.css @@ -0,0 +1,55 @@ +/* Tamanhos base */ +:root { + --spacing-sm: 4px; + --spacing-md: 8px; + --spacing-lg: 16px; + --spacing-xl: 24px; + --radius-sm: 8px; + } + + /* Estilos padrão */ + .search-container { + display: flex; + flex-direction: column; + justify-content: flex-end; + align-items: center; + gap: var(--spacing-lg, 8px); + flex: 1 0 0; + align-self: stretch; + } + + .search-input-container { + display: flex; + padding: 14px var(--spacing-xl, 16px) 15px var(--spacing-xl, 16px); + justify-content: space-between; + align-items: center; + gap: var(--spacing-md, 4px); + align-self: stretch; + border-radius: var(--radius-sm, 4px); + border: 1px solid #eee; + background: #fff; + box-shadow: 0px 4px 4px 0px rgba(0, 0, 0, 0.25); + } + + .search-input { + flex: 1; + border: none; + padding: 5px; + } + + .search-button { + background: transparent; + border: none; + color: #a5a5a5; + font-family: "Roboto Flex", sans-serif; + font-size: 13px; + font-weight: 400; + line-height: normal; + cursor: pointer; + } + + .search-icon { + width: 16px; + height: 16px; + } + diff --git a/src/components/Slices/CartSelector.js b/src/components/Slices/CartSelector.js new file mode 100644 index 0000000..bec0b4d --- /dev/null +++ b/src/components/Slices/CartSelector.js @@ -0,0 +1,4 @@ + +export const selectCartTotalItems = (state) => { + return state.cart.items.reduce((total, item) => total + item.amount, 0); + }; \ No newline at end of file diff --git a/src/components/Slices/CartSlice.js b/src/components/Slices/CartSlice.js new file mode 100644 index 0000000..150607b --- /dev/null +++ b/src/components/Slices/CartSlice.js @@ -0,0 +1,58 @@ +import { createSlice } from '@reduxjs/toolkit'; + +const cartSlice = createSlice({ + name: 'cart', + initialState: { + items: [], + totalAmount: 0, + }, + reducers: { + addToCart: (state, action) => { + const newItem = action.payload; + const existingItem = state.items.find(item => item.id === newItem.id); + + if (existingItem) { + existingItem.amount += newItem.amount; + } else { + state.items.push(newItem); + } + + state.totalAmount += newItem.price * newItem.amount; + }, + removeFromCart: (state, action) => { + const idToRemove = action.payload; + const existingItem = state.items.find(item => item.id === idToRemove); + + if (existingItem.amount === 1) { + state.items = state.items.filter(item => item.id !== idToRemove); + } else { + existingItem.amount--; + } + + state.totalAmount -= existingItem.price; + }, + removeAllById: (state, action) => { + const idToRemove = action.payload; + const itemsToRemove = state.items.filter(item => item.id === idToRemove); + + itemsToRemove.forEach(item => { + state.totalAmount -= item.price * item.amount; + }); + + state.items = state.items.filter(item => item.id !== idToRemove); + }, + }, + }); + + export const { addToCart, removeFromCart, removeAllById } = cartSlice.actions; + + export default cartSlice.reducer; + + + + + + + + + \ No newline at end of file diff --git a/src/components/Slices/TotalAmount.js b/src/components/Slices/TotalAmount.js new file mode 100644 index 0000000..279ea90 --- /dev/null +++ b/src/components/Slices/TotalAmount.js @@ -0,0 +1,3 @@ +export function selectTotalAmount(state) { + return state.cart.totalAmount; +} \ No newline at end of file diff --git a/src/constants/constant.js b/src/constants/constant.js deleted file mode 100644 index e69de29..0000000 diff --git a/src/data/dataDestaque.js b/src/data/dataDestaque.js new file mode 100644 index 0000000..d0a4f48 --- /dev/null +++ b/src/data/dataDestaque.js @@ -0,0 +1,20 @@ +import CardIcon from '../assets/images/Icons/card.svg'; +import LoadingIcon from '../assets/images/Icons/loading.svg'; +import CarIcon from '../assets/images/Icons/car.svg'; +export const dadosDestaque = [ + { + title: 'Comprou', + description: 'Aceitamos todos os cartões', + iconImage: CardIcon + }, + { + title: 'Atualizou', + description: 'Aprovação de compra', + iconImage: LoadingIcon + }, + { + title: 'Entrega', + description: 'Entregamos para todo o Brasil', + iconImage: CarIcon + } +]; \ No newline at end of file diff --git a/src/data/dataPomocao.js b/src/data/dataPomocao.js new file mode 100644 index 0000000..c3c389a --- /dev/null +++ b/src/data/dataPomocao.js @@ -0,0 +1,23 @@ +// mockedData.js + +export const dataPromocao = [ + { + title: "Novo relógio inteligente da série 8", + description: "Black Sport Band - Regular.", + price: 900.00, + priceDiscount: 700.00, + image: "https://encrypted-tbn0.gstatic.com/shopping?q=tbn:ANd9GcRU3aE-8vYhoF4Ih1S-xZo5wyRj_urlo_dbe3r1Jfzqw4q1RetUBae3ExlPIqc9Wzdongsai0m7pPt65RS6ih2oGwQgPLE3ZlHJ1u3-munDr247DCLcWhUy-A&usqp=CAc", + stars: 4.5, + date: "2023-09-28T16:00:00" + }, + { + title: "Novo relógio inteligente da série 7", + description: "Black Sport Band - Regular.", + price: 900.00, + priceDiscount: 700.00, + image: "https://encrypted-tbn0.gstatic.com/shopping?q=tbn:ANd9GcRU3aE-8vYhoF4Ih1S-xZo5wyRj_urlo_dbe3r1Jfzqw4q1RetUBae3ExlPIqc9Wzdongsai0m7pPt65RS6ih2oGwQgPLE3ZlHJ1u3-munDr247DCLcWhUy-A&usqp=CAc", + stars: 4.5, + date: "2023-10-30T16:00:00" + } + ]; + \ No newline at end of file diff --git a/src/main.jsx b/src/main.jsx index 6df3687..cafd940 100644 --- a/src/main.jsx +++ b/src/main.jsx @@ -1,11 +1,22 @@ -import React from 'react' -import ReactDOM from 'react-dom/client' -import { App } from './pages/Home' -import './assets/css/global.css' -import './assets/css/index.css' +import React from "react"; +import ReactDOM from "react-dom/client"; +import { BrowserRouter as Router } from "react-router-dom"; +import { MainRoutes } from "./router/routes"; +import { store } from '../src/components/App/store'; +import { Provider } from 'react-redux' +import { ToastContainer } from 'react-toastify'; +import 'react-toastify/dist/ReactToastify.css'; -ReactDOM.createRoot(document.getElementById('root')).render( + +import "./assets/css/global.css"; + +ReactDOM.createRoot(document.getElementById("root")).render( - - , -) + + + + + + + +); diff --git a/src/pages/Cart/CartPage.jsx b/src/pages/Cart/CartPage.jsx new file mode 100644 index 0000000..93701be --- /dev/null +++ b/src/pages/Cart/CartPage.jsx @@ -0,0 +1,19 @@ +import { Header } from "../../components/Header"; +import { CartContainer } from "../../components/CartContainer"; +import { Footer } from "../../components/Footer"; + +import { selectCartTotalItems } from '../../components/Slices/CartSelector'; +import { useSelector } from "react-redux/es/hooks/useSelector"; + + + +export function CartPage() { + const numberCart = useSelector(selectCartTotalItems); + return ( + <> +
+ +