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
+
Confira
+
+
+
+
+ );
+}
\ 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 (
+ <>
+ Comprar
+ >
+ );
+}
+
+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 (
+
+ <>
+
+ Carrinho
+
+
+ >
+ );
+}
+
+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 (
+ <>
+
+ Carrinho
+
+
+ >
+ );
+}
+
+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 (
+ <>
+
+ Carrinho
+
+
+ >
+ );
+ }
+ 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}
+
+
+
+
de {formatarPreco(price)}
+
{formatarPreco(priceDiscount)}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
+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}
+
+
+
+
+
+ )
+}
+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?
+
+
+
+
Comprar
+
+
+
+
+
+ {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)}
+
+
+
+
+
+ );
+}
+
+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 (
+
+
+
+ Ver Tudo
+
+
+
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 (
+
+ );
+}
+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
+
+
+
+
+
+
+
+
Você pode cancelar a inscrição a qualquer momento
+
+ Inscrever
+
+
+
+
+
+
Assine a Newsletter
+
Cadastre-se agora e ganhe 10% de desconto na sua próxima compra
+
+
+
+
+
+
+
+
+
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 (
+
+
+
+ {shouldRenderItemImg &&
}
+
+
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 &&
Confira}
+
+
+
+
+
+
+ )
+}
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 (
+ <>
+
+
+
+ >
+ );
+}
\ No newline at end of file
diff --git a/src/assets/js/javascript.js b/src/pages/Cart/style.css
similarity index 100%
rename from src/assets/js/javascript.js
rename to src/pages/Cart/style.css
diff --git a/src/pages/Home/index.css b/src/pages/Home/index.css
index b9d355d..e69de29 100644
--- a/src/pages/Home/index.css
+++ b/src/pages/Home/index.css
@@ -1,42 +0,0 @@
-#root {
- max-width: 1280px;
- margin: 0 auto;
- padding: 2rem;
- text-align: center;
-}
-
-.logo {
- height: 6em;
- padding: 1.5em;
- will-change: filter;
- transition: filter 300ms;
-}
-.logo:hover {
- filter: drop-shadow(0 0 2em #646cffaa);
-}
-.logo.react:hover {
- filter: drop-shadow(0 0 2em #61dafbaa);
-}
-
-@keyframes logo-spin {
- from {
- transform: rotate(0deg);
- }
- to {
- transform: rotate(360deg);
- }
-}
-
-@media (prefers-reduced-motion: no-preference) {
- a:nth-of-type(2) .logo {
- animation: logo-spin infinite 20s linear;
- }
-}
-
-.card {
- padding: 2em;
-}
-
-.read-the-docs {
- color: #888;
-}
diff --git a/src/pages/Home/index.jsx b/src/pages/Home/index.jsx
index 1f9c113..ac15cd9 100644
--- a/src/pages/Home/index.jsx
+++ b/src/pages/Home/index.jsx
@@ -1,33 +1,27 @@
-import { useState } from 'react'
-import reactLogo from './../../assets/images/logo/react.svg'
-import viteLogo from './../../../public/images/vite.svg'
-import './index.css'
+import { Header } from "../../components/Header";
+import { Destaque } from "../../components/Destaque";
+import { Desconto } from "../../components/Desconto";
+import ContainerList from "../../components/ContainerList/ContainerList";
+import { LowerBanner } from "../../components/LowerBanner";
+import {Banner } from "../../components/Banner";
+import { Footer } from "../../components/Footer";
+import { selectCartTotalItems } from '../../components/Slices/CartSelector';
+import { useSelector } from "react-redux/es/hooks/useSelector";
-export function App() {
- const [count, setCount] = useState(0)
+export function Home() {
+ const numberCart = useSelector(selectCartTotalItems);
+ console.log('%c🚀Gostou do projeto? Contrate nosso squad! 🚀', 'font-size: 18px; color: #f39c12; font-weight: bold;');
+console.log('%c📧 Segue nosso github: @ecsistem, @eduardokuritza, cristopherkovalski', 'font-size: 14px; color: #3498db;');
return (
<>
-
- Teste
-
-
setCount((count) => count + 1)}>
- count is {count}
-
-
- Edit src/App.jsx
and save to test HMR
-
-
-
- Click on the Vite and React logos to learn more
-
+
+
+
+
+
+
+
>
- )
+ );
}
diff --git a/src/pages/NotFound/index.jsx b/src/pages/NotFound/index.jsx
new file mode 100644
index 0000000..6ed0565
--- /dev/null
+++ b/src/pages/NotFound/index.jsx
@@ -0,0 +1,16 @@
+import { Header } from "../../components/Header";
+import { Footer } from "../../components/Footer";
+import './styles.css';
+
+export function NotFound() {
+ return (
+ <>
+
+
+
404
+
Desculpe mas a página que você busca não foi encontada ;(
+
+
+ >
+ )
+}
diff --git a/src/pages/NotFound/styles.css b/src/pages/NotFound/styles.css
new file mode 100644
index 0000000..5079844
--- /dev/null
+++ b/src/pages/NotFound/styles.css
@@ -0,0 +1,23 @@
+.not-found-container {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ height: calc(100vh - (280px));
+ background-color: #f8f8f8;
+ }
+
+ .not-found-title {
+ font-size: 6rem;
+ color: #F55157;
+ margin: 0;
+ align-self:auto
+ }
+
+ .not-found-message {
+ font-size: 1.5rem;
+ margin-top: 1rem;
+ color: #555;
+ text-align: center;
+ max-width: 500px;
+ }
\ No newline at end of file
diff --git a/src/pages/Products/ProductsPage.css b/src/pages/Products/ProductsPage.css
new file mode 100644
index 0000000..8cb45e7
--- /dev/null
+++ b/src/pages/Products/ProductsPage.css
@@ -0,0 +1,32 @@
+.content-wrapper {
+ display: flex;
+ flex-direction: column;
+ min-height: 100vh;
+}
+
+.content-container {
+ flex: 1;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ padding: 0px 20px 0px 20px;
+}
+
+/* Estilos para o conteúdo de carregamento */
+.loading-container {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ height: 100%;
+ font-size: 24px;
+ color: #555;
+}
+
+/* Estilos para a mensagem de erro */
+.error-message {
+ font-size: 18px;
+ color: red;
+ text-align: center;
+ margin-top: 20px;
+}
diff --git a/src/pages/Products/ProductsPage.jsx b/src/pages/Products/ProductsPage.jsx
new file mode 100644
index 0000000..764466d
--- /dev/null
+++ b/src/pages/Products/ProductsPage.jsx
@@ -0,0 +1,60 @@
+import { useState, useEffect } from 'react';
+import { useParams } from 'react-router-dom';
+import { Header } from '../../components/Header';
+import ContentContainer from '../../components/ContentContainer/ContentContainer';
+import { Footer } from '../../components/Footer';
+import { clienteAxios } from '../../utils/service/cliente-api';
+import './ProductsPage.css';
+import { selectCartTotalItems } from '../../components/Slices/CartSelector';
+import { useSelector } from "react-redux/es/hooks/useSelector";
+
+export function ProductsPage() {
+ const numberCart = useSelector(selectCartTotalItems);
+ const { productId } = useParams();
+ const [product, setProduct] = useState(null);
+ const [loading, setLoading] = useState(true);
+ const [error, setError] = useState(null);
+
+ useEffect(() => {
+ const fetchData = async () => {
+ try {
+ const response = await clienteAxios.get(`/products/${productId}`);
+ setProduct(response.data);
+ } catch (error) {
+ setError('Product not found');
+ } finally {
+ setLoading(false);
+ }
+ };
+
+ fetchData();
+ }, [productId]);
+
+ let content;
+
+ if (loading) {
+ content = (
+
+ );
+ } else if (error) {
+ content = (
+ {error}
+ );
+ } else if (product) {
+ content = ;
+ } else {
+ content = (
+ Produto não encontrado
+ );
+ }
+
+ return (
+
+ );
+}
diff --git a/src/router/routes.jsx b/src/router/routes.jsx
new file mode 100644
index 0000000..50c7d87
--- /dev/null
+++ b/src/router/routes.jsx
@@ -0,0 +1,20 @@
+import { Route, Routes } from "react-router-dom";
+import { Home } from "../pages/Home"
+import { ProductsPage } from "../pages/Products/ProductsPage";
+import { CartPage } from "../pages/Cart/CartPage";
+import { NotFound } from "../pages/NotFound";
+
+
+
+export function MainRoutes(){
+
+ return (
+
+ } />
+ } />
+ }/>
+ }/>
+ }/>
+
+ );
+}
\ No newline at end of file
diff --git a/src/types/BadgePropTypes.js b/src/types/BadgePropTypes.js
new file mode 100644
index 0000000..0cf8b48
--- /dev/null
+++ b/src/types/BadgePropTypes.js
@@ -0,0 +1,5 @@
+import PropTypes from 'prop-types';
+export const BadgePropTypes ={
+ price: PropTypes.number.isRequired,
+ priceDiscount: PropTypes.number.isRequired,
+ };
\ No newline at end of file
diff --git a/src/types/ButtonPaginationTypes.js b/src/types/ButtonPaginationTypes.js
new file mode 100644
index 0000000..44955fe
--- /dev/null
+++ b/src/types/ButtonPaginationTypes.js
@@ -0,0 +1,6 @@
+import PropTypes from 'prop-types';
+
+export const ButtonPaginationTypes = {
+ onClick: PropTypes.func.isRequired,
+ disabled: PropTypes.bool.isRequired,
+};
\ No newline at end of file
diff --git a/src/types/CardDescontoPropTypes.js b/src/types/CardDescontoPropTypes.js
new file mode 100644
index 0000000..630ed24
--- /dev/null
+++ b/src/types/CardDescontoPropTypes.js
@@ -0,0 +1,11 @@
+import PropTypes from 'prop-types';
+
+export const CardDescontoPropTypes = {
+ title: PropTypes.string.isRequired,
+ description: PropTypes.string.isRequired,
+ price: PropTypes.number.isRequired,
+ priceDiscount: PropTypes.number.isRequired, // Add this line
+ image: PropTypes.string.isRequired,
+ stars: PropTypes.number.isRequired,
+ date: PropTypes.string.isRequired,
+};
diff --git a/src/types/CardDestaquePropTypes.js b/src/types/CardDestaquePropTypes.js
new file mode 100644
index 0000000..db32d69
--- /dev/null
+++ b/src/types/CardDestaquePropTypes.js
@@ -0,0 +1,7 @@
+import PropTypes from 'prop-types';
+
+export const CardDestaquePropTypes = {
+ title: PropTypes.string.isRequired,
+ description: PropTypes.string.isRequired,
+ iconImage: PropTypes.string.isRequired,
+};
\ No newline at end of file
diff --git a/src/types/CartItensTypes.js b/src/types/CartItensTypes.js
new file mode 100644
index 0000000..7abaade
--- /dev/null
+++ b/src/types/CartItensTypes.js
@@ -0,0 +1,10 @@
+import PropTypes from 'prop-types';
+export const CartItemTypes = {
+ title: PropTypes.string.isRequired,
+ value: PropTypes.number.isRequired,
+ quantity: PropTypes.number.isRequired,
+ image: PropTypes.string.isRequired,
+ id: PropTypes.number.isRequired,
+ cartItems: PropTypes.array.isRequired,
+ updateCartItems: PropTypes.func.isRequired,
+ };
\ No newline at end of file
diff --git a/src/types/CountownPropTypes.js b/src/types/CountownPropTypes.js
new file mode 100644
index 0000000..065c637
--- /dev/null
+++ b/src/types/CountownPropTypes.js
@@ -0,0 +1,5 @@
+import PropTypes from 'prop-types';
+
+export const CountdownPropTypes = {
+ date: PropTypes.string.isRequired
+};
diff --git a/src/types/HeaderPropTypes.js b/src/types/HeaderPropTypes.js
new file mode 100644
index 0000000..81b0281
--- /dev/null
+++ b/src/types/HeaderPropTypes.js
@@ -0,0 +1,5 @@
+import PropTypes from 'prop-types';
+export const HeaderPropTypes ={
+ mumberCart: PropTypes.number,
+ username: PropTypes.string.isRequired,
+ };
\ No newline at end of file
diff --git a/src/types/ProductPropTypes.js b/src/types/ProductPropTypes.js
new file mode 100644
index 0000000..9c4380a
--- /dev/null
+++ b/src/types/ProductPropTypes.js
@@ -0,0 +1,12 @@
+import PropTypes from 'prop-types';
+
+export const ProductPropTypes = PropTypes.shape({
+ title: PropTypes.string.isRequired,
+ rating: PropTypes.shape({
+ count: PropTypes.number.isRequired,
+ rate: PropTypes.number.isRequired,
+ }).isRequired,
+ description: PropTypes.string.isRequired,
+ price: PropTypes.number.isRequired,
+ image: PropTypes.string.isRequired,
+});
diff --git a/src/types/ProductsContainerPropTypes.js b/src/types/ProductsContainerPropTypes.js
new file mode 100644
index 0000000..5a01f06
--- /dev/null
+++ b/src/types/ProductsContainerPropTypes.js
@@ -0,0 +1,9 @@
+import PropTypes from 'prop-types';
+export const ProductsContainerPropTypes = {
+ product: PropTypes.shape({
+ title: PropTypes.string,
+ price: PropTypes.number,
+ discount: PropTypes.number,
+ image: PropTypes.string
+ }).isRequired
+ };
\ No newline at end of file
diff --git a/src/types/RatingPropTypes.js b/src/types/RatingPropTypes.js
new file mode 100644
index 0000000..2380169
--- /dev/null
+++ b/src/types/RatingPropTypes.js
@@ -0,0 +1,5 @@
+import PropTypes from 'prop-types';
+export const RatingPropTypes ={
+ rating: PropTypes.number.isRequired,
+ maxStars: PropTypes.number.isRequired,
+ };
\ No newline at end of file
diff --git a/src/util/service/api.js b/src/util/service/api.js
deleted file mode 100644
index e69de29..0000000
diff --git a/src/utils/function/formatarPreco.js b/src/utils/function/formatarPreco.js
new file mode 100644
index 0000000..5aabda7
--- /dev/null
+++ b/src/utils/function/formatarPreco.js
@@ -0,0 +1,4 @@
+export function formatarPreco(preco, moeda = 'R$', casasDecimais = 2) {
+ const precoFormatado = `${moeda} ${preco.toFixed(casasDecimais).replace('.', ',').replace(/\d(?=(\d{3})+,)/g, '$&.')}`;
+ return precoFormatado;
+}
\ No newline at end of file
diff --git a/src/utils/function/pricelower.js b/src/utils/function/pricelower.js
new file mode 100644
index 0000000..b2034cd
--- /dev/null
+++ b/src/utils/function/pricelower.js
@@ -0,0 +1,3 @@
+export function isPriceLower(productPrice, priceAddition) {
+ return productPrice < priceAddition;
+ }
\ No newline at end of file
diff --git a/src/utils/service/cliente-api.js b/src/utils/service/cliente-api.js
new file mode 100644
index 0000000..3202202
--- /dev/null
+++ b/src/utils/service/cliente-api.js
@@ -0,0 +1,5 @@
+import axios from 'axios';
+
+export const clienteAxios = axios.create({
+ baseURL: 'https://fakestoreapi.com',
+ });
\ No newline at end of file