├── .gitignore ├── README.md ├── advertize ├── README.md └── text-animation-with-recording.js ├── axit-home-page ├── .gitignore ├── css │ ├── main.css │ ├── main.css.map │ ├── main.min.css │ ├── main.min.css.map │ └── main.prefixed.css ├── images │ ├── Logo.svg │ ├── about │ │ └── card-icons │ │ │ ├── keyboard.png │ │ │ ├── light-bulb.png │ │ │ ├── light-bulb.svg │ │ │ └── lightning.png │ ├── brand-bar │ │ ├── Social Media Icons.png │ │ └── Social Media Icons.svg │ ├── custom │ │ └── u25_state0.png │ ├── features │ │ ├── image_left_sub_list_u260.png │ │ ├── image_right_standard_u262.png │ │ ├── image_right_u255.png │ │ └── .svg │ ├── footer │ │ ├── social-media-icons.png │ │ └──       .svg │ ├── hero-section │ │ ├── Logo.png │ │ ├── Logo.svg │ │ └── background-image-large.png │ ├── pricing │ │ ├── $0.png │ │ ├── $0.svg │ │ ├── $19.png │ │ ├── $19.svg │ │ ├── $70.png │ │ └── $70.svg │ └── tesimonials │ │ ├── avatar_2_u231.png │ │ ├── u229.png │ │ └── u229.svg ├── index.html ├── js │ └── main.js ├── package-lock.json ├── package.json ├── postcss.config.js └── sass │ ├── main.scss │ └── partials │ ├── _base.scss │ ├── _components.scss │ ├── _mixins.scss │ ├── _variables.scss │ └── layout │ ├── _footer.scss │ ├── _header.scss │ └── sections │ ├── _about.scss │ ├── _brand-bar.scss │ ├── _contact-us.scss │ ├── _custom-section.scss │ ├── _features.scss │ ├── _hero.scss │ ├── _pricing.scss │ └── _testimonials.scss ├── dance-tour ├── .vscode │ └── settings.json ├── assets │ └── images │ │ ├── Facebook.svg │ │ ├── Instagram.svg │ │ ├── Twitter.svg │ │ ├── WhatsApp.svg │ │ ├── about-img-1.png │ │ ├── about-img-2.png │ │ ├── dance-card-1.png │ │ ├── dance-card-2.png │ │ ├── dance-card-3.png │ │ ├── hero.png │ │ ├── logo.svg │ │ ├── medal-img.svg │ │ └── quote-img.png ├── css │ ├── animations.css │ ├── base.css │ ├── components.css │ ├── layout.css │ ├── media-queries.css │ ├── sections │ │ ├── about.css │ │ ├── hero.css │ │ ├── product.css │ │ ├── promo.css │ │ ├── quote.css │ │ ├── statistics.css │ │ └── subscribe.css │ ├── utilties.css │ └── variables.css ├── index.html └── src │ └── script.js ├── dice-roll-simulator ├── index.html ├── index.js └── style.css ├── guess-my-number ├── .prettierrc ├── index.html ├── package.json ├── queries.css ├── script.js ├── style.css └── utils.js ├── modal ├── .prettierrc ├── index.html ├── queries.css ├── script.js └── style.css ├── pig-game ├── .prettierrc ├── dice-1.png ├── dice-2.png ├── dice-3.png ├── dice-4.png ├── dice-5.png ├── dice-6.png ├── index.html ├── queries.css ├── script.js └── style.css ├── space-invaders ├── app.js ├── img │ ├── ESA_root_pillars.jpg │ ├── cartoon-spaceship-illustration-vector.jpg │ ├── images.jpg │ └── istockphoto-1035676256-612x612.jpg ├── index.html ├── package.json ├── style.css └── util.js ├── space-shooter-game-new ├── background1.webp ├── enemy-fotor.png ├── first-aid-kit.png ├── heroShip.png ├── index.html ├── old-background-photo │ └── background1.jpg ├── script.js └── style.css ├── winters ├── .gitignore ├── css │ ├── fonts │ │ ├── linea-basic-10.eot │ │ ├── linea-basic-10.svg │ │ ├── linea-basic-10.ttf │ │ └── linea-basic-10.woff │ ├── icon-font.css │ ├── style.comp.css │ ├── style.concat.css │ ├── style.css │ └── style.prefix.css ├── img │ ├── book-small.webp │ ├── book.webp │ ├── favicon.png │ ├── heli-ski-large.webp │ ├── heli-ski-small.webp │ ├── hero-small.webp │ ├── hero.webp │ ├── ladySnowboarder-1-large.jpg │ ├── ladySnowboarder-1-small.jpg │ ├── logo-blue-1.png │ ├── logo-blue-small-1.png │ ├── logo-blue-small-2.png │ ├── logo-white.png │ ├── new-heli-large.webp │ ├── new-heli-small.webp │ ├── new-ninja-large.webp │ ├── new-ninja-small.webp │ ├── schtilthorn.webp │ ├── skier-large.jpg │ ├── skier-small.jpg │ ├── skiingman-new-small.webp │ ├── skiingman-new.webp │ ├── snowboarder-large.jpg │ ├── snowboarder-small.jpg │ ├── snowboarding-new-small.webp │ ├── snowboarding-new.webp │ ├── treck-large.webp │ ├── treck-small.webp │ ├── video-snow.mp4 │ └── video-snow.webm ├── index.html ├── js │ └── script.js ├── package-lock.json ├── package.json └── sass │ ├── abstracts │ ├── _functions.scss │ ├── _mixins.scss │ └── _variables.scss │ ├── base │ ├── _animations.scss │ ├── _base.scss │ ├── _typography.scss │ └── _utilities.scss │ ├── components │ ├── _bg-video.scss │ ├── _button.scss │ ├── _card.scss │ ├── _composition.scss │ ├── _feature-box.scss │ ├── _form.scss │ ├── _popup.scss │ └── _story.scss │ ├── layout │ ├── _footer.scss │ ├── _grid.scss │ ├── _header.scss │ └── _navigation.scss │ ├── main.scss │ └── pages │ └── _home.scss └── оmnifood ├── css ├── general.css ├── queries.css └── style.css ├── img ├── android-192.png ├── android-512.png ├── app │ ├── app-screen-1.png │ ├── app-screen-2.png │ └── app-screen-3.png ├── apple-touch-icon.png ├── customers │ ├── ben.jpg │ ├── customer-1.jpg │ ├── customer-2.jpg │ ├── customer-3.jpg │ ├── customer-4.jpg │ ├── customer-5.jpg │ ├── customer-6.jpg │ ├── dave.jpg │ ├── hannah.jpg │ └── steve.jpg ├── eating.jpg ├── favicon.png ├── favicon1.png ├── gallery │ ├── gallery-1.jpg │ ├── gallery-10.jpg │ ├── gallery-11.jpg │ ├── gallery-12.jpg │ ├── gallery-2.jpg │ ├── gallery-3.jpg │ ├── gallery-4.jpg │ ├── gallery-5.jpg │ ├── gallery-6.jpg │ ├── gallery-7.jpg │ ├── gallery-8.jpg │ └── gallery-9.jpg ├── hero-min.png ├── hero.png ├── hero.webp ├── logos │ ├── business-insider.png │ ├── forbes.png │ ├── techcrunch.png │ ├── the-new-york-times.png │ └── usa-today.png ├── meals │ ├── meal-1.jpg │ └── meal-2.jpg └── omnifood-logo.png ├── index.html ├── js └── script.js └── manifest.webmanifest /README.md: -------------------------------------------------------------------------------- 1 | # Simple Projects Portfolio 2 | 3 | Welcome to my repository where I collect simple projects that I have created to practice and develop my coding skills. Below you can find details and links to each project. 4 | 5 | ## Projects 6 | 7 | ### [Advertize](https://github.com/Nikolaj-Georgiev/simple-html-css-js-projects/tree/2e8da5c274c1d63c410e3d47f7d081d9041d5055/advertize) 8 | A script that replaces the current page content with an animated text display and records the animation into a downloadable video file. 9 | 10 | **Usage Instructions:** 11 | 1. Clone the repository and navigate to the `advertize` folder. 12 | 2. Include the script in your HTML file: 13 | ```html 14 | 15 | ``` 16 | 3. Alternatively, copy the script into the browser's developer tools console and run it. 17 | 4. The animation starts automatically, replacing the page content. 18 | 5. Use the stop button (`X`) to end the animation and download the video. 19 | 20 | **Tech Stack:** 21 | - Built with JavaScript and HTML5 Canvas API. 22 | 23 | ### [Roll Dice Simulator](https://dice-roll-sim.netlify.app) 24 | A simple dice roll simulator that generates random dice rolls with a click of a button. 25 | 26 | **Tech Stack:** 27 | - Built with HTML, CSS and JavaScript. 28 | 29 | ### [Pig Game](https://pig-game-gnikolay.netlify.app/) 30 | Pig Game is a two-player dice game where the goal is to score 100 points first. Players take turns rolling the dice, adding the rolled value to their current score, and can either hold to save their score or risk rolling again. Rolling a 1 resets the current score and ends the turn. Simple, fun, and strategic. 31 | 32 | **Tech Stack:** 33 | - Built with HTML, CSS and JavaScript. 34 | 35 | ### [Guess My Number](https://guess-my-number-gnikolay.netlify.app/) 36 | Guess My Number is a simple number-guessing game where the player tries to guess a randomly generated number between 1 and 20. The game provides feedback if the guess is too high or low. The player wins by guessing the correct number, with the goal of doing so in the fewest attempts possible. Fun and challenging! 37 | 38 | **Tech Stack:** 39 | - Built with HTML, CSS and JavaScript. 40 | 41 | ### [Modal](https://gnikolay-modal.netlify.app/) 42 | Modal is a project showcasing how to create and manage a popup modal window using HTML, CSS, and JavaScript. The modal appears when triggered (e.g., by a button) and can be closed by clicking a close button or outside the modal. 43 | 44 | **Tech Stack:** 45 | - Built with HTML, CSS and JavaScript. 46 | 47 | ### [Space Invaders](https://space-invaders-basic.netlify.app) 48 | A basic version of the classic Space Invaders game. 49 | 50 | **How to Play:** 51 | - The game starts automatically. 52 | - Use the left and right arrow keys on your keyboard to move the spaceship. 53 | - Press the space bar to shoot. 54 | - **Note:** The game is not optimized for mobile devices. 55 | 56 | ### [Space Invaders 2](https://space-invaders-gnikolay.netlify.app) 57 | An updated version of the Space Invaders game, designed to be played on any device. 58 | 59 | **Features:** 60 | - Slow auto-shoot functionality. 61 | - Additional shooting with the left mouse button or by touch on mobile devices. 62 | - Scoring is easier on smaller screens due to the increased number of enemies. 63 | 64 | **Known Issues:** 65 | - Some design flaws exist, but this is my first project using the canvas element. Despite the imperfections, I hope it's enjoyable! 66 | 67 | ### [Winters](https://winters-ngn.netlify.app) 68 | A home page designed for a winter tours company. 69 | 70 | **Tech Stack:** 71 | - Built using old school advanced CSS techniques with SCSS. 72 | 73 | ### [Omnifood](https://omnifood-ng.netlify.app) 74 | A home page for a food delivery company. 75 | 76 | **Tech Stack:** 77 | - Built with pure CSS and a few lines of JavaScript. 78 | 79 | ### [Dance Tour](https://dance-tour-nikolaj-georgiev.netlify.app/) 80 | A home page for a dance lesons company. 81 | 82 | **Tech Stack:** 83 | - Built with HTML, CSS and JavaScript. 84 | 85 | ### [Axit Home Page](https://axit-home-page-ng.netlify.app/) 86 | A home page for Axit company. 87 | 88 | **Tech Stack:** 89 | - Built with HTML, CSS, SCSS and JavaScript. 90 | 91 | ## Notes 92 | 93 | - All projects are hosted on Netlify for easy access. 94 | - Feedback and contributions are welcome! 95 | 96 | --- 97 | 98 | Thank you for taking the time to explore my projects. If you have any suggestions or improvements, feel free to reach out or submit an issue. 99 | -------------------------------------------------------------------------------- /advertize/README.md: -------------------------------------------------------------------------------- 1 | # Text Animation with Recording 2 | 3 | This project showcases an interactive JavaScript script that extracts visible text from a webpage, animates it on a canvas, and records the animation as a video file. 4 | 5 | ## Features 6 | 7 | - Extracts visible text dynamically from any webpage. 8 | - Animates text with smooth transitions (fade-in, display, fade-out). 9 | - Records the animation and saves it as a video file. 10 | - Fully responsive, resizing the canvas dynamically to fit the browser window. 11 | - Allows stopping the animation and recording at any time. 12 | 13 | ## How to Use 14 | 15 | ### Option 1: Using as a Standalone Script 16 | 17 | 1. Clone the repository or copy the script. 18 | 2. Include the script in your HTML file: 19 | 20 | ```html 21 | 22 | ``` 23 | 24 | 3. Open the HTML file in a browser. 25 | 4. The script will start automatically, displaying the animation. 26 | 5. Use the stop button (`X`) to end the animation and download the video. 27 | 28 | ### Option 2: Running in Browser Developer Tools 29 | 30 | 1. Copy the script into the browser's developer tools console. 31 | 2. Run the script. 32 | 3. The animation will start automatically, replacing the current content with a canvas overlay. 33 | 4. A stop button (`X`) is available to stop the animation and recording. 34 | 5. Once the animation completes or is stopped, a video file (`animation.webm` or another supported format) is automatically downloaded. 35 | 36 | ## How It Works 37 | 38 | 1. **Extracting Text:** 39 | 40 | - The script traverses the DOM using a `TreeWalker` to collect all visible text nodes, ignoring hidden or irrelevant elements (e.g., ` 18 | 19 | 20 | -------------------------------------------------------------------------------- /dice-roll-simulator/index.js: -------------------------------------------------------------------------------- 1 | const dice = document.getElementById('dice'); 2 | const rollHistory = document.getElementById('roll-history'); 3 | const button = document.getElementById('roll-button'); 4 | 5 | let historyList = []; 6 | const diceFaces = { 7 | '1': '⚀', 8 | '2': '⚁', 9 | '3': '⚂', 10 | '4': '⚃', 11 | '5': '⚄', 12 | '6': '⚅' 13 | } 14 | 15 | const getDiceFace = (number) => diceFaces[number]; 16 | const rollDice = () => { 17 | const rollResult = Math.floor(Math.random() * 6) + 1; 18 | const diceFace = getDiceFace(rollResult); 19 | dice.innerHTML = diceFace; 20 | historyList.push(rollResult); 21 | updateRollHistory(); 22 | } 23 | 24 | button.addEventListener('click', () => { 25 | dice.classList.add('roll-animation'); 26 | button.disabled = true; 27 | setTimeout(() => { 28 | dice.classList.remove('roll-animation'); 29 | rollDice(); 30 | button.disabled = false; 31 | }, 1000); 32 | 33 | }); 34 | 35 | function updateRollHistory() { 36 | rollHistory.innerHTML = ''; 37 | historyList.forEach((x, i) => { 38 | const li = document.createElement('li'); 39 | li.innerHTML = `Roll ${i + 1} ${getDiceFace(x)}`; 40 | rollHistory.appendChild(li); 41 | }) 42 | } -------------------------------------------------------------------------------- /dice-roll-simulator/style.css: -------------------------------------------------------------------------------- 1 | body { 2 | font-family: 'Open Sans', sans-serif; 3 | text-align: center; 4 | margin: 0; 5 | } 6 | 7 | h1{ 8 | font-size: 3rem; 9 | margin-top: 2rem; 10 | } 11 | 12 | .dice{ 13 | font-size: 7rem; 14 | margin: 5px; 15 | animation-duration: 1s; 16 | animation-fill-mode: forwards; 17 | 18 | } 19 | 20 | button{ 21 | background-color: #47a5c4; 22 | color: white; 23 | font-size: 1.5rem; 24 | padding: 1rem 2rem; 25 | border: none; 26 | border-radius: 1rem; 27 | cursor: pointer; 28 | transition: background-color .3s ease; 29 | 30 | } 31 | 32 | button:hover{ 33 | background-color: #2e8baf; 34 | } 35 | 36 | .roll-animation{ 37 | animation-name: roll; 38 | } 39 | 40 | @keyframes roll{ 41 | 0%{ 42 | transform: rotateY(0deg) rotateX(0deg); 43 | } 44 | 45 | 100%{ 46 | transform: rotateY(720deg) rotateX(720deg); 47 | } 48 | } 49 | 50 | ul{ 51 | list-style: none; 52 | padding: 0; 53 | max-width: 600px; 54 | margin: 2rem auto; 55 | 56 | } 57 | 58 | li{ 59 | font-size: 1.5rem; 60 | padding: .5rem; 61 | margin: .5rem; 62 | background-color: #f2f2f2; 63 | border-radius: .5rem; 64 | box-shadow: 0 2px 2px rgba(0, 0, 0, .3); 65 | display: flex; 66 | justify-content: space-between; 67 | align-items: center; 68 | padding-left: 1.5rem; 69 | } 70 | 71 | li span{ 72 | font-size: 3rem; 73 | margin-right: 1rem; 74 | } -------------------------------------------------------------------------------- /guess-my-number/.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "singleQuote": true, 3 | "arrowParens": "avoid" 4 | } 5 | -------------------------------------------------------------------------------- /guess-my-number/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | Guess My Number! 13 | 14 | 15 | 16 |
17 |

Guess My Number!

18 |

(Between 1 and 20)

19 | 20 |
?
21 |
22 |
23 |
24 | 25 | 26 |
27 |
28 |

Start guessing...

29 |

💯 Score: 20

30 |

31 | 🥇 Highscore: 0 32 |

33 |
34 |
35 | 36 | 37 | -------------------------------------------------------------------------------- /guess-my-number/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "guess-my-number", 3 | "version": "1.0.1", 4 | "description": "Number game", 5 | "main": "script.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "NG", 10 | "license": "MIT" 11 | } 12 | -------------------------------------------------------------------------------- /guess-my-number/queries.css: -------------------------------------------------------------------------------- 1 | @media (max-width: 34em) { 2 | html { 3 | font-size: 40%; 4 | } 5 | 6 | h1 { 7 | line-height: 1.6; 8 | } 9 | 10 | main { 11 | height: 55vh; 12 | flex-direction: column; 13 | } 14 | 15 | .guess { 16 | padding: 3rem; 17 | width: 20rem; 18 | text-align: center; 19 | display: block; 20 | margin-bottom: 3rem; 21 | margin-top: 15rem; 22 | } 23 | 24 | .right { 25 | margin-top: 5rem; 26 | width: 52rem; 27 | font-size: 2rem; 28 | display: flex; 29 | flex-direction: column; 30 | align-items: center; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /guess-my-number/script.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | import { bodyBackground, displayMessage, displayNumber, displayScore, displayTitle, numberWidth } from "./utils.js"; 4 | 5 | const highScore = document.querySelector('.highscore'); 6 | const guessField = document.querySelector('.guess'); 7 | 8 | let secretNumber = Math.trunc(Math.random() * 20) + 1; 9 | let highScoreCount = 0; 10 | let scoreCount = 20; //state variable; 11 | 12 | const gameOver = function () { 13 | scoreCount = 0; 14 | displayScore(scoreCount); 15 | displayMessage('💥 You lost the game!'); 16 | displayTitle('GAME OVER!'); 17 | bodyBackground('#682579'); 18 | displayNumber('💀'); 19 | }; 20 | 21 | document.querySelector('.check').addEventListener('click', function () { 22 | 23 | const guess = Number(guessField.value); 24 | 25 | // when there is no input 26 | if (!guess) { 27 | displayMessage('⛔ No number!'); 28 | 29 | // when player wins 30 | } else if (guess === secretNumber) { 31 | displayMessage('🎉 Correct Number!'); 32 | displayTitle('YOU WIN!'); 33 | bodyBackground('#60b347'); 34 | displayNumber(secretNumber); 35 | numberWidth('30rem'); 36 | if (scoreCount > highScoreCount) { 37 | highScoreCount = scoreCount; 38 | highScore.textContent = highScoreCount; 39 | displayNumber('🏆'); 40 | numberWidth('15rem'); 41 | } 42 | // highScoreCount = scoreCount > highScoreCount ? scoreCount : highScoreCount; 43 | // highScore.textContent = highScoreCount; 44 | 45 | // when player is wrong 46 | } else if (guess !== secretNumber) { 47 | if (scoreCount > 1) { 48 | displayMessage(guess > secretNumber ? '📈 Too high!' : '📉 Too low!'); 49 | scoreCount--; 50 | displayScore(scoreCount); 51 | } else { 52 | gameOver(); 53 | } 54 | } 55 | }); 56 | 57 | document.querySelector('.again').addEventListener('click', () => { 58 | bodyBackground('#222'); 59 | displayNumber('?'); 60 | scoreCount = 20; 61 | displayScore(scoreCount); 62 | secretNumber = Math.trunc(Math.random() * 20) + 1; 63 | guessField.value = ''; 64 | numberWidth('15rem'); 65 | displayMessage('Start guessing...'); 66 | displayTitle('Guess My Number!'); 67 | }); 68 | 69 | 70 | -------------------------------------------------------------------------------- /guess-my-number/style.css: -------------------------------------------------------------------------------- 1 | @import url('https://fonts.googleapis.com/css?family=Press+Start+2P&display=swap'); 2 | 3 | * { 4 | margin: 0; 5 | padding: 0; 6 | box-sizing: inherit; 7 | } 8 | 9 | html { 10 | font-size: 62.5%; 11 | box-sizing: border-box; 12 | } 13 | 14 | body { 15 | font-family: 'Press Start 2P', sans-serif; 16 | color: #eee; 17 | background-color: #222; 18 | /* background-color: #60b347; */ 19 | } 20 | 21 | /* LAYOUT */ 22 | header { 23 | position: relative; 24 | height: 35vh; 25 | border-bottom: 7px solid #eee; 26 | } 27 | 28 | main { 29 | height: 65vh; 30 | color: #eee; 31 | display: flex; 32 | align-items: center; 33 | justify-content: space-around; 34 | } 35 | 36 | .left { 37 | width: 52rem; 38 | display: flex; 39 | flex-direction: column; 40 | align-items: center; 41 | } 42 | 43 | .right { 44 | width: 52rem; 45 | font-size: 2rem; 46 | } 47 | 48 | /* ELEMENTS STYLE */ 49 | h1 { 50 | font-size: 4rem; 51 | text-align: center; 52 | position: absolute; 53 | width: 100%; 54 | top: 52%; 55 | left: 50%; 56 | transform: translate(-50%, -50%); 57 | } 58 | 59 | .number { 60 | background: #eee; 61 | color: #333; 62 | font-size: 6rem; 63 | width: 15rem; 64 | padding: 3rem 0rem; 65 | text-align: center; 66 | position: absolute; 67 | bottom: 0; 68 | left: 50%; 69 | transform: translate(-50%, 50%); 70 | } 71 | 72 | .between { 73 | font-size: 1.4rem; 74 | position: absolute; 75 | top: 2rem; 76 | right: 2rem; 77 | } 78 | 79 | .again { 80 | position: absolute; 81 | top: 2rem; 82 | left: 2rem; 83 | } 84 | 85 | .guess { 86 | background: none; 87 | border: 4px solid #eee; 88 | font-family: inherit; 89 | color: inherit; 90 | font-size: 5rem; 91 | padding: 2.5rem; 92 | width: 25rem; 93 | text-align: center; 94 | display: block; 95 | margin-bottom: 3rem; 96 | } 97 | 98 | .btn { 99 | border: none; 100 | background-color: #eee; 101 | color: #222; 102 | font-size: 2rem; 103 | font-family: inherit; 104 | padding: 2rem 3rem; 105 | cursor: pointer; 106 | } 107 | 108 | .btn:hover { 109 | background-color: #ccc; 110 | } 111 | 112 | .message { 113 | margin-bottom: 8rem; 114 | height: 3rem; 115 | } 116 | 117 | .label-score { 118 | margin-bottom: 2rem; 119 | } 120 | -------------------------------------------------------------------------------- /guess-my-number/utils.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | const message = document.querySelector('.message') 4 | const score = document.querySelector('.score'); 5 | const h1 = document.querySelector('h1'); 6 | const number = document.querySelector('.number'); 7 | const body = document.querySelector('body'); 8 | 9 | 10 | export const displayMessage = function (msg) { 11 | message.textContent = msg; 12 | }; 13 | 14 | export const displayTitle = function (titl) { 15 | h1.textContent = titl; 16 | }; 17 | 18 | export const displayNumber = function (n) { 19 | number.textContent = n; 20 | }; 21 | 22 | export const displayScore = function (scr) { 23 | score.textContent = scr; 24 | }; 25 | 26 | export const bodyBackground = function (color) { 27 | body.style.backgroundColor = color; 28 | }; 29 | 30 | export const numberWidth = (width) => { 31 | number.style.width = width; 32 | }; -------------------------------------------------------------------------------- /modal/.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "singleQuote": true, 3 | "arrowParens": "avoid" 4 | } 5 | -------------------------------------------------------------------------------- /modal/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | Modal window 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 31 | 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /modal/queries.css: -------------------------------------------------------------------------------- 1 | @media (max-width: 34em) { 2 | html { 3 | font-size: 40%; 4 | } 5 | 6 | h1 { 7 | line-height: 1.6; 8 | } 9 | 10 | body { 11 | flex-direction: column; 12 | align-items: center; 13 | justify-content: flex-start; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /modal/script.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const modal = document.querySelector('.modal'); 4 | const overlay = document.querySelector('.overlay'); 5 | const btnCloseModal = document.querySelector('.close-modal'); 6 | const btnsOpenModal = document.querySelectorAll('.show-modal'); 7 | 8 | const openModal = function () { 9 | console.log('Button logged'); 10 | modal.classList.remove('hidden'); 11 | overlay.classList.remove('hidden'); 12 | } 13 | 14 | const closeModal = function () { 15 | modal.classList.add('hidden'); 16 | overlay.classList.add('hidden'); 17 | }; 18 | 19 | for (let i = 0; i < btnsOpenModal.length; i++) { 20 | btnsOpenModal[i].addEventListener('click', openModal); 21 | } 22 | 23 | btnCloseModal.addEventListener('click', closeModal); 24 | overlay.addEventListener('click', closeModal); 25 | 26 | document.addEventListener('keydown', function (e) { 27 | if (e.key === 'Escape' && !modal.classList.contains('hidden')) { 28 | closeModal(); 29 | } 30 | }); -------------------------------------------------------------------------------- /modal/style.css: -------------------------------------------------------------------------------- 1 | * { 2 | margin: 0; 3 | padding: 0; 4 | box-sizing: inherit; 5 | } 6 | 7 | html { 8 | font-size: 62.5%; 9 | box-sizing: border-box; 10 | } 11 | 12 | body { 13 | font-family: sans-serif; 14 | color: #333; 15 | line-height: 1.5; 16 | height: 100vh; 17 | position: relative; 18 | display: flex; 19 | align-items: flex-start; 20 | justify-content: center; 21 | background: linear-gradient(to top left, #28b487, #7dd56f); 22 | } 23 | 24 | .show-modal { 25 | font-size: 2rem; 26 | font-weight: 600; 27 | padding: 1.75rem 3.5rem; 28 | margin: 5rem 2rem; 29 | border: none; 30 | background-color: #fff; 31 | color: #444; 32 | border-radius: 10rem; 33 | cursor: pointer; 34 | } 35 | 36 | .close-modal { 37 | position: absolute; 38 | top: 1.2rem; 39 | right: 2rem; 40 | font-size: 5rem; 41 | color: #333; 42 | cursor: pointer; 43 | border: none; 44 | background: none; 45 | } 46 | 47 | h1 { 48 | font-size: 2.5rem; 49 | margin-bottom: 2rem; 50 | } 51 | 52 | p { 53 | font-size: 1.8rem; 54 | } 55 | 56 | /* -------------------------- */ 57 | /* CLASSES TO MAKE MODAL WORK */ 58 | .hidden { 59 | display: none; 60 | } 61 | 62 | .modal { 63 | position: absolute; 64 | top: 50%; 65 | left: 50%; 66 | transform: translate(-50%, -50%); 67 | width: 70%; 68 | 69 | background-color: white; 70 | padding: 6rem; 71 | border-radius: 5px; 72 | box-shadow: 0 3rem 5rem rgba(0, 0, 0, 0.3); 73 | z-index: 10; 74 | } 75 | 76 | .overlay { 77 | position: absolute; 78 | top: 0; 79 | left: 0; 80 | width: 100%; 81 | height: 100%; 82 | background-color: rgba(0, 0, 0, 0.6); 83 | backdrop-filter: blur(3px); 84 | z-index: 5; 85 | } 86 | -------------------------------------------------------------------------------- /pig-game/.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "singleQuote": true, 3 | "arrowParens": "avoid" 4 | } 5 | -------------------------------------------------------------------------------- /pig-game/dice-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nikolaj-Georgiev/simple-html-css-js-projects/92bf9e534a3f354b5cf16b4f66fed3e9ffb13f50/pig-game/dice-1.png -------------------------------------------------------------------------------- /pig-game/dice-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nikolaj-Georgiev/simple-html-css-js-projects/92bf9e534a3f354b5cf16b4f66fed3e9ffb13f50/pig-game/dice-2.png -------------------------------------------------------------------------------- /pig-game/dice-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nikolaj-Georgiev/simple-html-css-js-projects/92bf9e534a3f354b5cf16b4f66fed3e9ffb13f50/pig-game/dice-3.png -------------------------------------------------------------------------------- /pig-game/dice-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nikolaj-Georgiev/simple-html-css-js-projects/92bf9e534a3f354b5cf16b4f66fed3e9ffb13f50/pig-game/dice-4.png -------------------------------------------------------------------------------- /pig-game/dice-5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nikolaj-Georgiev/simple-html-css-js-projects/92bf9e534a3f354b5cf16b4f66fed3e9ffb13f50/pig-game/dice-5.png -------------------------------------------------------------------------------- /pig-game/dice-6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nikolaj-Georgiev/simple-html-css-js-projects/92bf9e534a3f354b5cf16b4f66fed3e9ffb13f50/pig-game/dice-6.png -------------------------------------------------------------------------------- /pig-game/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 10 | 11 | 12 | Pig Game 13 | 14 | 15 | 16 |
17 |
18 |

Player 1

19 |

43

20 |
21 |

Current

22 |

0

23 |
24 |
25 |
26 |

Player 2

27 |

24

28 |
29 |

Current

30 |

0

31 |
32 |
33 | 34 | Playing dice 35 | 36 | 37 | 38 |
39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /pig-game/queries.css: -------------------------------------------------------------------------------- 1 | @media (max-width: 65em) { 2 | html { 3 | font-size: 50%; 4 | } 5 | 6 | main { 7 | max-width: 80rem; 8 | max-height: 50rem; 9 | } 10 | 11 | .player { 12 | padding: 7rem; 13 | } 14 | 15 | .btn { 16 | font-size: 1.4rem; 17 | padding-bottom: 1.2rem; 18 | } 19 | 20 | .btn--new { 21 | top: 2rem; 22 | } 23 | 24 | .btn--roll { 25 | top: 36rem; 26 | } 27 | .btn--hold { 28 | top: 42.5rem; 29 | } 30 | } 31 | 32 | @media (max-width: 38em) { 33 | html { 34 | font-size: 43.75%; 35 | } 36 | 37 | .grid { 38 | display: grid; 39 | row-gap: 9.6rem; 40 | /* column-gap: 6.4rem; */ 41 | } 42 | 43 | .grid--2-cols { 44 | grid-template-columns: repeat(2, 1fr); 45 | } 46 | 47 | .player { 48 | flex: 50%; 49 | padding: 4rem 2rem 4rem; 50 | } 51 | 52 | .name { 53 | font-size: 2rem; 54 | font-weight: 400; 55 | } 56 | 57 | #name--0 { 58 | align-self: start; 59 | margin-left: 4rem; 60 | } 61 | 62 | #name--1 { 63 | align-self: end; 64 | margin-right: 4rem; 65 | } 66 | 67 | .player--0 .current { 68 | width: 50%; 69 | padding: 2rem; 70 | align-self: start; 71 | margin-left: 4rem; 72 | } 73 | .player--1 .current { 74 | width: 50%; 75 | padding: 2rem; 76 | align-self: end; 77 | margin-right: 4rem; 78 | } 79 | 80 | .current-label { 81 | font-size: 1.6rem; 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /pig-game/script.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | // selecting elements 4 | const player0El = document.querySelector('.player--0'); 5 | const player1El = document.querySelector('.player--1'); 6 | const score0El = document.querySelector('#score--0'); 7 | const score1El = document.getElementById('score--1'); 8 | const current0El = document.getElementById('current--0'); 9 | const current1El = document.getElementById('current--1'); 10 | 11 | const diceEl = document.querySelector('.dice'); 12 | const btnNew = document.querySelector('.btn--new'); 13 | const btnRoll = document.querySelector('.btn--roll'); 14 | const btnHold = document.querySelector('.btn--hold'); 15 | 16 | let scores, currentScore, activePlayer, playing; 17 | 18 | // starting conditions 19 | const init = function () { 20 | scores = [0, 0]; 21 | currentScore = 0; 22 | activePlayer = 0; 23 | playing = true; 24 | 25 | score0El.textContent = 0; 26 | score1El.textContent = 0; 27 | current0El.textContent = 0; 28 | current1El.textContent = 0; 29 | player0El.classList.remove('player--winner'); 30 | player1El.classList.remove('player--winner'); 31 | player0El.classList.add('player--active'); 32 | player1El.classList.remove('player--winner'); 33 | diceEl.classList.add('hidden'); 34 | }; 35 | init(); 36 | 37 | const switchPlayer = function () { 38 | document.getElementById(`current--${activePlayer}`).textContent = 0; 39 | activePlayer = activePlayer === 0 ? 1 : 0; 40 | currentScore = 0; 41 | player0El.classList.toggle('player--active'); 42 | player1El.classList.toggle('player--active'); 43 | }; 44 | 45 | // Rolling dice functionality 46 | 47 | btnRoll.addEventListener('click', function () { 48 | if (playing) { 49 | 50 | //1. Generating random dice roll 51 | const dice = Math.trunc(Math.random() * 6) + 1; 52 | 53 | // 2. Display dice 54 | diceEl.classList.remove('hidden'); 55 | diceEl.src = `dice-${dice}.png`; 56 | 57 | // 3. Check for roll 1: if true, switch to nex player 58 | if (dice !== 1) { 59 | // Add dice to the currentScore 60 | currentScore += dice; 61 | document.getElementById(`current--${activePlayer}`).textContent = currentScore 62 | } else { 63 | // Switch to next player 64 | switchPlayer(); 65 | } 66 | } 67 | }); 68 | 69 | btnHold.addEventListener('click', () => { 70 | if (playing) { 71 | 72 | // 1. Add current score to active player score 73 | scores[activePlayer] += currentScore; 74 | document.getElementById(`score--${activePlayer}`).textContent = scores[activePlayer]; 75 | 76 | // 2. Check if player's score is >=100; 77 | if (scores[activePlayer] >= 100) { 78 | playing = false; 79 | // finish the game 80 | document.querySelector(`.player--${activePlayer}`).classList.add('player--winner'); 81 | document.querySelector(`.player--${activePlayer}`).classList.remove('player--active'); 82 | diceEl.classList.add('hidden'); 83 | 84 | } else { 85 | // Switch to the next player 86 | switchPlayer(); 87 | } 88 | } 89 | }); 90 | 91 | btnNew.addEventListener('click', init); -------------------------------------------------------------------------------- /pig-game/style.css: -------------------------------------------------------------------------------- 1 | @import url('https://fonts.googleapis.com/css2?family=Nunito&display=swap'); 2 | 3 | * { 4 | margin: 0; 5 | padding: 0; 6 | box-sizing: inherit; 7 | } 8 | 9 | html { 10 | font-size: 62.5%; 11 | box-sizing: border-box; 12 | } 13 | 14 | body { 15 | font-family: 'Nunito', sans-serif; 16 | font-weight: 400; 17 | height: 100vh; 18 | color: #333; 19 | background-image: linear-gradient(to top left, #753682 0%, #bf2e34 100%); 20 | display: flex; 21 | align-items: center; 22 | justify-content: center; 23 | } 24 | 25 | /* LAYOUT */ 26 | main { 27 | position: relative; 28 | width: 100rem; 29 | height: 60rem; 30 | background-color: rgba(255, 255, 255, 0.35); 31 | backdrop-filter: blur(200px); 32 | filter: blur(); 33 | box-shadow: 0 3rem 5rem rgba(0, 0, 0, 0.25); 34 | border-radius: 9px; 35 | overflow: hidden; 36 | display: flex; 37 | } 38 | 39 | .player { 40 | flex: 50%; 41 | padding: 9rem; 42 | display: flex; 43 | flex-direction: column; 44 | align-items: center; 45 | transition: all 0.75s; 46 | } 47 | 48 | /* ELEMENTS */ 49 | .name { 50 | position: relative; 51 | font-size: 4rem; 52 | text-transform: uppercase; 53 | letter-spacing: 1px; 54 | word-spacing: 2px; 55 | font-weight: 300; 56 | margin-bottom: 1rem; 57 | } 58 | 59 | .score { 60 | font-size: 8rem; 61 | font-weight: 300; 62 | color: #c7365f; 63 | margin-bottom: auto; 64 | } 65 | 66 | .player--active { 67 | background-color: rgba(255, 255, 255, 0.4); 68 | } 69 | .player--active .name { 70 | font-weight: 700; 71 | } 72 | .player--active .score { 73 | font-weight: 400; 74 | } 75 | 76 | .player--active .current { 77 | opacity: 1; 78 | } 79 | 80 | .current { 81 | background-color: #c7365f; 82 | opacity: 0.8; 83 | border-radius: 9px; 84 | color: #fff; 85 | width: 65%; 86 | padding: 2rem; 87 | text-align: center; 88 | transition: all 0.75s; 89 | } 90 | 91 | .current-label { 92 | text-transform: uppercase; 93 | margin-bottom: 1rem; 94 | font-size: 1.7rem; 95 | color: #ddd; 96 | } 97 | 98 | .current-score { 99 | font-size: 3.5rem; 100 | } 101 | 102 | /* ABSOLUTE POSITIONED ELEMENTS */ 103 | .btn { 104 | position: absolute; 105 | left: 50%; 106 | transform: translateX(-50%); 107 | color: #444; 108 | background: none; 109 | border: none; 110 | font-family: inherit; 111 | font-size: 1.8rem; 112 | text-transform: uppercase; 113 | cursor: pointer; 114 | font-weight: 400; 115 | transition: all 0.2s; 116 | 117 | background-color: white; 118 | background-color: rgba(255, 255, 255, 0.6); 119 | backdrop-filter: blur(10px); 120 | 121 | padding: 0.7rem 2.5rem; 122 | border-radius: 50rem; 123 | box-shadow: 0 1.75rem 3.5rem rgba(0, 0, 0, 0.1); 124 | } 125 | 126 | .btn::first-letter { 127 | font-size: 2.4rem; 128 | display: inline-block; 129 | margin-right: 0.7rem; 130 | } 131 | 132 | .btn--new { 133 | top: 4rem; 134 | } 135 | .btn--roll { 136 | top: 39.3rem; 137 | } 138 | .btn--hold { 139 | top: 46.1rem; 140 | } 141 | 142 | .btn:active { 143 | transform: translate(-50%, 3px); 144 | box-shadow: 0 1rem 2rem rgba(0, 0, 0, 0.15); 145 | } 146 | 147 | .btn:focus { 148 | outline: none; 149 | } 150 | 151 | .dice { 152 | position: absolute; 153 | left: 50%; 154 | top: 16.5rem; 155 | transform: translateX(-50%); 156 | height: 10rem; 157 | box-shadow: 0 2rem 5rem rgba(0, 0, 0, 0.2); 158 | } 159 | 160 | .player--winner { 161 | background-color: #2f2f2f; 162 | } 163 | 164 | .player--winner .name { 165 | font-weight: 700; 166 | color: #c7365f; 167 | } 168 | 169 | .hidden { 170 | display: none; 171 | } 172 | -------------------------------------------------------------------------------- /space-invaders/app.js: -------------------------------------------------------------------------------- 1 | import { draw, remove } from "./util.js"; 2 | const btn = document.querySelector('.start') 3 | btn.addEventListener('click', () => location.reload()); 4 | btn.disabled = true; 5 | const grid = document.querySelector('.grid'); 6 | const resultsDisplay = document.querySelector('.results'); 7 | let currentShooterIndex = 587; 8 | let width = 25; 9 | let invadersId; 10 | let direction = 1; 11 | let goingRight = true; 12 | export let aliensRemoved = []; 13 | let result = 0; 14 | 15 | for (let i = 0; i < 625; i++) { 16 | const square = document.createElement('div'); 17 | grid.appendChild(square); 18 | } 19 | 20 | export const squares = [...document.querySelectorAll('.grid div')]; 21 | 22 | export const alienInvaders = [ 23 | 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 24 | 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 25 | 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 26 | 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89 27 | ]; 28 | 29 | 30 | draw(); 31 | 32 | 33 | squares[currentShooterIndex].classList.add('shooter'); 34 | 35 | 36 | function moveShooter(e) { 37 | 38 | squares[currentShooterIndex].classList.remove('shooter'); 39 | e.key === 'ArrowLeft' ? (currentShooterIndex % width !== 0 ? currentShooterIndex -= 1 : null) : null; 40 | e.key === 'ArrowRight' ? (currentShooterIndex % width < width - 1 ? currentShooterIndex += 1 : null) : null; 41 | squares[currentShooterIndex].classList.add('shooter'); 42 | } 43 | 44 | document.addEventListener('keydown', moveShooter) 45 | 46 | function moveInvaders() { 47 | btn.disabled = true; 48 | const leftEdge = alienInvaders[0] % width === 0; 49 | const rightEdge = alienInvaders[alienInvaders.length - 1] % width === width - 1; 50 | remove() 51 | 52 | if (rightEdge && goingRight) { 53 | for (let i = 0; i < alienInvaders.length; i++) { 54 | alienInvaders[i] += width + 1; 55 | direction = -1; 56 | goingRight = false; 57 | } 58 | } 59 | 60 | if (leftEdge && !goingRight) { 61 | for (let i = 0; i < alienInvaders.length; i++) { 62 | alienInvaders[i] += width - 1; 63 | direction = 1; 64 | goingRight = true; 65 | 66 | } 67 | } 68 | 69 | for (let i = 0; i < alienInvaders.length; i++) { 70 | alienInvaders[i] += direction; 71 | } 72 | draw(); 73 | 74 | if (squares[currentShooterIndex].classList.contains('invader', 'shooter')) { 75 | resultsDisplay.innerHTML = 'Game Over'; 76 | clearInterval(invadersId); 77 | btn.disabled = false; 78 | } 79 | 80 | for (let i = 0; i < alienInvaders.length; i++) { 81 | if (alienInvaders[i] > squares.length - width) { 82 | resultsDisplay.innerHTML = 'Game Over'; 83 | clearInterval(invadersId); 84 | btn.disabled = false; 85 | } 86 | } 87 | if (aliensRemoved.length === alienInvaders.length) { 88 | resultsDisplay.innerHTML = 'You Win!'; 89 | clearInterval(invadersId); 90 | btn.disabled = false; 91 | } 92 | } 93 | 94 | invadersId = setInterval(moveInvaders, 150); 95 | 96 | function shoot(e) { 97 | 98 | let laserId; 99 | let currentLaserIndex = currentShooterIndex; 100 | function moveLaser() { 101 | squares[currentLaserIndex].classList.remove('laser'); 102 | if (currentLaserIndex > width - 1) { 103 | currentLaserIndex -= width; 104 | 105 | squares[currentLaserIndex].classList.add('laser'); 106 | 107 | if (squares[currentLaserIndex].classList.contains('invader')) { 108 | squares[currentLaserIndex].classList.remove('laser'); 109 | squares[currentLaserIndex].classList.remove('invader'); 110 | squares[currentLaserIndex].classList.add('boom'); 111 | 112 | setTimeout(() => squares[currentLaserIndex].classList.remove('boom'), 100); 113 | clearInterval(laserId); 114 | const alienRemoved = alienInvaders.indexOf(currentLaserIndex); 115 | result++; 116 | resultsDisplay.innerHTML = result; 117 | aliensRemoved.push(alienRemoved); 118 | } 119 | 120 | 121 | 122 | } 123 | } 124 | 125 | e.key === ' ' ? laserId = setInterval(moveLaser, 100) : null; 126 | } 127 | 128 | document.addEventListener('keydown', shoot); -------------------------------------------------------------------------------- /space-invaders/img/ESA_root_pillars.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nikolaj-Georgiev/simple-html-css-js-projects/92bf9e534a3f354b5cf16b4f66fed3e9ffb13f50/space-invaders/img/ESA_root_pillars.jpg -------------------------------------------------------------------------------- /space-invaders/img/cartoon-spaceship-illustration-vector.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nikolaj-Georgiev/simple-html-css-js-projects/92bf9e534a3f354b5cf16b4f66fed3e9ffb13f50/space-invaders/img/cartoon-spaceship-illustration-vector.jpg -------------------------------------------------------------------------------- /space-invaders/img/images.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nikolaj-Georgiev/simple-html-css-js-projects/92bf9e534a3f354b5cf16b4f66fed3e9ffb13f50/space-invaders/img/images.jpg -------------------------------------------------------------------------------- /space-invaders/img/istockphoto-1035676256-612x612.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nikolaj-Georgiev/simple-html-css-js-projects/92bf9e534a3f354b5cf16b4f66fed3e9ffb13f50/space-invaders/img/istockphoto-1035676256-612x612.jpg -------------------------------------------------------------------------------- /space-invaders/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Space Invaders 9 | 10 | 11 | 12 | 13 | 14 | 15 |

0

16 |
17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /space-invaders/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "space-invaders", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "app.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC" 12 | } 13 | -------------------------------------------------------------------------------- /space-invaders/style.css: -------------------------------------------------------------------------------- 1 | body { 2 | font-family: 'Open Sans', sans-serif; 3 | text-align: center; 4 | margin: 0; 5 | background-image: url('./img/ESA_root_pillars.jpg'); 6 | background-size:cover; 7 | background-origin:border-box; 8 | background-repeat: no-repeat; 9 | } 10 | 11 | .grid { 12 | margin:auto; 13 | width: 500px; 14 | height: 500px; 15 | border: solid black 1px; 16 | display: flex; 17 | flex-wrap: wrap; 18 | } 19 | 20 | .grid div { 21 | width: 20px; 22 | height: 20px; 23 | 24 | } 25 | 26 | .invader { 27 | background-image: url('./img/images.jpg'); 28 | border-radius: 10px; 29 | background-size:cover; 30 | background-origin:border-box; 31 | background-repeat: no-repeat; 32 | } 33 | 34 | .shooter { 35 | background-image: url('./img/cartoon-spaceship-illustration-vector.jpg'); 36 | border-radius: 10px; 37 | background-size:cover; 38 | background-origin:border-box; 39 | background-repeat: no-repeat; 40 | } 41 | 42 | .laser { 43 | background-color: orange; 44 | border-radius: 50px; 45 | } 46 | 47 | .boom { 48 | background-color: red; 49 | } 50 | 51 | .results { 52 | display: block; 53 | text-align: center; 54 | color: blanchedalmond; 55 | } 56 | 57 | .start{ 58 | display: inline; 59 | text-align:center; 60 | background-color: #47a5c4; 61 | color: blanchedalmond; 62 | margin-top: 1rem; 63 | font-size: 1rem; 64 | padding: .5rem 1rem; 65 | border: none; 66 | border-radius: 1rem; 67 | cursor: pointer; 68 | transition: background-color .3s ease; 69 | } 70 | 71 | .start:hover{ 72 | background-color: #2e8baf; 73 | } -------------------------------------------------------------------------------- /space-invaders/util.js: -------------------------------------------------------------------------------- 1 | import { alienInvaders, aliensRemoved, squares } from "./app.js"; 2 | 3 | export function draw() { 4 | alienInvaders?.forEach((alien, i) => !aliensRemoved.includes(i) ? squares[alien]?.classList.add('invader') : null); 5 | } 6 | 7 | export function remove() { 8 | alienInvaders?.forEach((alien) => squares[alien]?.classList.remove('invader')); 9 | } -------------------------------------------------------------------------------- /space-shooter-game-new/background1.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nikolaj-Georgiev/simple-html-css-js-projects/92bf9e534a3f354b5cf16b4f66fed3e9ffb13f50/space-shooter-game-new/background1.webp -------------------------------------------------------------------------------- /space-shooter-game-new/enemy-fotor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nikolaj-Georgiev/simple-html-css-js-projects/92bf9e534a3f354b5cf16b4f66fed3e9ffb13f50/space-shooter-game-new/enemy-fotor.png -------------------------------------------------------------------------------- /space-shooter-game-new/first-aid-kit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nikolaj-Georgiev/simple-html-css-js-projects/92bf9e534a3f354b5cf16b4f66fed3e9ffb13f50/space-shooter-game-new/first-aid-kit.png -------------------------------------------------------------------------------- /space-shooter-game-new/heroShip.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nikolaj-Georgiev/simple-html-css-js-projects/92bf9e534a3f354b5cf16b4f66fed3e9ffb13f50/space-shooter-game-new/heroShip.png -------------------------------------------------------------------------------- /space-shooter-game-new/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Space Shooter Game 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /space-shooter-game-new/old-background-photo/background1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nikolaj-Georgiev/simple-html-css-js-projects/92bf9e534a3f354b5cf16b4f66fed3e9ffb13f50/space-shooter-game-new/old-background-photo/background1.jpg -------------------------------------------------------------------------------- /space-shooter-game-new/script.js: -------------------------------------------------------------------------------- 1 | window.addEventListener('DOMContentLoaded', () => { 2 | const canvas = document.querySelector('canvas'); 3 | const ctx = canvas.getContext('2d'); 4 | canvas.width = window.innerWidth; 5 | canvas.height = window.innerHeight; 6 | 7 | const mouse = { 8 | x: window.innerWidth / 2, 9 | y: window.innerHeight - 33, 10 | }; 11 | 12 | const player = { 13 | x: mouse.x - 16, 14 | y: mouse.y - 16, 15 | width: 32, 16 | height: 32, 17 | }; 18 | const playerImage = new Image(); 19 | playerImage.src = '/heroShip.png'; 20 | 21 | playerImage.onload = () => { // Wait for the player's image to load 22 | const bullets = []; 23 | const enemies = []; 24 | const healthKits = []; 25 | 26 | let score = 0; 27 | let health = 100; 28 | 29 | function spawnEnemies() { 30 | for (let i = 0; i < 4; i++) { 31 | const x = Math.random() * (canvas.width - 32); 32 | const y = -32; 33 | const speed = Math.random() * 2; 34 | const enemy = { 35 | x: x, 36 | y: y, 37 | width: 32, 38 | height: 32, 39 | speed: speed, 40 | image: new Image(), 41 | }; 42 | enemy.image.src = '/enemy-fotor.png'; 43 | enemies.push(enemy); 44 | } 45 | } 46 | setInterval(spawnEnemies, 1234); 47 | 48 | function spawnHealthKits() { 49 | for (let i = 0; i < 1; i++) { 50 | const x = Math.random() * (canvas.width - 32); 51 | const y = -32; 52 | const speed = Math.random() * 2.6; 53 | const healthKit = { 54 | x: x, 55 | y: y, 56 | width: 32, 57 | height: 32, 58 | speed: speed, 59 | image: new Image(), 60 | }; 61 | healthKit.image.src = '/first-aid-kit.png'; 62 | healthKits.push(healthKit); 63 | } 64 | } 65 | setInterval(spawnHealthKits, 10000); 66 | setInterval(fire, 300); 67 | 68 | function fire() { 69 | const bullet = { 70 | x: player.x + player.width / 2 + 13, 71 | y: player.y - 5, 72 | width: 6, 73 | height: 8, 74 | speed: 10, 75 | }; 76 | bullets.push(bullet); 77 | } 78 | canvas.addEventListener('click', fire); 79 | 80 | canvas.addEventListener('mousemove', (e) => { 81 | mouse.x = e.clientX; 82 | player.x = mouse.x - player.width / 2; 83 | }); 84 | 85 | canvas.addEventListener('touchmove', (e) => { 86 | e.preventDefault(); 87 | mouse.x = e.touches[0].clientX; 88 | player.x = mouse.x - player.width / 2; 89 | }); 90 | 91 | canvas.addEventListener('touchstart', fire, { passive: true }); 92 | 93 | function collision(a, b) { 94 | return ( 95 | a.x < b.x + b.width && 96 | a.x + a.width > b.x && 97 | a.y < b.y + b.height && 98 | a.y + a.height > b.y 99 | ); 100 | } 101 | 102 | function updateGame() { 103 | requestAnimationFrame(updateGame); 104 | ctx.clearRect(0, 0, canvas.width, canvas.height); 105 | ctx.fillStyle = 'white'; 106 | ctx.font = '1em Arial'; 107 | ctx.fillText('Health: ' + health, 5, 20); 108 | ctx.fillText('Score: ' + score, canvas.width - 100, 20); 109 | 110 | ctx.drawImage(playerImage, player.x, player.y); 111 | 112 | for (let i = bullets.length - 1; i >= 0; i--) { 113 | bullets[i].y -= bullets[i].speed; 114 | ctx.fillStyle = 'white'; 115 | ctx.fillRect(bullets[i].x, bullets[i].y, bullets[i].width, bullets[i].height); 116 | if (bullets[i].y < 0) { 117 | bullets.splice(i, 1); 118 | } 119 | } 120 | 121 | for (let i = enemies.length - 1; i >= 0; i--) { 122 | enemies[i].y += enemies[i].speed; 123 | ctx.drawImage(enemies[i].image, enemies[i].x, enemies[i].y); 124 | if (enemies[i].y > canvas.height) { 125 | enemies.splice(i, 1); 126 | health -= 10; 127 | if (health === 0) { 128 | alert('You LOST!\nYour score was ' + score); 129 | location.reload(); // Restart the game 130 | } 131 | } 132 | } 133 | 134 | for (let i = enemies.length - 1; i >= 0; i--) { 135 | for (let j = bullets.length - 1; j >= 0; j--) { 136 | if (collision(enemies[i], bullets[j])) { 137 | enemies.splice(i, 1); 138 | bullets.splice(j, 1); 139 | score++; 140 | } 141 | } 142 | } 143 | 144 | for (let i = healthKits.length - 1; i >= 0; i--) { 145 | healthKits[i].y += healthKits[i].speed; 146 | ctx.drawImage(healthKits[i].image, healthKits[i].x, healthKits[i].y); 147 | if (collision(healthKits[i], player)) { 148 | healthKits.splice(i, 1); 149 | health += 10; 150 | } 151 | } 152 | 153 | for (let i = healthKits.length - 1; i >= 0; i--) { 154 | for (let j = bullets.length - 1; j >= 0; j--) { 155 | if (collision(healthKits[i], bullets[j])) { 156 | healthKits.splice(i, 1); 157 | bullets.splice(j, 1); 158 | health += 10; 159 | } 160 | } 161 | } 162 | } 163 | 164 | updateGame(); 165 | }; 166 | }); -------------------------------------------------------------------------------- /space-shooter-game-new/style.css: -------------------------------------------------------------------------------- 1 | body { 2 | background: url('background1.webp'); 3 | background-repeat: no-repeat; 4 | background-attachment: fixed; 5 | background-size: cover; 6 | display: flex; 7 | justify-content: center; 8 | align-items: center; 9 | height: 100vh; 10 | margin: 0; 11 | } 12 | -------------------------------------------------------------------------------- /winters/css/fonts/linea-basic-10.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nikolaj-Georgiev/simple-html-css-js-projects/92bf9e534a3f354b5cf16b4f66fed3e9ffb13f50/winters/css/fonts/linea-basic-10.eot -------------------------------------------------------------------------------- /winters/css/fonts/linea-basic-10.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nikolaj-Georgiev/simple-html-css-js-projects/92bf9e534a3f354b5cf16b4f66fed3e9ffb13f50/winters/css/fonts/linea-basic-10.ttf -------------------------------------------------------------------------------- /winters/css/fonts/linea-basic-10.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nikolaj-Georgiev/simple-html-css-js-projects/92bf9e534a3f354b5cf16b4f66fed3e9ffb13f50/winters/css/fonts/linea-basic-10.woff -------------------------------------------------------------------------------- /winters/img/book-small.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nikolaj-Georgiev/simple-html-css-js-projects/92bf9e534a3f354b5cf16b4f66fed3e9ffb13f50/winters/img/book-small.webp -------------------------------------------------------------------------------- /winters/img/book.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nikolaj-Georgiev/simple-html-css-js-projects/92bf9e534a3f354b5cf16b4f66fed3e9ffb13f50/winters/img/book.webp -------------------------------------------------------------------------------- /winters/img/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nikolaj-Georgiev/simple-html-css-js-projects/92bf9e534a3f354b5cf16b4f66fed3e9ffb13f50/winters/img/favicon.png -------------------------------------------------------------------------------- /winters/img/heli-ski-large.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nikolaj-Georgiev/simple-html-css-js-projects/92bf9e534a3f354b5cf16b4f66fed3e9ffb13f50/winters/img/heli-ski-large.webp -------------------------------------------------------------------------------- /winters/img/heli-ski-small.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nikolaj-Georgiev/simple-html-css-js-projects/92bf9e534a3f354b5cf16b4f66fed3e9ffb13f50/winters/img/heli-ski-small.webp -------------------------------------------------------------------------------- /winters/img/hero-small.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nikolaj-Georgiev/simple-html-css-js-projects/92bf9e534a3f354b5cf16b4f66fed3e9ffb13f50/winters/img/hero-small.webp -------------------------------------------------------------------------------- /winters/img/hero.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nikolaj-Georgiev/simple-html-css-js-projects/92bf9e534a3f354b5cf16b4f66fed3e9ffb13f50/winters/img/hero.webp -------------------------------------------------------------------------------- /winters/img/ladySnowboarder-1-large.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nikolaj-Georgiev/simple-html-css-js-projects/92bf9e534a3f354b5cf16b4f66fed3e9ffb13f50/winters/img/ladySnowboarder-1-large.jpg -------------------------------------------------------------------------------- /winters/img/ladySnowboarder-1-small.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nikolaj-Georgiev/simple-html-css-js-projects/92bf9e534a3f354b5cf16b4f66fed3e9ffb13f50/winters/img/ladySnowboarder-1-small.jpg -------------------------------------------------------------------------------- /winters/img/logo-blue-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nikolaj-Georgiev/simple-html-css-js-projects/92bf9e534a3f354b5cf16b4f66fed3e9ffb13f50/winters/img/logo-blue-1.png -------------------------------------------------------------------------------- /winters/img/logo-blue-small-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nikolaj-Georgiev/simple-html-css-js-projects/92bf9e534a3f354b5cf16b4f66fed3e9ffb13f50/winters/img/logo-blue-small-1.png -------------------------------------------------------------------------------- /winters/img/logo-blue-small-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nikolaj-Georgiev/simple-html-css-js-projects/92bf9e534a3f354b5cf16b4f66fed3e9ffb13f50/winters/img/logo-blue-small-2.png -------------------------------------------------------------------------------- /winters/img/logo-white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nikolaj-Georgiev/simple-html-css-js-projects/92bf9e534a3f354b5cf16b4f66fed3e9ffb13f50/winters/img/logo-white.png -------------------------------------------------------------------------------- /winters/img/new-heli-large.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nikolaj-Georgiev/simple-html-css-js-projects/92bf9e534a3f354b5cf16b4f66fed3e9ffb13f50/winters/img/new-heli-large.webp -------------------------------------------------------------------------------- /winters/img/new-heli-small.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nikolaj-Georgiev/simple-html-css-js-projects/92bf9e534a3f354b5cf16b4f66fed3e9ffb13f50/winters/img/new-heli-small.webp -------------------------------------------------------------------------------- /winters/img/new-ninja-large.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nikolaj-Georgiev/simple-html-css-js-projects/92bf9e534a3f354b5cf16b4f66fed3e9ffb13f50/winters/img/new-ninja-large.webp -------------------------------------------------------------------------------- /winters/img/new-ninja-small.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nikolaj-Georgiev/simple-html-css-js-projects/92bf9e534a3f354b5cf16b4f66fed3e9ffb13f50/winters/img/new-ninja-small.webp -------------------------------------------------------------------------------- /winters/img/schtilthorn.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nikolaj-Georgiev/simple-html-css-js-projects/92bf9e534a3f354b5cf16b4f66fed3e9ffb13f50/winters/img/schtilthorn.webp -------------------------------------------------------------------------------- /winters/img/skier-large.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nikolaj-Georgiev/simple-html-css-js-projects/92bf9e534a3f354b5cf16b4f66fed3e9ffb13f50/winters/img/skier-large.jpg -------------------------------------------------------------------------------- /winters/img/skier-small.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nikolaj-Georgiev/simple-html-css-js-projects/92bf9e534a3f354b5cf16b4f66fed3e9ffb13f50/winters/img/skier-small.jpg -------------------------------------------------------------------------------- /winters/img/skiingman-new-small.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nikolaj-Georgiev/simple-html-css-js-projects/92bf9e534a3f354b5cf16b4f66fed3e9ffb13f50/winters/img/skiingman-new-small.webp -------------------------------------------------------------------------------- /winters/img/skiingman-new.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nikolaj-Georgiev/simple-html-css-js-projects/92bf9e534a3f354b5cf16b4f66fed3e9ffb13f50/winters/img/skiingman-new.webp -------------------------------------------------------------------------------- /winters/img/snowboarder-large.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nikolaj-Georgiev/simple-html-css-js-projects/92bf9e534a3f354b5cf16b4f66fed3e9ffb13f50/winters/img/snowboarder-large.jpg -------------------------------------------------------------------------------- /winters/img/snowboarder-small.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nikolaj-Georgiev/simple-html-css-js-projects/92bf9e534a3f354b5cf16b4f66fed3e9ffb13f50/winters/img/snowboarder-small.jpg -------------------------------------------------------------------------------- /winters/img/snowboarding-new-small.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nikolaj-Georgiev/simple-html-css-js-projects/92bf9e534a3f354b5cf16b4f66fed3e9ffb13f50/winters/img/snowboarding-new-small.webp -------------------------------------------------------------------------------- /winters/img/snowboarding-new.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nikolaj-Georgiev/simple-html-css-js-projects/92bf9e534a3f354b5cf16b4f66fed3e9ffb13f50/winters/img/snowboarding-new.webp -------------------------------------------------------------------------------- /winters/img/treck-large.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nikolaj-Georgiev/simple-html-css-js-projects/92bf9e534a3f354b5cf16b4f66fed3e9ffb13f50/winters/img/treck-large.webp -------------------------------------------------------------------------------- /winters/img/treck-small.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nikolaj-Georgiev/simple-html-css-js-projects/92bf9e534a3f354b5cf16b4f66fed3e9ffb13f50/winters/img/treck-small.webp -------------------------------------------------------------------------------- /winters/img/video-snow.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nikolaj-Georgiev/simple-html-css-js-projects/92bf9e534a3f354b5cf16b4f66fed3e9ffb13f50/winters/img/video-snow.mp4 -------------------------------------------------------------------------------- /winters/img/video-snow.webm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nikolaj-Georgiev/simple-html-css-js-projects/92bf9e534a3f354b5cf16b4f66fed3e9ffb13f50/winters/img/video-snow.webm -------------------------------------------------------------------------------- /winters/js/script.js: -------------------------------------------------------------------------------- 1 | const checkbox = document.querySelector('.navigation__checkbox'); 2 | const navLinks = document.querySelector('.navigation__list'); 3 | navLinks.addEventListener('click', (e) => { 4 | const navLinkClass = e.target.classList[0]; 5 | if (navLinkClass === 'navigation__link') { 6 | checkbox.checked = false; 7 | } 8 | }) 9 | -------------------------------------------------------------------------------- /winters/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "winters", 3 | "version": "1.0.0", 4 | "description": "Landing page for winters", 5 | "main": "index.js", 6 | "scripts": { 7 | "watch:sass": "node-sass sass/main.scss css/style.css -w", 8 | "devserver": "live-server", 9 | "start": "npm-run-all --parallel devserver watch:sass", 10 | "compile:sass": "node-sass sass/main.scss css/style.comp.css", 11 | "concat:css": "concat -o css/style.concat.css css/icon-font.css css/style.comp.css", 12 | "prefix:css": "postcss --use autoprefixer -b 'last 10 versions' css/style.concat.css -o css/style.prefix.css", 13 | "compress:css": "node-sass css/style.prefix.css css/style.css --output-style compressed", 14 | "build:css": "npm-run-all compile:sass concat:css prefix:css compress:css" 15 | }, 16 | "author": "Nikolay", 17 | "license": "ISC", 18 | "devDependencies": { 19 | "node-sass": "^8.0.0", 20 | "autoprefixer": "^10.4.18", 21 | "concat": "^1.0.3", 22 | "npm-run-all": "^4.1.5", 23 | "postcss": "^8.4.35", 24 | "postcss-cli": "^11.0.0" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /winters/sass/abstracts/_functions.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nikolaj-Georgiev/simple-html-css-js-projects/92bf9e534a3f354b5cf16b4f66fed3e9ffb13f50/winters/sass/abstracts/_functions.scss -------------------------------------------------------------------------------- /winters/sass/abstracts/_mixins.scss: -------------------------------------------------------------------------------- 1 | @mixin clearfix { 2 | &::after { 3 | content: ''; 4 | display: table; 5 | clear: both; 6 | } 7 | } 8 | @mixin center-horizontal-vertical { 9 | position: absolute; 10 | top: 50%; 11 | left: 50%; 12 | transform: translate(-50%, -50%); 13 | } 14 | @mixin absCenter { 15 | position: absolute; 16 | top: 50%; 17 | left: 50%; 18 | transform: translate(-50%, -50%); 19 | } 20 | 21 | // MEDIA QUERY MANAGER 22 | /* 23 | 0-600px: Phone 24 | 600-900px: Tablet portrait mode 25 | 900-1260px: Tablet in landscape 26 | [where our normal styles apply] 27 | 1800px + : Big desktop screens 28 | 29 | $breakpoint argument choices: 30 | - phone 31 | - tab-port 32 | - tab-land 33 | - desktop 34 | - big-desktop 35 | */ 36 | 37 | // ORDER: Base + typography > general layout + grid > page layout > components 38 | 39 | // 1em == 16px for the media queries. And 16px is the default browser font-size. If user goes for 20px then 1em == 20px etc. 40 | // only screen and -> this means that they only apply to screens, if someone tries to print it, the media query won's apply 41 | @mixin respond($breakpoint) { 42 | @if $breakpoint == phone { 43 | @media only screen and (max-width: 37.5em) { 44 | //600px; 45 | @content; 46 | } 47 | } 48 | @if $breakpoint == tab-port { 49 | //900px; 50 | @media only screen and (max-width: 56.25em) { 51 | @content; 52 | } 53 | } 54 | @if $breakpoint == tab-land { 55 | //1260px; 56 | @media only screen and (max-width: 78.75em) { 57 | @content; 58 | } 59 | } 60 | @if $breakpoint == desktop { 61 | //1440px; 62 | @media only screen and (max-width: 90em) { 63 | @content; 64 | } 65 | } 66 | @if $breakpoint == big-desktop { 67 | //1800px; 68 | @media only screen and (min-width: 112.5em) { 69 | @content; 70 | } 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /winters/sass/abstracts/_variables.scss: -------------------------------------------------------------------------------- 1 | // COLORS 2 | $color-primary-light: #a9d6ff; 3 | $color-primary: #69b7ff; 4 | $color-primary-dark: #2998ff; 5 | 6 | $color-secondary: #fa5252; 7 | $color-secondary-light: #fb6363; 8 | $color-secondary-dark: #c84242; 9 | 10 | $color-tertiary-light: #fff3bf; 11 | $color-tertiary: #fff3bf; 12 | $color-tertiary-dark: #807a60; 13 | 14 | $color-grey-light-1: #f7f7f7; 15 | $color-grey-light-2: #eee; 16 | 17 | $color-grey-dark: #777; 18 | $color-grey-dark-2: #999; 19 | $color-grey-dark-3: #333; 20 | 21 | $color-white: #fff; 22 | $color-black: #000; 23 | 24 | $color-card-1: linear-gradient( 25 | to bottom right, 26 | $color-tertiary-light, 27 | $color-tertiary-dark 28 | ); 29 | $color-card-2: linear-gradient( 30 | to bottom right, 31 | $color-secondary-light, 32 | $color-secondary-dark 33 | ); 34 | $color-card-3: linear-gradient( 35 | to bottom right, 36 | $color-primary-light, 37 | $color-primary-dark 38 | ); 39 | 40 | //FONT 41 | $default-font-size: 1.6rem; 42 | 43 | // GRID 44 | $grid-width: 114rem; 45 | $gutter-vertical: 8rem; 46 | $gutter-vertical-small: 6rem; 47 | $gutter-horizontal: 6rem; 48 | 49 | //margins 50 | $small: 1.5rem; 51 | $medium: 4rem; 52 | $big: 8rem; 53 | $huge: 10rem; 54 | -------------------------------------------------------------------------------- /winters/sass/base/_animations.scss: -------------------------------------------------------------------------------- 1 | @keyframes moveInLeft { 2 | 0% { 3 | opacity: 0; 4 | transform: translateX(-10rem); 5 | } 6 | /* 7 | 50% { 8 | transform: rotate(100deg); 9 | } */ 10 | 11 | 80% { 12 | transform: translate(1rem); 13 | } 14 | 100% { 15 | opacity: 1; 16 | transform: translateX(0); 17 | } 18 | } 19 | 20 | @keyframes moveInRight { 21 | 0% { 22 | opacity: 0; 23 | transform: translateX(10rem); 24 | } 25 | /* 26 | 50% { 27 | transform: rotate(300deg); 28 | } */ 29 | 30 | 80% { 31 | transform: translate(-1rem); 32 | } 33 | 100% { 34 | opacity: 1; 35 | transform: translateX(0); 36 | } 37 | } 38 | 39 | @keyframes moveInBottom { 40 | 0% { 41 | opacity: 0; 42 | transform: translateY(3rem); 43 | } 44 | 45 | 100% { 46 | opacity: 1; 47 | transform: translateY(0); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /winters/sass/base/_base.scss: -------------------------------------------------------------------------------- 1 | *, 2 | *::after, 3 | *::before { 4 | margin: 0; 5 | padding: 0; 6 | box-sizing: inherit; 7 | } 8 | 9 | html { 10 | // this defines what 1 rem is. 11 | font-size: 62.5%; //1rem == 10px; 10px/16px == 62.5%; 12 | 13 | @include respond(tab-land) { 14 | font-size: 56.25%; // 1rem = 9px; 9/16 == 56.25%; 15 | } 16 | @include respond(tab-port) { 17 | font-size: 50%; // 1rem = 8px; 8/16 == 50%; 18 | } 19 | 20 | // @include respond(phone) { 21 | // font-size: 30%; // 1rem = 8px; 8/16 == 50%; 22 | // } 23 | @include respond(big-desktop) { 24 | font-size: 75%; // 1rem = 12px; 12/16 == 75%; 25 | } 26 | 27 | scroll-behavior: smooth; 28 | } 29 | 30 | body { 31 | box-sizing: border-box; 32 | padding: 3rem; 33 | 34 | @include respond(tab-port) { 35 | padding: 0; 36 | } 37 | } 38 | 39 | ::selection { 40 | background-color: $color-primary; 41 | color: $color-white; 42 | } 43 | -------------------------------------------------------------------------------- /winters/sass/base/_typography.scss: -------------------------------------------------------------------------------- 1 | body { 2 | font-family: 'Lato', sans-serif; 3 | font-weight: 400; 4 | /* font-size: 16px; */ 5 | line-height: 1.7; 6 | color: $color-grey-dark; 7 | } 8 | 9 | .heading-primary { 10 | display: block; 11 | color: $color-white; 12 | text-transform: uppercase; 13 | 14 | backface-visibility: hidden; 15 | margin-bottom: 6rem; 16 | 17 | &--main { 18 | display: block; 19 | font-size: 6rem; 20 | font-weight: 400; 21 | letter-spacing: 4.3rem; 22 | 23 | animation-name: moveInLeft; 24 | animation-duration: 1s; 25 | animation-timing-function: ease-out; 26 | /* 27 | animation-delay: 0.3s; 28 | animation-iteration-count: 3; 29 | */ 30 | 31 | @include respond(phone) { 32 | letter-spacing: 1rem; 33 | font-size: 5rem; 34 | } 35 | } 36 | 37 | &--sub { 38 | display: block; 39 | font-size: 2rem; 40 | font-weight: 700; 41 | letter-spacing: 1.5rem; 42 | 43 | animation: moveInRight 1s ease-out; 44 | 45 | @include respond(phone) { 46 | letter-spacing: 0.5rem; 47 | } 48 | } 49 | } 50 | 51 | .heading-secondary { 52 | font-size: 3.5rem; 53 | text-transform: uppercase; 54 | font-weight: 700; 55 | display: inline-block; 56 | background-image: linear-gradient( 57 | to right, 58 | $color-primary, 59 | $color-primary-dark 60 | ); 61 | -webkit-background-clip: text; 62 | background-clip: text; 63 | letter-spacing: 0.2rem; 64 | color: transparent; 65 | transition: all 0.2s; 66 | 67 | @include respond(tab-port) { 68 | font-size: 3rem; 69 | } 70 | 71 | @include respond(phone) { 72 | font-size: 2.2rem; 73 | } 74 | 75 | &:hover { 76 | transform: skewY(2deg) skewX(15deg) scale(1.1); 77 | text-shadow: 0.5rem 1rem 2rem rgba($color-black, 0.2); 78 | } 79 | } 80 | 81 | .heading-tertiary { 82 | font-size: $default-font-size; 83 | font-weight: 700; 84 | text-transform: uppercase; 85 | } 86 | 87 | .paragraph { 88 | font-size: $default-font-size; 89 | 90 | &:not(:last-child) { 91 | padding-bottom: 3rem; 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /winters/sass/base/_utilities.scss: -------------------------------------------------------------------------------- 1 | .u-center-text { 2 | text-align: center !important; 3 | } 4 | 5 | .u-margin-bottom-small { 6 | margin-bottom: $small !important; 7 | } 8 | .u-margin-bottom-medium { 9 | margin-bottom: $medium !important; 10 | 11 | @include respond(tab-port) { 12 | margin-bottom: 3rem !important; 13 | } 14 | } 15 | .u-margin-bottom-big { 16 | margin-bottom: $big !important; 17 | 18 | @include respond(tab-port) { 19 | margin-bottom: 5rem !important; 20 | } 21 | } 22 | 23 | .u-margin-top-big { 24 | margin-top: $big !important; 25 | } 26 | .u-margin-top-huge { 27 | margin-top: $huge !important; 28 | } 29 | -------------------------------------------------------------------------------- /winters/sass/components/_bg-video.scss: -------------------------------------------------------------------------------- 1 | .bg-video { 2 | position: absolute; 3 | top: 0; 4 | left: 0; 5 | width: 100%; 6 | height: 100%; 7 | z-index: -1; 8 | opacity: 0.15; 9 | overflow: hidden; 10 | 11 | &__content { 12 | width: 100%; 13 | height: 100%; 14 | object-fit: cover; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /winters/sass/components/_button.scss: -------------------------------------------------------------------------------- 1 | .btn { 2 | &, 3 | &:link, 4 | &:visited { 5 | text-transform: uppercase; 6 | text-decoration: none; 7 | padding: 1.5rem 4rem; 8 | display: inline-block; 9 | border-radius: 10rem; 10 | transition: all 0.2s; 11 | position: relative; 12 | font-size: $default-font-size; 13 | 14 | // change for the