├── .gitignore
├── README.md
├── package.json
├── public
├── favicon.png
├── index.html
├── manifest.json
└── robots.txt
├── src
├── App.js
├── App.scss
├── api
│ ├── apiConfig.js
│ ├── axiosClient.js
│ └── tmdbApi.js
├── assets
│ ├── boxicons-2.0.7
│ │ ├── LICENSE.txt
│ │ ├── css
│ │ │ ├── animations.css
│ │ │ ├── boxicons.css
│ │ │ ├── boxicons.min.css
│ │ │ └── transformations.css
│ │ └── fonts
│ │ │ ├── boxicons.eot
│ │ │ ├── boxicons.svg
│ │ │ ├── boxicons.ttf
│ │ │ ├── boxicons.woff
│ │ │ └── boxicons.woff2
│ ├── footer-bg.jpg
│ ├── logo.png
│ └── tmovie.png
├── components
│ ├── button
│ │ ├── Button.jsx
│ │ └── button.scss
│ ├── footer
│ │ ├── Footer.jsx
│ │ └── footer.scss
│ ├── header
│ │ ├── Header.jsx
│ │ └── header.scss
│ ├── hero-slide
│ │ ├── HeroSlide.jsx
│ │ └── hero-slide.scss
│ ├── input
│ │ ├── Input.jsx
│ │ └── input.scss
│ ├── modal
│ │ ├── Modal.jsx
│ │ └── modal.scss
│ ├── movie-card
│ │ ├── MovieCard.jsx
│ │ └── movie-card.scss
│ ├── movie-grid
│ │ ├── MovieGrid.jsx
│ │ └── movie-grid.scss
│ ├── movie-list
│ │ ├── MovieList.jsx
│ │ └── movie-list.scss
│ └── page-header
│ │ ├── PageHeader.jsx
│ │ └── page-header.scss
├── constants
│ └── Config.js
├── index.js
├── pages
│ ├── Catalog.jsx
│ ├── Home.jsx
│ └── detail
│ │ ├── CastList.jsx
│ │ ├── Detail.jsx
│ │ ├── VideoList.jsx
│ │ └── detail.scss
├── routes
│ └── Routes.jsx
└── scss
│ ├── _breakpoint.scss
│ ├── _index.scss
│ ├── _mixin.scss
│ └── _variables.scss
└── yarn.lock
/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 |
8 | # testing
9 | /coverage
10 |
11 | # production
12 | /build
13 |
14 | # misc
15 | .DS_Store
16 | .env.local
17 | .env.development.local
18 | .env.test.local
19 | .env.production.local
20 |
21 | npm-debug.log*
22 | yarn-debug.log*
23 | yarn-error.log*
24 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Getting Started with Create React App
2 |
3 | This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app).
4 |
5 | ## Available Scripts
6 |
7 | In the project directory, you can run:
8 |
9 | ### `yarn start`
10 |
11 | Runs the app in the development mode.\
12 | Open [http://localhost:3000](http://localhost:3000) to view it in the browser.
13 |
14 | The page will reload if you make edits.\
15 | You will also see any lint errors in the console.
16 |
17 | ### `yarn test`
18 |
19 | Launches the test runner in the interactive watch mode.\
20 | See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information.
21 |
22 | ### `yarn build`
23 |
24 | Builds the app for production to the `build` folder.\
25 | It correctly bundles React in production mode and optimizes the build for the best performance.
26 |
27 | The build is minified and the filenames include the hashes.\
28 | Your app is ready to be deployed!
29 |
30 | See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information.
31 |
32 | ### `yarn eject`
33 |
34 | **Note: this is a one-way operation. Once you `eject`, you can’t go back!**
35 |
36 | If you aren’t satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project.
37 |
38 | Instead, it will copy all the configuration files and the transitive dependencies (webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you’re on your own.
39 |
40 | You don’t have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn’t feel obligated to use this feature. However we understand that this tool wouldn’t be useful if you couldn’t customize it when you are ready for it.
41 |
42 | ## Learn More
43 |
44 | You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started).
45 |
46 | To learn React, check out the [React documentation](https://reactjs.org/).
47 |
48 | ### Code Splitting
49 |
50 | This section has moved here: [https://facebook.github.io/create-react-app/docs/code-splitting](https://facebook.github.io/create-react-app/docs/code-splitting)
51 |
52 | ### Analyzing the Bundle Size
53 |
54 | This section has moved here: [https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size](https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size)
55 |
56 | ### Making a Progressive Web App
57 |
58 | This section has moved here: [https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app](https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app)
59 |
60 | ### Advanced Configuration
61 |
62 | This section has moved here: [https://facebook.github.io/create-react-app/docs/advanced-configuration](https://facebook.github.io/create-react-app/docs/advanced-configuration)
63 |
64 | ### Deployment
65 |
66 | This section has moved here: [https://facebook.github.io/create-react-app/docs/deployment](https://facebook.github.io/create-react-app/docs/deployment)
67 |
68 | ### `yarn build` fails to minify
69 |
70 | This section has moved here: [https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify](https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify)
71 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react-movie-app",
3 | "version": "0.1.0",
4 | "private": true,
5 | "homepage": "https://nvanha.github.io/react-movie-app/",
6 | "dependencies": {
7 | "@testing-library/jest-dom": "^5.11.4",
8 | "@testing-library/react": "^11.1.0",
9 | "@testing-library/user-event": "^12.1.10",
10 | "axios": "^0.23.0",
11 | "gh-pages": "^3.2.3",
12 | "query-string": "^7.0.1",
13 | "react": "^17.0.2",
14 | "react-dom": "^17.0.2",
15 | "react-router-dom": "^5.3.0",
16 | "react-scripts": "4.0.3",
17 | "sass": "^1.43.2",
18 | "swiper": "6.8.4",
19 | "web-vitals": "^1.0.1"
20 | },
21 | "scripts": {
22 | "start": "react-scripts start",
23 | "build": "react-scripts build",
24 | "test": "react-scripts test",
25 | "eject": "react-scripts eject",
26 | "predeploy": "npm run build",
27 | "deploy": "gh-pages -d build"
28 | },
29 | "eslintConfig": {
30 | "extends": [
31 | "react-app",
32 | "react-app/jest"
33 | ]
34 | },
35 | "browserslist": {
36 | "production": [
37 | ">0.2%",
38 | "not dead",
39 | "not op_mini all"
40 | ],
41 | "development": [
42 | "last 1 chrome version",
43 | "last 1 firefox version",
44 | "last 1 safari version"
45 | ]
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/public/favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/harryngdev/react-movie-app/102cd0220ed6564159ba9b038d53e4e3059eca4e/public/favicon.png
--------------------------------------------------------------------------------
/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 | hMovies
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "React App",
3 | "name": "Create React App Sample",
4 | "icons": [
5 | {
6 | "src": "favicon.png",
7 | "sizes": "64x64 32x32 24x24 16x16",
8 | "type": "image/x-icon"
9 | },
10 | {
11 | "src": "favicon.png",
12 | "type": "image/png",
13 | "sizes": "192x192"
14 | },
15 | {
16 | "src": "favicon.png",
17 | "type": "image/png",
18 | "sizes": "512x512"
19 | }
20 | ],
21 | "start_url": ".",
22 | "display": "standalone",
23 | "theme_color": "#000000",
24 | "background_color": "#ffffff"
25 | }
26 |
--------------------------------------------------------------------------------
/public/robots.txt:
--------------------------------------------------------------------------------
1 | # https://www.robotstxt.org/robotstxt.html
2 | User-agent: *
3 | Disallow:
4 |
--------------------------------------------------------------------------------
/src/App.js:
--------------------------------------------------------------------------------
1 | import "swiper/swiper.min.css";
2 | import "./assets/boxicons-2.0.7/css/boxicons.min.css";
3 | import "./App.scss";
4 |
5 | import { BrowserRouter, Route } from "react-router-dom";
6 |
7 | import Header from "./components/header/Header";
8 | import Footer from "./components/footer/Footer";
9 |
10 | import Routes from "./routes/Routes";
11 |
12 | function App() {
13 | return (
14 |
15 | (
17 | <>
18 |
19 |
20 |
21 |
22 |
23 | >
24 | )}
25 | />
26 |
27 | );
28 | }
29 |
30 | export default App;
31 |
--------------------------------------------------------------------------------
/src/App.scss:
--------------------------------------------------------------------------------
1 | @use "./scss/" as *;
2 |
3 | @import url("https://fonts.googleapis.com/css2?family=Montserrat:wght@300;400;500;600;700;900&display=swap");
4 |
5 | * {
6 | padding: 0;
7 | margin: 0;
8 | box-sizing: border-box;
9 | -webkit-box-sizing: border-box;
10 | -webkit-tap-highlight-color: transparent;
11 | }
12 |
13 | html {
14 | font-size: 100%;
15 |
16 | @include tablet {
17 | font-size: 80%;
18 | }
19 |
20 | @include mobile {
21 | font-size: 60%;
22 | }
23 | }
24 |
25 | body {
26 | font-family: $font-family;
27 | font-weight: 400;
28 | line-height: 1.5;
29 |
30 | background-color: $body-bg;
31 | color: $txt-color;
32 |
33 | @include mobile {
34 | margin-bottom: 3rem;
35 | }
36 | }
37 |
38 | a {
39 | text-decoration: none;
40 | color: unset;
41 | }
42 |
43 | @media (hover: hover) {
44 | a:hover {
45 | color: $main-color;
46 | }
47 | }
48 |
49 | button,
50 | input {
51 | outline: 0;
52 | }
53 |
54 | ul {
55 | list-style-type: none;
56 | }
57 |
58 | img {
59 | max-width: 100%;
60 | }
61 |
62 | iframe {
63 | border: 0;
64 | }
65 |
66 | .container {
67 | // max-width: 1440px;
68 | max-width: 1660px;
69 | margin: auto;
70 | }
71 |
72 | .mb-3 {
73 | margin-bottom: 3rem;
74 | }
75 |
76 | .mb-2 {
77 | margin-bottom: 2rem;
78 | }
79 |
80 | .section {
81 | padding: 0 2rem;
82 | }
83 |
84 | .section__header {
85 | @include flex(center, space-between);
86 | }
87 |
--------------------------------------------------------------------------------
/src/api/apiConfig.js:
--------------------------------------------------------------------------------
1 | const apiConfig = {
2 | baseUrl: "https://api.themoviedb.org/3/",
3 | apiKey: "193593681eeeb9f10b20ee6506e9af8b",
4 | originalImage: (imgPath) => `https://image.tmdb.org/t/p/original/${imgPath}`,
5 | w500Image: (imgPath) => `https://image.tmdb.org/t/p/w500/${imgPath}`,
6 | };
7 |
8 | export default apiConfig;
9 |
--------------------------------------------------------------------------------
/src/api/axiosClient.js:
--------------------------------------------------------------------------------
1 | import axios from "axios";
2 | import queryString from "query-string";
3 |
4 | import apiConfig from "./apiConfig";
5 |
6 | const axiosClient = axios.create({
7 | baseURL: apiConfig.baseUrl,
8 | headers: {
9 | "Content-Type": "application/json",
10 | },
11 | paramsSerializer: (params) =>
12 | queryString.stringify({ ...params, api_key: apiConfig.apiKey }),
13 | });
14 |
15 | axiosClient.interceptors.request.use(async (config) => config);
16 |
17 | axiosClient.interceptors.response.use(
18 | (response) => {
19 | if (response && response.data) {
20 | return response.data;
21 | }
22 |
23 | return response;
24 | },
25 | (error) => {
26 | throw error;
27 | }
28 | );
29 |
30 | export default axiosClient;
31 |
--------------------------------------------------------------------------------
/src/api/tmdbApi.js:
--------------------------------------------------------------------------------
1 | import axiosClient from "./axiosClient";
2 |
3 | export const category = {
4 | movie: "movie",
5 | tv: "tv",
6 | };
7 |
8 | export const movieType = {
9 | upcoming: "upcoming",
10 | popular: "popular",
11 | top_rated: "top_rated",
12 | };
13 |
14 | export const tvType = {
15 | popular: "popular",
16 | top_rated: "top_rated",
17 | on_the_air: "on_the_air",
18 | };
19 |
20 | const tmdbApi = {
21 | getMoviesList: (type, params) => {
22 | const url = "movie/" + movieType[type];
23 | return axiosClient.get(url, params);
24 | },
25 | getTvList: (type, params) => {
26 | const url = "tv/" + tvType[type];
27 | return axiosClient.get(url, params);
28 | },
29 | getVideos: (cate, id) => {
30 | const url = category[cate] + "/" + id + "/videos";
31 | return axiosClient.get(url, { params: {} });
32 | },
33 | search: (cate, params) => {
34 | const url = "search/" + category[cate];
35 | return axiosClient.get(url, params);
36 | },
37 | detail: (cate, id, params) => {
38 | const url = category[cate] + "/" + id;
39 | return axiosClient.get(url, params);
40 | },
41 | credits: (cate, id) => {
42 | const url = category[cate] + "/" + id + "/credits";
43 | return axiosClient.get(url, { params: {} });
44 | },
45 | similar: (cate, id) => {
46 | const url = category[cate] + "/" + id + "/similar";
47 | return axiosClient.get(url, { params: {} });
48 | },
49 | };
50 |
51 | export default tmdbApi;
52 |
--------------------------------------------------------------------------------
/src/assets/boxicons-2.0.7/LICENSE.txt:
--------------------------------------------------------------------------------
1 | Boxicons License
2 | -------------------------Boxicons is an open source project , you can use them in your commercial projects too.
3 | The icons (.svg) files are free to download are licensed under CC 4.0 .
4 | The fonts files are licensed under SIL OFL 1.1
5 | Attribution is not required but is appreciated
6 | Other files which are not fonts or icons are licensed under the MIT License
--------------------------------------------------------------------------------
/src/assets/boxicons-2.0.7/css/animations.css:
--------------------------------------------------------------------------------
1 | @-webkit-keyframes spin
2 | {
3 | 0%
4 | {
5 | -webkit-transform: rotate(0);
6 | transform: rotate(0);
7 | }
8 | 100%
9 | {
10 | -webkit-transform: rotate(359deg);
11 | transform: rotate(359deg);
12 | }
13 | }
14 | @keyframes spin
15 | {
16 | 0%
17 | {
18 | -webkit-transform: rotate(0);
19 | transform: rotate(0);
20 | }
21 | 100%
22 | {
23 | -webkit-transform: rotate(359deg);
24 | transform: rotate(359deg);
25 | }
26 | }
27 | @-webkit-keyframes burst
28 | {
29 | 0%
30 | {
31 | -webkit-transform: scale(1);
32 | transform: scale(1);
33 |
34 | opacity: 1;
35 | }
36 | 90%
37 | {
38 | -webkit-transform: scale(1.5);
39 | transform: scale(1.5);
40 |
41 | opacity: 0;
42 | }
43 | }
44 | @keyframes burst
45 | {
46 | 0%
47 | {
48 | -webkit-transform: scale(1);
49 | transform: scale(1);
50 |
51 | opacity: 1;
52 | }
53 | 90%
54 | {
55 | -webkit-transform: scale(1.5);
56 | transform: scale(1.5);
57 |
58 | opacity: 0;
59 | }
60 | }
61 | @-webkit-keyframes flashing
62 | {
63 | 0%
64 | {
65 | opacity: 1;
66 | }
67 | 45%
68 | {
69 | opacity: 0;
70 | }
71 | 90%
72 | {
73 | opacity: 1;
74 | }
75 | }
76 | @keyframes flashing
77 | {
78 | 0%
79 | {
80 | opacity: 1;
81 | }
82 | 45%
83 | {
84 | opacity: 0;
85 | }
86 | 90%
87 | {
88 | opacity: 1;
89 | }
90 | }
91 | @-webkit-keyframes fade-left
92 | {
93 | 0%
94 | {
95 | -webkit-transform: translateX(0);
96 | transform: translateX(0);
97 |
98 | opacity: 1;
99 | }
100 | 75%
101 | {
102 | -webkit-transform: translateX(-20px);
103 | transform: translateX(-20px);
104 |
105 | opacity: 0;
106 | }
107 | }
108 | @keyframes fade-left
109 | {
110 | 0%
111 | {
112 | -webkit-transform: translateX(0);
113 | transform: translateX(0);
114 |
115 | opacity: 1;
116 | }
117 | 75%
118 | {
119 | -webkit-transform: translateX(-20px);
120 | transform: translateX(-20px);
121 |
122 | opacity: 0;
123 | }
124 | }
125 | @-webkit-keyframes fade-right
126 | {
127 | 0%
128 | {
129 | -webkit-transform: translateX(0);
130 | transform: translateX(0);
131 |
132 | opacity: 1;
133 | }
134 | 75%
135 | {
136 | -webkit-transform: translateX(20px);
137 | transform: translateX(20px);
138 |
139 | opacity: 0;
140 | }
141 | }
142 | @keyframes fade-right
143 | {
144 | 0%
145 | {
146 | -webkit-transform: translateX(0);
147 | transform: translateX(0);
148 |
149 | opacity: 1;
150 | }
151 | 75%
152 | {
153 | -webkit-transform: translateX(20px);
154 | transform: translateX(20px);
155 |
156 | opacity: 0;
157 | }
158 | }
159 | @-webkit-keyframes fade-up
160 | {
161 | 0%
162 | {
163 | -webkit-transform: translateY(0);
164 | transform: translateY(0);
165 |
166 | opacity: 1;
167 | }
168 | 75%
169 | {
170 | -webkit-transform: translateY(-20px);
171 | transform: translateY(-20px);
172 |
173 | opacity: 0;
174 | }
175 | }
176 | @keyframes fade-up
177 | {
178 | 0%
179 | {
180 | -webkit-transform: translateY(0);
181 | transform: translateY(0);
182 |
183 | opacity: 1;
184 | }
185 | 75%
186 | {
187 | -webkit-transform: translateY(-20px);
188 | transform: translateY(-20px);
189 |
190 | opacity: 0;
191 | }
192 | }
193 | @-webkit-keyframes fade-down
194 | {
195 | 0%
196 | {
197 | -webkit-transform: translateY(0);
198 | transform: translateY(0);
199 |
200 | opacity: 1;
201 | }
202 | 75%
203 | {
204 | -webkit-transform: translateY(20px);
205 | transform: translateY(20px);
206 |
207 | opacity: 0;
208 | }
209 | }
210 | @keyframes fade-down
211 | {
212 | 0%
213 | {
214 | -webkit-transform: translateY(0);
215 | transform: translateY(0);
216 |
217 | opacity: 1;
218 | }
219 | 75%
220 | {
221 | -webkit-transform: translateY(20px);
222 | transform: translateY(20px);
223 |
224 | opacity: 0;
225 | }
226 | }
227 | @-webkit-keyframes tada
228 | {
229 | from
230 | {
231 | -webkit-transform: scale3d(1, 1, 1);
232 | transform: scale3d(1, 1, 1);
233 | }
234 |
235 | 10%,
236 | 20%
237 | {
238 | -webkit-transform: scale3d(.95, .95, .95) rotate3d(0, 0, 1, -10deg);
239 | transform: scale3d(.95, .95, .95) rotate3d(0, 0, 1, -10deg);
240 | }
241 |
242 | 30%,
243 | 50%,
244 | 70%,
245 | 90%
246 | {
247 | -webkit-transform: scale3d(1, 1, 1) rotate3d(0, 0, 1, 10deg);
248 | transform: scale3d(1, 1, 1) rotate3d(0, 0, 1, 10deg);
249 | }
250 |
251 | 40%,
252 | 60%,
253 | 80%
254 | {
255 | -webkit-transform: scale3d(1, 1, 1) rotate3d(0, 0, 1, -10deg);
256 | transform: scale3d(1, 1, 1) rotate3d(0, 0, 1, -10deg);
257 | }
258 |
259 | to
260 | {
261 | -webkit-transform: scale3d(1, 1, 1);
262 | transform: scale3d(1, 1, 1);
263 | }
264 | }
265 |
266 | @keyframes tada
267 | {
268 | from
269 | {
270 | -webkit-transform: scale3d(1, 1, 1);
271 | transform: scale3d(1, 1, 1);
272 | }
273 |
274 | 10%,
275 | 20%
276 | {
277 | -webkit-transform: scale3d(.95, .95, .95) rotate3d(0, 0, 1, -10deg);
278 | transform: scale3d(.95, .95, .95) rotate3d(0, 0, 1, -10deg);
279 | }
280 |
281 | 30%,
282 | 50%,
283 | 70%,
284 | 90%
285 | {
286 | -webkit-transform: scale3d(1, 1, 1) rotate3d(0, 0, 1, 10deg);
287 | transform: scale3d(1, 1, 1) rotate3d(0, 0, 1, 10deg);
288 | }
289 |
290 | 40%,
291 | 60%,
292 | 80%
293 | {
294 | -webkit-transform: rotate3d(0, 0, 1, -10deg);
295 | transform: rotate3d(0, 0, 1, -10deg);
296 | }
297 |
298 | to
299 | {
300 | -webkit-transform: scale3d(1, 1, 1);
301 | transform: scale3d(1, 1, 1);
302 | }
303 | }
304 | .bx-spin
305 | {
306 | -webkit-animation: spin 2s linear infinite;
307 | animation: spin 2s linear infinite;
308 | }
309 | .bx-spin-hover:hover
310 | {
311 | -webkit-animation: spin 2s linear infinite;
312 | animation: spin 2s linear infinite;
313 | }
314 |
315 | .bx-tada
316 | {
317 | -webkit-animation: tada 1.5s ease infinite;
318 | animation: tada 1.5s ease infinite;
319 | }
320 | .bx-tada-hover:hover
321 | {
322 | -webkit-animation: tada 1.5s ease infinite;
323 | animation: tada 1.5s ease infinite;
324 | }
325 |
326 | .bx-flashing
327 | {
328 | -webkit-animation: flashing 1.5s infinite linear;
329 | animation: flashing 1.5s infinite linear;
330 | }
331 | .bx-flashing-hover:hover
332 | {
333 | -webkit-animation: flashing 1.5s infinite linear;
334 | animation: flashing 1.5s infinite linear;
335 | }
336 |
337 | .bx-burst
338 | {
339 | -webkit-animation: burst 1.5s infinite linear;
340 | animation: burst 1.5s infinite linear;
341 | }
342 | .bx-burst-hover:hover
343 | {
344 | -webkit-animation: burst 1.5s infinite linear;
345 | animation: burst 1.5s infinite linear;
346 | }
347 | .bx-fade-up
348 | {
349 | -webkit-animation: fade-up 1.5s infinite linear;
350 | animation: fade-up 1.5s infinite linear;
351 | }
352 | .bx-fade-up-hover:hover
353 | {
354 | -webkit-animation: fade-up 1.5s infinite linear;
355 | animation: fade-up 1.5s infinite linear;
356 | }
357 | .bx-fade-down
358 | {
359 | -webkit-animation: fade-down 1.5s infinite linear;
360 | animation: fade-down 1.5s infinite linear;
361 | }
362 | .bx-fade-down-hover:hover
363 | {
364 | -webkit-animation: fade-down 1.5s infinite linear;
365 | animation: fade-down 1.5s infinite linear;
366 | }
367 | .bx-fade-left
368 | {
369 | -webkit-animation: fade-left 1.5s infinite linear;
370 | animation: fade-left 1.5s infinite linear;
371 | }
372 | .bx-fade-left-hover:hover
373 | {
374 | -webkit-animation: fade-left 1.5s infinite linear;
375 | animation: fade-left 1.5s infinite linear;
376 | }
377 | .bx-fade-right
378 | {
379 | -webkit-animation: fade-right 1.5s infinite linear;
380 | animation: fade-right 1.5s infinite linear;
381 | }
382 | .bx-fade-right-hover:hover
383 | {
384 | -webkit-animation: fade-right 1.5s infinite linear;
385 | animation: fade-right 1.5s infinite linear;
386 | }
--------------------------------------------------------------------------------
/src/assets/boxicons-2.0.7/css/boxicons.min.css:
--------------------------------------------------------------------------------
1 | @font-face{font-family:'boxicons';font-weight:normal;font-style:normal;src:url('../fonts/boxicons.eot');src:url('../fonts/boxicons.eot') format('embedded-opentype'),url('../fonts/boxicons.woff2') format('woff2'),url('../fonts/boxicons.woff') format('woff'),url('../fonts/boxicons.ttf') format('truetype'),url('../fonts/boxicons.svg?#boxicons') format('svg')}.bx{font-family:'boxicons'!important;font-weight:normal;font-style:normal;font-variant:normal;line-height:1;display:inline-block;text-transform:none;speak:none;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.bx-ul{margin-left:2em;padding-left:0;list-style:none}.bx-ul>li{position:relative}.bx-ul .bx{font-size:inherit;line-height:inherit;position:absolute;left:-2em;width:2em;text-align:center}@-webkit-keyframes spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-webkit-keyframes burst{0%{-webkit-transform:scale(1);transform:scale(1);opacity:1}90%{-webkit-transform:scale(1.5);transform:scale(1.5);opacity:0}}@keyframes burst{0%{-webkit-transform:scale(1);transform:scale(1);opacity:1}90%{-webkit-transform:scale(1.5);transform:scale(1.5);opacity:0}}@-webkit-keyframes flashing{0%{opacity:1}45%{opacity:0}90%{opacity:1}}@keyframes flashing{0%{opacity:1}45%{opacity:0}90%{opacity:1}}@-webkit-keyframes fade-left{0%{-webkit-transform:translateX(0);transform:translateX(0);opacity:1}75%{-webkit-transform:translateX(-20px);transform:translateX(-20px);opacity:0}}@keyframes fade-left{0%{-webkit-transform:translateX(0);transform:translateX(0);opacity:1}75%{-webkit-transform:translateX(-20px);transform:translateX(-20px);opacity:0}}@-webkit-keyframes fade-right{0%{-webkit-transform:translateX(0);transform:translateX(0);opacity:1}75%{-webkit-transform:translateX(20px);transform:translateX(20px);opacity:0}}@keyframes fade-right{0%{-webkit-transform:translateX(0);transform:translateX(0);opacity:1}75%{-webkit-transform:translateX(20px);transform:translateX(20px);opacity:0}}@-webkit-keyframes fade-up{0%{-webkit-transform:translateY(0);transform:translateY(0);opacity:1}75%{-webkit-transform:translateY(-20px);transform:translateY(-20px);opacity:0}}@keyframes fade-up{0%{-webkit-transform:translateY(0);transform:translateY(0);opacity:1}75%{-webkit-transform:translateY(-20px);transform:translateY(-20px);opacity:0}}@-webkit-keyframes fade-down{0%{-webkit-transform:translateY(0);transform:translateY(0);opacity:1}75%{-webkit-transform:translateY(20px);transform:translateY(20px);opacity:0}}@keyframes fade-down{0%{-webkit-transform:translateY(0);transform:translateY(0);opacity:1}75%{-webkit-transform:translateY(20px);transform:translateY(20px);opacity:0}}@-webkit-keyframes tada{from{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}10%,20%{-webkit-transform:scale3d(.95,.95,.95) rotate3d(0,0,1,-10deg);transform:scale3d(.95,.95,.95) rotate3d(0,0,1,-10deg)}30%,50%,70%,90%{-webkit-transform:scale3d(1,1,1) rotate3d(0,0,1,10deg);transform:scale3d(1,1,1) rotate3d(0,0,1,10deg)}40%,60%,80%{-webkit-transform:scale3d(1,1,1) rotate3d(0,0,1,-10deg);transform:scale3d(1,1,1) rotate3d(0,0,1,-10deg)}to{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}}@keyframes tada{from{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}10%,20%{-webkit-transform:scale3d(.95,.95,.95) rotate3d(0,0,1,-10deg);transform:scale3d(.95,.95,.95) rotate3d(0,0,1,-10deg)}30%,50%,70%,90%{-webkit-transform:scale3d(1,1,1) rotate3d(0,0,1,10deg);transform:scale3d(1,1,1) rotate3d(0,0,1,10deg)}40%,60%,80%{-webkit-transform:rotate3d(0,0,1,-10deg);transform:rotate3d(0,0,1,-10deg)}to{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}}.bx-spin{-webkit-animation:spin 2s linear infinite;animation:spin 2s linear infinite}.bx-spin-hover:hover{-webkit-animation:spin 2s linear infinite;animation:spin 2s linear infinite}.bx-tada{-webkit-animation:tada 1.5s ease infinite;animation:tada 1.5s ease infinite}.bx-tada-hover:hover{-webkit-animation:tada 1.5s ease infinite;animation:tada 1.5s ease infinite}.bx-flashing{-webkit-animation:flashing 1.5s infinite linear;animation:flashing 1.5s infinite linear}.bx-flashing-hover:hover{-webkit-animation:flashing 1.5s infinite linear;animation:flashing 1.5s infinite linear}.bx-burst{-webkit-animation:burst 1.5s infinite linear;animation:burst 1.5s infinite linear}.bx-burst-hover:hover{-webkit-animation:burst 1.5s infinite linear;animation:burst 1.5s infinite linear}.bx-fade-up{-webkit-animation:fade-up 1.5s infinite linear;animation:fade-up 1.5s infinite linear}.bx-fade-up-hover:hover{-webkit-animation:fade-up 1.5s infinite linear;animation:fade-up 1.5s infinite linear}.bx-fade-down{-webkit-animation:fade-down 1.5s infinite linear;animation:fade-down 1.5s infinite linear}.bx-fade-down-hover:hover{-webkit-animation:fade-down 1.5s infinite linear;animation:fade-down 1.5s infinite linear}.bx-fade-left{-webkit-animation:fade-left 1.5s infinite linear;animation:fade-left 1.5s infinite linear}.bx-fade-left-hover:hover{-webkit-animation:fade-left 1.5s infinite linear;animation:fade-left 1.5s infinite linear}.bx-fade-right{-webkit-animation:fade-right 1.5s infinite linear;animation:fade-right 1.5s infinite linear}.bx-fade-right-hover:hover{-webkit-animation:fade-right 1.5s infinite linear;animation:fade-right 1.5s infinite linear}.bx-xs{font-size:1rem!important}.bx-sm{font-size:1.55rem!important}.bx-md{font-size:2.25rem!important}.bx-fw{font-size:1.2857142857em;line-height:.8em;width:1.2857142857em;height:.8em;margin-top:-.2em!important;vertical-align:middle}.bx-lg{font-size:3.0!important}.bx-pull-left{float:left;margin-right:.3em!important}.bx-pull-right{float:right;margin-left:.3em!important}.bx-rotate-90{transform:rotate(90deg);-ms-filter:'progid:DXImageTransform.Microsoft.BasicImage(rotation=1)'}.bx-rotate-180{transform:rotate(180deg);-ms-filter:'progid:DXImageTransform.Microsoft.BasicImage(rotation=2)'}.bx-rotate-270{transform:rotate(270deg);-ms-filter:'progid:DXImageTransform.Microsoft.BasicImage(rotation=3)'}.bx-flip-horizontal{transform:scaleX(-1);-ms-filter:'progid:DXImageTransform.Microsoft.BasicImage(rotation=0,mirror=1)'}.bx-flip-vertical{transform:scaleY(-1);-ms-filter:'progid:DXImageTransform.Microsoft.BasicImage(rotation=2,mirror=1)'}.bx-border{padding:.25em;border:.07em solid rgba(0,0,0,.1);border-radius:.25em}.bx-border-circle{padding:.25em;border:.07em solid rgba(0,0,0,.1);border-radius:50%}.bx-abacus:before{content:"\e900"}.bx-accessibility:before{content:"\e901"}.bx-add-to-queue:before{content:"\e902"}.bx-adjust:before{content:"\e903"}.bx-alarm:before{content:"\e904"}.bx-alarm-add:before{content:"\e905"}.bx-alarm-exclamation:before{content:"\e906"}.bx-alarm-off:before{content:"\e907"}.bx-alarm-snooze:before{content:"\e908"}.bx-album:before{content:"\e909"}.bx-align-justify:before{content:"\e90a"}.bx-align-left:before{content:"\e90b"}.bx-align-middle:before{content:"\e90c"}.bx-align-right:before{content:"\e90d"}.bx-analyse:before{content:"\e90e"}.bx-anchor:before{content:"\e90f"}.bx-angry:before{content:"\e910"}.bx-aperture:before{content:"\e911"}.bx-arch:before{content:"\e912"}.bx-archive:before{content:"\e913"}.bx-archive-in:before{content:"\e914"}.bx-archive-out:before{content:"\e915"}.bx-area:before{content:"\e916"}.bx-arrow-back:before{content:"\e917"}.bx-arrow-from-bottom:before{content:"\e918"}.bx-arrow-from-left:before{content:"\e919"}.bx-arrow-from-right:before{content:"\e91a"}.bx-arrow-from-top:before{content:"\e91b"}.bx-arrow-to-bottom:before{content:"\e91c"}.bx-arrow-to-left:before{content:"\e91d"}.bx-arrow-to-right:before{content:"\e91e"}.bx-arrow-to-top:before{content:"\e91f"}.bx-at:before{content:"\e920"}.bx-atom:before{content:"\e921"}.bx-award:before{content:"\e922"}.bx-badge:before{content:"\e923"}.bx-badge-check:before{content:"\e924"}.bx-ball:before{content:"\e925"}.bx-band-aid:before{content:"\e926"}.bx-bar-chart:before{content:"\e927"}.bx-bar-chart-alt:before{content:"\e928"}.bx-bar-chart-alt-2:before{content:"\e929"}.bx-bar-chart-square:before{content:"\e92a"}.bx-barcode:before{content:"\e92b"}.bx-barcode-reader:before{content:"\e92c"}.bx-baseball:before{content:"\e92d"}.bx-basket:before{content:"\e92e"}.bx-basketball:before{content:"\e92f"}.bx-bath:before{content:"\e930"}.bx-battery:before{content:"\e931"}.bx-bed:before{content:"\e932"}.bx-been-here:before{content:"\e933"}.bx-beer:before{content:"\e934"}.bx-bell:before{content:"\e935"}.bx-bell-minus:before{content:"\e936"}.bx-bell-off:before{content:"\e937"}.bx-bell-plus:before{content:"\e938"}.bx-bible:before{content:"\e939"}.bx-bitcoin:before{content:"\e93a"}.bx-blanket:before{content:"\e93b"}.bx-block:before{content:"\e93c"}.bx-bluetooth:before{content:"\e93d"}.bx-body:before{content:"\e93e"}.bx-bold:before{content:"\e93f"}.bx-bolt-circle:before{content:"\e940"}.bx-bomb:before{content:"\e941"}.bx-bone:before{content:"\e942"}.bx-bong:before{content:"\e943"}.bx-book:before{content:"\e944"}.bx-book-add:before{content:"\e945"}.bx-book-alt:before{content:"\e946"}.bx-book-bookmark:before{content:"\e947"}.bx-book-content:before{content:"\e948"}.bx-book-heart:before{content:"\e949"}.bx-bookmark:before{content:"\e94a"}.bx-bookmark-alt:before{content:"\e94b"}.bx-bookmark-alt-minus:before{content:"\e94c"}.bx-bookmark-alt-plus:before{content:"\e94d"}.bx-bookmark-heart:before{content:"\e94e"}.bx-bookmark-minus:before{content:"\e94f"}.bx-bookmark-plus:before{content:"\e950"}.bx-bookmarks:before{content:"\e951"}.bx-book-open:before{content:"\e952"}.bx-book-reader:before{content:"\e953"}.bx-border-all:before{content:"\e954"}.bx-border-bottom:before{content:"\e955"}.bx-border-inner:before{content:"\e956"}.bx-border-left:before{content:"\e957"}.bx-border-none:before{content:"\e958"}.bx-border-outer:before{content:"\e959"}.bx-border-radius:before{content:"\e95a"}.bx-border-right:before{content:"\e95b"}.bx-border-top:before{content:"\e95c"}.bx-bot:before{content:"\e95d"}.bx-bowling-ball:before{content:"\e95e"}.bx-box:before{content:"\e95f"}.bx-bracket:before{content:"\e960"}.bx-braille:before{content:"\e961"}.bx-brain:before{content:"\e962"}.bx-briefcase:before{content:"\e963"}.bx-briefcase-alt:before{content:"\e964"}.bx-briefcase-alt-2:before{content:"\e965"}.bx-brightness:before{content:"\e966"}.bx-brightness-half:before{content:"\e967"}.bx-broadcast:before{content:"\e968"}.bx-brush:before{content:"\e969"}.bx-brush-alt:before{content:"\e96a"}.bx-bug:before{content:"\e96b"}.bx-bug-alt:before{content:"\e96c"}.bx-building:before{content:"\e96d"}.bx-building-house:before{content:"\e96e"}.bx-buildings:before{content:"\e96f"}.bx-bulb:before{content:"\e970"}.bx-bullseye:before{content:"\e971"}.bx-buoy:before{content:"\e972"}.bx-bus:before{content:"\e973"}.bx-bus-school:before{content:"\e974"}.bx-cabinet:before{content:"\e975"}.bx-cake:before{content:"\e976"}.bx-calculator:before{content:"\e977"}.bx-calendar:before{content:"\e978"}.bx-calendar-alt:before{content:"\e979"}.bx-calendar-check:before{content:"\e97a"}.bx-calendar-edit:before{content:"\e97b"}.bx-calendar-event:before{content:"\e97c"}.bx-calendar-exclamation:before{content:"\e97d"}.bx-calendar-heart:before{content:"\e97e"}.bx-calendar-minus:before{content:"\e97f"}.bx-calendar-plus:before{content:"\e980"}.bx-calendar-star:before{content:"\e981"}.bx-calendar-week:before{content:"\e982"}.bx-calendar-x:before{content:"\e983"}.bx-camera:before{content:"\e984"}.bx-camera-home:before{content:"\e985"}.bx-camera-movie:before{content:"\e986"}.bx-camera-off:before{content:"\e987"}.bx-capsule:before{content:"\e988"}.bx-captions:before{content:"\e989"}.bx-car:before{content:"\e98a"}.bx-card:before{content:"\e98b"}.bx-caret-down:before{content:"\e98c"}.bx-caret-down-circle:before{content:"\e98d"}.bx-caret-down-square:before{content:"\e98e"}.bx-caret-left:before{content:"\e98f"}.bx-caret-left-circle:before{content:"\e990"}.bx-caret-left-square:before{content:"\e991"}.bx-caret-right:before{content:"\e992"}.bx-caret-right-circle:before{content:"\e993"}.bx-caret-right-square:before{content:"\e994"}.bx-caret-up:before{content:"\e995"}.bx-caret-up-circle:before{content:"\e996"}.bx-caret-up-square:before{content:"\e997"}.bx-carousel:before{content:"\e998"}.bx-cart:before{content:"\e999"}.bx-cart-alt:before{content:"\e99a"}.bx-cast:before{content:"\e99b"}.bx-category:before{content:"\e99c"}.bx-category-alt:before{content:"\e99d"}.bx-cctv:before{content:"\e99e"}.bx-certification:before{content:"\e99f"}.bx-chair:before{content:"\e9a0"}.bx-chalkboard:before{content:"\e9a1"}.bx-chart:before{content:"\e9a2"}.bx-chat:before{content:"\e9a3"}.bx-check:before{content:"\e9a4"}.bx-checkbox:before{content:"\e9a5"}.bx-checkbox-checked:before{content:"\e9a6"}.bx-checkbox-square:before{content:"\e9a7"}.bx-check-circle:before{content:"\e9a8"}.bx-check-double:before{content:"\e9a9"}.bx-check-shield:before{content:"\e9aa"}.bx-check-square:before{content:"\e9ab"}.bx-chevron-down:before{content:"\e9ac"}.bx-chevron-down-circle:before{content:"\e9ad"}.bx-chevron-down-square:before{content:"\e9ae"}.bx-chevron-left:before{content:"\e9af"}.bx-chevron-left-circle:before{content:"\e9b0"}.bx-chevron-left-square:before{content:"\e9b1"}.bx-chevron-right:before{content:"\e9b2"}.bx-chevron-right-circle:before{content:"\e9b3"}.bx-chevron-right-square:before{content:"\e9b4"}.bx-chevrons-down:before{content:"\e9b5"}.bx-chevrons-left:before{content:"\e9b6"}.bx-chevrons-right:before{content:"\e9b7"}.bx-chevrons-up:before{content:"\e9b8"}.bx-chevron-up:before{content:"\e9b9"}.bx-chevron-up-circle:before{content:"\e9ba"}.bx-chevron-up-square:before{content:"\e9bb"}.bx-chip:before{content:"\e9bc"}.bx-church:before{content:"\e9bd"}.bx-circle:before{content:"\e9be"}.bx-clinic:before{content:"\e9bf"}.bx-clipboard:before{content:"\e9c0"}.bx-closet:before{content:"\e9c1"}.bx-cloud:before{content:"\e9c2"}.bx-cloud-download:before{content:"\e9c3"}.bx-cloud-drizzle:before{content:"\e9c4"}.bx-cloud-lightning:before{content:"\e9c5"}.bx-cloud-light-rain:before{content:"\e9c6"}.bx-cloud-rain:before{content:"\e9c7"}.bx-cloud-snow:before{content:"\e9c8"}.bx-cloud-upload:before{content:"\e9c9"}.bx-code:before{content:"\e9ca"}.bx-code-alt:before{content:"\e9cb"}.bx-code-block:before{content:"\e9cc"}.bx-code-curly:before{content:"\e9cd"}.bx-coffee:before{content:"\e9ce"}.bx-coffee-togo:before{content:"\e9cf"}.bx-cog:before{content:"\e9d0"}.bx-coin:before{content:"\e9d1"}.bx-coin-stack:before{content:"\e9d2"}.bx-collapse:before{content:"\e9d3"}.bx-collection:before{content:"\e9d4"}.bx-color-fill:before{content:"\e9d5"}.bx-columns:before{content:"\e9d6"}.bx-command:before{content:"\e9d7"}.bx-comment:before{content:"\e9d8"}.bx-comment-add:before{content:"\e9d9"}.bx-comment-check:before{content:"\e9da"}.bx-comment-detail:before{content:"\e9db"}.bx-comment-dots:before{content:"\e9dc"}.bx-comment-edit:before{content:"\e9dd"}.bx-comment-error:before{content:"\e9de"}.bx-comment-minus:before{content:"\e9df"}.bx-comment-x:before{content:"\e9e0"}.bx-compass:before{content:"\e9e1"}.bx-confused:before{content:"\e9e2"}.bx-conversation:before{content:"\e9e3"}.bx-cookie:before{content:"\e9e4"}.bx-cool:before{content:"\e9e5"}.bx-copy:before{content:"\e9e6"}.bx-copy-alt:before{content:"\e9e7"}.bx-copyright:before{content:"\e9e8"}.bx-credit-card:before{content:"\e9e9"}.bx-credit-card-alt:before{content:"\e9ea"}.bx-credit-card-front:before{content:"\e9eb"}.bx-crop:before{content:"\e9ec"}.bx-crosshair:before{content:"\e9ed"}.bx-crown:before{content:"\e9ee"}.bx-cube:before{content:"\e9ef"}.bx-cube-alt:before{content:"\e9f0"}.bx-cuboid:before{content:"\e9f1"}.bx-current-location:before{content:"\e9f2"}.bx-customize:before{content:"\e9f3"}.bx-cut:before{content:"\e9f4"}.bx-cycling:before{content:"\e9f5"}.bx-cylinder:before{content:"\e9f6"}.bx-data:before{content:"\e9f7"}.bx-desktop:before{content:"\e9f8"}.bx-detail:before{content:"\e9f9"}.bx-devices:before{content:"\e9fa"}.bx-dialpad:before{content:"\e9fb"}.bx-dialpad-alt:before{content:"\e9fc"}.bx-diamond:before{content:"\e9fd"}.bx-dice-1:before{content:"\e9fe"}.bx-dice-2:before{content:"\e9ff"}.bx-dice-3:before{content:"\ea00"}.bx-dice-4:before{content:"\ea01"}.bx-dice-5:before{content:"\ea02"}.bx-dice-6:before{content:"\ea03"}.bx-directions:before{content:"\ea04"}.bx-disc:before{content:"\ea05"}.bx-dish:before{content:"\ea06"}.bx-dislike:before{content:"\ea07"}.bx-dizzy:before{content:"\ea08"}.bx-dna:before{content:"\ea09"}.bx-dock-bottom:before{content:"\ea0a"}.bx-dock-left:before{content:"\ea0b"}.bx-dock-right:before{content:"\ea0c"}.bx-dock-top:before{content:"\ea0d"}.bx-dollar:before{content:"\ea0e"}.bx-dollar-circle:before{content:"\ea0f"}.bx-donate-blood:before{content:"\ea10"}.bx-donate-heart:before{content:"\ea11"}.bx-door-open:before{content:"\ea12"}.bx-dots-horizontal:before{content:"\ea13"}.bx-dots-horizontal-rounded:before{content:"\ea14"}.bx-dots-vertical:before{content:"\ea15"}.bx-dots-vertical-rounded:before{content:"\ea16"}.bx-doughnut-chart:before{content:"\ea17"}.bx-down-arrow:before{content:"\ea18"}.bx-down-arrow-alt:before{content:"\ea19"}.bx-down-arrow-circle:before{content:"\ea1a"}.bx-download:before{content:"\ea1b"}.bx-downvote:before{content:"\ea1c"}.bx-drink:before{content:"\ea1d"}.bx-droplet:before{content:"\ea1e"}.bx-dumbbell:before{content:"\ea1f"}.bx-duplicate:before{content:"\ea20"}.bx-edit:before{content:"\ea21"}.bx-edit-alt:before{content:"\ea22"}.bx-envelope:before{content:"\ea23"}.bx-envelope-open:before{content:"\ea24"}.bx-equalizer:before{content:"\ea25"}.bx-eraser:before{content:"\ea26"}.bx-error:before{content:"\ea27"}.bx-error-alt:before{content:"\ea28"}.bx-error-circle:before{content:"\ea29"}.bx-euro:before{content:"\ea2a"}.bx-exclude:before{content:"\ea2b"}.bx-exit:before{content:"\ea2c"}.bx-exit-fullscreen:before{content:"\ea2d"}.bx-expand:before{content:"\ea2e"}.bx-expand-alt:before{content:"\ea2f"}.bx-export:before{content:"\ea30"}.bx-extension:before{content:"\ea31"}.bx-face:before{content:"\ea32"}.bx-fast-forward:before{content:"\ea33"}.bx-fast-forward-circle:before{content:"\ea34"}.bx-female:before{content:"\ea35"}.bx-female-sign:before{content:"\ea36"}.bx-file:before{content:"\ea37"}.bx-file-blank:before{content:"\ea38"}.bx-file-find:before{content:"\ea39"}.bx-film:before{content:"\ea3a"}.bx-filter:before{content:"\ea3b"}.bx-filter-alt:before{content:"\ea3c"}.bx-fingerprint:before{content:"\ea3d"}.bx-first-aid:before{content:"\ea3e"}.bx-first-page:before{content:"\ea3f"}.bx-flag:before{content:"\ea40"}.bx-folder:before{content:"\ea41"}.bx-folder-minus:before{content:"\ea42"}.bx-folder-open:before{content:"\ea43"}.bx-folder-plus:before{content:"\ea44"}.bx-font:before{content:"\ea45"}.bx-font-color:before{content:"\ea46"}.bx-font-family:before{content:"\ea47"}.bx-font-size:before{content:"\ea48"}.bx-food-menu:before{content:"\ea49"}.bx-food-tag:before{content:"\ea4a"}.bx-football:before{content:"\ea4b"}.bx-fridge:before{content:"\ea4c"}.bx-fullscreen:before{content:"\ea4d"}.bx-game:before{content:"\ea4e"}.bx-gas-pump:before{content:"\ea4f"}.bx-ghost:before{content:"\ea50"}.bx-gift:before{content:"\ea51"}.bx-git-branch:before{content:"\ea52"}.bx-git-commit:before{content:"\ea53"}.bx-git-compare:before{content:"\ea54"}.bx-git-merge:before{content:"\ea55"}.bx-git-pull-request:before{content:"\ea56"}.bx-git-repo-forked:before{content:"\ea57"}.bx-glasses:before{content:"\ea58"}.bx-glasses-alt:before{content:"\ea59"}.bx-globe:before{content:"\ea5a"}.bx-globe-alt:before{content:"\ea5b"}.bx-grid:before{content:"\ea5c"}.bx-grid-alt:before{content:"\ea5d"}.bx-grid-horizontal:before{content:"\ea5e"}.bx-grid-small:before{content:"\ea5f"}.bx-grid-vertical:before{content:"\ea60"}.bx-group:before{content:"\ea61"}.bx-handicap:before{content:"\ea62"}.bx-happy:before{content:"\ea63"}.bx-happy-alt:before{content:"\ea64"}.bx-happy-beaming:before{content:"\ea65"}.bx-happy-heart-eyes:before{content:"\ea66"}.bx-hash:before{content:"\ea67"}.bx-hdd:before{content:"\ea68"}.bx-heading:before{content:"\ea69"}.bx-headphone:before{content:"\ea6a"}.bx-health:before{content:"\ea6b"}.bx-heart:before{content:"\ea6c"}.bx-heart-circle:before{content:"\ea6d"}.bx-heart-square:before{content:"\ea6e"}.bx-help-circle:before{content:"\ea6f"}.bx-hide:before{content:"\ea70"}.bx-highlight:before{content:"\ea71"}.bx-history:before{content:"\ea72"}.bx-hive:before{content:"\ea73"}.bx-home:before{content:"\ea74"}.bx-home-alt:before{content:"\ea75"}.bx-home-circle:before{content:"\ea76"}.bx-home-heart:before{content:"\ea77"}.bx-home-smile:before{content:"\ea78"}.bx-horizontal-center:before{content:"\ea79"}.bx-hotel:before{content:"\ea7a"}.bx-hourglass:before{content:"\ea7b"}.bx-id-card:before{content:"\ea7c"}.bx-image:before{content:"\ea7d"}.bx-image-add:before{content:"\ea7e"}.bx-image-alt:before{content:"\ea7f"}.bx-images:before{content:"\ea80"}.bx-import:before{content:"\ea81"}.bx-infinite:before{content:"\ea82"}.bx-info-circle:before{content:"\ea83"}.bx-info-square:before{content:"\ea84"}.bx-intersect:before{content:"\ea85"}.bx-italic:before{content:"\ea86"}.bx-joystick:before{content:"\ea87"}.bx-joystick-alt:before{content:"\ea88"}.bx-joystick-button:before{content:"\ea89"}.bx-key:before{content:"\ea8a"}.bx-label:before{content:"\ea8b"}.bx-landscape:before{content:"\ea8c"}.bx-laptop:before{content:"\ea8d"}.bx-last-page:before{content:"\ea8e"}.bx-laugh:before{content:"\ea8f"}.bx-layer:before{content:"\ea90"}.bx-layer-minus:before{content:"\ea91"}.bx-layer-plus:before{content:"\ea92"}.bx-layout:before{content:"\ea93"}.bx-left-arrow:before{content:"\ea94"}.bx-left-arrow-alt:before{content:"\ea95"}.bx-left-arrow-circle:before{content:"\ea96"}.bx-left-down-arrow-circle:before{content:"\ea97"}.bx-left-indent:before{content:"\ea98"}.bx-left-top-arrow-circle:before{content:"\ea99"}.bx-library:before{content:"\ea9a"}.bx-like:before{content:"\ea9b"}.bx-line-chart:before{content:"\ea9c"}.bx-line-chart-down:before{content:"\ea9d"}.bx-link:before{content:"\ea9e"}.bx-link-alt:before{content:"\ea9f"}.bx-link-external:before{content:"\eaa0"}.bx-lira:before{content:"\eaa1"}.bx-list-check:before{content:"\eaa2"}.bx-list-minus:before{content:"\eaa3"}.bx-list-ol:before{content:"\eaa4"}.bx-list-plus:before{content:"\eaa5"}.bx-list-ul:before{content:"\eaa6"}.bx-loader:before{content:"\eaa7"}.bx-loader-alt:before{content:"\eaa8"}.bx-loader-circle:before{content:"\eaa9"}.bx-location-plus:before{content:"\eaaa"}.bx-lock:before{content:"\eaab"}.bx-lock-alt:before{content:"\eaac"}.bx-lock-open:before{content:"\eaad"}.bx-lock-open-alt:before{content:"\eaae"}.bx-log-in:before{content:"\eaaf"}.bx-log-in-circle:before{content:"\eab0"}.bx-log-out:before{content:"\eab1"}.bx-log-out-circle:before{content:"\eab2"}.bx-low-vision:before{content:"\eab3"}.bx-magnet:before{content:"\eab4"}.bx-mail-send:before{content:"\eab5"}.bx-male:before{content:"\eab6"}.bx-male-sign:before{content:"\eab7"}.bx-map:before{content:"\eab8"}.bx-map-alt:before{content:"\eab9"}.bx-map-pin:before{content:"\eaba"}.bx-mask:before{content:"\eabb"}.bx-medal:before{content:"\eabc"}.bx-meh:before{content:"\eabd"}.bx-meh-alt:before{content:"\eabe"}.bx-meh-blank:before{content:"\eabf"}.bx-memory-card:before{content:"\eac0"}.bx-menu:before{content:"\eac1"}.bx-menu-alt-left:before{content:"\eac2"}.bx-menu-alt-right:before{content:"\eac3"}.bx-merge:before{content:"\eac4"}.bx-message:before{content:"\eac5"}.bx-message-add:before{content:"\eac6"}.bx-message-alt:before{content:"\eac7"}.bx-message-alt-add:before{content:"\eac8"}.bx-message-alt-check:before{content:"\eac9"}.bx-message-alt-detail:before{content:"\eaca"}.bx-message-alt-dots:before{content:"\eacb"}.bx-message-alt-edit:before{content:"\eacc"}.bx-message-alt-error:before{content:"\eacd"}.bx-message-alt-minus:before{content:"\eace"}.bx-message-alt-x:before{content:"\eacf"}.bx-message-check:before{content:"\ead0"}.bx-message-detail:before{content:"\ead1"}.bx-message-dots:before{content:"\ead2"}.bx-message-edit:before{content:"\ead3"}.bx-message-error:before{content:"\ead4"}.bx-message-minus:before{content:"\ead5"}.bx-message-rounded:before{content:"\ead6"}.bx-message-rounded-add:before{content:"\ead7"}.bx-message-rounded-check:before{content:"\ead8"}.bx-message-rounded-detail:before{content:"\ead9"}.bx-message-rounded-dots:before{content:"\eada"}.bx-message-rounded-edit:before{content:"\eadb"}.bx-message-rounded-error:before{content:"\eadc"}.bx-message-rounded-minus:before{content:"\eadd"}.bx-message-rounded-x:before{content:"\eade"}.bx-message-square:before{content:"\eadf"}.bx-message-square-add:before{content:"\eae0"}.bx-message-square-check:before{content:"\eae1"}.bx-message-square-detail:before{content:"\eae2"}.bx-message-square-dots:before{content:"\eae3"}.bx-message-square-edit:before{content:"\eae4"}.bx-message-square-error:before{content:"\eae5"}.bx-message-square-minus:before{content:"\eae6"}.bx-message-square-x:before{content:"\eae7"}.bx-message-x:before{content:"\eae8"}.bx-meteor:before{content:"\eae9"}.bx-microchip:before{content:"\eaea"}.bx-microphone:before{content:"\eaeb"}.bx-microphone-off:before{content:"\eaec"}.bx-minus:before{content:"\eaed"}.bx-minus-back:before{content:"\eaee"}.bx-minus-circle:before{content:"\eaef"}.bx-minus-front:before{content:"\eaf0"}.bx-mobile:before{content:"\eaf1"}.bx-mobile-alt:before{content:"\eaf2"}.bx-mobile-landscape:before{content:"\eaf3"}.bx-mobile-vibration:before{content:"\eaf4"}.bx-money:before{content:"\eaf5"}.bx-moon:before{content:"\eaf6"}.bx-mouse:before{content:"\eaf7"}.bx-mouse-alt:before{content:"\eaf8"}.bx-move:before{content:"\eaf9"}.bx-move-horizontal:before{content:"\eafa"}.bx-move-vertical:before{content:"\eafb"}.bx-movie:before{content:"\eafc"}.bx-movie-play:before{content:"\eafd"}.bx-music:before{content:"\eafe"}.bx-navigation:before{content:"\eaff"}.bx-network-chart:before{content:"\eb00"}.bx-news:before{content:"\eb01"}.bx-no-entry:before{content:"\eb02"}.bx-note:before{content:"\eb03"}.bx-notepad:before{content:"\eb04"}.bx-notification:before{content:"\eb05"}.bx-notification-off:before{content:"\eb06"}.bx-outline:before{content:"\eb07"}.bx-package:before{content:"\eb08"}.bx-paint:before{content:"\eb09"}.bx-paint-roll:before{content:"\eb0a"}.bx-palette:before{content:"\eb0b"}.bx-paperclip:before{content:"\eb0c"}.bx-paper-plane:before{content:"\eb0d"}.bx-paragraph:before{content:"\eb0e"}.bx-paste:before{content:"\eb0f"}.bx-pause:before{content:"\eb10"}.bx-pause-circle:before{content:"\eb11"}.bx-pen:before{content:"\eb12"}.bx-pencil:before{content:"\eb13"}.bx-phone:before{content:"\eb14"}.bx-phone-call:before{content:"\eb15"}.bx-phone-incoming:before{content:"\eb16"}.bx-phone-outgoing:before{content:"\eb17"}.bx-photo-album:before{content:"\eb18"}.bx-pie-chart:before{content:"\eb19"}.bx-pie-chart-alt:before{content:"\eb1a"}.bx-pie-chart-alt-2:before{content:"\eb1b"}.bx-pin:before{content:"\eb1c"}.bx-planet:before{content:"\eb1d"}.bx-play:before{content:"\eb1e"}.bx-play-circle:before{content:"\eb1f"}.bx-plug:before{content:"\eb20"}.bx-plus:before{content:"\eb21"}.bx-plus-circle:before{content:"\eb22"}.bx-plus-medical:before{content:"\eb23"}.bx-pointer:before{content:"\eb24"}.bx-poll:before{content:"\eb25"}.bx-polygon:before{content:"\eb26"}.bx-pound:before{content:"\eb27"}.bx-power-off:before{content:"\eb28"}.bx-printer:before{content:"\eb29"}.bx-pulse:before{content:"\eb2a"}.bx-purchase-tag:before{content:"\eb2b"}.bx-purchase-tag-alt:before{content:"\eb2c"}.bx-pyramid:before{content:"\eb2d"}.bx-question-mark:before{content:"\eb2e"}.bx-radar:before{content:"\eb2f"}.bx-radio:before{content:"\eb30"}.bx-radio-circle:before{content:"\eb31"}.bx-radio-circle-marked:before{content:"\eb32"}.bx-receipt:before{content:"\eb33"}.bx-rectangle:before{content:"\eb34"}.bx-recycle:before{content:"\eb35"}.bx-redo:before{content:"\eb36"}.bx-refresh:before{content:"\eb37"}.bx-rename:before{content:"\eb38"}.bx-repeat:before{content:"\eb39"}.bx-reply:before{content:"\eb3a"}.bx-reply-all:before{content:"\eb3b"}.bx-repost:before{content:"\eb3c"}.bx-reset:before{content:"\eb3d"}.bx-restaurant:before{content:"\eb3e"}.bx-revision:before{content:"\eb3f"}.bx-rewind:before{content:"\eb40"}.bx-rewind-circle:before{content:"\eb41"}.bx-right-arrow:before{content:"\eb42"}.bx-right-arrow-alt:before{content:"\eb43"}.bx-right-arrow-circle:before{content:"\eb44"}.bx-right-down-arrow-circle:before{content:"\eb45"}.bx-right-indent:before{content:"\eb46"}.bx-right-top-arrow-circle:before{content:"\eb47"}.bx-rocket:before{content:"\eb48"}.bx-rotate-left:before{content:"\eb49"}.bx-rotate-right:before{content:"\eb4a"}.bx-rss:before{content:"\eb4b"}.bx-ruble:before{content:"\eb4c"}.bx-ruler:before{content:"\eb4d"}.bx-run:before{content:"\eb4e"}.bx-rupee:before{content:"\eb4f"}.bx-sad:before{content:"\eb50"}.bx-save:before{content:"\eb51"}.bx-scan:before{content:"\eb52"}.bx-screenshot:before{content:"\eb53"}.bx-search:before{content:"\eb54"}.bx-search-alt:before{content:"\eb55"}.bx-search-alt-2:before{content:"\eb56"}.bx-selection:before{content:"\eb57"}.bx-select-multiple:before{content:"\eb58"}.bx-send:before{content:"\eb59"}.bx-server:before{content:"\eb5a"}.bx-shape-circle:before{content:"\eb5b"}.bx-shape-polygon:before{content:"\eb5c"}.bx-shape-square:before{content:"\eb5d"}.bx-shape-triangle:before{content:"\eb5e"}.bx-share:before{content:"\eb5f"}.bx-share-alt:before{content:"\eb60"}.bx-shekel:before{content:"\eb61"}.bx-shield:before{content:"\eb62"}.bx-shield-alt:before{content:"\eb63"}.bx-shield-alt-2:before{content:"\eb64"}.bx-shield-quarter:before{content:"\eb65"}.bx-shield-x:before{content:"\eb66"}.bx-shocked:before{content:"\eb67"}.bx-shopping-bag:before{content:"\eb68"}.bx-show:before{content:"\eb69"}.bx-show-alt:before{content:"\eb6a"}.bx-shuffle:before{content:"\eb6b"}.bx-sidebar:before{content:"\eb6c"}.bx-sitemap:before{content:"\eb6d"}.bx-skip-next:before{content:"\eb6e"}.bx-skip-next-circle:before{content:"\eb6f"}.bx-skip-previous:before{content:"\eb70"}.bx-skip-previous-circle:before{content:"\eb71"}.bx-sleepy:before{content:"\eb72"}.bx-slider:before{content:"\eb73"}.bx-slider-alt:before{content:"\eb74"}.bx-slideshow:before{content:"\eb75"}.bx-smile:before{content:"\eb76"}.bx-sort:before{content:"\eb77"}.bx-sort-alt-2:before{content:"\eb78"}.bx-sort-a-z:before{content:"\eb79"}.bx-sort-down:before{content:"\eb7a"}.bx-sort-up:before{content:"\eb7b"}.bx-sort-z-a:before{content:"\eb7c"}.bx-spa:before{content:"\eb7d"}.bx-space-bar:before{content:"\eb7e"}.bx-spray-can:before{content:"\eb7f"}.bx-spreadsheet:before{content:"\eb80"}.bx-square:before{content:"\eb81"}.bx-square-rounded:before{content:"\eb82"}.bx-star:before{content:"\eb83"}.bx-station:before{content:"\eb84"}.bx-stats:before{content:"\eb85"}.bx-sticker:before{content:"\eb86"}.bx-stop:before{content:"\eb87"}.bx-stop-circle:before{content:"\eb88"}.bx-stopwatch:before{content:"\eb89"}.bx-store:before{content:"\eb8a"}.bx-store-alt:before{content:"\eb8b"}.bx-street-view:before{content:"\eb8c"}.bx-strikethrough:before{content:"\eb8d"}.bx-subdirectory-left:before{content:"\eb8e"}.bx-subdirectory-right:before{content:"\eb8f"}.bx-sun:before{content:"\eb90"}.bx-support:before{content:"\eb91"}.bx-swim:before{content:"\eb92"}.bx-sync:before{content:"\eb93"}.bx-tab:before{content:"\eb94"}.bx-table:before{content:"\eb95"}.bx-tachometer:before{content:"\eb96"}.bx-tag:before{content:"\eb97"}.bx-tag-alt:before{content:"\eb98"}.bx-target-lock:before{content:"\eb99"}.bx-task:before{content:"\eb9a"}.bx-task-x:before{content:"\eb9b"}.bx-taxi:before{content:"\eb9c"}.bx-tennis-ball:before{content:"\eb9d"}.bx-terminal:before{content:"\eb9e"}.bx-test-tube:before{content:"\eb9f"}.bx-text:before{content:"\eba0"}.bx-time:before{content:"\eba1"}.bx-time-five:before{content:"\eba2"}.bx-timer:before{content:"\eba3"}.bx-tired:before{content:"\eba4"}.bx-toggle-left:before{content:"\eba5"}.bx-toggle-right:before{content:"\eba6"}.bx-tone:before{content:"\eba7"}.bx-traffic-cone:before{content:"\eba8"}.bx-train:before{content:"\eba9"}.bx-transfer:before{content:"\ebaa"}.bx-transfer-alt:before{content:"\ebab"}.bx-trash:before{content:"\ebac"}.bx-trash-alt:before{content:"\ebad"}.bx-trending-down:before{content:"\ebae"}.bx-trending-up:before{content:"\ebaf"}.bx-trim:before{content:"\ebb0"}.bx-trip:before{content:"\ebb1"}.bx-trophy:before{content:"\ebb2"}.bx-tv:before{content:"\ebb3"}.bx-underline:before{content:"\ebb4"}.bx-undo:before{content:"\ebb5"}.bx-unite:before{content:"\ebb6"}.bx-unlink:before{content:"\ebb7"}.bx-up-arrow:before{content:"\ebb8"}.bx-up-arrow-alt:before{content:"\ebb9"}.bx-up-arrow-circle:before{content:"\ebba"}.bx-upload:before{content:"\ebbb"}.bx-upside-down:before{content:"\ebbc"}.bx-upvote:before{content:"\ebbd"}.bx-usb:before{content:"\ebbe"}.bx-user:before{content:"\ebbf"}.bx-user-check:before{content:"\ebc0"}.bx-user-circle:before{content:"\ebc1"}.bx-user-minus:before{content:"\ebc2"}.bx-user-pin:before{content:"\ebc3"}.bx-user-plus:before{content:"\ebc4"}.bx-user-voice:before{content:"\ebc5"}.bx-user-x:before{content:"\ebc6"}.bx-vector:before{content:"\ebc7"}.bx-vertical-center:before{content:"\ebc8"}.bx-vial:before{content:"\ebc9"}.bx-video:before{content:"\ebca"}.bx-video-off:before{content:"\ebcb"}.bx-video-plus:before{content:"\ebcc"}.bx-video-recording:before{content:"\ebcd"}.bx-voicemail:before{content:"\ebce"}.bx-volume:before{content:"\ebcf"}.bx-volume-full:before{content:"\ebd0"}.bx-volume-low:before{content:"\ebd1"}.bx-volume-mute:before{content:"\ebd2"}.bx-walk:before{content:"\ebd3"}.bx-wallet:before{content:"\ebd4"}.bx-wallet-alt:before{content:"\ebd5"}.bx-water:before{content:"\ebd6"}.bx-webcam:before{content:"\ebd7"}.bx-wifi:before{content:"\ebd8"}.bx-wifi-0:before{content:"\ebd9"}.bx-wifi-1:before{content:"\ebda"}.bx-wifi-2:before{content:"\ebdb"}.bx-wifi-off:before{content:"\ebdc"}.bx-wind:before{content:"\ebdd"}.bx-window:before{content:"\ebde"}.bx-window-alt:before{content:"\ebdf"}.bx-window-close:before{content:"\ebe0"}.bx-window-open:before{content:"\ebe1"}.bx-windows:before{content:"\ebe2"}.bx-wine:before{content:"\ebe3"}.bx-wink-smile:before{content:"\ebe4"}.bx-wink-tongue:before{content:"\ebe5"}.bx-won:before{content:"\ebe6"}.bx-world:before{content:"\ebe7"}.bx-wrench:before{content:"\ebe8"}.bx-x:before{content:"\ebe9"}.bx-x-circle:before{content:"\ebea"}.bx-yen:before{content:"\ebeb"}.bx-zoom-in:before{content:"\ebec"}.bx-zoom-out:before{content:"\ebed"}.bxs-add-to-queue:before{content:"\ebee"}.bxs-adjust:before{content:"\ebef"}.bxs-adjust-alt:before{content:"\ebf0"}.bxs-alarm:before{content:"\ebf1"}.bxs-alarm-add:before{content:"\ebf2"}.bxs-alarm-exclamation:before{content:"\ebf3"}.bxs-alarm-off:before{content:"\ebf4"}.bxs-alarm-snooze:before{content:"\ebf5"}.bxs-album:before{content:"\ebf6"}.bxs-ambulance:before{content:"\ebf7"}.bxs-analyse:before{content:"\ebf8"}.bxs-angry:before{content:"\ebf9"}.bxs-arch:before{content:"\ebfa"}.bxs-archive:before{content:"\ebfb"}.bxs-archive-in:before{content:"\ebfc"}.bxs-archive-out:before{content:"\ebfd"}.bxs-area:before{content:"\ebfe"}.bxs-arrow-from-bottom:before{content:"\ebff"}.bxs-arrow-from-left:before{content:"\ec00"}.bxs-arrow-from-right:before{content:"\ec01"}.bxs-arrow-from-top:before{content:"\ec02"}.bxs-arrow-to-bottom:before{content:"\ec03"}.bxs-arrow-to-left:before{content:"\ec04"}.bxs-arrow-to-right:before{content:"\ec05"}.bxs-arrow-to-top:before{content:"\ec06"}.bxs-award:before{content:"\ec07"}.bxs-baby-carriage:before{content:"\ec08"}.bxs-backpack:before{content:"\ec09"}.bxs-badge:before{content:"\ec0a"}.bxs-badge-check:before{content:"\ec0b"}.bxs-badge-dollar:before{content:"\ec0c"}.bxs-ball:before{content:"\ec0d"}.bxs-band-aid:before{content:"\ec0e"}.bxs-bank:before{content:"\ec0f"}.bxs-bar-chart-alt-2:before{content:"\ec10"}.bxs-bar-chart-square:before{content:"\ec11"}.bxs-barcode:before{content:"\ec12"}.bxs-baseball:before{content:"\ec13"}.bxs-basket:before{content:"\ec14"}.bxs-basketball:before{content:"\ec15"}.bxs-bath:before{content:"\ec16"}.bxs-battery:before{content:"\ec17"}.bxs-battery-charging:before{content:"\ec18"}.bxs-battery-full:before{content:"\ec19"}.bxs-battery-low:before{content:"\ec1a"}.bxs-bed:before{content:"\ec1b"}.bxs-been-here:before{content:"\ec1c"}.bxs-beer:before{content:"\ec1d"}.bxs-bell:before{content:"\ec1e"}.bxs-bell-minus:before{content:"\ec1f"}.bxs-bell-off:before{content:"\ec20"}.bxs-bell-plus:before{content:"\ec21"}.bxs-bell-ring:before{content:"\ec22"}.bxs-bible:before{content:"\ec23"}.bxs-binoculars:before{content:"\ec24"}.bxs-blanket:before{content:"\ec25"}.bxs-bolt:before{content:"\ec26"}.bxs-bolt-circle:before{content:"\ec27"}.bxs-bomb:before{content:"\ec28"}.bxs-bone:before{content:"\ec29"}.bxs-bong:before{content:"\ec2a"}.bxs-book:before{content:"\ec2b"}.bxs-book-add:before{content:"\ec2c"}.bxs-book-alt:before{content:"\ec2d"}.bxs-book-bookmark:before{content:"\ec2e"}.bxs-book-content:before{content:"\ec2f"}.bxs-book-heart:before{content:"\ec30"}.bxs-bookmark:before{content:"\ec31"}.bxs-bookmark-alt:before{content:"\ec32"}.bxs-bookmark-alt-minus:before{content:"\ec33"}.bxs-bookmark-alt-plus:before{content:"\ec34"}.bxs-bookmark-heart:before{content:"\ec35"}.bxs-bookmark-minus:before{content:"\ec36"}.bxs-bookmark-plus:before{content:"\ec37"}.bxs-bookmarks:before{content:"\ec38"}.bxs-bookmark-star:before{content:"\ec39"}.bxs-book-open:before{content:"\ec3a"}.bxs-book-reader:before{content:"\ec3b"}.bxs-bot:before{content:"\ec3c"}.bxs-bowling-ball:before{content:"\ec3d"}.bxs-box:before{content:"\ec3e"}.bxs-brain:before{content:"\ec3f"}.bxs-briefcase:before{content:"\ec40"}.bxs-briefcase-alt:before{content:"\ec41"}.bxs-briefcase-alt-2:before{content:"\ec42"}.bxs-brightness:before{content:"\ec43"}.bxs-brightness-half:before{content:"\ec44"}.bxs-brush:before{content:"\ec45"}.bxs-brush-alt:before{content:"\ec46"}.bxs-bug:before{content:"\ec47"}.bxs-bug-alt:before{content:"\ec48"}.bxs-building:before{content:"\ec49"}.bxs-building-house:before{content:"\ec4a"}.bxs-buildings:before{content:"\ec4b"}.bxs-bulb:before{content:"\ec4c"}.bxs-bullseye:before{content:"\ec4d"}.bxs-buoy:before{content:"\ec4e"}.bxs-bus:before{content:"\ec4f"}.bxs-business:before{content:"\ec50"}.bxs-bus-school:before{content:"\ec51"}.bxs-cabinet:before{content:"\ec52"}.bxs-cake:before{content:"\ec53"}.bxs-calculator:before{content:"\ec54"}.bxs-calendar:before{content:"\ec55"}.bxs-calendar-alt:before{content:"\ec56"}.bxs-calendar-check:before{content:"\ec57"}.bxs-calendar-edit:before{content:"\ec58"}.bxs-calendar-event:before{content:"\ec59"}.bxs-calendar-exclamation:before{content:"\ec5a"}.bxs-calendar-heart:before{content:"\ec5b"}.bxs-calendar-minus:before{content:"\ec5c"}.bxs-calendar-plus:before{content:"\ec5d"}.bxs-calendar-star:before{content:"\ec5e"}.bxs-calendar-week:before{content:"\ec5f"}.bxs-calendar-x:before{content:"\ec60"}.bxs-camera:before{content:"\ec61"}.bxs-camera-home:before{content:"\ec62"}.bxs-camera-movie:before{content:"\ec63"}.bxs-camera-off:before{content:"\ec64"}.bxs-camera-plus:before{content:"\ec65"}.bxs-capsule:before{content:"\ec66"}.bxs-captions:before{content:"\ec67"}.bxs-car:before{content:"\ec68"}.bxs-car-battery:before{content:"\ec69"}.bxs-car-crash:before{content:"\ec6a"}.bxs-card:before{content:"\ec6b"}.bxs-caret-down-circle:before{content:"\ec6c"}.bxs-caret-down-square:before{content:"\ec6d"}.bxs-caret-left-circle:before{content:"\ec6e"}.bxs-caret-left-square:before{content:"\ec6f"}.bxs-caret-right-circle:before{content:"\ec70"}.bxs-caret-right-square:before{content:"\ec71"}.bxs-caret-up-circle:before{content:"\ec72"}.bxs-caret-up-square:before{content:"\ec73"}.bxs-car-garage:before{content:"\ec74"}.bxs-car-mechanic:before{content:"\ec75"}.bxs-carousel:before{content:"\ec76"}.bxs-cart:before{content:"\ec77"}.bxs-cart-add:before{content:"\ec78"}.bxs-cart-alt:before{content:"\ec79"}.bxs-cart-download:before{content:"\ec7a"}.bxs-car-wash:before{content:"\ec7b"}.bxs-category:before{content:"\ec7c"}.bxs-category-alt:before{content:"\ec7d"}.bxs-cctv:before{content:"\ec7e"}.bxs-certification:before{content:"\ec7f"}.bxs-chalkboard:before{content:"\ec80"}.bxs-chart:before{content:"\ec81"}.bxs-chat:before{content:"\ec82"}.bxs-checkbox:before{content:"\ec83"}.bxs-checkbox-checked:before{content:"\ec84"}.bxs-check-circle:before{content:"\ec85"}.bxs-check-shield:before{content:"\ec86"}.bxs-check-square:before{content:"\ec87"}.bxs-chess:before{content:"\ec88"}.bxs-chevron-down:before{content:"\ec89"}.bxs-chevron-down-circle:before{content:"\ec8a"}.bxs-chevron-down-square:before{content:"\ec8b"}.bxs-chevron-left:before{content:"\ec8c"}.bxs-chevron-left-circle:before{content:"\ec8d"}.bxs-chevron-left-square:before{content:"\ec8e"}.bxs-chevron-right:before{content:"\ec8f"}.bxs-chevron-right-circle:before{content:"\ec90"}.bxs-chevron-right-square:before{content:"\ec91"}.bxs-chevrons-down:before{content:"\ec92"}.bxs-chevrons-left:before{content:"\ec93"}.bxs-chevrons-right:before{content:"\ec94"}.bxs-chevrons-up:before{content:"\ec95"}.bxs-chevron-up:before{content:"\ec96"}.bxs-chevron-up-circle:before{content:"\ec97"}.bxs-chevron-up-square:before{content:"\ec98"}.bxs-chip:before{content:"\ec99"}.bxs-church:before{content:"\ec9a"}.bxs-circle:before{content:"\ec9b"}.bxs-city:before{content:"\ec9c"}.bxs-clinic:before{content:"\ec9d"}.bxs-cloud:before{content:"\ec9e"}.bxs-cloud-download:before{content:"\ec9f"}.bxs-cloud-lightning:before{content:"\eca0"}.bxs-cloud-rain:before{content:"\eca1"}.bxs-cloud-upload:before{content:"\eca2"}.bxs-coffee:before{content:"\eca3"}.bxs-coffee-alt:before{content:"\eca4"}.bxs-coffee-togo:before{content:"\eca5"}.bxs-cog:before{content:"\eca6"}.bxs-coin:before{content:"\eca7"}.bxs-coin-stack:before{content:"\eca8"}.bxs-collection:before{content:"\eca9"}.bxs-color-fill:before{content:"\ecaa"}.bxs-comment:before{content:"\ecab"}.bxs-comment-add:before{content:"\ecac"}.bxs-comment-check:before{content:"\ecad"}.bxs-comment-detail:before{content:"\ecae"}.bxs-comment-dots:before{content:"\ecaf"}.bxs-comment-edit:before{content:"\ecb0"}.bxs-comment-error:before{content:"\ecb1"}.bxs-comment-minus:before{content:"\ecb2"}.bxs-comment-x:before{content:"\ecb3"}.bxs-compass:before{content:"\ecb4"}.bxs-component:before{content:"\ecb5"}.bxs-confused:before{content:"\ecb6"}.bxs-contact:before{content:"\ecb7"}.bxs-conversation:before{content:"\ecb8"}.bxs-cookie:before{content:"\ecb9"}.bxs-cool:before{content:"\ecba"}.bxs-copy:before{content:"\ecbb"}.bxs-copy-alt:before{content:"\ecbc"}.bxs-copyright:before{content:"\ecbd"}.bxs-coupon:before{content:"\ecbe"}.bxs-credit-card:before{content:"\ecbf"}.bxs-credit-card-alt:before{content:"\ecc0"}.bxs-credit-card-front:before{content:"\ecc1"}.bxs-crop:before{content:"\ecc2"}.bxs-crown:before{content:"\ecc3"}.bxs-cube:before{content:"\ecc4"}.bxs-cube-alt:before{content:"\ecc5"}.bxs-cuboid:before{content:"\ecc6"}.bxs-customize:before{content:"\ecc7"}.bxs-cylinder:before{content:"\ecc8"}.bxs-dashboard:before{content:"\ecc9"}.bxs-data:before{content:"\ecca"}.bxs-detail:before{content:"\eccb"}.bxs-devices:before{content:"\eccc"}.bxs-diamond:before{content:"\eccd"}.bxs-dice-1:before{content:"\ecce"}.bxs-dice-2:before{content:"\eccf"}.bxs-dice-3:before{content:"\ecd0"}.bxs-dice-4:before{content:"\ecd1"}.bxs-dice-5:before{content:"\ecd2"}.bxs-dice-6:before{content:"\ecd3"}.bxs-direction-left:before{content:"\ecd4"}.bxs-direction-right:before{content:"\ecd5"}.bxs-directions:before{content:"\ecd6"}.bxs-disc:before{content:"\ecd7"}.bxs-discount:before{content:"\ecd8"}.bxs-dish:before{content:"\ecd9"}.bxs-dislike:before{content:"\ecda"}.bxs-dizzy:before{content:"\ecdb"}.bxs-dock-bottom:before{content:"\ecdc"}.bxs-dock-left:before{content:"\ecdd"}.bxs-dock-right:before{content:"\ecde"}.bxs-dock-top:before{content:"\ecdf"}.bxs-dollar-circle:before{content:"\ece0"}.bxs-donate-blood:before{content:"\ece1"}.bxs-donate-heart:before{content:"\ece2"}.bxs-door-open:before{content:"\ece3"}.bxs-doughnut-chart:before{content:"\ece4"}.bxs-down-arrow:before{content:"\ece5"}.bxs-down-arrow-alt:before{content:"\ece6"}.bxs-down-arrow-circle:before{content:"\ece7"}.bxs-down-arrow-square:before{content:"\ece8"}.bxs-download:before{content:"\ece9"}.bxs-downvote:before{content:"\ecea"}.bxs-drink:before{content:"\eceb"}.bxs-droplet:before{content:"\ecec"}.bxs-droplet-half:before{content:"\eced"}.bxs-dryer:before{content:"\ecee"}.bxs-duplicate:before{content:"\ecef"}.bxs-edit:before{content:"\ecf0"}.bxs-edit-alt:before{content:"\ecf1"}.bxs-edit-location:before{content:"\ecf2"}.bxs-eject:before{content:"\ecf3"}.bxs-envelope:before{content:"\ecf4"}.bxs-envelope-open:before{content:"\ecf5"}.bxs-eraser:before{content:"\ecf6"}.bxs-error:before{content:"\ecf7"}.bxs-error-alt:before{content:"\ecf8"}.bxs-error-circle:before{content:"\ecf9"}.bxs-ev-station:before{content:"\ecfa"}.bxs-exit:before{content:"\ecfb"}.bxs-extension:before{content:"\ecfc"}.bxs-eyedropper:before{content:"\ecfd"}.bxs-face:before{content:"\ecfe"}.bxs-face-mask:before{content:"\ecff"}.bxs-factory:before{content:"\ed00"}.bxs-fast-forward-circle:before{content:"\ed01"}.bxs-file:before{content:"\ed02"}.bxs-file-archive:before{content:"\ed03"}.bxs-file-blank:before{content:"\ed04"}.bxs-file-css:before{content:"\ed05"}.bxs-file-doc:before{content:"\ed06"}.bxs-file-export:before{content:"\ed07"}.bxs-file-find:before{content:"\ed08"}.bxs-file-gif:before{content:"\ed09"}.bxs-file-html:before{content:"\ed0a"}.bxs-file-image:before{content:"\ed0b"}.bxs-file-import:before{content:"\ed0c"}.bxs-file-jpg:before{content:"\ed0d"}.bxs-file-js:before{content:"\ed0e"}.bxs-file-json:before{content:"\ed0f"}.bxs-file-md:before{content:"\ed10"}.bxs-file-pdf:before{content:"\ed11"}.bxs-file-plus:before{content:"\ed12"}.bxs-file-png:before{content:"\ed13"}.bxs-file-txt:before{content:"\ed14"}.bxs-film:before{content:"\ed15"}.bxs-filter-alt:before{content:"\ed16"}.bxs-first-aid:before{content:"\ed17"}.bxs-flag:before{content:"\ed18"}.bxs-flag-alt:before{content:"\ed19"}.bxs-flag-checkered:before{content:"\ed1a"}.bxs-flame:before{content:"\ed1b"}.bxs-flask:before{content:"\ed1c"}.bxs-florist:before{content:"\ed1d"}.bxs-folder:before{content:"\ed1e"}.bxs-folder-minus:before{content:"\ed1f"}.bxs-folder-open:before{content:"\ed20"}.bxs-folder-plus:before{content:"\ed21"}.bxs-food-menu:before{content:"\ed22"}.bxs-fridge:before{content:"\ed23"}.bxs-game:before{content:"\ed24"}.bxs-gas-pump:before{content:"\ed25"}.bxs-ghost:before{content:"\ed26"}.bxs-gift:before{content:"\ed27"}.bxs-graduation:before{content:"\ed28"}.bxs-grid:before{content:"\ed29"}.bxs-grid-alt:before{content:"\ed2a"}.bxs-group:before{content:"\ed2b"}.bxs-guitar-amp:before{content:"\ed2c"}.bxs-hand-down:before{content:"\ed2d"}.bxs-hand-left:before{content:"\ed2e"}.bxs-hand-right:before{content:"\ed2f"}.bxs-hand-up:before{content:"\ed30"}.bxs-happy:before{content:"\ed31"}.bxs-happy-alt:before{content:"\ed32"}.bxs-happy-beaming:before{content:"\ed33"}.bxs-happy-heart-eyes:before{content:"\ed34"}.bxs-hdd:before{content:"\ed35"}.bxs-heart:before{content:"\ed36"}.bxs-heart-circle:before{content:"\ed37"}.bxs-heart-square:before{content:"\ed38"}.bxs-help-circle:before{content:"\ed39"}.bxs-hide:before{content:"\ed3a"}.bxs-home:before{content:"\ed3b"}.bxs-home-circle:before{content:"\ed3c"}.bxs-home-heart:before{content:"\ed3d"}.bxs-home-smile:before{content:"\ed3e"}.bxs-hot:before{content:"\ed3f"}.bxs-hotel:before{content:"\ed40"}.bxs-hourglass:before{content:"\ed41"}.bxs-hourglass-bottom:before{content:"\ed42"}.bxs-hourglass-top:before{content:"\ed43"}.bxs-id-card:before{content:"\ed44"}.bxs-image:before{content:"\ed45"}.bxs-image-add:before{content:"\ed46"}.bxs-image-alt:before{content:"\ed47"}.bxs-inbox:before{content:"\ed48"}.bxs-info-circle:before{content:"\ed49"}.bxs-info-square:before{content:"\ed4a"}.bxs-institution:before{content:"\ed4b"}.bxs-joystick:before{content:"\ed4c"}.bxs-joystick-alt:before{content:"\ed4d"}.bxs-joystick-button:before{content:"\ed4e"}.bxs-key:before{content:"\ed4f"}.bxs-keyboard:before{content:"\ed50"}.bxs-label:before{content:"\ed51"}.bxs-landmark:before{content:"\ed52"}.bxs-landscape:before{content:"\ed53"}.bxs-laugh:before{content:"\ed54"}.bxs-layer:before{content:"\ed55"}.bxs-layer-minus:before{content:"\ed56"}.bxs-layer-plus:before{content:"\ed57"}.bxs-layout:before{content:"\ed58"}.bxs-left-arrow:before{content:"\ed59"}.bxs-left-arrow-alt:before{content:"\ed5a"}.bxs-left-arrow-circle:before{content:"\ed5b"}.bxs-left-arrow-square:before{content:"\ed5c"}.bxs-left-down-arrow-circle:before{content:"\ed5d"}.bxs-left-top-arrow-circle:before{content:"\ed5e"}.bxs-like:before{content:"\ed5f"}.bxs-location-plus:before{content:"\ed60"}.bxs-lock:before{content:"\ed61"}.bxs-lock-alt:before{content:"\ed62"}.bxs-lock-open:before{content:"\ed63"}.bxs-lock-open-alt:before{content:"\ed64"}.bxs-log-in:before{content:"\ed65"}.bxs-log-in-circle:before{content:"\ed66"}.bxs-log-out:before{content:"\ed67"}.bxs-log-out-circle:before{content:"\ed68"}.bxs-low-vision:before{content:"\ed69"}.bxs-magic-wand:before{content:"\ed6a"}.bxs-magnet:before{content:"\ed6b"}.bxs-map:before{content:"\ed6c"}.bxs-map-alt:before{content:"\ed6d"}.bxs-map-pin:before{content:"\ed6e"}.bxs-mask:before{content:"\ed6f"}.bxs-medal:before{content:"\ed70"}.bxs-megaphone:before{content:"\ed71"}.bxs-meh:before{content:"\ed72"}.bxs-meh-alt:before{content:"\ed73"}.bxs-meh-blank:before{content:"\ed74"}.bxs-memory-card:before{content:"\ed75"}.bxs-message:before{content:"\ed76"}.bxs-message-add:before{content:"\ed77"}.bxs-message-alt:before{content:"\ed78"}.bxs-message-alt-add:before{content:"\ed79"}.bxs-message-alt-check:before{content:"\ed7a"}.bxs-message-alt-detail:before{content:"\ed7b"}.bxs-message-alt-dots:before{content:"\ed7c"}.bxs-message-alt-edit:before{content:"\ed7d"}.bxs-message-alt-error:before{content:"\ed7e"}.bxs-message-alt-minus:before{content:"\ed7f"}.bxs-message-alt-x:before{content:"\ed80"}.bxs-message-check:before{content:"\ed81"}.bxs-message-detail:before{content:"\ed82"}.bxs-message-dots:before{content:"\ed83"}.bxs-message-edit:before{content:"\ed84"}.bxs-message-error:before{content:"\ed85"}.bxs-message-minus:before{content:"\ed86"}.bxs-message-rounded:before{content:"\ed87"}.bxs-message-rounded-add:before{content:"\ed88"}.bxs-message-rounded-check:before{content:"\ed89"}.bxs-message-rounded-detail:before{content:"\ed8a"}.bxs-message-rounded-dots:before{content:"\ed8b"}.bxs-message-rounded-edit:before{content:"\ed8c"}.bxs-message-rounded-error:before{content:"\ed8d"}.bxs-message-rounded-minus:before{content:"\ed8e"}.bxs-message-rounded-x:before{content:"\ed8f"}.bxs-message-square:before{content:"\ed90"}.bxs-message-square-add:before{content:"\ed91"}.bxs-message-square-check:before{content:"\ed92"}.bxs-message-square-detail:before{content:"\ed93"}.bxs-message-square-dots:before{content:"\ed94"}.bxs-message-square-edit:before{content:"\ed95"}.bxs-message-square-error:before{content:"\ed96"}.bxs-message-square-minus:before{content:"\ed97"}.bxs-message-square-x:before{content:"\ed98"}.bxs-message-x:before{content:"\ed99"}.bxs-meteor:before{content:"\ed9a"}.bxs-microchip:before{content:"\ed9b"}.bxs-microphone:before{content:"\ed9c"}.bxs-microphone-alt:before{content:"\ed9d"}.bxs-microphone-off:before{content:"\ed9e"}.bxs-minus-circle:before{content:"\ed9f"}.bxs-minus-square:before{content:"\eda0"}.bxs-mobile:before{content:"\eda1"}.bxs-mobile-vibration:before{content:"\eda2"}.bxs-moon:before{content:"\eda3"}.bxs-mouse:before{content:"\eda4"}.bxs-mouse-alt:before{content:"\eda5"}.bxs-movie:before{content:"\eda6"}.bxs-movie-play:before{content:"\eda7"}.bxs-music:before{content:"\eda8"}.bxs-navigation:before{content:"\eda9"}.bxs-network-chart:before{content:"\edaa"}.bxs-news:before{content:"\edab"}.bxs-no-entry:before{content:"\edac"}.bxs-note:before{content:"\edad"}.bxs-notepad:before{content:"\edae"}.bxs-notification:before{content:"\edaf"}.bxs-notification-off:before{content:"\edb0"}.bxs-offer:before{content:"\edb1"}.bxs-package:before{content:"\edb2"}.bxs-paint:before{content:"\edb3"}.bxs-paint-roll:before{content:"\edb4"}.bxs-palette:before{content:"\edb5"}.bxs-paper-plane:before{content:"\edb6"}.bxs-parking:before{content:"\edb7"}.bxs-paste:before{content:"\edb8"}.bxs-pen:before{content:"\edb9"}.bxs-pencil:before{content:"\edba"}.bxs-phone:before{content:"\edbb"}.bxs-phone-call:before{content:"\edbc"}.bxs-phone-incoming:before{content:"\edbd"}.bxs-phone-outgoing:before{content:"\edbe"}.bxs-photo-album:before{content:"\edbf"}.bxs-piano:before{content:"\edc0"}.bxs-pie-chart:before{content:"\edc1"}.bxs-pie-chart-alt:before{content:"\edc2"}.bxs-pie-chart-alt-2:before{content:"\edc3"}.bxs-pin:before{content:"\edc4"}.bxs-pizza:before{content:"\edc5"}.bxs-plane:before{content:"\edc6"}.bxs-plane-alt:before{content:"\edc7"}.bxs-plane-land:before{content:"\edc8"}.bxs-planet:before{content:"\edc9"}.bxs-plane-take-off:before{content:"\edca"}.bxs-playlist:before{content:"\edcb"}.bxs-plug:before{content:"\edcc"}.bxs-plus-circle:before{content:"\edcd"}.bxs-plus-square:before{content:"\edce"}.bxs-pointer:before{content:"\edcf"}.bxs-polygon:before{content:"\edd0"}.bxs-printer:before{content:"\edd1"}.bxs-purchase-tag:before{content:"\edd2"}.bxs-purchase-tag-alt:before{content:"\edd3"}.bxs-pyramid:before{content:"\edd4"}.bxs-quote-alt-left:before{content:"\edd5"}.bxs-quote-alt-right:before{content:"\edd6"}.bxs-quote-left:before{content:"\edd7"}.bxs-quote-right:before{content:"\edd8"}.bxs-quote-single-left:before{content:"\edd9"}.bxs-quote-single-right:before{content:"\edda"}.bxs-radiation:before{content:"\eddb"}.bxs-radio:before{content:"\eddc"}.bxs-receipt:before{content:"\eddd"}.bxs-rectangle:before{content:"\edde"}.bxs-rename:before{content:"\eddf"}.bxs-report:before{content:"\ede0"}.bxs-rewind-circle:before{content:"\ede1"}.bxs-right-arrow:before{content:"\ede2"}.bxs-right-arrow-alt:before{content:"\ede3"}.bxs-right-arrow-circle:before{content:"\ede4"}.bxs-right-arrow-square:before{content:"\ede5"}.bxs-right-down-arrow-circle:before{content:"\ede6"}.bxs-right-top-arrow-circle:before{content:"\ede7"}.bxs-rocket:before{content:"\ede8"}.bxs-ruler:before{content:"\ede9"}.bxs-sad:before{content:"\edea"}.bxs-save:before{content:"\edeb"}.bxs-school:before{content:"\edec"}.bxs-search:before{content:"\eded"}.bxs-search-alt-2:before{content:"\edee"}.bxs-select-multiple:before{content:"\edef"}.bxs-send:before{content:"\edf0"}.bxs-server:before{content:"\edf1"}.bxs-shapes:before{content:"\edf2"}.bxs-share:before{content:"\edf3"}.bxs-share-alt:before{content:"\edf4"}.bxs-shield:before{content:"\edf5"}.bxs-shield-alt-2:before{content:"\edf6"}.bxs-shield-x:before{content:"\edf7"}.bxs-ship:before{content:"\edf8"}.bxs-shocked:before{content:"\edf9"}.bxs-shopping-bag:before{content:"\edfa"}.bxs-shopping-bag-alt:before{content:"\edfb"}.bxs-shopping-bags:before{content:"\edfc"}.bxs-show:before{content:"\edfd"}.bxs-skip-next-circle:before{content:"\edfe"}.bxs-skip-previous-circle:before{content:"\edff"}.bxs-skull:before{content:"\ee00"}.bxs-sleepy:before{content:"\ee01"}.bxs-slideshow:before{content:"\ee02"}.bxs-smile:before{content:"\ee03"}.bxs-sort-alt:before{content:"\ee04"}.bxs-spa:before{content:"\ee05"}.bxs-spray-can:before{content:"\ee06"}.bxs-spreadsheet:before{content:"\ee07"}.bxs-square:before{content:"\ee08"}.bxs-square-rounded:before{content:"\ee09"}.bxs-star:before{content:"\ee0a"}.bxs-star-half:before{content:"\ee0b"}.bxs-sticker:before{content:"\ee0c"}.bxs-stopwatch:before{content:"\ee0d"}.bxs-store:before{content:"\ee0e"}.bxs-store-alt:before{content:"\ee0f"}.bxs-sun:before{content:"\ee10"}.bxs-tachometer:before{content:"\ee11"}.bxs-tag:before{content:"\ee12"}.bxs-tag-alt:before{content:"\ee13"}.bxs-tag-x:before{content:"\ee14"}.bxs-taxi:before{content:"\ee15"}.bxs-tennis-ball:before{content:"\ee16"}.bxs-terminal:before{content:"\ee17"}.bxs-thermometer:before{content:"\ee18"}.bxs-time:before{content:"\ee19"}.bxs-time-five:before{content:"\ee1a"}.bxs-timer:before{content:"\ee1b"}.bxs-tired:before{content:"\ee1c"}.bxs-toggle-left:before{content:"\ee1d"}.bxs-toggle-right:before{content:"\ee1e"}.bxs-tone:before{content:"\ee1f"}.bxs-torch:before{content:"\ee20"}.bxs-to-top:before{content:"\ee21"}.bxs-traffic:before{content:"\ee22"}.bxs-traffic-barrier:before{content:"\ee23"}.bxs-traffic-cone:before{content:"\ee24"}.bxs-train:before{content:"\ee25"}.bxs-trash:before{content:"\ee26"}.bxs-trash-alt:before{content:"\ee27"}.bxs-tree:before{content:"\ee28"}.bxs-trophy:before{content:"\ee29"}.bxs-truck:before{content:"\ee2a"}.bxs-t-shirt:before{content:"\ee2b"}.bxs-tv:before{content:"\ee2c"}.bxs-up-arrow:before{content:"\ee2d"}.bxs-up-arrow-alt:before{content:"\ee2e"}.bxs-up-arrow-circle:before{content:"\ee2f"}.bxs-up-arrow-square:before{content:"\ee30"}.bxs-upside-down:before{content:"\ee31"}.bxs-upvote:before{content:"\ee32"}.bxs-user:before{content:"\ee33"}.bxs-user-account:before{content:"\ee34"}.bxs-user-badge:before{content:"\ee35"}.bxs-user-check:before{content:"\ee36"}.bxs-user-circle:before{content:"\ee37"}.bxs-user-detail:before{content:"\ee38"}.bxs-user-minus:before{content:"\ee39"}.bxs-user-pin:before{content:"\ee3a"}.bxs-user-plus:before{content:"\ee3b"}.bxs-user-rectangle:before{content:"\ee3c"}.bxs-user-voice:before{content:"\ee3d"}.bxs-user-x:before{content:"\ee3e"}.bxs-vector:before{content:"\ee3f"}.bxs-vial:before{content:"\ee40"}.bxs-video:before{content:"\ee41"}.bxs-video-off:before{content:"\ee42"}.bxs-video-plus:before{content:"\ee43"}.bxs-video-recording:before{content:"\ee44"}.bxs-videos:before{content:"\ee45"}.bxs-virus:before{content:"\ee46"}.bxs-virus-block:before{content:"\ee47"}.bxs-volume:before{content:"\ee48"}.bxs-volume-full:before{content:"\ee49"}.bxs-volume-low:before{content:"\ee4a"}.bxs-volume-mute:before{content:"\ee4b"}.bxs-wallet:before{content:"\ee4c"}.bxs-wallet-alt:before{content:"\ee4d"}.bxs-washer:before{content:"\ee4e"}.bxs-watch:before{content:"\ee4f"}.bxs-watch-alt:before{content:"\ee50"}.bxs-webcam:before{content:"\ee51"}.bxs-widget:before{content:"\ee52"}.bxs-window-alt:before{content:"\ee53"}.bxs-wine:before{content:"\ee54"}.bxs-wink-smile:before{content:"\ee55"}.bxs-wink-tongue:before{content:"\ee56"}.bxs-wrench:before{content:"\ee57"}.bxs-x-circle:before{content:"\ee58"}.bxs-x-square:before{content:"\ee59"}.bxs-yin-yang:before{content:"\ee5a"}.bxs-zap:before{content:"\ee5b"}.bxs-zoom-in:before{content:"\ee5c"}.bxs-zoom-out:before{content:"\ee5d"}.bxl-500px:before{content:"\ee5e"}.bxl-adobe:before{content:"\ee5f"}.bxl-airbnb:before{content:"\ee60"}.bxl-algolia:before{content:"\ee61"}.bxl-amazon:before{content:"\ee62"}.bxl-android:before{content:"\ee63"}.bxl-angular:before{content:"\ee64"}.bxl-apple:before{content:"\ee65"}.bxl-audible:before{content:"\ee66"}.bxl-baidu:before{content:"\ee67"}.bxl-behance:before{content:"\ee68"}.bxl-bing:before{content:"\ee69"}.bxl-bitcoin:before{content:"\ee6a"}.bxl-blender:before{content:"\ee6b"}.bxl-blogger:before{content:"\ee6c"}.bxl-bootstrap:before{content:"\ee6d"}.bxl-chrome:before{content:"\ee6e"}.bxl-codepen:before{content:"\ee6f"}.bxl-c-plus-plus:before{content:"\ee70"}.bxl-creative-commons:before{content:"\ee71"}.bxl-css3:before{content:"\ee72"}.bxl-dailymotion:before{content:"\ee73"}.bxl-deviantart:before{content:"\ee74"}.bxl-dev-to:before{content:"\ee75"}.bxl-digg:before{content:"\ee76"}.bxl-digitalocean:before{content:"\ee77"}.bxl-discord:before{content:"\ee78"}.bxl-discourse:before{content:"\ee79"}.bxl-django:before{content:"\ee7a"}.bxl-dribbble:before{content:"\ee7b"}.bxl-dropbox:before{content:"\ee7c"}.bxl-drupal:before{content:"\ee7d"}.bxl-ebay:before{content:"\ee7e"}.bxl-edge:before{content:"\ee7f"}.bxl-etsy:before{content:"\ee80"}.bxl-facebook:before{content:"\ee81"}.bxl-facebook-circle:before{content:"\ee82"}.bxl-facebook-square:before{content:"\ee83"}.bxl-figma:before{content:"\ee84"}.bxl-firebase:before{content:"\ee85"}.bxl-firefox:before{content:"\ee86"}.bxl-flickr:before{content:"\ee87"}.bxl-flickr-square:before{content:"\ee88"}.bxl-foursquare:before{content:"\ee89"}.bxl-git:before{content:"\ee8a"}.bxl-github:before{content:"\ee8b"}.bxl-gitlab:before{content:"\ee8c"}.bxl-google:before{content:"\ee8d"}.bxl-google-cloud:before{content:"\ee8e"}.bxl-google-plus:before{content:"\ee8f"}.bxl-google-plus-circle:before{content:"\ee90"}.bxl-html5:before{content:"\ee91"}.bxl-imdb:before{content:"\ee92"}.bxl-instagram:before{content:"\ee93"}.bxl-instagram-alt:before{content:"\ee94"}.bxl-internet-explorer:before{content:"\ee95"}.bxl-invision:before{content:"\ee96"}.bxl-javascript:before{content:"\ee97"}.bxl-joomla:before{content:"\ee98"}.bxl-jquery:before{content:"\ee99"}.bxl-jsfiddle:before{content:"\ee9a"}.bxl-kickstarter:before{content:"\ee9b"}.bxl-kubernetes:before{content:"\ee9c"}.bxl-less:before{content:"\ee9d"}.bxl-linkedin:before{content:"\ee9e"}.bxl-linkedin-square:before{content:"\ee9f"}.bxl-magento:before{content:"\eea0"}.bxl-mailchimp:before{content:"\eea1"}.bxl-markdown:before{content:"\eea2"}.bxl-mastercard:before{content:"\eea3"}.bxl-medium:before{content:"\eea4"}.bxl-medium-old:before{content:"\eea5"}.bxl-medium-square:before{content:"\eea6"}.bxl-messenger:before{content:"\eea7"}.bxl-microsoft:before{content:"\eea8"}.bxl-microsoft-teams:before{content:"\eea9"}.bxl-nodejs:before{content:"\eeaa"}.bxl-ok-ru:before{content:"\eeab"}.bxl-opera:before{content:"\eeac"}.bxl-patreon:before{content:"\eead"}.bxl-paypal:before{content:"\eeae"}.bxl-periscope:before{content:"\eeaf"}.bxl-pinterest:before{content:"\eeb0"}.bxl-pinterest-alt:before{content:"\eeb1"}.bxl-play-store:before{content:"\eeb2"}.bxl-pocket:before{content:"\eeb3"}.bxl-product-hunt:before{content:"\eeb4"}.bxl-python:before{content:"\eeb5"}.bxl-quora:before{content:"\eeb6"}.bxl-react:before{content:"\eeb7"}.bxl-redbubble:before{content:"\eeb8"}.bxl-reddit:before{content:"\eeb9"}.bxl-redux:before{content:"\eeba"}.bxl-sass:before{content:"\eebb"}.bxl-shopify:before{content:"\eebc"}.bxl-skype:before{content:"\eebd"}.bxl-slack:before{content:"\eebe"}.bxl-slack-old:before{content:"\eebf"}.bxl-snapchat:before{content:"\eec0"}.bxl-soundcloud:before{content:"\eec1"}.bxl-spotify:before{content:"\eec2"}.bxl-spring-boot:before{content:"\eec3"}.bxl-squarespace:before{content:"\eec4"}.bxl-stack-overflow:before{content:"\eec5"}.bxl-stripe:before{content:"\eec6"}.bxl-telegram:before{content:"\eec7"}.bxl-trello:before{content:"\eec8"}.bxl-tumblr:before{content:"\eec9"}.bxl-tux:before{content:"\eeca"}.bxl-twitch:before{content:"\eecb"}.bxl-twitter:before{content:"\eecc"}.bxl-unsplash:before{content:"\eecd"}.bxl-vimeo:before{content:"\eece"}.bxl-visa:before{content:"\eecf"}.bxl-vk:before{content:"\eed0"}.bxl-vuejs:before{content:"\eed1"}.bxl-whatsapp:before{content:"\eed2"}.bxl-whatsapp-square:before{content:"\eed3"}.bxl-wikipedia:before{content:"\eed4"}.bxl-windows:before{content:"\eed5"}.bxl-wix:before{content:"\eed6"}.bxl-wordpress:before{content:"\eed7"}.bxl-yahoo:before{content:"\eed8"}.bxl-yelp:before{content:"\eed9"}.bxl-youtube:before{content:"\eeda"}.bxl-zoom:before{content:"\eedb"}
--------------------------------------------------------------------------------
/src/assets/boxicons-2.0.7/css/transformations.css:
--------------------------------------------------------------------------------
1 | .bx-rotate-90
2 | {
3 | transform: rotate(90deg);
4 |
5 | -ms-filter: 'progid:DXImageTransform.Microsoft.BasicImage(rotation=1)';
6 | }
7 | .bx-rotate-180
8 | {
9 | transform: rotate(180deg);
10 |
11 | -ms-filter: 'progid:DXImageTransform.Microsoft.BasicImage(rotation=2)';
12 | }
13 | .bx-rotate-270
14 | {
15 | transform: rotate(270deg);
16 |
17 | -ms-filter: 'progid:DXImageTransform.Microsoft.BasicImage(rotation=3)';
18 | }
19 | .bx-flip-horizontal
20 | {
21 | transform: scaleX(-1);
22 |
23 | -ms-filter: 'progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)';
24 | }
25 | .bx-flip-vertical
26 | {
27 | transform: scaleY(-1);
28 |
29 | -ms-filter: 'progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)';
30 | }
31 |
--------------------------------------------------------------------------------
/src/assets/boxicons-2.0.7/fonts/boxicons.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/harryngdev/react-movie-app/102cd0220ed6564159ba9b038d53e4e3059eca4e/src/assets/boxicons-2.0.7/fonts/boxicons.eot
--------------------------------------------------------------------------------
/src/assets/boxicons-2.0.7/fonts/boxicons.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/harryngdev/react-movie-app/102cd0220ed6564159ba9b038d53e4e3059eca4e/src/assets/boxicons-2.0.7/fonts/boxicons.ttf
--------------------------------------------------------------------------------
/src/assets/boxicons-2.0.7/fonts/boxicons.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/harryngdev/react-movie-app/102cd0220ed6564159ba9b038d53e4e3059eca4e/src/assets/boxicons-2.0.7/fonts/boxicons.woff
--------------------------------------------------------------------------------
/src/assets/boxicons-2.0.7/fonts/boxicons.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/harryngdev/react-movie-app/102cd0220ed6564159ba9b038d53e4e3059eca4e/src/assets/boxicons-2.0.7/fonts/boxicons.woff2
--------------------------------------------------------------------------------
/src/assets/footer-bg.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/harryngdev/react-movie-app/102cd0220ed6564159ba9b038d53e4e3059eca4e/src/assets/footer-bg.jpg
--------------------------------------------------------------------------------
/src/assets/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/harryngdev/react-movie-app/102cd0220ed6564159ba9b038d53e4e3059eca4e/src/assets/logo.png
--------------------------------------------------------------------------------
/src/assets/tmovie.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/harryngdev/react-movie-app/102cd0220ed6564159ba9b038d53e4e3059eca4e/src/assets/tmovie.png
--------------------------------------------------------------------------------
/src/components/button/Button.jsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import PropTypes from "prop-types";
3 |
4 | import "./button.scss";
5 |
6 | const Button = (props) => {
7 | return (
8 |
14 | );
15 | };
16 |
17 | export const OutlineButton = (props) => {
18 | return (
19 |
25 | );
26 | };
27 |
28 | Button.propTypes = {
29 | onClick: PropTypes.func,
30 | };
31 |
32 | export default Button;
33 |
--------------------------------------------------------------------------------
/src/components/button/button.scss:
--------------------------------------------------------------------------------
1 | @use "../../scss/" as *;
2 |
3 | button {
4 | cursor: pointer;
5 | font-family: $font-family;
6 | }
7 |
8 | .btn {
9 | border: 4px solid transparent;
10 | background-color: $main-color;
11 | color: $white;
12 | border-radius: $border-radius;
13 | padding: 0.5rem 1.8rem;
14 | font-size: 1.5rem;
15 | font-weight: 600;
16 | box-shadow: 0px 0px 7px 8px #ff00004d;
17 | transition: box-shadow 0.3s ease;
18 | position: relative;
19 |
20 | &:hover {
21 | box-shadow: 0px 0px 7px 15px #ff00004d;
22 | }
23 |
24 | &.small {
25 | border-width: 2px;
26 | padding: 0.25rem 1.5rem;
27 | font-size: 1rem;
28 | }
29 | }
30 |
31 | .btn-outline {
32 | border: 3px solid $white;
33 | background-color: transparent;
34 | color: $white;
35 | box-shadow: unset;
36 | transition: color 0.3s ease, background-color 0.3s ease;
37 |
38 | &:hover {
39 | box-shadow: unset;
40 | color: $main-color;
41 | background-color: $white;
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/src/components/footer/Footer.jsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 |
3 | import "./footer.scss";
4 |
5 | import { Link } from "react-router-dom";
6 |
7 | import bg from "./../../assets/footer-bg.jpg";
8 | import logo from "./../../assets/logo.png";
9 |
10 | import * as Config from "./../../constants/Config";
11 |
12 | const Footer = () => {
13 | return (
14 |
15 |
16 |
17 |
18 |

19 |
hMovies
20 |
21 |
22 |
23 |
24 |
25 | Home
26 | Contact us
27 | Term of service
28 | About us
29 |
30 |
31 | Live
32 | FAQ
33 | Premium
34 | Privacy policy
35 |
36 |
37 | You must watch
38 | Recent release
39 | Top IMDB
40 |
41 |
42 |
43 |
44 | );
45 | };
46 |
47 | export default Footer;
48 |
--------------------------------------------------------------------------------
/src/components/footer/footer.scss:
--------------------------------------------------------------------------------
1 | @use "../../scss/" as *;
2 |
3 | .footer {
4 | position: relative;
5 | padding: 6rem 2rem;
6 | background-position: top;
7 | background-size: cover;
8 | background-repeat: no-repeat;
9 |
10 | &__content {
11 | max-width: 1000px;
12 |
13 | &__logo {
14 | @include flex(center, center);
15 |
16 | margin-bottom: 3rem;
17 | }
18 |
19 | &__menus {
20 | display: grid;
21 | grid-template-columns: repeat(3, 1fr);
22 |
23 | @include mobile {
24 | grid-template-columns: repeat(2, 1fr);
25 | }
26 | }
27 |
28 | &__menu {
29 | @include flex(flex-start, flex-start);
30 |
31 | flex-direction: column;
32 | margin-top: 1rem;
33 | font-size: 1.5rem;
34 | font-weight: 600;
35 |
36 | & > * ~ * {
37 | margin-top: 1rem;
38 | }
39 | }
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/src/components/header/Header.jsx:
--------------------------------------------------------------------------------
1 | import React, { useEffect, useRef } from "react";
2 | import { Link, useLocation } from "react-router-dom";
3 |
4 | import "./header.scss";
5 |
6 | import logo from "./../../assets/logo.png";
7 |
8 | import * as Config from "./../../constants/Config";
9 |
10 | const headerNav = [
11 | {
12 | display: "Home",
13 | path: `/${Config.HOME_PAGE}`,
14 | },
15 | {
16 | display: "Movies",
17 | path: `/${Config.HOME_PAGE}/movie`,
18 | },
19 | {
20 | display: "TV Series",
21 | path: `/${Config.HOME_PAGE}/tv`,
22 | },
23 | ];
24 |
25 | const Header = () => {
26 | const { pathname } = useLocation();
27 | const headerRef = useRef(null);
28 |
29 | const active = headerNav.findIndex((e) => e.path === pathname);
30 |
31 | useEffect(() => {
32 | const shrinkHeader = () => {
33 | if (
34 | document.body.scrollTop > 100 ||
35 | document.documentElement.scrollTop > 100
36 | ) {
37 | headerRef.current.classList.add("shrink");
38 | } else {
39 | headerRef.current.classList.remove("shrink");
40 | }
41 | };
42 |
43 | window.addEventListener("scroll", shrinkHeader);
44 |
45 | return () => {
46 | window.removeEventListener("scroll", shrinkHeader);
47 | };
48 | }, []);
49 |
50 | return (
51 |
52 |
53 |
54 |

55 |
hMovies
56 |
57 |
58 |
59 | {headerNav.map((e, i) => (
60 | -
61 | {e.display}
62 |
63 | ))}
64 |
65 |
66 |
67 | );
68 | };
69 |
70 | export default Header;
71 |
--------------------------------------------------------------------------------
/src/components/header/header.scss:
--------------------------------------------------------------------------------
1 | @use "../../scss/" as *;
2 |
3 | .logo {
4 | font-size: 2.5rem;
5 | font-weight: 600;
6 |
7 | @include flex(center, unset);
8 |
9 | img {
10 | margin-right: 10px;
11 | width: 50px;
12 |
13 | @include mobile {
14 | width: 30px;
15 | margin-right: 0;
16 | }
17 | }
18 | }
19 |
20 | .header {
21 | height: $header-height;
22 | position: fixed;
23 | top: 0;
24 | left: 0;
25 | width: 100%;
26 | z-index: 99;
27 | transition: height 0.3s ease, background-color 0.3s ease;
28 |
29 | &.shrink {
30 | height: $header-shrink-height;
31 | background-color: $body-bg;
32 | }
33 |
34 | &__wrap {
35 | @include flex(center, space-between);
36 |
37 | height: 100%;
38 | padding: 0 2rem;
39 |
40 | @include mobile {
41 | justify-content: center;
42 | }
43 | }
44 |
45 | &__nav {
46 | @include flex(center, unset);
47 |
48 | & > * ~ * {
49 | margin-left: 2rem;
50 | }
51 |
52 | li {
53 | padding: 5px 0;
54 | font-weight: 700;
55 | position: relative;
56 | font-size: 1.5rem;
57 |
58 | &:after {
59 | content: "";
60 | position: absolute;
61 | bottom: 0;
62 | left: 50%;
63 | transform: translateX(-50%);
64 | width: 0;
65 | transition: width 0.5s ease;
66 | height: 2px;
67 | background-color: $main-color;
68 | }
69 |
70 | &.active:after,
71 | &:hover:after {
72 | width: 100%;
73 | }
74 | }
75 |
76 | @include mobile {
77 | position: fixed;
78 | bottom: 0;
79 | left: 0;
80 | height: 5rem;
81 | width: 100%;
82 | background-color: $body-bg;
83 | padding: 0 2rem;
84 | box-shadow: $box-shadow;
85 |
86 | @include flex(center, space-between);
87 |
88 | & > * ~ * {
89 | margin-left: 0;
90 | }
91 | }
92 | }
93 | }
94 |
--------------------------------------------------------------------------------
/src/components/hero-slide/HeroSlide.jsx:
--------------------------------------------------------------------------------
1 | import React, { useEffect, useRef, useState } from "react";
2 |
3 | import SwiperCore, { Autoplay } from "swiper";
4 | import { Swiper, SwiperSlide } from "swiper/react";
5 |
6 | import Button, { OutlineButton } from "./../button/Button";
7 | import Modal, { ModalContent } from "./../modal/Modal";
8 |
9 | import tmdbApi, { category, movieType } from "./../../api/tmdbApi";
10 | import apiConfig from "./../../api/apiConfig";
11 |
12 | import "./hero-slide.scss";
13 | import { useHistory } from "react-router";
14 |
15 | import * as Config from "./../../constants/Config";
16 |
17 | const HeroSlide = () => {
18 | SwiperCore.use([Autoplay]);
19 |
20 | const [movieItems, setMovieItems] = useState([]);
21 |
22 | useEffect(() => {
23 | const getMovies = async () => {
24 | const params = { page: 1 };
25 | try {
26 | const response = await tmdbApi.getMoviesList(movieType.popular, {
27 | params,
28 | });
29 | setMovieItems(response.results.slice(0, 4));
30 | console.log(response);
31 | } catch {
32 | console.log("error");
33 | }
34 | };
35 | getMovies();
36 | }, []);
37 |
38 | return (
39 |
40 |
47 | {movieItems.map((item, index) => (
48 |
49 | {({ isActive }) => (
50 | // eslint-disable-next-line jsx-a11y/alt-text
51 |
55 | )}
56 |
57 | ))}
58 |
59 | {movieItems.map((item, index) => (
60 |
61 | ))}
62 |
63 | );
64 | };
65 |
66 | const HeroSlideItem = (props) => {
67 | let history = useHistory();
68 |
69 | const item = props.item;
70 |
71 | const background = apiConfig.originalImage(
72 | item.backdrop_path ? item.backdrop_path : item.poster_path
73 | );
74 |
75 | const setModalActive = async () => {
76 | const modal = document.querySelector(`#modal_${item.id}`);
77 |
78 | const videos = await tmdbApi.getVideos(category.movie, item.id);
79 |
80 | if (videos.results.length > 0) {
81 | const videoSrc = "https://www.youtube.com/embed/" + videos.results[0].key;
82 | modal
83 | .querySelector(".modal__content > iframe")
84 | .setAttribute("src", videoSrc);
85 | } else {
86 | modal.querySelector(".modal__content").innerHTML = "No trailer";
87 | }
88 |
89 | modal.classList.toggle("active");
90 | };
91 |
92 | return (
93 |
97 |
98 |
99 |
{item.title}
100 |
{item.overview}
101 |
102 |
109 |
110 | Watch trailer
111 |
112 |
113 |
114 |
115 |
116 |
})
117 |
118 |
119 |
120 | );
121 | };
122 |
123 | const TrailerModal = (props) => {
124 | const item = props.item;
125 |
126 | const iframeRef = useRef(null);
127 |
128 | const onClose = () => iframeRef.current.setAttribute("src", "");
129 |
130 | return (
131 |
132 |
133 |
139 |
140 |
141 | );
142 | };
143 |
144 | export default HeroSlide;
145 |
--------------------------------------------------------------------------------
/src/components/hero-slide/hero-slide.scss:
--------------------------------------------------------------------------------
1 | @use "../../scss/" as *;
2 |
3 | .hero-slide {
4 | margin-bottom: 3rem;
5 | }
6 |
7 | .hero-slide__item {
8 | padding: 9rem 0;
9 | width: 100%;
10 | position: relative;
11 | background-position: center;
12 | background-size: cover;
13 | background-repeat: no-repeat;
14 |
15 | &:before {
16 | content: "";
17 | position: absolute;
18 | top: 0;
19 | left: 0;
20 | width: 100%;
21 | height: 100%;
22 |
23 | @include overlay();
24 | }
25 |
26 | &:after {
27 | content: "";
28 | position: absolute;
29 | bottom: 0;
30 | left: 0;
31 | width: 100%;
32 | height: 100px;
33 | background-image: linear-gradient(to top, $body-bg, rgba($black, 0));
34 | }
35 |
36 | &__content {
37 | @include flex(center, center);
38 |
39 | position: relative;
40 |
41 | &__info {
42 | width: 55%;
43 | padding: 0 3rem;
44 | position: relative;
45 |
46 | @include tablet {
47 | width: 100%;
48 | }
49 |
50 | & > * ~ * {
51 | margin-top: 3rem;
52 | }
53 |
54 | .title {
55 | font-size: 5rem;
56 | font-weight: 700;
57 | line-height: 1;
58 |
59 | @include tablet {
60 | font-size: 4rem;
61 | }
62 | }
63 |
64 | .overview {
65 | font-weight: 700;
66 | letter-spacing: 0.5px;
67 | }
68 |
69 | .btns > * ~ * {
70 | margin-left: 1rem;
71 | }
72 |
73 | .btns,
74 | .title,
75 | .overview {
76 | opacity: 0;
77 | transform: translateY(-100px);
78 | transition: transform 0.5s ease, opacity 0.5s ease;
79 | }
80 | }
81 |
82 | &__poster {
83 | flex: 1;
84 | position: relative;
85 |
86 | @include flex(center, center);
87 |
88 | img {
89 | width: 400px;
90 | border-radius: $border-radius;
91 | box-shadow: $box-shadow;
92 | transform: scale(0);
93 | transition: transform 0.7s ease;
94 | }
95 |
96 | @include tablet {
97 | display: none;
98 | }
99 | }
100 | }
101 |
102 | &.active > &__content > &__content__poster {
103 | img {
104 | transform: scale(1);
105 | }
106 | }
107 |
108 | &.active > &__content > &__content__info {
109 | .btns,
110 | .title,
111 | .overview {
112 | opacity: 1;
113 | transform: translateY(0);
114 | }
115 |
116 | .title {
117 | transition-delay: 0.3s, 0.3s;
118 | }
119 |
120 | .overview {
121 | transition-delay: 0.6s, 0.6s;
122 | }
123 |
124 | .btns {
125 | transition-delay: 0.9s, 0.9s;
126 | }
127 | }
128 | }
129 |
--------------------------------------------------------------------------------
/src/components/input/Input.jsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 |
3 | import "./input.scss";
4 |
5 | const Input = (props) => {
6 | return (
7 | props.onChange(e) : null}
12 | />
13 | );
14 | };
15 |
16 | export default Input;
17 |
--------------------------------------------------------------------------------
/src/components/input/input.scss:
--------------------------------------------------------------------------------
1 | @use "../../scss/variables" as *;
2 |
3 | input {
4 | border: 0;
5 | background-color: $black;
6 | padding: 0.5rem 1.5rem;
7 | font-size: 1rem;
8 | border-radius: $border-radius;
9 | color: $txt-color;
10 | font-family: $font-family;
11 | }
12 |
--------------------------------------------------------------------------------
/src/components/modal/Modal.jsx:
--------------------------------------------------------------------------------
1 | import React, { useEffect, useRef, useState } from "react";
2 | import PropTypes from "prop-types";
3 |
4 | import "./modal.scss";
5 |
6 | const Modal = (props) => {
7 | const [active, setActive] = useState(false);
8 |
9 | useEffect(() => {
10 | setActive(props.active);
11 | }, [props.active]);
12 |
13 | return (
14 |
15 | {props.children}
16 |
17 | );
18 | };
19 |
20 | Modal.propTypes = {
21 | active: PropTypes.bool,
22 | id: PropTypes.string,
23 | };
24 |
25 | export const ModalContent = (props) => {
26 | const contentRef = useRef(null);
27 |
28 | const closeModal = () => {
29 | contentRef.current.parentNode.classList.remove("active");
30 | if (props.onClose) props.onClose();
31 | };
32 |
33 | return (
34 |
35 | {props.children}
36 |
37 |
38 |
39 |
40 |
41 | );
42 | };
43 |
44 | ModalContent.propTypes = {
45 | onClose: PropTypes.func,
46 | };
47 |
48 | export default Modal;
49 |
--------------------------------------------------------------------------------
/src/components/modal/modal.scss:
--------------------------------------------------------------------------------
1 | @use "../../scss/" as *;
2 |
3 | .modal {
4 | @include flex(center, center);
5 | position: fixed;
6 | z-index: 100;
7 | top: 0;
8 | left: 0;
9 | right: 0;
10 | bottom: 0;
11 | overflow: auto;
12 | background-color: rgba($color: $black, $alpha: 0.4);
13 | opacity: 0;
14 | visibility: hidden;
15 |
16 | &.active {
17 | opacity: 1;
18 | visibility: visible;
19 | }
20 |
21 | &__content {
22 | padding: 2rem;
23 | background-color: $body-bg;
24 | width: 50%;
25 | opacity: 0;
26 | transform: translateY(-250px);
27 | transition: transform 0.6s ease, opacity 0.6s ease;
28 | position: relative;
29 |
30 | @include tablet {
31 | width: 80%;
32 | }
33 |
34 | &__close {
35 | position: absolute;
36 | right: 5px;
37 | top: 5px;
38 | font-size: 1.5rem;
39 | cursor: pointer;
40 |
41 | &:hover {
42 | color: $main-color;
43 | }
44 | }
45 | }
46 |
47 | &.active &__content {
48 | opacity: 1;
49 | transform: translateY(0);
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/src/components/movie-card/MovieCard.jsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 |
3 | import "./movie-card.scss";
4 |
5 | import { Link } from "react-router-dom";
6 |
7 | import Button from "../button/Button";
8 |
9 | import { category } from "../../api/tmdbApi";
10 | import apiConfig from "../../api/apiConfig";
11 | import * as Config from "./../../constants/Config";
12 |
13 | const MovieCard = (props) => {
14 | const item = props.item;
15 |
16 | const link =
17 | "/" + Config.HOME_PAGE + "/" + category[props.category] + "/" + item.id;
18 |
19 | const bg = apiConfig.w500Image(item.poster_path || item.backdrop_path);
20 |
21 | return (
22 |
23 |
24 |
27 |
28 | {item.title || item.name}
29 |
30 | );
31 | };
32 |
33 | export default MovieCard;
34 |
--------------------------------------------------------------------------------
/src/components/movie-card/movie-card.scss:
--------------------------------------------------------------------------------
1 | @use "../../scss/" as *;
2 |
3 | .movie-card {
4 | position: relative;
5 | background-position: top;
6 | background-repeat: no-repeat;
7 | background-size: cover;
8 | padding-top: 160%;
9 | border-radius: $border-radius;
10 | margin-bottom: 1rem;
11 |
12 | .btn {
13 | position: absolute;
14 | top: 50%;
15 | left: 50%;
16 | transform: translate(-50%, -50%) scale(0);
17 | transition: transform 0.3s ease, box-shadow 0.3s ease;
18 | }
19 |
20 | &:before {
21 | content: "";
22 | position: absolute;
23 | top: 0;
24 | left: 0;
25 | bottom: 0;
26 | right: 0;
27 | background-color: $black;
28 | opacity: 0;
29 | transition: opacity 0.3s ease;
30 | border-radius: $border-radius;
31 | }
32 |
33 | @media (hover: hover) and (pointer: fine) {
34 | &:hover:before {
35 | opacity: 0.8;
36 | }
37 |
38 | &:hover .btn {
39 | transform: translate(-50%, -50%) scale(1);
40 | }
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/components/movie-grid/MovieGrid.jsx:
--------------------------------------------------------------------------------
1 | import React, { useCallback, useEffect, useState } from "react";
2 |
3 | import "./movie-grid.scss";
4 |
5 | import { useHistory, useParams } from "react-router";
6 |
7 | import MovieCard from "./../movie-card/MovieCard";
8 |
9 | import tmdbApi, { category, movieType, tvType } from "../../api/tmdbApi";
10 | import Button, { OutlineButton } from "../button/Button";
11 | import Input from "../input/Input";
12 |
13 | import * as Config from "./../../constants/Config";
14 |
15 | const MovieGrid = (props) => {
16 | const [items, setItems] = useState([]);
17 |
18 | const [page, setPage] = useState(1);
19 | const [totalPage, setTotalPage] = useState(0);
20 |
21 | const { keyword } = useParams();
22 |
23 | useEffect(() => {
24 | const getList = async () => {
25 | let response = null;
26 |
27 | if (keyword === undefined) {
28 | const params = {};
29 | switch (props.category) {
30 | case category.movie:
31 | response = await tmdbApi.getMoviesList(movieType.upcoming, {
32 | params,
33 | });
34 | break;
35 | default:
36 | response = await tmdbApi.getTvList(tvType.popular, { params });
37 | }
38 | } else {
39 | const params = {
40 | query: keyword,
41 | };
42 | response = await tmdbApi.search(props.category, { params });
43 | }
44 | setItems(response.results);
45 | setTotalPage(response.total_pages);
46 | };
47 | getList();
48 | }, [keyword, props.category]);
49 |
50 | const loadMore = async () => {
51 | let response = null;
52 |
53 | if (keyword === undefined) {
54 | const params = {
55 | page: page + 1,
56 | };
57 | switch (props.category) {
58 | case category.movie:
59 | response = await tmdbApi.getMoviesList(movieType.upcoming, {
60 | params,
61 | });
62 | break;
63 | default:
64 | response = await tmdbApi.getTvList(tvType.popular, { params });
65 | }
66 | } else {
67 | const params = {
68 | page: page + 1,
69 | query: keyword,
70 | };
71 | response = await tmdbApi.search(props.category, { params });
72 | }
73 | setItems([...items, ...response.results]);
74 | setPage(page + 1);
75 | };
76 |
77 | return (
78 | <>
79 |
80 |
81 |
82 |
83 | {items.map((item, index) => (
84 |
85 | ))}
86 |
87 | {page < totalPage ? (
88 |
89 |
90 | Load more
91 |
92 |
93 | ) : (
94 | ""
95 | )}
96 | >
97 | );
98 | };
99 |
100 | const MovieSearch = (props) => {
101 | const history = useHistory();
102 |
103 | const [keyword, setKeyword] = useState(props.keyword ? props.keyword : "");
104 |
105 | const goToSearch = useCallback(() => {
106 | if (keyword.trim().length > 0) {
107 | history.push(
108 | `/${Config.HOME_PAGE}/${category[props.category]}/search/${keyword}`
109 | );
110 | }
111 | }, [keyword, props.category, history]);
112 |
113 | useEffect(() => {
114 | const enterEvent = (e) => {
115 | e.preventDefault();
116 | if (e.keyCode === 13) {
117 | goToSearch();
118 | }
119 | };
120 | document.addEventListener("keyup", enterEvent);
121 | return () => {
122 | document.removeEventListener("keyup", enterEvent);
123 | };
124 | }, [goToSearch]);
125 |
126 | return (
127 |
128 | setKeyword(e.target.value)}
133 | />
134 |
137 |
138 | );
139 | };
140 |
141 | export default MovieGrid;
142 |
--------------------------------------------------------------------------------
/src/components/movie-grid/movie-grid.scss:
--------------------------------------------------------------------------------
1 | @use "../../scss/" as *;
2 |
3 | .movie-grid {
4 | display: grid;
5 | grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
6 | gap: 20px;
7 | margin-bottom: 2rem;
8 |
9 | @include tablet {
10 | grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
11 | }
12 |
13 | &__loadmore {
14 | text-align: center;
15 | }
16 | }
17 |
18 | .movie-search {
19 | position: relative;
20 | width: 100%;
21 | max-width: 500px;
22 |
23 | input {
24 | width: 100%;
25 | padding-right: 8rem;
26 | }
27 |
28 | button {
29 | position: absolute;
30 | right: 0;
31 | top: 2px;
32 |
33 | @include mobile {
34 | right: 1px;
35 | top: 1px;
36 | }
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/components/movie-list/MovieList.jsx:
--------------------------------------------------------------------------------
1 | import React, { useEffect, useState } from "react";
2 | import PropTypes from "prop-types";
3 |
4 | import "./movie-list.scss";
5 |
6 | import { SwiperSlide, Swiper } from "swiper/react";
7 |
8 | import MovieCard from "../movie-card/MovieCard";
9 |
10 | import tmdbApi, { category } from "./../../api/tmdbApi";
11 |
12 | const MovieList = (props) => {
13 | const [items, setItems] = useState([]);
14 |
15 | useEffect(() => {
16 | const getList = async () => {
17 | let response = null;
18 | const params = {};
19 |
20 | if (props.type !== "similar") {
21 | switch (props.category) {
22 | case category.movie:
23 | response = await tmdbApi.getMoviesList(props.type, { params });
24 | break;
25 | default:
26 | response = await tmdbApi.getTvList(props.type, { params });
27 | }
28 | } else {
29 | response = await tmdbApi.similar(props.category, props.id);
30 | }
31 | setItems(response.results);
32 | };
33 | getList();
34 | }, [props.category, props.id, props.type]);
35 |
36 | return (
37 |
38 |
39 | {items.map((item, index) => (
40 |
41 |
42 |
43 | ))}
44 |
45 |
46 | );
47 | };
48 |
49 | MovieList.propTypes = {
50 | category: PropTypes.string.isRequired,
51 | type: PropTypes.string.isRequired,
52 | };
53 |
54 | export default MovieList;
55 |
--------------------------------------------------------------------------------
/src/components/movie-list/movie-list.scss:
--------------------------------------------------------------------------------
1 | @use "./../../scss/breakpoint" as *;
2 |
3 | .movie-list {
4 | .swiper-slide {
5 | width: 15%;
6 |
7 | @include tablet {
8 | width: 30%;
9 | }
10 |
11 | @include mobile {
12 | width: 40%;
13 | }
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/src/components/page-header/PageHeader.jsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 |
3 | import "./page-header.scss";
4 |
5 | import bg from "../../assets/footer-bg.jpg";
6 |
7 | const PageHeader = (props) => {
8 | return (
9 |
10 |
{props.children}
11 |
12 | );
13 | };
14 |
15 | export default PageHeader;
16 |
--------------------------------------------------------------------------------
/src/components/page-header/page-header.scss:
--------------------------------------------------------------------------------
1 | @use "../../scss/variables" as *;
2 |
3 | .page-header {
4 | padding: $header-height 0 2rem;
5 | text-align: center;
6 | margin-bottom: 2rem;
7 | position: relative;
8 | background-position: top;
9 | background-size: cover;
10 | background-repeat: no-repeat;
11 |
12 | h2 {
13 | position: relative;
14 | z-index: 99;
15 | }
16 |
17 | &:after {
18 | content: "";
19 | position: absolute;
20 | bottom: 0;
21 | left: 0;
22 | width: 100%;
23 | height: 100px;
24 | background-image: linear-gradient(to top, $body-bg, rgba($black, 0));
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/src/constants/Config.js:
--------------------------------------------------------------------------------
1 | export const HOME_PAGE = "react-movie-app";
2 |
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import ReactDOM from "react-dom";
3 | import App from "./App";
4 |
5 | ReactDOM.render(
6 |
7 |
8 | ,
9 | document.getElementById("root")
10 | );
11 |
--------------------------------------------------------------------------------
/src/pages/Catalog.jsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 |
3 | import { useParams } from "react-router";
4 | import MovieGrid from "../components/movie-grid/MovieGrid";
5 |
6 | import PageHeader from "../components/page-header/PageHeader";
7 |
8 | import { category as cate } from "./../api/tmdbApi";
9 |
10 | const Catalog = () => {
11 | const { category } = useParams();
12 |
13 | console.log(category);
14 |
15 | return (
16 | <>
17 |
18 | {category === cate.movie ? "Movies" : "TV Series"}
19 |
20 |
21 |
26 | >
27 | );
28 | };
29 |
30 | export default Catalog;
31 |
--------------------------------------------------------------------------------
/src/pages/Home.jsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { Link } from "react-router-dom";
3 |
4 | import { OutlineButton } from "../components/button/Button";
5 | import HeroSlide from "../components/hero-slide/HeroSlide";
6 | import MovieList from "../components/movie-list/MovieList";
7 |
8 | import { category, movieType, tvType } from "../api/tmdbApi";
9 |
10 | import * as Config from "./../constants/Config";
11 |
12 | const Home = () => {
13 | return (
14 | <>
15 |
16 |
17 |
18 |
19 |
20 |
Trending Movies
21 |
22 | View more
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
Top Rated Movies
31 |
32 | View more
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
Trending TV
41 |
42 | View more
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
Top Rated TV
51 |
52 | View more
53 |
54 |
55 |
56 |
57 |
58 | >
59 | );
60 | };
61 |
62 | export default Home;
63 |
--------------------------------------------------------------------------------
/src/pages/detail/CastList.jsx:
--------------------------------------------------------------------------------
1 | import React, { useEffect, useState } from "react";
2 |
3 | import { useParams } from "react-router";
4 |
5 | import tmdbApi from "../../api/tmdbApi";
6 | import apiConfig from "../../api/apiConfig";
7 |
8 | const CastList = (props) => {
9 | const { category } = useParams();
10 |
11 | const [casts, setCasts] = useState([]);
12 |
13 | useEffect(() => {
14 | const getCredits = async () => {
15 | const response = await tmdbApi.credits(category, props.id);
16 | setCasts(response.cast.slice(0, 5));
17 | };
18 | getCredits();
19 | }, [category, props.id]);
20 |
21 | return (
22 |
23 | {casts.map((cast, index) => (
24 |
25 |
31 |
{cast.name}
32 |
33 | ))}
34 |
35 | );
36 | };
37 |
38 | export default CastList;
39 |
--------------------------------------------------------------------------------
/src/pages/detail/Detail.jsx:
--------------------------------------------------------------------------------
1 | import React, { useEffect, useState } from "react";
2 | import { useParams } from "react-router";
3 |
4 | import tmdbApi from "./../../api/tmdbApi";
5 | import apiConfig from "../../api/apiConfig";
6 |
7 | import "./detail.scss";
8 | import CastList from "./CastList";
9 | import VideoList from "./VideoList";
10 | import MovieList from "./../../components/movie-list/MovieList";
11 |
12 | const Detail = () => {
13 | const { category, id } = useParams();
14 |
15 | const [item, setItem] = useState(null);
16 |
17 | useEffect(() => {
18 | const getDetail = async () => {
19 | const response = await tmdbApi.detail(category, id, { params: {} });
20 | setItem(response);
21 | window.scrollTo(0, 0);
22 | };
23 | getDetail();
24 | }, [category, id]);
25 |
26 | return (
27 | <>
28 | {item && (
29 | <>
30 |
38 |
39 |
40 |
50 |
51 |
52 |
{item.title || item.name}
53 |
54 | {item.genres &&
55 | item.genres.slice(0, 5).map((genre, index) => (
56 |
57 | {genre.name}
58 |
59 | ))}
60 |
61 |
{item.overview}
62 |
63 |
64 |
Casts
65 |
66 | {/* casts list */}
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
Similar
79 |
80 |
81 |
82 |
83 | >
84 | )}
85 | >
86 | );
87 | };
88 |
89 | export default Detail;
90 |
--------------------------------------------------------------------------------
/src/pages/detail/VideoList.jsx:
--------------------------------------------------------------------------------
1 | import React, { useEffect, useRef, useState } from "react";
2 |
3 | import { useParams } from "react-router";
4 |
5 | import tmdbApi from "../../api/tmdbApi";
6 |
7 | const VideoList = (props) => {
8 | const { category } = useParams();
9 |
10 | const [videos, setVideos] = useState([]);
11 |
12 | useEffect(() => {
13 | const getVideos = async () => {
14 | const response = await tmdbApi.getVideos(category, props.id);
15 | setVideos(response.results.slice(0, 5));
16 | };
17 | getVideos();
18 | }, [category, props.id]);
19 |
20 | return (
21 | <>
22 | {videos.map((item, index) => (
23 |
24 | ))}
25 | >
26 | );
27 | };
28 |
29 | const Video = (props) => {
30 | const item = props.item;
31 |
32 | const iframeRef = useRef(null);
33 |
34 | useEffect(() => {
35 | const height = (iframeRef.current.offsetWidth * 9) / 16 + "px";
36 | iframeRef.current.setAttribute("height", height);
37 | }, []);
38 |
39 | return (
40 |
41 |
42 |
{item.name}
43 |
44 |
50 |
51 | );
52 | };
53 |
54 | export default VideoList;
55 |
--------------------------------------------------------------------------------
/src/pages/detail/detail.scss:
--------------------------------------------------------------------------------
1 | @use "../../scss/" as *;
2 |
3 | .banner {
4 | height: 50vh;
5 | position: relative;
6 | background-position: center;
7 | background-size: cover;
8 | background-repeat: no-repeat;
9 |
10 | &:before {
11 | content: "";
12 | position: absolute;
13 | top: 0;
14 | left: 0;
15 | width: 100%;
16 | height: 100%;
17 |
18 | @include overlay();
19 | }
20 |
21 | &:after {
22 | content: "";
23 | position: absolute;
24 | bottom: 0;
25 | left: 0;
26 | width: 100%;
27 | height: 100px;
28 | background-image: linear-gradient(to top, $body-bg, rgba($black, 0));
29 | }
30 | }
31 |
32 | .movie-content {
33 | @include flex(flex-start, flex-start);
34 |
35 | max-width: 1260px;
36 | margin-left: auto;
37 | margin-right: auto;
38 | margin-top: -200px;
39 | position: relative;
40 | padding: 0 2rem;
41 |
42 | &__poster {
43 | flex: 1;
44 |
45 | @include mobile {
46 | display: none;
47 | }
48 |
49 | &__img {
50 | background-position: center;
51 | background-size: cover;
52 | background-repeat: no-repeat;
53 | border-radius: $border-radius;
54 | padding-top: 165%;
55 | }
56 | }
57 |
58 | &__info {
59 | width: 70%;
60 | padding-left: 2rem;
61 | position: relative;
62 |
63 | @include mobile {
64 | width: 100%;
65 | padding-left: 0;
66 | }
67 |
68 | & > * {
69 | margin-bottom: 2rem;
70 | }
71 |
72 | .title {
73 | font-size: 4rem;
74 | line-height: 1;
75 | }
76 |
77 | .genres {
78 | & > * ~ * {
79 | margin-left: 0.5rem;
80 | }
81 |
82 | &__item {
83 | padding: 0.5rem 1.5rem;
84 | border: 2px solid $white;
85 | border-radius: $border-radius;
86 | font-size: 0.8rem;
87 | font-weight: 600;
88 | background-color: $body-bg;
89 | }
90 | }
91 |
92 | .overview {
93 | letter-spacing: 0.5px;
94 | }
95 | }
96 | }
97 |
98 | .casts {
99 | display: grid;
100 | grid-template-columns: repeat(auto-fill, minmax(90px, 1fr));
101 | gap: 10px;
102 |
103 | &__item {
104 | &__img {
105 | padding-top: 160px;
106 | background-size: cover;
107 | margin-bottom: 0.5rem;
108 | }
109 |
110 | &__name {
111 | font-size: 0.8rem;
112 | }
113 | }
114 | }
115 |
116 | .video {
117 | margin-bottom: 3rem;
118 |
119 | &__title {
120 | margin-bottom: 1.5rem;
121 | }
122 | }
123 |
--------------------------------------------------------------------------------
/src/routes/Routes.jsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { Route, Switch } from "react-router-dom";
3 |
4 | import Home from "../pages/Home";
5 | import Catalog from "../pages/Catalog";
6 | import Detail from "../pages/detail/Detail";
7 |
8 | import * as Config from "../constants/Config";
9 |
10 | const Routes = () => {
11 | return (
12 |
13 |
17 |
18 |
19 |
20 |
21 | );
22 | };
23 |
24 | export default Routes;
25 |
--------------------------------------------------------------------------------
/src/scss/_breakpoint.scss:
--------------------------------------------------------------------------------
1 | @use "./variables" as *;
2 |
3 | @mixin mobile {
4 | @media only screen and (max-width: $mobile-width) {
5 | @content;
6 | }
7 | }
8 |
9 | @mixin tablet {
10 | @media only screen and (max-width: $tablet-width) {
11 | @content;
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/src/scss/_index.scss:
--------------------------------------------------------------------------------
1 | @forward "./variables";
2 | @forward "./mixin";
3 | @forward "./breakpoint";
4 |
--------------------------------------------------------------------------------
/src/scss/_mixin.scss:
--------------------------------------------------------------------------------
1 | @mixin flex($aligin-item, $justify-content) {
2 | display: flex;
3 | align-items: $aligin-item;
4 | justify-content: $justify-content;
5 | }
6 |
7 | @mixin overlay {
8 | background-color: rgba($color: #000000, $alpha: 0.6);
9 | }
10 |
--------------------------------------------------------------------------------
/src/scss/_variables.scss:
--------------------------------------------------------------------------------
1 | $body-bg: #0f0f0f;
2 | $main-color: #ff0000;
3 | $txt-color: #fff;
4 |
5 | $white: #fff;
6 | $black: #000;
7 |
8 | $box-shadow: rgba(100, 100, 111, 0.2) 0px 7px 29px 0px;
9 |
10 | $header-height: 8rem;
11 | $header-shrink-height: 5rem;
12 | $border-radius: 30px;
13 |
14 | $mobile-width: 600px;
15 | $tablet-width: 1024px;
16 |
17 | $font-family: "Montserrat", sans-serif;
18 |
--------------------------------------------------------------------------------