├── .github
├── CODEOWNERS
└── FUNDING.yml
├── public
├── robots.txt
├── favicon.ico
├── js-logo.png
├── 50daysofjavascript.png
├── 50-days-of-javascript.png
├── 50daysofjavascript_logo.png
├── star-3.svg
├── twitter-icon.svg
├── star-2.svg
├── star-btn.svg
├── star-1.svg
├── manifest.json
├── fork-btn.svg
├── moon.svg
├── cube.svg
├── index.html
└── bg-gradient-img-1.svg
├── src
├── setupTests.js
├── App.test.js
├── index.css
├── reportWebVitals.js
├── index.js
├── components
│ └── GitHubButtons
│ │ ├── GithubButtons.css
│ │ └── GitHubButtons.js
├── logo.svg
├── App.js
└── App.css
├── .gitignore
├── package.json
├── LICENSE
├── _config.yml
└── README.md
/.github/CODEOWNERS:
--------------------------------------------------------------------------------
1 | * @vinitshahdeo
2 |
--------------------------------------------------------------------------------
/public/robots.txt:
--------------------------------------------------------------------------------
1 | # https://www.robotstxt.org/robotstxt.html
2 | User-agent: *
3 | Disallow:
4 |
--------------------------------------------------------------------------------
/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vinitshahdeo/50DaysOfJavaScript/HEAD/public/favicon.ico
--------------------------------------------------------------------------------
/public/js-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vinitshahdeo/50DaysOfJavaScript/HEAD/public/js-logo.png
--------------------------------------------------------------------------------
/public/50daysofjavascript.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vinitshahdeo/50DaysOfJavaScript/HEAD/public/50daysofjavascript.png
--------------------------------------------------------------------------------
/public/50-days-of-javascript.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vinitshahdeo/50DaysOfJavaScript/HEAD/public/50-days-of-javascript.png
--------------------------------------------------------------------------------
/public/50daysofjavascript_logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vinitshahdeo/50DaysOfJavaScript/HEAD/public/50daysofjavascript_logo.png
--------------------------------------------------------------------------------
/src/setupTests.js:
--------------------------------------------------------------------------------
1 | // jest-dom adds custom jest matchers for asserting on DOM nodes.
2 | // allows you to do things like:
3 | // expect(element).toHaveTextContent(/react/i)
4 | // learn more: https://github.com/testing-library/jest-dom
5 | import '@testing-library/jest-dom';
6 |
--------------------------------------------------------------------------------
/src/App.test.js:
--------------------------------------------------------------------------------
1 | import { render, screen } from '@testing-library/react';
2 | import App from './App';
3 |
4 | test('renders learn react link', () => {
5 | render( );
6 | const linkElement = screen.getByText(/learn react/i);
7 | expect(linkElement).toBeInTheDocument();
8 | });
9 |
--------------------------------------------------------------------------------
/public/star-3.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/.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 |
--------------------------------------------------------------------------------
/public/twitter-icon.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/src/index.css:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0;
3 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
4 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
5 | sans-serif;
6 | -webkit-font-smoothing: antialiased;
7 | -moz-osx-font-smoothing: grayscale;
8 | }
9 |
10 | code {
11 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
12 | monospace;
13 | }
14 |
--------------------------------------------------------------------------------
/src/reportWebVitals.js:
--------------------------------------------------------------------------------
1 | const reportWebVitals = onPerfEntry => {
2 | if (onPerfEntry && onPerfEntry instanceof Function) {
3 | import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
4 | getCLS(onPerfEntry);
5 | getFID(onPerfEntry);
6 | getFCP(onPerfEntry);
7 | getLCP(onPerfEntry);
8 | getTTFB(onPerfEntry);
9 | });
10 | }
11 | };
12 |
13 | export default reportWebVitals;
14 |
--------------------------------------------------------------------------------
/public/star-2.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/public/star-btn.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/public/star-1.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom/client';
3 | import './index.css';
4 | import App from './App';
5 | import reportWebVitals from './reportWebVitals';
6 |
7 | const root = ReactDOM.createRoot(document.getElementById('root'));
8 |
9 | console.log('Code awesome shit with @vinitshahdeo & friends!');
10 |
11 | root.render(
12 |
13 |
14 |
15 | );
16 |
17 | // If you want to start measuring performance in your app, pass a function
18 | // to log results (for example: reportWebVitals(console.log))
19 | // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
20 | reportWebVitals();
21 |
--------------------------------------------------------------------------------
/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "50JS",
3 | "name": "50DaysOfJavaScript",
4 | "description": "Elevate JavaScript skills with daily coding challenges in a global, community-driven initiative.",
5 | "icons": [
6 | {
7 | "src": "favicon.ico",
8 | "sizes": "64x64 32x32 24x24 16x16",
9 | "type": "image/x-icon"
10 | },
11 | {
12 | "src": "js-logo.png",
13 | "type": "image/png",
14 | "sizes": "192x192"
15 | },
16 | {
17 | "src": "js-logo.png",
18 | "type": "image/png",
19 | "sizes": "512x512"
20 | }
21 | ],
22 | "start_url": "/",
23 | "display": "standalone",
24 | "scope": "/",
25 | "orientation": "portrait",
26 | "theme_color": "#933ffe",
27 | "background_color": "#0b0b0f"
28 | }
29 |
--------------------------------------------------------------------------------
/public/fork-btn.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | # These are supported funding model platforms
2 |
3 | github: [vinitshahdeo]
4 | patreon: # Replace with a single Patreon username
5 | open_collective: # Replace with a single Open Collective username
6 | ko_fi: # Replace with a single Ko-fi username
7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
9 | liberapay: # Replace with a single Liberapay username
10 | issuehunt: # Replace with a single IssueHunt username
11 | otechie: # Replace with a single Otechie username
12 | lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry
13 | custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
14 |
--------------------------------------------------------------------------------
/src/components/GitHubButtons/GithubButtons.css:
--------------------------------------------------------------------------------
1 | .github_buttons {
2 | margin-top: 2rem;
3 | font-size: 2rem;
4 | display: flex;
5 | justify-items: center;
6 | align-items: center;
7 | column-gap: 12px;
8 | }
9 |
10 | .github_buttons__link {
11 | display: flex;
12 | justify-items: center;
13 | align-items: center;
14 | column-gap: 6px;
15 |
16 | padding-top: 4px;
17 | padding-bottom: 4px;
18 | padding-left: 12px;
19 | padding-right: 12px;
20 |
21 | border-radius: 2.2rem;
22 | background: #1a1b23;
23 |
24 | text-decoration: none;
25 | }
26 |
27 | .github_buttons__icon {
28 | width: 20px;
29 | height: 20px;
30 | }
31 |
32 | .github_buttons__text {
33 | color: white;
34 | font-weight: bold;
35 | text-decoration: none;
36 | }
37 |
38 | @media only screen and (max-width: 720px) {
39 | .github_buttons {
40 | font-size: 1.8rem;
41 | }
42 |
43 | .github_buttons__icon {
44 | width: 18px;
45 | height: 18px;
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "50daysofjavascript",
3 | "version": "0.1.0",
4 | "private": true,
5 | "dependencies": {
6 | "@testing-library/jest-dom": "^5.16.5",
7 | "@testing-library/react": "^13.4.0",
8 | "@testing-library/user-event": "^13.5.0",
9 | "react": "^18.2.0",
10 | "react-dom": "^18.2.0",
11 | "react-scripts": "5.0.1",
12 | "web-vitals": "^2.1.4"
13 | },
14 | "author": {
15 | "name": "Vinit Shahdeo",
16 | "url": "https://github.com/vinitshahdeo"
17 | },
18 | "scripts": {
19 | "start": "react-scripts start",
20 | "build": "react-scripts build",
21 | "test": "react-scripts test",
22 | "eject": "react-scripts eject"
23 | },
24 | "eslintConfig": {
25 | "extends": [
26 | "react-app",
27 | "react-app/jest"
28 | ]
29 | },
30 | "browserslist": {
31 | "production": [
32 | ">0.2%",
33 | "not dead",
34 | "not op_mini all"
35 | ],
36 | "development": [
37 | "last 1 chrome version",
38 | "last 1 firefox version",
39 | "last 1 safari version"
40 | ]
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2023 Vinit Shahdeo
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/public/moon.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/src/components/GitHubButtons/GitHubButtons.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import "./GithubButtons.css";
3 |
4 | const settings = {
5 | namepsace: "vinitshahdeo",
6 | repo: "50DaysOfJavaScript",
7 | };
8 |
9 | function GitHubButtons() {
10 | const [forkCount, setForkCount] = React.useState();
11 | const [starCount, setStarCount] = React.useState();
12 |
13 | React.useEffect(() => {
14 | function getCount(data, type) {
15 | return data[`${type}_count`];
16 | }
17 | ajaxGet(getRequestUrl(), (response) => {
18 | setStarCount(getCount(response, "stargazers"));
19 | setForkCount(getCount(response, "forks"));
20 | });
21 | }, []);
22 |
23 | function getRequestUrl() {
24 | return `//api.github.com/repos/${settings.namepsace}/${settings.repo}`;
25 | }
26 | function getRepoStargazersUrl() {
27 | return `//github.com/${settings.namepsace}/${settings.repo}/stargazers`;
28 | }
29 | function getRepoForkUrl() {
30 | return `//github.com/${settings.namepsace}/${settings.repo}/fork`;
31 | }
32 |
33 | return (
34 |
58 | );
59 | }
60 |
61 | function ajaxGet(url, callback) {
62 | if (typeof XDomainRequest !== "undefined") {
63 | callback(null);
64 | return null;
65 | }
66 |
67 | const xhr = new XMLHttpRequest();
68 | xhr.onreadystatechange = () => {
69 | if (xhr.readyState === XMLHttpRequest.DONE && xhr.status === 200) {
70 | callback(JSON.parse(xhr.responseText));
71 | }
72 | };
73 | xhr.open("GET", url, true);
74 | xhr.send();
75 | return xhr;
76 | }
77 |
78 | export default GitHubButtons;
79 |
--------------------------------------------------------------------------------
/src/logo.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/_config.yml:
--------------------------------------------------------------------------------
1 | title: 50DaysOfJavaScript — Solve one question daily to ace your next interview!
2 | author:
3 | name: Vinit Shahdeo
4 | email: vinitshahdeo@gmail.com
5 |
6 | # The `>` after `description:` means to ignore line-breaks until next key.
7 | # If you want to omit the line-break after the end of text, use `>-` instead.
8 | description: >
9 | A community-driven open-source initiative by Vinit Shahdeo for elevating JavaScript skills through daily, practical coding challenges tailored to real-world tasks, led by a supportive global community of developers.
10 |
11 | # Build settings
12 |
13 | # If you clone the Minima repo and build locally, use this setting.
14 | theme: minima
15 |
16 | # As of November 2023, GitHub Pages still uses Minima 2.5.1 (https://pages.github.com/versions/).
17 | # If you want to use the latest Minima version on GitHub Pages, use the following setting and
18 | # add a line comment on "theme: minima" above.
19 | #remote_theme: jekyll/minima
20 |
21 | plugins:
22 | - jekyll-feed
23 | - jekyll-seo-tag
24 |
25 | # Theme-specific settings
26 |
27 | # If you want to link only specific pages in your header, use this and add the path to the pages
28 | # in order as they should show up.
29 | # header_pages:
30 | # - OLD_README.md
31 |
32 | # Set to `true` to show excerpts on the homepage.
33 | #show_excerpts: false
34 |
35 | # Minima specific settings, which are only available from Minima 3.0 onward.
36 | minima:
37 | # Minima skin selection.
38 | # Available skins are:
39 | # classic Default, light color scheme.
40 | # dark Dark variant of the classic skin.
41 | # auto Adaptive skin based on the default classic and dark skins.
42 | # solarized-light Light variant of solarized color scheme.
43 | # solarized-dark Dark variant of solarized color scheme.
44 | # solarized Adaptive skin for solarized color scheme skins.
45 | skin: solarized-dark
46 |
47 | # Minima date format.
48 | # The default value is "%b %d, %Y" (e.g. Nov 14, 2023)
49 | # Refer to https://shopify.github.io/liquid/filters/date/ if you want to customize this.
50 | #date_format: "%b-%d-%Y"
51 |
52 | # Generate social links in footer.
53 | social_links:
54 | # - { platform: devto, user_url: "https://dev.to/jekyll" }
55 | # - { platform: dribbble, user_url: "https://dribbble.com/jekyll" }
56 | # - { platform: facebook, user_url: "https://www.facebook.com/jekyll" }
57 | # - { platform: flickr, user_url: "https://www.flickr.com/photos/jekyll" }
58 | - { platform: github, user_url: "https://github.com/vinitshahdeo" }
59 | # - { platform: google_scholar, user_url: "https://scholar.google.com/citations?user=qc6CJjYAAAAJ" }
60 | - { platform: instagram, user_url: "https://www.instagram.com/vinitshahdeo" }
61 | # - { platform: keybase, user_url: "https://keybase.io/jekyll" }
62 | - { platform: linkedin, user_url: "https://www.linkedin.com/in/vinitshahdeo" }
63 | # - { platform: microdotblog, user_url: "https://micro.blog/jekyll" }
64 | # - { platform: pinterest, user_url: "https://www.pinterest.com/jekyll" }
65 | # - { platform: stackoverflow, user_url: "https://stackoverflow.com/users/1234567/jekyll" }
66 | # - { platform: telegram, user_url: "https://t.me/jekyll" }
67 | # - { platform: twitter, user_url: "https://twitter.com/jekyllrb" }
68 | - { platform: x, user_url: "https://x.com/vinit_shahdeo" }
69 | # - { platform: youtube, user_url: "https://www.youtube.com/jekyll" }
70 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
13 |
14 | Similar to the [Hactoberfest'21](https://vinitshahdeo.dev/hacktoberfest-2021) initiative, we're planning another community-led open-source initiative to help the community level up their JavaScript coding skills by solving a non-trivial problem daily. None of the questions will be tricks ━ you don’t have to worry about handling big integers or knowing how to balance a red-black tree. Every problem will be based on what you do daily as a JavaScript developer.
15 |
16 | [](https://50daysofjavascript.netlify.app/)
17 |
18 | [Join `#50DaysOfJavaScript`](https://tinyurl.com/50DaysOfJavaScript) ━ **Solve just a single coding challenge each day to improve your JavaScript skills!** This will tentatively start from **Jan 20, 2024**. Begin any day and stick for the next 50 days to complete the challenge. **More details to follow!** ✨
19 |
20 | **Learn more**: [50daysofjavascript.netlify.app](https://50daysofjavascript.netlify.app/)
21 |
22 | > [!NOTE]
23 | > This repository hosts the launch website of **`#50DaysOfJavaScript`** challenge which is currently deployed on [Netlify](https://50daysofjavascript.netlify.app/).
24 | > [](https://app.netlify.com/sites/50daysofjavascript/deploys)
25 |
26 | ## Quick links
27 |
28 | Calling out **participants**, **mentors**, and **communities** for an open-source initiative—join us to make a difference.
29 |
30 | - ***[🏄 Join as a participant](https://forms.gle/83ZKpF4S5VEqNG6P8)***
31 | - ***[🍿 Become a mentor](https://forms.gle/zGHWps1t7heYbcrP7)***
32 | - ***[🚀 Collaborate as a community](https://forms.gle/oQAFMDofBtjeawhp8)***
33 |
34 |
35 | ```javascript
36 | console.log('#50DaysOfJavaScript ━ Code awesome stuffs with @vinitshahdeo & friends!');
37 | ```
38 |
39 | ## Similar initiative
40 |
41 | A community-led initiative to help beginners get started with open-source during Hacktoberfest'21—[learn more](https://vinitshahdeo.dev/hacktoberfest-2021)!
42 |
43 | [](https://github.com/vinitshahdeo/Hacktoberfest2021)
44 |
45 | ## Local development
46 |
47 | ```terminal
48 | npm i
49 | npm start
50 | ```
51 |
52 | This is created using [create-react-app](https://legacy.reactjs.org/docs/create-a-new-react-app.html) and can be run locally in the development mode using the above commands. Open http://localhost:3000 to view it in your browser.
53 |
54 | ## Contributors
55 |
56 | - [@yashvi2001](https://github.com/yashvi2001)
57 | - [@vinitshahdeo](https://github.com/vinitshahdeo)
58 |
59 |
60 | ## Support
61 |
62 | Please help us spread the registration link among your connections—**[tinyurl.com/50DaysOfJavaScript](https://tinyurl.com/50DaysOfJavaScript)**. For any suggestions or feedback, please hit me up on [Twitter](https://twitter.com/Vinit_Shahdeo).
63 |
64 | [](https://50daysofjavascript.netlify.app/) [](https://twitter.com/Vinit_Shahdeo)
65 |
--------------------------------------------------------------------------------
/public/cube.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
--------------------------------------------------------------------------------
/src/App.js:
--------------------------------------------------------------------------------
1 | import "./App.css";
2 | import { useEffect, useMemo, useState } from "react";
3 | import GitHubButtons from "./components/GitHubButtons/GitHubButtons";
4 |
5 | const SECOND = 1000;
6 | const MINUTE = SECOND * 60;
7 | const HOUR = MINUTE * 60;
8 | const DAY = HOUR * 24;
9 |
10 | function App() {
11 | return (
12 | <>
13 |
14 |
15 |
#50DaysOfJavaScript
16 |
17 | A community-driven open-source initiative for elevating JavaScript
18 | skills through daily, practical coding challenges tailored to
19 | real-world tasks, led by a supportive global community of developers.
20 |
21 |
27 | Join Now
28 |
29 |
30 |
53 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
83 |
88 | >
89 | );
90 | }
91 | export const Timer = ({ deadline = new Date().toString() }) => {
92 | const parsedDeadline = useMemo(() => Date.parse(deadline), [deadline]);
93 | const [time, setTime] = useState(parsedDeadline - Date.now());
94 |
95 | useEffect(() => {
96 | const interval = setInterval(
97 | () => setTime(parsedDeadline - Date.now()),
98 | 1000
99 | );
100 |
101 | return () => clearInterval(interval);
102 | }, [parsedDeadline]);
103 |
104 | return (
105 |
106 | {Object.entries({
107 | Days: time / DAY,
108 | Hours: (time / HOUR) % 24,
109 | Minutes: (time / MINUTE) % 60,
110 | Seconds: (time / SECOND) % 60,
111 | }).map(([label, value]) => (
112 |
113 |
{`${Math.floor(value)}`.padStart(2, "0")}
114 |
{label}
115 |
116 | ))}
117 |
118 | );
119 | };
120 |
121 | export default App;
122 |
--------------------------------------------------------------------------------
/src/App.css:
--------------------------------------------------------------------------------
1 | @import url("https://fonts.googleapis.com/css2?family=DM+Sans:opsz,wght@9..40,400;9..40,500;9..40,600;9..40,700;9..40,800;9..40,900;9..40,1000&display=swap");
2 |
3 | :root {
4 | --primary: #fff;
5 | --secondary: #0b0b0f;
6 | }
7 |
8 | * {
9 | box-sizing: border-box;
10 | margin: 0;
11 | padding: 0;
12 | }
13 |
14 | html {
15 | font-size: 62.5%;
16 | }
17 |
18 | html,
19 | body {
20 | background: var(--secondary);
21 | color: var(--primary);
22 | font-family: "DM Sans", sans-serif;
23 | width: 100vw;
24 | overflow-x: hidden;
25 | position: relative;
26 | z-index: -1;
27 | }
28 |
29 | .container {
30 | padding: 1.6rem;
31 | height: 100vh;
32 | display: flex;
33 | flex-direction: column;
34 | align-items: center;
35 | }
36 |
37 | .title {
38 | margin-top: 4.2rem;
39 | text-align: center;
40 | font-size: 6.4rem;
41 | font-weight: 900;
42 | }
43 |
44 | .description {
45 | color: #898ca9;
46 | text-align: center;
47 | font-size: 2rem;
48 | font-weight: 400;
49 | line-height: 130%;
50 | margin-top: 2.2rem;
51 | max-width: 80rem;
52 | }
53 |
54 | .join-button:link,
55 | .join-button:visited {
56 | display: flex;
57 | justify-content: center;
58 | align-items: center;
59 | text-decoration: none;
60 |
61 | margin-top: 3.4rem;
62 | padding: 1.4rem 3.3rem;
63 | text-align: center;
64 | font-size: 2rem;
65 | font-weight: 600;
66 | cursor: pointer;
67 | transition: 0.5s;
68 |
69 | border-radius: 1rem;
70 | color: var(--primary);
71 | border: none;
72 | background: linear-gradient(245deg, #18c8ff 8.05%, #933ffe 86.9%);
73 | }
74 |
75 | .join-button:hover,
76 | .join-button:active {
77 | box-shadow: 0px 0px 10px 6px rgba(69, 149, 254, 0.286);
78 | }
79 |
80 | .timer {
81 | display: flex;
82 | align-items: center;
83 | justify-content: center;
84 | gap: 2.6rem;
85 | margin-top: 8.2rem;
86 | }
87 |
88 | .box {
89 | width: 20rem;
90 | height: 20rem;
91 | display: flex;
92 | align-items: center;
93 | justify-content: center;
94 | flex-direction: column;
95 | gap: 2.8rem;
96 | border-radius: 2.2rem;
97 | background: #1a1b23;
98 | }
99 |
100 | .timetext {
101 | color: #fff;
102 | text-align: center;
103 | font-size: 4.8rem;
104 | font-weight: 700;
105 | }
106 |
107 | .text {
108 | text-transform: uppercase;
109 | color: #b982ff;
110 | text-align: center;
111 | font-size: 2rem;
112 | font-weight: 500;
113 | }
114 |
115 | .buttons {
116 | display: flex;
117 | justify-content: space-evenly;
118 | align-items: center;
119 | gap: 3.6rem;
120 | margin-top: 10rem;
121 | }
122 |
123 | .btn {
124 | border-radius: 1rem;
125 | padding: 2rem;
126 | background-image: linear-gradient(
127 | to right,
128 | #982dec,
129 | #da8af8,
130 | #a9c4f3,
131 | #982dec
132 | );
133 | border: none;
134 | background-size: 200% auto;
135 | color: #fff;
136 | text-align: center;
137 | font-weight: 600;
138 | line-height: 130%;
139 | font-size: 2rem;
140 |
141 | transition: 0.5s;
142 | cursor: pointer;
143 |
144 | background-size: 300% 100%;
145 |
146 | -moz-transition: all 0.4s ease-in-out;
147 | -o-transition: all 0.4s ease-in-out;
148 | -webkit-transition: all 0.4s ease-in-out;
149 | transition: all 0.4s ease-in-out;
150 | }
151 |
152 | .btn:hover {
153 | background-position: 100% 0;
154 | -moz-transition: all 0.4s ease-in-out;
155 | -o-transition: all 0.4s ease-in-out;
156 | -webkit-transition: all 0.4s ease-in-out;
157 | transition: all 0.4s ease-in-out;
158 | }
159 |
160 | .btn:focus {
161 | outline: none;
162 | }
163 |
164 | .footer {
165 | margin-top: 10rem;
166 | display: flex;
167 | align-items: center;
168 | justify-content: center;
169 | gap: 1rem;
170 | }
171 |
172 | .footer p {
173 | color: #fff;
174 | text-align: center;
175 | font-size: 2rem;
176 | font-weight: 400;
177 | line-height: 130%;
178 | }
179 |
180 | .footer p a {
181 | display: inline-block;
182 | position: relative;
183 | text-decoration: none;
184 | color: inherit;
185 | margin: 0 var(--spacing, 0px);
186 | transition: margin 0.25s;
187 | }
188 |
189 | .footer p a svg {
190 | width: 76px;
191 | height: 40px;
192 | position: absolute;
193 | left: 50%;
194 | bottom: 0;
195 | transform: translate(-50%, 7px) translateZ(0);
196 | fill: none;
197 | stroke: var(--stroke, #bbc1e1);
198 | stroke-linecap: round;
199 | stroke-width: 2px;
200 | stroke-dasharray: var(--offset, 69px) 278px;
201 | stroke-dashoffset: 361px;
202 | transition: stroke 0.25s ease var(--stroke-delay, 0s), stroke-dasharray 0.35s;
203 | }
204 |
205 | .footer p a svg:hover {
206 | --spacing: 4px;
207 | --stroke: #7d41e7;
208 | --stroke-delay: 0.1s;
209 | --offset: 180px;
210 | }
211 |
212 | .moon,
213 | .cube,
214 | .star-1,
215 | .star-2,
216 | .star-3,
217 | .star-4,
218 | .star-5,
219 | .bg-gradient-img-1,
220 | .bg-gradient-img-2 {
221 | position: absolute;
222 | }
223 |
224 | .moon,
225 | .cube,
226 | .star-1,
227 | .star-2,
228 | .star-3,
229 | .star-4,
230 | .star-5 {
231 | z-index: -1;
232 | }
233 |
234 | .moon {
235 | top: 30%;
236 | left: 88%;
237 | }
238 |
239 | .cube {
240 | top: 65%;
241 | right: 87%;
242 | }
243 | .star-1,
244 | .star-2,
245 | .star-3,
246 | .star-4,
247 | .star-5 {
248 | animation-timing-function: ease-in-out;
249 | animation-iteration-count: infinite;
250 | animation-duration: 1.5s;
251 | }
252 |
253 | @keyframes scale-star {
254 | 0%,
255 | 100% {
256 | transform: scale(1);
257 | }
258 | 25% {
259 | transform: scale(1.8);
260 | }
261 | 50% {
262 | transform: scale(1);
263 | }
264 | }
265 |
266 | .star-1 {
267 | top: 20%;
268 | right: 85%;
269 | animation-name: scale-star;
270 | animation-delay: 1s;
271 | }
272 |
273 | .star-2 {
274 | top: 10%;
275 | left: 83%;
276 | animation-name: scale-star;
277 | animation-delay: 3s;
278 | }
279 |
280 | .star-3 {
281 | top: 90%;
282 | left: 88%;
283 | animation-name: scale-star;
284 | animation-delay: 5s;
285 | }
286 |
287 | .star-4 {
288 | top: 20%;
289 | left: 90%;
290 | animation-name: scale-star;
291 | animation-delay: 7s;
292 | }
293 |
294 | .star-5 {
295 | top: 30%;
296 | right: 92%;
297 | animation-name: scale-star;
298 | animation-delay: 9s;
299 | }
300 |
301 | .bg-gradient-img-1 {
302 | bottom: 0%;
303 | right: 0%;
304 | z-index: -2;
305 | }
306 |
307 | .bg-gradient-img-2 {
308 | top: 0%;
309 | left: 0%;
310 | z-index: -2;
311 | }
312 |
313 | @media only screen and (max-width: 924px) {
314 | .title {
315 | font-size: 5.2rem;
316 | }
317 |
318 | .description {
319 | font-size: 1.8rem;
320 | }
321 |
322 | .join-button {
323 | font-size: 1.8rem;
324 | }
325 |
326 | .timer {
327 | gap: 2rem;
328 | margin-top: 8.2rem;
329 | }
330 |
331 | .box {
332 | width: 16rem;
333 | height: 16rem;
334 | gap: 2.8rem;
335 | }
336 |
337 | .timetext {
338 | font-size: 3.6rem;
339 | }
340 |
341 | .text {
342 | font-size: 1.8rem;
343 | }
344 |
345 | .buttons {
346 | gap: 2rem;
347 | margin-top: 8rem;
348 | }
349 |
350 | .btn {
351 | font-size: 1.6rem;
352 | padding: 1.8rem;
353 | }
354 |
355 | .footer p {
356 | font-size: 1.6rem;
357 | font-weight: 400;
358 | }
359 |
360 | .footer p a svg {
361 | width: 62px;
362 | height: 40px;
363 | bottom: -10%;
364 | }
365 |
366 | .star-1,
367 | .star-2,
368 | .star-3,
369 | .star-4,
370 | .star-5 {
371 | display: none;
372 | }
373 |
374 | .moon {
375 | left: 83%;
376 | }
377 | }
378 |
379 | @media only screen and (max-width: 720px) {
380 | .title {
381 | font-size: 4.8rem;
382 | }
383 |
384 | .description {
385 | margin-left: 1.6rem;
386 | margin-right: 1.6rem;
387 | font-size: 1.6rem;
388 | }
389 |
390 | .join-button {
391 | font-size: 1.6rem;
392 | }
393 |
394 | .timer {
395 | gap: 1.6rem;
396 | }
397 |
398 | .box {
399 | width: 12rem;
400 | height: 12rem;
401 | gap: 1.6rem;
402 | }
403 |
404 | .timetext {
405 | font-size: 2.6rem;
406 | }
407 |
408 | .text {
409 | font-size: 1.4rem;
410 | }
411 |
412 | .buttons {
413 | flex-direction: column;
414 | gap: 1.8rem;
415 | margin-top: 6rem;
416 | width: fit-content;
417 | align-items: stretch;
418 | }
419 |
420 | .btn {
421 | width: 100%;
422 | }
423 | }
424 |
425 | @media only screen and (max-width: 548px) {
426 | .title {
427 | font-size: 3.2rem;
428 | }
429 |
430 | .box {
431 | width: 10rem;
432 | height: 10rem;
433 | gap: 1.2rem;
434 | }
435 |
436 | .timetext {
437 | font-size: 2rem;
438 | }
439 |
440 | .text {
441 | font-size: 1.2rem;
442 | }
443 |
444 | .buttons {
445 | gap: 1.6rem;
446 | }
447 |
448 | .btn {
449 | font-size: 1.6rem;
450 | padding: 1.6rem;
451 | }
452 |
453 | .star-3,
454 | .moon {
455 | display: none;
456 | }
457 |
458 | .footer {
459 | margin-top: 6rem;
460 | }
461 | }
462 |
463 | @media only screen and (max-width: 458px) {
464 | .timer {
465 | margin-top: 5.6rem;
466 | gap: 1rem;
467 | }
468 |
469 | .box {
470 | width: 9rem;
471 | height: 9rem;
472 | }
473 |
474 | .buttons {
475 | margin-top: 5.4rem;
476 | }
477 | }
478 |
--------------------------------------------------------------------------------
/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
12 |
13 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
28 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
44 |
45 |
49 |
50 |
51 |
55 |
56 |
57 |
58 |
62 |
63 |
72 | 50 Days Of JavaScript
73 |
254 |
255 |
256 | You need to enable JavaScript to run this app.
257 |
258 |
268 |
269 |
270 |
--------------------------------------------------------------------------------
/public/bg-gradient-img-1.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------