├── .gitignore ├── dist ├── img │ ├── logo.png │ ├── logo2.png │ ├── euphorus.png │ ├── favicon.png │ ├── ozdevs.png │ ├── qut-Logo.png │ ├── bfsproject.JPG │ ├── job-track.png │ ├── ozdevs-two.png │ ├── techprowl2.png │ ├── asset-trading.PNG │ ├── binary-game.png │ ├── cryptocrowd2.png │ ├── flyingpostman.png │ ├── logo-minimal.png │ ├── ozdevs-three.png │ ├── task-manager.png │ └── euphorus-backend.png ├── particles.json ├── css │ ├── main.css.map │ └── main.css ├── js │ └── app.js └── index.html ├── scss ├── _variables.scss ├── main.scss ├── _education.scss ├── _footer.scss ├── _skills.scss ├── _projects.scss ├── _contact.scss ├── _header.scss └── _globals.scss └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | .vscode 2 | .DS_Store 3 | /dist/.DS_Store 4 | /dist/img/.DS_Store -------------------------------------------------------------------------------- /dist/img/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ben04rogers/personal-portfolio/HEAD/dist/img/logo.png -------------------------------------------------------------------------------- /dist/img/logo2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ben04rogers/personal-portfolio/HEAD/dist/img/logo2.png -------------------------------------------------------------------------------- /dist/img/euphorus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ben04rogers/personal-portfolio/HEAD/dist/img/euphorus.png -------------------------------------------------------------------------------- /dist/img/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ben04rogers/personal-portfolio/HEAD/dist/img/favicon.png -------------------------------------------------------------------------------- /dist/img/ozdevs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ben04rogers/personal-portfolio/HEAD/dist/img/ozdevs.png -------------------------------------------------------------------------------- /dist/img/qut-Logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ben04rogers/personal-portfolio/HEAD/dist/img/qut-Logo.png -------------------------------------------------------------------------------- /dist/img/bfsproject.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ben04rogers/personal-portfolio/HEAD/dist/img/bfsproject.JPG -------------------------------------------------------------------------------- /dist/img/job-track.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ben04rogers/personal-portfolio/HEAD/dist/img/job-track.png -------------------------------------------------------------------------------- /dist/img/ozdevs-two.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ben04rogers/personal-portfolio/HEAD/dist/img/ozdevs-two.png -------------------------------------------------------------------------------- /dist/img/techprowl2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ben04rogers/personal-portfolio/HEAD/dist/img/techprowl2.png -------------------------------------------------------------------------------- /dist/img/asset-trading.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ben04rogers/personal-portfolio/HEAD/dist/img/asset-trading.PNG -------------------------------------------------------------------------------- /dist/img/binary-game.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ben04rogers/personal-portfolio/HEAD/dist/img/binary-game.png -------------------------------------------------------------------------------- /dist/img/cryptocrowd2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ben04rogers/personal-portfolio/HEAD/dist/img/cryptocrowd2.png -------------------------------------------------------------------------------- /dist/img/flyingpostman.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ben04rogers/personal-portfolio/HEAD/dist/img/flyingpostman.png -------------------------------------------------------------------------------- /dist/img/logo-minimal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ben04rogers/personal-portfolio/HEAD/dist/img/logo-minimal.png -------------------------------------------------------------------------------- /dist/img/ozdevs-three.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ben04rogers/personal-portfolio/HEAD/dist/img/ozdevs-three.png -------------------------------------------------------------------------------- /dist/img/task-manager.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ben04rogers/personal-portfolio/HEAD/dist/img/task-manager.png -------------------------------------------------------------------------------- /dist/img/euphorus-backend.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ben04rogers/personal-portfolio/HEAD/dist/img/euphorus-backend.png -------------------------------------------------------------------------------- /scss/_variables.scss: -------------------------------------------------------------------------------- 1 | $website-width: 1200px; 2 | $color-blue: #3b82f6; 3 | $dark-grey: #181a1b; 4 | $text-color: white; 5 | $text-light: #dcdcdc; 6 | 7 | -------------------------------------------------------------------------------- /scss/main.scss: -------------------------------------------------------------------------------- 1 | @import "variables"; 2 | @import "globals"; 3 | @import "header"; 4 | @import "projects"; 5 | @import "education"; 6 | @import "skills"; 7 | @import "contact"; 8 | @import "footer"; 9 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Personal Porfolio Site 2 | 3 | ## Built with 4 | 5 | - HTML 6 | - SCSS 7 | - JavaScript 8 | 9 | ## Acknowledgments 10 | 11 | - [GSAP](https://greensock.com/gsap/) - Contact form animation 12 | - [AOS](https://github.com/michalsnik/aos) - Scroll animations 13 | - [Iconify](https://iconify.design/) - Icons used 14 | - [Formspree](https://formspree.io/) - Contact Form 15 | -------------------------------------------------------------------------------- /scss/_education.scss: -------------------------------------------------------------------------------- 1 | .education { 2 | background: white; 3 | padding-bottom: 3rem; 4 | 5 | .container { 6 | max-width: 900px; 7 | 8 | h2 { 9 | text-align: center; 10 | color: black; 11 | margin-bottom: 3rem; 12 | } 13 | 14 | .education-card { 15 | display: flex; 16 | flex-direction: column; 17 | justify-content: space-between; 18 | box-shadow: 0 0.15rem 0.6rem rgba(43, 52, 56, 0.15); 19 | padding: 40px; 20 | border-radius: 3px; 21 | 22 | & > *:last-child { 23 | margin-top: 40px; 24 | } 25 | 26 | @media (max-width: 500px) { 27 | padding: 20px; 28 | } 29 | 30 | .education-card-column { 31 | display: flex; 32 | 33 | .card-column-image { 34 | flex: 0 0 20%; 35 | img { 36 | width: 100%; 37 | } 38 | } 39 | 40 | .card-column-large { 41 | flex: 0 0 80%; 42 | padding-left: 1.5rem; 43 | 44 | & > * { 45 | margin: 0.25rem 0; 46 | } 47 | 48 | h4 { 49 | font-weight: normal; 50 | } 51 | 52 | ul { 53 | padding-left: 1.5rem; 54 | } 55 | 56 | hr { 57 | border: 0; 58 | border-top: 1px solid #eee; 59 | margin-top: 40px; 60 | } 61 | } 62 | } 63 | } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /scss/_footer.scss: -------------------------------------------------------------------------------- 1 | .footer { 2 | background: $dark-grey; 3 | padding: 1.5rem 0; 4 | color: white; 5 | 6 | // Particles.js canvas 7 | canvas { 8 | position: absolute; 9 | top: 0; 10 | left: 0; 11 | bottom: 0; 12 | width: 100%; 13 | height: 100%; 14 | } 15 | 16 | .footer-flex { 17 | display: flex; 18 | justify-content: space-between; 19 | 20 | #logo-footer { 21 | width: 200px; 22 | } 23 | 24 | .top-scroll-button { 25 | cursor: pointer; 26 | display: flex; 27 | justify-content: center; 28 | align-items: center; 29 | width: 35px; 30 | height: 35px; 31 | text-align: center; 32 | border: 3px solid white; 33 | border-radius: 50%; 34 | transition: 0.3s; 35 | } 36 | 37 | .top-scroll-button:hover { 38 | color: $color-blue; 39 | border: 3px solid $color-blue; 40 | } 41 | 42 | .footer-icon-links a { 43 | margin-left: 2rem; 44 | transition: 0.3s; 45 | &:hover { 46 | color: $color-blue; 47 | } 48 | 49 | i { 50 | transition: 0.3s; 51 | &:hover { 52 | transform: translateY(-20%); 53 | } 54 | } 55 | } 56 | } 57 | } 58 | 59 | @media screen and (max-width: 500px) { 60 | .footer { 61 | .footer-flex { 62 | flex-direction: column; 63 | justify-content: center; 64 | align-items: center; 65 | 66 | .top-scroll-button { 67 | margin-top: 2rem; 68 | } 69 | 70 | .footer-icon-links { 71 | margin-top: 2rem; 72 | 73 | a { 74 | margin: 0 1rem; 75 | } 76 | } 77 | } 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /scss/_skills.scss: -------------------------------------------------------------------------------- 1 | .skills { 2 | padding: 3rem 0; 3 | position: relative; 4 | overflow: hidden; 5 | 6 | // Particles.js canvas 7 | canvas { 8 | position: absolute; 9 | top: 0; 10 | left: 0; 11 | bottom: 0; 12 | width: 100%; 13 | height: 100%; 14 | } 15 | 16 | h2, 17 | h2 span { 18 | text-align: center; 19 | margin-bottom: 3rem; 20 | font-weight: bold; 21 | } 22 | 23 | .container { 24 | padding: 6rem 0; 25 | } 26 | 27 | .skills-icons { 28 | list-style-type: none; 29 | display: flex; 30 | flex-wrap: wrap; 31 | justify-content: center; 32 | max-width: 1100px; 33 | margin: 0 auto; 34 | position: relative; 35 | z-index: 10; 36 | 37 | svg { 38 | margin: 0.5rem; 39 | width: 90px; 40 | 41 | @media (max-width: 420px) { 42 | width: 70px; 43 | } 44 | } 45 | li { 46 | transition: 0.3s; 47 | display: flex; 48 | flex-direction: column; 49 | justify-content: center; 50 | align-items: center; 51 | color: white; 52 | font-size: 1rem; 53 | margin: 1rem; 54 | 55 | @media (max-width: 420px) { 56 | margin: 1rem 0.75rem; 57 | } 58 | 59 | .aws-logo { 60 | background: white; 61 | padding: 10px; 62 | border-radius: 3px; 63 | } 64 | } 65 | li:hover { 66 | transform: scale(1.3); 67 | } 68 | } 69 | 70 | .seperator-skew-top { 71 | position: absolute; 72 | top: -1px; 73 | left: 0; 74 | right: 0; 75 | height: 150px; 76 | width: 120%; 77 | overflow: hidden; 78 | 79 | svg { 80 | position: absolute; 81 | top: 0; 82 | transform: scaleY(-1) scaleX(-1); 83 | .fill-white { 84 | fill: white; 85 | } 86 | } 87 | } 88 | 89 | .seperator-skew-bottom { 90 | position: absolute; 91 | bottom: -0.5px; 92 | left: 0; 93 | right: 0; 94 | height: 150px; 95 | width: 120%; 96 | overflow: hidden; 97 | 98 | svg { 99 | position: absolute; 100 | bottom: 0; 101 | .fill-white { 102 | fill: white; 103 | } 104 | } 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /scss/_projects.scss: -------------------------------------------------------------------------------- 1 | .projects { 2 | background: white; 3 | padding: 3rem 0; 4 | 5 | h2, 6 | h2 span { 7 | text-align: center; 8 | margin-bottom: 3rem; 9 | font-weight: bold; 10 | } 11 | 12 | .project-row { 13 | display: flex; 14 | margin-bottom: 3rem; 15 | 16 | .project-left { 17 | width: 50%; 18 | margin-right: 2rem; 19 | img { 20 | width: 100%; 21 | border: 1px solid lightgray; 22 | } 23 | } 24 | .project-right { 25 | width: 50%; 26 | display: flex; 27 | flex-direction: column; 28 | justify-content: center; 29 | 30 | h3 { 31 | font-size: 1.25rem; 32 | } 33 | 34 | .tech-stack-list { 35 | display: flex; 36 | flex-wrap: wrap; 37 | list-style-type: none; 38 | margin-top: 1rem; 39 | 40 | p { 41 | margin-right: 1rem; 42 | } 43 | 44 | li { 45 | margin-right: 20px; 46 | font-size: 1.5rem; 47 | } 48 | } 49 | 50 | .project-links { 51 | margin-top: 1rem; 52 | } 53 | } 54 | 55 | #webscraper { 56 | background-image: url("../img/top10songs.JPG"); 57 | background-size: 100% 100%; 58 | background-repeat: no-repeat; 59 | // Background image transition only supported in Chrome, Opera, and Safari. Not firefox. 60 | -webkit-transition: background-image 0.2s ease-in-out; 61 | transition: background-image 0.2s ease-in-out; 62 | } 63 | 64 | #webscraper:hover { 65 | background-image: url("../img/top10songs.gif"); 66 | } 67 | } 68 | } 69 | 70 | @media screen and (max-width: 860px) { 71 | .projects { 72 | .project-row { 73 | display: flex; 74 | margin-bottom: 3rem; 75 | flex-direction: column; 76 | .project-left { 77 | width: 100%; 78 | // max-height: 400px; 79 | } 80 | .project-right { 81 | width: 100%; 82 | } 83 | } 84 | } 85 | } 86 | 87 | @media screen and (max-width: 500px) { 88 | .project-left { 89 | min-height: 200px; 90 | } 91 | } 92 | 93 | @media screen and (min-width: 501px) and (max-width: 700px) { 94 | .project-left { 95 | min-height: 300px; 96 | } 97 | } 98 | 99 | @media screen and (min-width: 701px) and (max-width: 859px) { 100 | .project-left { 101 | min-height: 350px; 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /dist/particles.json: -------------------------------------------------------------------------------- 1 | { 2 | "particles": { 3 | "number": { 4 | "value": 80, 5 | "density": { 6 | "enable": true, 7 | "value_area": 800 8 | } 9 | }, 10 | "color": { 11 | "value": "#ffffff" 12 | }, 13 | "shape": { 14 | "type": "circle", 15 | "stroke": { 16 | "width": 0, 17 | "color": "#000000" 18 | }, 19 | "polygon": { 20 | "nb_sides": 5 21 | }, 22 | "image": { 23 | "src": "img/github.svg", 24 | "width": 100, 25 | "height": 100 26 | } 27 | }, 28 | "opacity": { 29 | "value": 0.3, 30 | "random": false, 31 | "anim": { 32 | "enable": false, 33 | "speed": 1, 34 | "opacity_min": 0.1, 35 | "sync": false 36 | } 37 | }, 38 | "size": { 39 | "value": 2, 40 | "random": true, 41 | "anim": { 42 | "enable": false, 43 | "speed": 40, 44 | "size_min": 0.1, 45 | "sync": false 46 | } 47 | }, 48 | "line_linked": { 49 | "enable": true, 50 | "distance": 150, 51 | "color": "#ffffff", 52 | "opacity": 0.2, 53 | "width": 1 54 | }, 55 | "move": { 56 | "enable": true, 57 | "speed": 2, 58 | "direction": "none", 59 | "random": false, 60 | "straight": false, 61 | "out_mode": "out", 62 | "bounce": false, 63 | "attract": { 64 | "enable": false, 65 | "rotateX": 600, 66 | "rotateY": 1200 67 | } 68 | } 69 | }, 70 | "interactivity": { 71 | "detect_on": "canvas", 72 | "events": { 73 | "onhover": { 74 | "enable": true, 75 | "mode": "grab" 76 | }, 77 | "onclick": { 78 | "enable": true, 79 | "mode": "push" 80 | }, 81 | "resize": true 82 | }, 83 | "modes": { 84 | "grab": { 85 | "distance": 150, 86 | "line_linked": { 87 | "opacity": 1 88 | } 89 | }, 90 | "bubble": { 91 | "distance": 400, 92 | "size": 40, 93 | "duration": 2, 94 | "opacity": 8, 95 | "speed": 3 96 | }, 97 | "repulse": { 98 | "distance": 200, 99 | "duration": 0.4 100 | }, 101 | "push": { 102 | "particles_nb": 4 103 | }, 104 | "remove": { 105 | "particles_nb": 2 106 | } 107 | } 108 | }, 109 | "retina_detect": true 110 | } 111 | -------------------------------------------------------------------------------- /scss/_contact.scss: -------------------------------------------------------------------------------- 1 | .contact { 2 | background: white; 3 | padding: 3rem 0; 4 | 5 | .section-title { 6 | margin-bottom: 2rem; 7 | text-align: center; 8 | } 9 | 10 | .card-container { 11 | display: flex; 12 | justify-content: space-around; 13 | margin-bottom: 3rem; 14 | flex-wrap: wrap; 15 | 16 | .card { 17 | background: #fff; 18 | width: 260px; 19 | margin: 20px; 20 | padding: 30px; 21 | display: flex; 22 | justify-content: center; 23 | align-items: center; 24 | flex-direction: column; 25 | box-shadow: 0 0.15rem 0.6rem rgba(43, 52, 56, 0.15); 26 | border-radius: 3px; 27 | 28 | i { 29 | font-size: 3.5rem; 30 | color: $color-blue; 31 | margin-bottom: 1rem; 32 | transition: 0.4s; 33 | } 34 | 35 | i:hover { 36 | transform: translateY(-20%); 37 | } 38 | 39 | & > * { 40 | margin: 0.5rem; 41 | } 42 | } 43 | } 44 | 45 | form { 46 | h2 { 47 | text-align: center; 48 | margin: 1.5rem 0; 49 | } 50 | 51 | max-width: 600px; 52 | margin: 0 auto; 53 | border-radius: 3px; 54 | box-shadow: 0 0.15rem 0.6rem rgba(43, 52, 56, 0.15); 55 | padding: 2rem; 56 | 57 | .form-group { 58 | input { 59 | margin: 0.75rem 0; 60 | width: 100%; 61 | border-radius: 3px; 62 | border: 1px solid #afafaf; 63 | padding: 0.75rem; 64 | font-size: 1rem; 65 | } 66 | 67 | input:focus { 68 | outline: none; 69 | } 70 | 71 | textarea { 72 | width: 100%; 73 | border-radius: 3px; 74 | margin: 0.75rem 0; 75 | border: 1px solid #afafaf; 76 | padding: 0.75rem; 77 | font-size: 1rem; 78 | resize: vertical; 79 | } 80 | 81 | textarea:focus { 82 | outline: none; 83 | } 84 | } 85 | 86 | #status { 87 | width: 100%; 88 | text-align: center; 89 | // padding: 10px; 90 | margin: 0 auto; 91 | border-radius: 3px; 92 | color: #00b700; 93 | } 94 | #status.success { 95 | color: #00b700; 96 | animation: status 4s ease forwards; 97 | } 98 | #status.error { 99 | color: red; 100 | animation: status 4s ease forwards; 101 | } 102 | @keyframes status { 103 | 0% { 104 | opacity: 1; 105 | pointer-events: all; 106 | } 107 | 90% { 108 | opacity: 1; 109 | pointer-events: all; 110 | } 111 | 100% { 112 | opacity: 0; 113 | pointer-events: none; 114 | } 115 | } 116 | } 117 | } 118 | -------------------------------------------------------------------------------- /dist/css/main.css.map: -------------------------------------------------------------------------------- 1 | {"version":3,"sourceRoot":"","sources":["../../scss/_globals.scss","../../scss/_variables.scss","../../scss/_header.scss","../../scss/_projects.scss","../../scss/_education.scss","../../scss/_skills.scss","../../scss/_contact.scss","../../scss/_footer.scss"],"names":[],"mappings":"AAAA;EACE;;;AAGF;EACE;EACA;EACA;EACA;;;AAGF;EAIE;EACA;EACA,YCfU;;ADUV;EACE;;;AAOJ;EACE;EACA,OCnBW;;;ADsBb;EACE;;;AAIF;EACE;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;EACE,WC/Cc;EDgDd;EACA;EACA;EACA;;;AAIF;EACE,OCvDW;;;AD0Db;EACE;;;AAGF;EACE;;;AAGF;EACE;;;AAIF;EACE,kBCxEW;;;AD2Eb;EACE;;;AAGF;EACE;;;AAIF;EACE;EACA;EACA;EACA;EACA;EACA;;;AAKA;EACE;EAEA,kBClGS;EDmGT;;AAGF;EAEE;EACA,kBCxGQ;;AD2GV;EAEE,OC9GS;ED+GT;EACA;;AAGF;EACE;EACA;EACA;;AAGF;EACE;EACA,kBC3HS;;AD8HX;EACE;;;AAIJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;;;AAKJ;EACE;EACA;EACA;;;AAIF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AACA;AAAA;EAEE;EACA;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;;AAEA;AAAA;EAEE;EACA;EACA;EACA;EACA;EACA;EACA;;AAKA;AAAA;AAAA;EAEE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EAEA;EACA;EACA;;AAUJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAGJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEF;EACE;EACA;EACA;EACA;;AACA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AACA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAMR;EACE;EACA;;;AAGF;EACE;;;AAIF;EACE;;;AAKA;EADF;IAEI;;;;AAKF;EADF;IAEI;;;;AErXJ;EACE,YDCU;ECAV;EACA;EACA;;AAEA;EACE;EACA;;AAGA;EACE;EACA;EACA;EACA;EACA;EACA;;AAIJ;EACE;;AACA;EACE;EACA;EACA;;AAEA;EACE;EACA;;AACA;EACE;;AAIJ;EACE;;AACA;EACE;EACA;EACA;EACA;EACA;;AAEF;EACE;EACA;EACA,OD7CG;;AC+CL;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEF;EACE;;AAKN;EACE;EACA;;AACA;EACE;;AAEE;EACE;EACA;EACA;;AACA;EACE;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA,YDvFD;ECwFC;;AAEF;EACE;;AASZ;EACE;EACA;EACA;EACA;EACA;;AAEA;AAAA;EAEE,OD3GO;;AC8GT;AAAA;EAEE;EACA;EACA;EACA;EACA;;AAGF;EACE,ODvHO;ECwHP;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAIJ;EACE;EACA;EACA;;AAIJ;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;;AACA;EACE;EACA;;AAIJ;EACE;;AAMR;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;;AACA;EAEE;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;IACE;IACA;;EAEF;IACE;;EAEF;IACE;IACA;;;AAOV;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;;AACA;EACE;;;AAOR;EAGM;IACE;;EAEF;IACE;;EAIJ;IACE;;EAGF;IACE;;;AAKN;EACE;IACE;;EAGF;IACE;;;AAIJ;EAIQ;IACE;;EAOI;IACE;;EAQV;IACE;;EAEF;IACE;;;AAMR;EACE;IACE;;EAEA;IACE;;;AChUN;EACE;EACA;;AAEA;AAAA;EAEE;EACA;EACA;;AAGF;EACE;EACA;;AAEA;EACE;EACA;;AACA;EACE;EACA;;AAGJ;EACE;EACA;EACA;EACA;;AAEA;EACE;;AAGF;EACE;EACA;EACA;EACA;;AAEA;EACE;;AAGF;EACE;EACA;;AAIJ;EACE;;AAIJ;EACE;EACA;EACA;EAEA;EACA;;AAGF;EACE;;;AAKN;EAEI;IACE;IACA;IACA;;EACA;IACE;;EAGF;IACE;;;AAMR;EACE;IACE;;;AAIJ;EACE;IACE;;;AAIJ;EACE;IACE;;;ACpGJ;EACE;EACA;;AAEA;EACE;;AAEA;EACE;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAGF;EAZF;IAaI;;;AAGF;EACE;;AAEA;EACE;;AACA;EACE;;AAIJ;EACE;EACA;;AAEA;EACE;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;EACA;EACA;;;AC1DZ;EACE;EACA;EACA;;AAGA;EACE;EACA;EACA;EACA;EACA;EACA;;AAGF;AAAA;EAEE;EACA;EACA;;AAGF;EACE;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAEA;EAJF;IAKI;;;AAGJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EAVF;IAWI;;;AAGF;EACE;EACA;EACA;;AAGJ;EACE;;AAIJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;;AACA;EACE;;AAKN;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;;AACA;EACE;;;ACrGR;EACE;EACA;;AAEA;EACE;EACA;;AAGF;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA,OL5BK;EK6BL;EACA;;AAGF;EACE;;AAGF;EACE;;AAKN;EAME;EACA;EACA;EACA;EACA;;AATA;EACE;EACA;;AAUA;EACE;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;;AAIJ;EACE;EACA;EAEA;EACA;EACA;;AAEF;EACE;EACA;;AAEF;EACE;EACA;;AAEF;EACE;IACE;IACA;;EAEF;IACE;IACA;;EAEF;IACE;IACA;;;;AChHR;EACE,YNCU;EMAV;EACA;;AAGA;EACE;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;;AAEA;EACE;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE,ONpCO;EMqCP;;AAGF;EACE;EACA;;AACA;EACE,ON5CK;;AM+CP;EACE;;AACA;EACE;;;AAOV;EAEI;IACE;IACA;IACA;;EAEA;IACE;;EAGF;IACE;;EAEA;IACE","file":"main.css"} -------------------------------------------------------------------------------- /dist/js/app.js: -------------------------------------------------------------------------------- 1 | const logoName = document.getElementById("logo-name"); 2 | const body = document.querySelector("body"); 3 | const navbar = document.querySelector("nav"); 4 | 5 | window.addEventListener("DOMContentLoaded", function () { 6 | var form = document.getElementById("contact-form"); 7 | 8 | var status = document.getElementById("status"); 9 | 10 | // Success and Error functions for after the form is submitted 11 | function success() { 12 | form.reset(); 13 | } 14 | 15 | function error() { 16 | status.classList.add("error"); 17 | status.innerHTML = "There was a problem. Please try again."; 18 | } 19 | 20 | // Handle the form submission event 21 | form.addEventListener("submit", function (ev) { 22 | ev.preventDefault(); 23 | var data = new FormData(form); 24 | ajax(form.method, form.action, data, success, error); 25 | }); 26 | }); 27 | 28 | // Helper function for sending an AJAX request 29 | function ajax(method, url, data, success, error) { 30 | var xhr = new XMLHttpRequest(); 31 | xhr.open(method, url); 32 | xhr.setRequestHeader("Accept", "application/json"); 33 | xhr.onreadystatechange = function () { 34 | if (xhr.readyState !== XMLHttpRequest.DONE) return; 35 | if (xhr.status === 200) { 36 | success(xhr.response, xhr.responseType); 37 | 38 | // Paper plane animation 39 | // Credit: https://codepen.io/aaroniker/pen/BajabVN 40 | document.querySelectorAll(".btn-email").forEach((button) => { 41 | let getVar = (variable) => 42 | getComputedStyle(button).getPropertyValue(variable); 43 | 44 | if (!button.classList.contains("active")) { 45 | button.classList.add("active"); 46 | 47 | gsap.to(button, { 48 | keyframes: [ 49 | { 50 | "--left-wing-first-x": 50, 51 | "--left-wing-first-y": 100, 52 | "--right-wing-second-x": 50, 53 | "--right-wing-second-y": 100, 54 | duration: 0.2, 55 | onComplete() { 56 | gsap.set(button, { 57 | "--left-wing-first-y": 0, 58 | "--left-wing-second-x": 40, 59 | "--left-wing-second-y": 100, 60 | "--left-wing-third-x": 0, 61 | "--left-wing-third-y": 100, 62 | "--left-body-third-x": 40, 63 | "--right-wing-first-x": 50, 64 | "--right-wing-first-y": 0, 65 | "--right-wing-second-x": 60, 66 | "--right-wing-second-y": 100, 67 | "--right-wing-third-x": 100, 68 | "--right-wing-third-y": 100, 69 | "--right-body-third-x": 60, 70 | }); 71 | }, 72 | }, 73 | { 74 | "--left-wing-third-x": 20, 75 | "--left-wing-third-y": 90, 76 | "--left-wing-second-y": 90, 77 | "--left-body-third-y": 90, 78 | "--right-wing-third-x": 80, 79 | "--right-wing-third-y": 90, 80 | "--right-body-third-y": 90, 81 | "--right-wing-second-y": 90, 82 | duration: 0.2, 83 | }, 84 | { 85 | "--rotate": 50, 86 | "--left-wing-third-y": 95, 87 | "--left-wing-third-x": 27, 88 | "--right-body-third-x": 45, 89 | "--right-wing-second-x": 45, 90 | "--right-wing-third-x": 60, 91 | "--right-wing-third-y": 83, 92 | duration: 0.25, 93 | }, 94 | { 95 | "--rotate": 60, 96 | "--plane-x": -8, 97 | "--plane-y": 40, 98 | duration: 0.2, 99 | }, 100 | { 101 | "--rotate": 40, 102 | "--plane-x": 45, 103 | "--plane-y": -300, 104 | "--plane-opacity": 0, 105 | duration: 0.375, 106 | onComplete() { 107 | setTimeout(() => { 108 | button.removeAttribute("style"); 109 | gsap.fromTo( 110 | button, 111 | { 112 | opacity: 0, 113 | y: -8, 114 | }, 115 | { 116 | opacity: 1, 117 | y: 0, 118 | clearProps: true, 119 | duration: 0.3, 120 | onComplete() { 121 | button.classList.remove("active"); 122 | }, 123 | } 124 | ); 125 | }, 1800); 126 | }, 127 | }, 128 | ], 129 | }); 130 | 131 | gsap.to(button, { 132 | keyframes: [ 133 | { 134 | "--text-opacity": 0, 135 | "--border-radius": 0, 136 | "--left-wing-background": getVar("--primary-dark"), 137 | "--right-wing-background": getVar("--primary-dark"), 138 | duration: 0.11, 139 | }, 140 | { 141 | "--left-wing-background": getVar("--primary"), 142 | "--right-wing-background": getVar("--primary"), 143 | duration: 0.14, 144 | }, 145 | { 146 | "--left-body-background": getVar("--primary-dark"), 147 | "--right-body-background": getVar("--primary-darkest"), 148 | duration: 0.25, 149 | delay: 0.1, 150 | }, 151 | { 152 | "--trails-stroke": 171, 153 | duration: 0.22, 154 | delay: 0.22, 155 | }, 156 | { 157 | "--success-opacity": 1, 158 | "--success-x": 0, 159 | duration: 0.2, 160 | delay: 0.15, 161 | }, 162 | { 163 | "--success-stroke": 0, 164 | duration: 0.15, 165 | }, 166 | ], 167 | }); 168 | } 169 | }); 170 | } else { 171 | error(xhr.status, xhr.response, xhr.responseType); 172 | } 173 | }; 174 | xhr.send(data); 175 | } 176 | 177 | // Back to top arrow button 178 | 179 | const backToTopBtn = $("#backToTopBtn"); 180 | 181 | $(window).scroll(function () { 182 | if ($(window).scrollTop() > 300) { 183 | backToTopBtn.addClass("show"); 184 | } else { 185 | backToTopBtn.removeClass("show"); 186 | } 187 | }); 188 | 189 | backToTopBtn.on("click", function (e) { 190 | e.preventDefault(); 191 | $("html, body").animate({ scrollTop: 0 }, "300"); 192 | }); 193 | -------------------------------------------------------------------------------- /scss/_header.scss: -------------------------------------------------------------------------------- 1 | header { 2 | background: $dark-grey; 3 | background-size: cover; 4 | min-height: 80vh; 5 | position: relative; 6 | 7 | #particles-js { 8 | height: 80vh; 9 | position: relative; 10 | 11 | // Particles.js canvas 12 | canvas { 13 | position: absolute; 14 | top: 0; 15 | left: 0; 16 | bottom: 0; 17 | width: 100%; 18 | height: 100%; 19 | } 20 | } 21 | 22 | nav { 23 | width: 100%; 24 | .nav-container { 25 | position: relative; 26 | display: flex; 27 | justify-content: space-between; 28 | 29 | #logo { 30 | margin: auto 0; 31 | z-index: 10; 32 | img { 33 | width: 250px; 34 | } 35 | } 36 | 37 | .nav-links { 38 | z-index: 1000; 39 | li { 40 | list-style: none; 41 | display: flex; 42 | flex-direction: row; 43 | align-items: center; 44 | margin-left: 2rem; 45 | } 46 | a { 47 | text-decoration: none; 48 | letter-spacing: 2px; 49 | color: $text-color; 50 | } 51 | .link::after { 52 | content: ""; 53 | position: relative; 54 | display: block; 55 | width: 0%; 56 | height: 2px; 57 | top: 3px; 58 | margin: auto; 59 | background: #3b82f6; 60 | transition: width 0.3s ease; 61 | } 62 | .link:hover::after { 63 | width: 100%; 64 | } 65 | } 66 | } 67 | 68 | .mobile-menu { 69 | position: relative; 70 | z-index: 1000; 71 | .container { 72 | padding-top: 0; 73 | .mobile-menu-links { 74 | ul { 75 | justify-content: center; 76 | align-items: center; 77 | list-style-type: none; 78 | li { 79 | margin: 0rem 1rem; 80 | } 81 | .link::after { 82 | content: ""; 83 | position: relative; 84 | display: block; 85 | width: 0; 86 | height: 2px; 87 | top: 3px; 88 | margin: auto; 89 | background: $color-blue; 90 | transition: width 0.3s ease; 91 | } 92 | .link:hover::after { 93 | width: 100%; 94 | } 95 | } 96 | } 97 | } 98 | } 99 | } 100 | 101 | // Hero Section 102 | .hero { 103 | z-index: 5; 104 | position: absolute; 105 | top: 50%; 106 | left: 50%; 107 | transform: translate(-50%, -50%); 108 | 109 | h1, 110 | p { 111 | color: $text-color; 112 | } 113 | 114 | h1, 115 | h2 span { 116 | letter-spacing: 2px; 117 | white-space: nowrap; 118 | text-align: center; 119 | font-size: clamp(2rem, 5vw, 4rem); 120 | font-weight: bold; 121 | } 122 | 123 | p { 124 | color: $text-light; 125 | line-height: 1.6; 126 | font-size: clamp(1.25rem, 2vw, 1.5rem); 127 | text-align: center; 128 | max-width: 800px; 129 | margin: 0 auto; 130 | padding: 0.5rem; 131 | 132 | .blue-link-underline { 133 | color: #3783ff; 134 | } 135 | } 136 | 137 | .hero-btns { 138 | white-space: nowrap; 139 | text-align: center; 140 | margin-top: 1rem; 141 | } 142 | } 143 | 144 | .socials { 145 | position: absolute; 146 | bottom: 40%; 147 | left: -125px; 148 | z-index: 10; 149 | 150 | ul { 151 | display: flex; 152 | flex-direction: column; 153 | align-items: flex-end; 154 | 155 | li { 156 | transition: 0.3s; 157 | width: 100%; 158 | display: flex; 159 | justify-content: end; 160 | font-size: 1.5rem; 161 | width: 100%; 162 | height: 100%; 163 | 164 | a { 165 | text-align: right; 166 | height: 100%; 167 | width: 100%; 168 | padding: 15px 20px; 169 | i { 170 | font-size: 1.75rem; 171 | margin-left: 1.5rem; 172 | } 173 | } 174 | 175 | &:hover { 176 | transform: translateX(115px); 177 | } 178 | } 179 | } 180 | } 181 | 182 | .scroll-btn-container { 183 | position: absolute; 184 | width: 100%; 185 | background: red; 186 | bottom: 150px; 187 | 188 | div { 189 | display: flex; 190 | justify-content: center; 191 | width: 100%; 192 | a { 193 | // height: 50px; 194 | display: flex; 195 | flex-direction: column; 196 | justify-content: space-between; 197 | 198 | span { 199 | display: block; 200 | height: 20px; 201 | width: 20px; 202 | border-bottom: 2px solid $color-blue; 203 | border-right: 2px solid $color-blue; 204 | transform: rotate(45deg); 205 | margin: -20px 0; 206 | animation: animate 2s infinite; 207 | } 208 | 209 | span:nth-child(2) { 210 | animation-delay: -0.2s; 211 | } 212 | 213 | span:nth-child(3) { 214 | animation-delay: -0.4s; 215 | } 216 | 217 | @keyframes animate { 218 | 0% { 219 | opacity: 0; 220 | transform: rotate(45deg) translate(-20px, -20px); 221 | } 222 | 50% { 223 | opacity: 1; 224 | } 225 | 100% { 226 | opacity: 0; 227 | transform: rotate(45deg) translate(20px, 20px); 228 | } 229 | } 230 | } 231 | } 232 | } 233 | 234 | .seperator-skew { 235 | position: absolute; 236 | bottom: 0; 237 | left: 0; 238 | right: 0; 239 | height: 150px; 240 | width: 100%; 241 | overflow: hidden; 242 | 243 | svg { 244 | position: absolute; 245 | bottom: 0; 246 | .fill-white { 247 | fill: white; 248 | } 249 | } 250 | } 251 | } 252 | 253 | // Media queries 254 | @media screen and (max-width: 999px) { 255 | header { 256 | nav { 257 | .container { 258 | padding-bottom: 0.75rem; 259 | } 260 | .nav-container { 261 | justify-content: center; 262 | } 263 | } 264 | 265 | .hero { 266 | top: 55%; 267 | } 268 | 269 | .socials { 270 | display: none; 271 | } 272 | } 273 | } 274 | 275 | @media screen and (max-width: 768px) { 276 | .hero { 277 | width: 90%; 278 | } 279 | 280 | header nav .nav-container #logo img { 281 | width: 200px; 282 | } 283 | } 284 | 285 | @media screen and (max-width: 500px) { 286 | header { 287 | nav { 288 | .nav-container { 289 | #logo { 290 | font-size: 1.5rem; 291 | } 292 | } 293 | .mobile-menu { 294 | .container { 295 | .mobile-menu-links { 296 | ul { 297 | li { 298 | margin: 0 0.5rem; 299 | } 300 | } 301 | } 302 | } 303 | } 304 | } 305 | .hero { 306 | span { 307 | max-width: 100%; 308 | } 309 | p { 310 | width: 100%; 311 | } 312 | } 313 | } 314 | } 315 | 316 | @media screen and (min-height: 900px) { 317 | header { 318 | min-height: 70vh; 319 | 320 | #particles-js { 321 | height: 70vh; 322 | } 323 | } 324 | } 325 | -------------------------------------------------------------------------------- /scss/_globals.scss: -------------------------------------------------------------------------------- 1 | html { 2 | scroll-behavior: smooth; 3 | } 4 | 5 | * { 6 | margin: 0; 7 | padding: 0; 8 | box-sizing: border-box; 9 | font-family: "Nunito", sans-serif; 10 | } 11 | 12 | body { 13 | .noscroll { 14 | overflow-x: hidden; 15 | } 16 | padding: 0; 17 | line-height: 1.5; 18 | background: $dark-grey; 19 | } 20 | 21 | a { 22 | text-decoration: none; 23 | color: $text-color; 24 | } 25 | 26 | .main-font { 27 | font-family: "Nunito", sans-serif; 28 | } 29 | 30 | // Utility classes 31 | .text-center { 32 | text-align: center; 33 | } 34 | 35 | .my-1 { 36 | margin: 1rem 0; 37 | } 38 | 39 | .mx-1 { 40 | margin: 0 0.5rem; 41 | } 42 | 43 | .h-100 { 44 | height: 100%; 45 | } 46 | 47 | .container { 48 | max-width: $website-width; 49 | padding: 1.5rem 1.5rem; 50 | margin: auto; 51 | overflow: hidden; 52 | transition: all 0.3s ease; 53 | } 54 | 55 | // Text 56 | .text-blue { 57 | color: $color-blue; 58 | } 59 | 60 | .text-white { 61 | color: white; 62 | } 63 | 64 | .text-grey { 65 | color: grey; 66 | } 67 | 68 | .text-dark-grey { 69 | color: #2e3031; 70 | } 71 | 72 | // Backgrounds 73 | .bg-blue { 74 | background-color: $color-blue; 75 | } 76 | 77 | .bg-dark-grey { 78 | background-color: #2e3031; 79 | } 80 | 81 | .bg-white { 82 | background-color: white; 83 | } 84 | 85 | // Buttons 86 | %btn-shared { 87 | display: inline-block; 88 | padding: 0.8rem 1.5rem; 89 | transition: all 0.3s; 90 | border-radius: 3px; 91 | border: none; 92 | cursor: pointer; 93 | } 94 | 95 | .btn { 96 | @extend %btn-shared; 97 | &-blue { 98 | color: white; 99 | @extend %btn-shared; 100 | background-color: $color-blue; 101 | border: 2px solid $color-blue; 102 | } 103 | 104 | &-dark { 105 | @extend %btn-shared; 106 | color: white; 107 | background-color: $dark-grey; 108 | } 109 | 110 | &-blue-outline { 111 | @extend %btn-shared; 112 | color: $color-blue; 113 | background-color: transparent; 114 | border: 2px solid $color-blue; 115 | } 116 | 117 | &-blue:hover { 118 | transition: all 0.3s ease; 119 | background: darken($color-blue, 10%); 120 | border: 2px solid darken($color-blue, 10%); 121 | } 122 | 123 | &-blue-outline:hover { 124 | color: white; 125 | background-color: $color-blue; 126 | } 127 | 128 | &-small { 129 | padding: 0.5rem 1rem; 130 | } 131 | } 132 | 133 | #backToTopBtn { 134 | position: fixed; 135 | right: 20px; 136 | bottom: 20px; 137 | padding: 0.5rem 0.9rem; 138 | opacity: 0; 139 | visibility: hidden; 140 | z-index: 1000; 141 | 142 | &.show { 143 | opacity: 1; 144 | visibility: visible; 145 | } 146 | } 147 | 148 | // Sections 149 | .section-subtext { 150 | text-align: center; 151 | margin-top: 2rem; 152 | margin-bottom: 3rem; 153 | } 154 | 155 | // Credit: https://codepen.io/aaroniker/pen/BajabVN 156 | .btn-email { 157 | --primary: #3b82f6; 158 | --primary-dark: #0455d8; 159 | --primary-darkest: #013281; 160 | --shadow: #{rgba(#000, 0.3)}; 161 | --text: #fff; 162 | --text-opacity: 1; 163 | --success: #3b82f6; 164 | --success-x: -12; 165 | --success-stroke: 14; 166 | --success-opacity: 0; 167 | --border-radius: 3; 168 | --overflow: hidden; 169 | --x: 0; 170 | --y: 0; 171 | --rotate: 0; 172 | --plane-x: 0; 173 | --plane-y: 0; 174 | --plane-opacity: 1; 175 | --trails: #{rgba(#3b82f6, 0.15)}; 176 | --trails-stroke: 57; 177 | --left-wing-background: var(--primary); 178 | --left-wing-first-x: 0; 179 | --left-wing-first-y: 0; 180 | --left-wing-second-x: 50; 181 | --left-wing-second-y: 0; 182 | --left-wing-third-x: 0; 183 | --left-wing-third-y: 100; 184 | --left-body-background: var(--primary); 185 | --left-body-first-x: 51; 186 | --left-body-first-y: 0; 187 | --left-body-second-x: 51; 188 | --left-body-second-y: 100; 189 | --left-body-third-x: 0; 190 | --left-body-third-y: 100; 191 | --right-wing-background: var(--primary); 192 | --right-wing-first-x: 49; 193 | --right-wing-first-y: 0; 194 | --right-wing-second-x: 100; 195 | --right-wing-second-y: 0; 196 | --right-wing-third-x: 100; 197 | --right-wing-third-y: 100; 198 | --right-body-background: var(--primary); 199 | --right-body-first-x: 49; 200 | --right-body-first-y: 0; 201 | --right-body-second-x: 49; 202 | --right-body-second-y: 100; 203 | --right-body-third-x: 100; 204 | --right-body-third-y: 100; 205 | display: block; 206 | cursor: pointer; 207 | position: relative; 208 | border: 0; 209 | padding: 8px 0; 210 | min-width: 100px; 211 | text-align: center; 212 | margin: 0; 213 | line-height: 24px; 214 | font-family: inherit; 215 | font-weight: 600; 216 | font-size: 14px; 217 | background: none; 218 | outline: none; 219 | color: var(--text); 220 | -webkit-appearance: none; 221 | -webkit-tap-highlight-color: transparent; 222 | .plane, 223 | .trails { 224 | pointer-events: none; 225 | position: absolute; 226 | } 227 | .plane { 228 | left: 0; 229 | top: 0; 230 | right: 0; 231 | bottom: 0; 232 | filter: drop-shadow(0 3px 6px var(--shadow)); 233 | transform: translate(calc(var(--x) * 1px), calc(var(--y) * 1px)) 234 | rotate(calc(var(--rotate) * 1deg)) translateZ(0); 235 | .left, 236 | .right { 237 | position: absolute; 238 | left: 0; 239 | top: 0; 240 | right: 0; 241 | bottom: 0; 242 | opacity: var(--plane-opacity); 243 | transform: translate( 244 | calc(var(--plane-x) * 1px), 245 | calc(var(--plane-y) * 1px) 246 | ) 247 | translateZ(0); 248 | &:before, 249 | &:after { 250 | content: ""; 251 | position: absolute; 252 | left: 0; 253 | top: 0; 254 | right: 0; 255 | bottom: 0; 256 | border-radius: calc(var(--border-radius) * 1px); 257 | transform: translate(var(--part-x, 0.4%), var(--part-y, 0)) 258 | translateZ(0); 259 | z-index: var(--z-index, 2); 260 | background: var(--background, var(--left-wing-background)); 261 | clip-path: polygon( 262 | calc(var(--first-x, var(--left-wing-first-x)) * 1%) 263 | calc(var(--first-y, var(--left-wing-first-y)) * 1%), 264 | calc(var(--second-x, var(--left-wing-second-x)) * 1%) 265 | calc(var(--second-y, var(--left-wing-second-y)) * 1%), 266 | calc(var(--third-x, var(--left-wing-third-x)) * 1%) 267 | calc(var(--third-y, var(--left-wing-third-y)) * 1%) 268 | ); 269 | } 270 | } 271 | .left:after { 272 | --part-x: -1%; 273 | --z-index: 1; 274 | --background: var(--left-body-background); 275 | --first-x: var(--left-body-first-x); 276 | --first-y: var(--left-body-first-y); 277 | --second-x: var(--left-body-second-x); 278 | --second-y: var(--left-body-second-y); 279 | --third-x: var(--left-body-third-x); 280 | --third-y: var(--left-body-third-y); 281 | } 282 | .right:before { 283 | --part-x: -1%; 284 | --z-index: 2; 285 | --background: var(--right-wing-background); 286 | --first-x: var(--right-wing-first-x); 287 | --first-y: var(--right-wing-first-y); 288 | --second-x: var(--right-wing-second-x); 289 | --second-y: var(--right-wing-second-y); 290 | --third-x: var(--right-wing-third-x); 291 | --third-y: var(--right-wing-third-y); 292 | } 293 | .right:after { 294 | --part-x: 0; 295 | --z-index: 1; 296 | --background: var(--right-body-background); 297 | --first-x: var(--right-body-first-x); 298 | --first-y: var(--right-body-first-y); 299 | --second-x: var(--right-body-second-x); 300 | --second-y: var(--right-body-second-y); 301 | --third-x: var(--right-body-third-x); 302 | --third-y: var(--right-body-third-y); 303 | } 304 | } 305 | .trails { 306 | display: block; 307 | width: 33px; 308 | height: 64px; 309 | top: -4px; 310 | left: 16px; 311 | fill: none; 312 | stroke: var(--trails); 313 | stroke-linecap: round; 314 | stroke-width: 2; 315 | stroke-dasharray: 57px; 316 | stroke-dashoffset: calc(var(--trails-stroke) * 1px); 317 | transform: rotate(68deg) translateZ(0); 318 | } 319 | span { 320 | display: block; 321 | position: relative; 322 | z-index: 4; 323 | opacity: var(--text-opacity); 324 | &.success { 325 | z-index: 0; 326 | position: absolute; 327 | left: 0; 328 | right: 0; 329 | top: 8px; 330 | transform: translateX(calc(var(--success-x) * 1px)) translateZ(0); 331 | opacity: var(--success-opacity); 332 | color: var(--success); 333 | svg { 334 | display: inline-block; 335 | vertical-align: top; 336 | width: 16px; 337 | height: 16px; 338 | margin: 4px 8px 0 0; 339 | fill: none; 340 | stroke-width: 2; 341 | stroke-linecap: round; 342 | stroke-linejoin: round; 343 | stroke-dasharray: 14px; 344 | stroke: var(--success); 345 | stroke-dashoffset: calc(var(--success-stroke) * 1px); 346 | } 347 | } 348 | } 349 | } 350 | 351 | .blue-link-underline { 352 | color: #0b63f3; 353 | border-bottom: 1px solid #0b63f3; 354 | } 355 | 356 | .flex { 357 | display: flex; 358 | } 359 | 360 | // Image colours 361 | .white-image { 362 | filter: brightness(0) invert(1); 363 | } 364 | 365 | // Global media queries 366 | .hide-for-mobile { 367 | @media screen and (max-width: 999px) { 368 | display: none; 369 | } 370 | } 371 | 372 | .hide-for-desktop { 373 | @media screen and (min-width: 1000px) { 374 | display: none; 375 | } 376 | } 377 | -------------------------------------------------------------------------------- /dist/css/main.css: -------------------------------------------------------------------------------- 1 | html { 2 | scroll-behavior: smooth; 3 | } 4 | 5 | * { 6 | margin: 0; 7 | padding: 0; 8 | box-sizing: border-box; 9 | font-family: "Nunito", sans-serif; 10 | } 11 | 12 | body { 13 | padding: 0; 14 | line-height: 1.5; 15 | background: #181a1b; 16 | } 17 | body .noscroll { 18 | overflow-x: hidden; 19 | } 20 | 21 | a { 22 | text-decoration: none; 23 | color: white; 24 | } 25 | 26 | .main-font { 27 | font-family: "Nunito", sans-serif; 28 | } 29 | 30 | .text-center { 31 | text-align: center; 32 | } 33 | 34 | .my-1 { 35 | margin: 1rem 0; 36 | } 37 | 38 | .mx-1 { 39 | margin: 0 0.5rem; 40 | } 41 | 42 | .h-100 { 43 | height: 100%; 44 | } 45 | 46 | .container { 47 | max-width: 1200px; 48 | padding: 1.5rem 1.5rem; 49 | margin: auto; 50 | overflow: hidden; 51 | transition: all 0.3s ease; 52 | } 53 | 54 | .text-blue { 55 | color: #3b82f6; 56 | } 57 | 58 | .text-white { 59 | color: white; 60 | } 61 | 62 | .text-grey { 63 | color: grey; 64 | } 65 | 66 | .text-dark-grey { 67 | color: #2e3031; 68 | } 69 | 70 | .bg-blue { 71 | background-color: #3b82f6; 72 | } 73 | 74 | .bg-dark-grey { 75 | background-color: #2e3031; 76 | } 77 | 78 | .bg-white { 79 | background-color: white; 80 | } 81 | 82 | .btn-blue-outline, .btn-dark, .btn-blue, .btn { 83 | display: inline-block; 84 | padding: 0.8rem 1.5rem; 85 | transition: all 0.3s; 86 | border-radius: 3px; 87 | border: none; 88 | cursor: pointer; 89 | } 90 | 91 | .btn-blue { 92 | color: white; 93 | background-color: #3b82f6; 94 | border: 2px solid #3b82f6; 95 | } 96 | .btn-dark { 97 | color: white; 98 | background-color: #181a1b; 99 | } 100 | .btn-blue-outline { 101 | color: #3b82f6; 102 | background-color: transparent; 103 | border: 2px solid #3b82f6; 104 | } 105 | .btn-blue:hover { 106 | transition: all 0.3s ease; 107 | background: #0b63f3; 108 | border: 2px solid #0b63f3; 109 | } 110 | .btn-blue-outline:hover { 111 | color: white; 112 | background-color: #3b82f6; 113 | } 114 | .btn-small { 115 | padding: 0.5rem 1rem; 116 | } 117 | 118 | #backToTopBtn { 119 | position: fixed; 120 | right: 20px; 121 | bottom: 20px; 122 | padding: 0.5rem 0.9rem; 123 | opacity: 0; 124 | visibility: hidden; 125 | z-index: 1000; 126 | } 127 | #backToTopBtn.show { 128 | opacity: 1; 129 | visibility: visible; 130 | } 131 | 132 | .section-subtext { 133 | text-align: center; 134 | margin-top: 2rem; 135 | margin-bottom: 3rem; 136 | } 137 | 138 | .btn-email { 139 | --primary: #3b82f6; 140 | --primary-dark: #0455d8; 141 | --primary-darkest: #013281; 142 | --shadow: rgba(0, 0, 0, 0.3); 143 | --text: #fff; 144 | --text-opacity: 1; 145 | --success: #3b82f6; 146 | --success-x: -12; 147 | --success-stroke: 14; 148 | --success-opacity: 0; 149 | --border-radius: 3; 150 | --overflow: hidden; 151 | --x: 0; 152 | --y: 0; 153 | --rotate: 0; 154 | --plane-x: 0; 155 | --plane-y: 0; 156 | --plane-opacity: 1; 157 | --trails: rgba(59, 130, 246, 0.15); 158 | --trails-stroke: 57; 159 | --left-wing-background: var(--primary); 160 | --left-wing-first-x: 0; 161 | --left-wing-first-y: 0; 162 | --left-wing-second-x: 50; 163 | --left-wing-second-y: 0; 164 | --left-wing-third-x: 0; 165 | --left-wing-third-y: 100; 166 | --left-body-background: var(--primary); 167 | --left-body-first-x: 51; 168 | --left-body-first-y: 0; 169 | --left-body-second-x: 51; 170 | --left-body-second-y: 100; 171 | --left-body-third-x: 0; 172 | --left-body-third-y: 100; 173 | --right-wing-background: var(--primary); 174 | --right-wing-first-x: 49; 175 | --right-wing-first-y: 0; 176 | --right-wing-second-x: 100; 177 | --right-wing-second-y: 0; 178 | --right-wing-third-x: 100; 179 | --right-wing-third-y: 100; 180 | --right-body-background: var(--primary); 181 | --right-body-first-x: 49; 182 | --right-body-first-y: 0; 183 | --right-body-second-x: 49; 184 | --right-body-second-y: 100; 185 | --right-body-third-x: 100; 186 | --right-body-third-y: 100; 187 | display: block; 188 | cursor: pointer; 189 | position: relative; 190 | border: 0; 191 | padding: 8px 0; 192 | min-width: 100px; 193 | text-align: center; 194 | margin: 0; 195 | line-height: 24px; 196 | font-family: inherit; 197 | font-weight: 600; 198 | font-size: 14px; 199 | background: none; 200 | outline: none; 201 | color: var(--text); 202 | -webkit-appearance: none; 203 | -webkit-tap-highlight-color: transparent; 204 | } 205 | .btn-email .plane, 206 | .btn-email .trails { 207 | pointer-events: none; 208 | position: absolute; 209 | } 210 | .btn-email .plane { 211 | left: 0; 212 | top: 0; 213 | right: 0; 214 | bottom: 0; 215 | filter: drop-shadow(0 3px 6px var(--shadow)); 216 | transform: translate(calc(var(--x) * 1px), calc(var(--y) * 1px)) rotate(calc(var(--rotate) * 1deg)) translateZ(0); 217 | } 218 | .btn-email .plane .left, 219 | .btn-email .plane .right { 220 | position: absolute; 221 | left: 0; 222 | top: 0; 223 | right: 0; 224 | bottom: 0; 225 | opacity: var(--plane-opacity); 226 | transform: translate(calc(var(--plane-x) * 1px), calc(var(--plane-y) * 1px)) translateZ(0); 227 | } 228 | .btn-email .plane .left:before, .btn-email .plane .left:after, 229 | .btn-email .plane .right:before, 230 | .btn-email .plane .right:after { 231 | content: ""; 232 | position: absolute; 233 | left: 0; 234 | top: 0; 235 | right: 0; 236 | bottom: 0; 237 | border-radius: calc(var(--border-radius) * 1px); 238 | transform: translate(var(--part-x, 0.4%), var(--part-y, 0)) translateZ(0); 239 | z-index: var(--z-index, 2); 240 | background: var(--background, var(--left-wing-background)); 241 | clip-path: polygon(calc(var(--first-x, var(--left-wing-first-x)) * 1%) calc(var(--first-y, var(--left-wing-first-y)) * 1%), calc(var(--second-x, var(--left-wing-second-x)) * 1%) calc(var(--second-y, var(--left-wing-second-y)) * 1%), calc(var(--third-x, var(--left-wing-third-x)) * 1%) calc(var(--third-y, var(--left-wing-third-y)) * 1%)); 242 | } 243 | .btn-email .plane .left:after { 244 | --part-x: -1%; 245 | --z-index: 1; 246 | --background: var(--left-body-background); 247 | --first-x: var(--left-body-first-x); 248 | --first-y: var(--left-body-first-y); 249 | --second-x: var(--left-body-second-x); 250 | --second-y: var(--left-body-second-y); 251 | --third-x: var(--left-body-third-x); 252 | --third-y: var(--left-body-third-y); 253 | } 254 | .btn-email .plane .right:before { 255 | --part-x: -1%; 256 | --z-index: 2; 257 | --background: var(--right-wing-background); 258 | --first-x: var(--right-wing-first-x); 259 | --first-y: var(--right-wing-first-y); 260 | --second-x: var(--right-wing-second-x); 261 | --second-y: var(--right-wing-second-y); 262 | --third-x: var(--right-wing-third-x); 263 | --third-y: var(--right-wing-third-y); 264 | } 265 | .btn-email .plane .right:after { 266 | --part-x: 0; 267 | --z-index: 1; 268 | --background: var(--right-body-background); 269 | --first-x: var(--right-body-first-x); 270 | --first-y: var(--right-body-first-y); 271 | --second-x: var(--right-body-second-x); 272 | --second-y: var(--right-body-second-y); 273 | --third-x: var(--right-body-third-x); 274 | --third-y: var(--right-body-third-y); 275 | } 276 | .btn-email .trails { 277 | display: block; 278 | width: 33px; 279 | height: 64px; 280 | top: -4px; 281 | left: 16px; 282 | fill: none; 283 | stroke: var(--trails); 284 | stroke-linecap: round; 285 | stroke-width: 2; 286 | stroke-dasharray: 57px; 287 | stroke-dashoffset: calc(var(--trails-stroke) * 1px); 288 | transform: rotate(68deg) translateZ(0); 289 | } 290 | .btn-email span { 291 | display: block; 292 | position: relative; 293 | z-index: 4; 294 | opacity: var(--text-opacity); 295 | } 296 | .btn-email span.success { 297 | z-index: 0; 298 | position: absolute; 299 | left: 0; 300 | right: 0; 301 | top: 8px; 302 | transform: translateX(calc(var(--success-x) * 1px)) translateZ(0); 303 | opacity: var(--success-opacity); 304 | color: var(--success); 305 | } 306 | .btn-email span.success svg { 307 | display: inline-block; 308 | vertical-align: top; 309 | width: 16px; 310 | height: 16px; 311 | margin: 4px 8px 0 0; 312 | fill: none; 313 | stroke-width: 2; 314 | stroke-linecap: round; 315 | stroke-linejoin: round; 316 | stroke-dasharray: 14px; 317 | stroke: var(--success); 318 | stroke-dashoffset: calc(var(--success-stroke) * 1px); 319 | } 320 | 321 | .blue-link-underline { 322 | color: #0b63f3; 323 | border-bottom: 1px solid #0b63f3; 324 | } 325 | 326 | .flex { 327 | display: flex; 328 | } 329 | 330 | .white-image { 331 | filter: brightness(0) invert(1); 332 | } 333 | 334 | @media screen and (max-width: 999px) { 335 | .hide-for-mobile { 336 | display: none; 337 | } 338 | } 339 | 340 | @media screen and (min-width: 1000px) { 341 | .hide-for-desktop { 342 | display: none; 343 | } 344 | } 345 | 346 | header { 347 | background: #181a1b; 348 | background-size: cover; 349 | min-height: 80vh; 350 | position: relative; 351 | } 352 | header #particles-js { 353 | height: 80vh; 354 | position: relative; 355 | } 356 | header #particles-js canvas { 357 | position: absolute; 358 | top: 0; 359 | left: 0; 360 | bottom: 0; 361 | width: 100%; 362 | height: 100%; 363 | } 364 | header nav { 365 | width: 100%; 366 | } 367 | header nav .nav-container { 368 | position: relative; 369 | display: flex; 370 | justify-content: space-between; 371 | } 372 | header nav .nav-container #logo { 373 | margin: auto 0; 374 | z-index: 10; 375 | } 376 | header nav .nav-container #logo img { 377 | width: 250px; 378 | } 379 | header nav .nav-container .nav-links { 380 | z-index: 1000; 381 | } 382 | header nav .nav-container .nav-links li { 383 | list-style: none; 384 | display: flex; 385 | flex-direction: row; 386 | align-items: center; 387 | margin-left: 2rem; 388 | } 389 | header nav .nav-container .nav-links a { 390 | text-decoration: none; 391 | letter-spacing: 2px; 392 | color: white; 393 | } 394 | header nav .nav-container .nav-links .link::after { 395 | content: ""; 396 | position: relative; 397 | display: block; 398 | width: 0%; 399 | height: 2px; 400 | top: 3px; 401 | margin: auto; 402 | background: #3b82f6; 403 | transition: width 0.3s ease; 404 | } 405 | header nav .nav-container .nav-links .link:hover::after { 406 | width: 100%; 407 | } 408 | header nav .mobile-menu { 409 | position: relative; 410 | z-index: 1000; 411 | } 412 | header nav .mobile-menu .container { 413 | padding-top: 0; 414 | } 415 | header nav .mobile-menu .container .mobile-menu-links ul { 416 | justify-content: center; 417 | align-items: center; 418 | list-style-type: none; 419 | } 420 | header nav .mobile-menu .container .mobile-menu-links ul li { 421 | margin: 0rem 1rem; 422 | } 423 | header nav .mobile-menu .container .mobile-menu-links ul .link::after { 424 | content: ""; 425 | position: relative; 426 | display: block; 427 | width: 0; 428 | height: 2px; 429 | top: 3px; 430 | margin: auto; 431 | background: #3b82f6; 432 | transition: width 0.3s ease; 433 | } 434 | header nav .mobile-menu .container .mobile-menu-links ul .link:hover::after { 435 | width: 100%; 436 | } 437 | header .hero { 438 | z-index: 5; 439 | position: absolute; 440 | top: 50%; 441 | left: 50%; 442 | transform: translate(-50%, -50%); 443 | } 444 | header .hero h1, 445 | header .hero p { 446 | color: white; 447 | } 448 | header .hero h1, 449 | header .hero h2 span { 450 | letter-spacing: 2px; 451 | white-space: nowrap; 452 | text-align: center; 453 | font-size: clamp(2rem, 5vw, 4rem); 454 | font-weight: bold; 455 | } 456 | header .hero p { 457 | color: #dcdcdc; 458 | line-height: 1.6; 459 | font-size: clamp(1.25rem, 2vw, 1.5rem); 460 | text-align: center; 461 | max-width: 800px; 462 | margin: 0 auto; 463 | padding: 0.5rem; 464 | } 465 | header .hero p .blue-link-underline { 466 | color: #3783ff; 467 | } 468 | header .hero .hero-btns { 469 | white-space: nowrap; 470 | text-align: center; 471 | margin-top: 1rem; 472 | } 473 | header .socials { 474 | position: absolute; 475 | bottom: 40%; 476 | left: -125px; 477 | z-index: 10; 478 | } 479 | header .socials ul { 480 | display: flex; 481 | flex-direction: column; 482 | align-items: flex-end; 483 | } 484 | header .socials ul li { 485 | transition: 0.3s; 486 | width: 100%; 487 | display: flex; 488 | justify-content: end; 489 | font-size: 1.5rem; 490 | width: 100%; 491 | height: 100%; 492 | } 493 | header .socials ul li a { 494 | text-align: right; 495 | height: 100%; 496 | width: 100%; 497 | padding: 15px 20px; 498 | } 499 | header .socials ul li a i { 500 | font-size: 1.75rem; 501 | margin-left: 1.5rem; 502 | } 503 | header .socials ul li:hover { 504 | transform: translateX(115px); 505 | } 506 | header .scroll-btn-container { 507 | position: absolute; 508 | width: 100%; 509 | background: red; 510 | bottom: 150px; 511 | } 512 | header .scroll-btn-container div { 513 | display: flex; 514 | justify-content: center; 515 | width: 100%; 516 | } 517 | header .scroll-btn-container div a { 518 | display: flex; 519 | flex-direction: column; 520 | justify-content: space-between; 521 | } 522 | header .scroll-btn-container div a span { 523 | display: block; 524 | height: 20px; 525 | width: 20px; 526 | border-bottom: 2px solid #3b82f6; 527 | border-right: 2px solid #3b82f6; 528 | transform: rotate(45deg); 529 | margin: -20px 0; 530 | animation: animate 2s infinite; 531 | } 532 | header .scroll-btn-container div a span:nth-child(2) { 533 | animation-delay: -0.2s; 534 | } 535 | header .scroll-btn-container div a span:nth-child(3) { 536 | animation-delay: -0.4s; 537 | } 538 | @keyframes animate { 539 | 0% { 540 | opacity: 0; 541 | transform: rotate(45deg) translate(-20px, -20px); 542 | } 543 | 50% { 544 | opacity: 1; 545 | } 546 | 100% { 547 | opacity: 0; 548 | transform: rotate(45deg) translate(20px, 20px); 549 | } 550 | } 551 | header .seperator-skew { 552 | position: absolute; 553 | bottom: 0; 554 | left: 0; 555 | right: 0; 556 | height: 150px; 557 | width: 100%; 558 | overflow: hidden; 559 | } 560 | header .seperator-skew svg { 561 | position: absolute; 562 | bottom: 0; 563 | } 564 | header .seperator-skew svg .fill-white { 565 | fill: white; 566 | } 567 | 568 | @media screen and (max-width: 999px) { 569 | header nav .container { 570 | padding-bottom: 0.75rem; 571 | } 572 | header nav .nav-container { 573 | justify-content: center; 574 | } 575 | header .hero { 576 | top: 55%; 577 | } 578 | header .socials { 579 | display: none; 580 | } 581 | } 582 | @media screen and (max-width: 768px) { 583 | .hero { 584 | width: 90%; 585 | } 586 | header nav .nav-container #logo img { 587 | width: 200px; 588 | } 589 | } 590 | @media screen and (max-width: 500px) { 591 | header nav .nav-container #logo { 592 | font-size: 1.5rem; 593 | } 594 | header nav .mobile-menu .container .mobile-menu-links ul li { 595 | margin: 0 0.5rem; 596 | } 597 | header .hero span { 598 | max-width: 100%; 599 | } 600 | header .hero p { 601 | width: 100%; 602 | } 603 | } 604 | @media screen and (min-height: 900px) { 605 | header { 606 | min-height: 70vh; 607 | } 608 | header #particles-js { 609 | height: 70vh; 610 | } 611 | } 612 | .projects { 613 | background: white; 614 | padding: 3rem 0; 615 | } 616 | .projects h2, 617 | .projects h2 span { 618 | text-align: center; 619 | margin-bottom: 3rem; 620 | font-weight: bold; 621 | } 622 | .projects .project-row { 623 | display: flex; 624 | margin-bottom: 3rem; 625 | } 626 | .projects .project-row .project-left { 627 | width: 50%; 628 | margin-right: 2rem; 629 | } 630 | .projects .project-row .project-left img { 631 | width: 100%; 632 | border: 1px solid lightgray; 633 | } 634 | .projects .project-row .project-right { 635 | width: 50%; 636 | display: flex; 637 | flex-direction: column; 638 | justify-content: center; 639 | } 640 | .projects .project-row .project-right h3 { 641 | font-size: 1.25rem; 642 | } 643 | .projects .project-row .project-right .tech-stack-list { 644 | display: flex; 645 | flex-wrap: wrap; 646 | list-style-type: none; 647 | margin-top: 1rem; 648 | } 649 | .projects .project-row .project-right .tech-stack-list p { 650 | margin-right: 1rem; 651 | } 652 | .projects .project-row .project-right .tech-stack-list li { 653 | margin-right: 20px; 654 | font-size: 1.5rem; 655 | } 656 | .projects .project-row .project-right .project-links { 657 | margin-top: 1rem; 658 | } 659 | .projects .project-row #webscraper { 660 | background-image: url("../img/top10songs.JPG"); 661 | background-size: 100% 100%; 662 | background-repeat: no-repeat; 663 | -webkit-transition: background-image 0.2s ease-in-out; 664 | transition: background-image 0.2s ease-in-out; 665 | } 666 | .projects .project-row #webscraper:hover { 667 | background-image: url("../img/top10songs.gif"); 668 | } 669 | 670 | @media screen and (max-width: 860px) { 671 | .projects .project-row { 672 | display: flex; 673 | margin-bottom: 3rem; 674 | flex-direction: column; 675 | } 676 | .projects .project-row .project-left { 677 | width: 100%; 678 | } 679 | .projects .project-row .project-right { 680 | width: 100%; 681 | } 682 | } 683 | @media screen and (max-width: 500px) { 684 | .project-left { 685 | min-height: 200px; 686 | } 687 | } 688 | @media screen and (min-width: 501px) and (max-width: 700px) { 689 | .project-left { 690 | min-height: 300px; 691 | } 692 | } 693 | @media screen and (min-width: 701px) and (max-width: 859px) { 694 | .project-left { 695 | min-height: 350px; 696 | } 697 | } 698 | .education { 699 | background: white; 700 | padding-bottom: 3rem; 701 | } 702 | .education .container { 703 | max-width: 900px; 704 | } 705 | .education .container h2 { 706 | text-align: center; 707 | color: black; 708 | margin-bottom: 3rem; 709 | } 710 | .education .container .education-card { 711 | display: flex; 712 | flex-direction: column; 713 | justify-content: space-between; 714 | box-shadow: 0 0.15rem 0.6rem rgba(43, 52, 56, 0.15); 715 | padding: 40px; 716 | border-radius: 3px; 717 | } 718 | .education .container .education-card > *:last-child { 719 | margin-top: 40px; 720 | } 721 | @media (max-width: 500px) { 722 | .education .container .education-card { 723 | padding: 20px; 724 | } 725 | } 726 | .education .container .education-card .education-card-column { 727 | display: flex; 728 | } 729 | .education .container .education-card .education-card-column .card-column-image { 730 | flex: 0 0 20%; 731 | } 732 | .education .container .education-card .education-card-column .card-column-image img { 733 | width: 100%; 734 | } 735 | .education .container .education-card .education-card-column .card-column-large { 736 | flex: 0 0 80%; 737 | padding-left: 1.5rem; 738 | } 739 | .education .container .education-card .education-card-column .card-column-large > * { 740 | margin: 0.25rem 0; 741 | } 742 | .education .container .education-card .education-card-column .card-column-large h4 { 743 | font-weight: normal; 744 | } 745 | .education .container .education-card .education-card-column .card-column-large ul { 746 | padding-left: 1.5rem; 747 | } 748 | .education .container .education-card .education-card-column .card-column-large hr { 749 | border: 0; 750 | border-top: 1px solid #eee; 751 | margin-top: 40px; 752 | } 753 | 754 | .skills { 755 | padding: 3rem 0; 756 | position: relative; 757 | overflow: hidden; 758 | } 759 | .skills canvas { 760 | position: absolute; 761 | top: 0; 762 | left: 0; 763 | bottom: 0; 764 | width: 100%; 765 | height: 100%; 766 | } 767 | .skills h2, 768 | .skills h2 span { 769 | text-align: center; 770 | margin-bottom: 3rem; 771 | font-weight: bold; 772 | } 773 | .skills .container { 774 | padding: 6rem 0; 775 | } 776 | .skills .skills-icons { 777 | list-style-type: none; 778 | display: flex; 779 | flex-wrap: wrap; 780 | justify-content: center; 781 | max-width: 1100px; 782 | margin: 0 auto; 783 | position: relative; 784 | z-index: 10; 785 | } 786 | .skills .skills-icons svg { 787 | margin: 0.5rem; 788 | width: 90px; 789 | } 790 | @media (max-width: 420px) { 791 | .skills .skills-icons svg { 792 | width: 70px; 793 | } 794 | } 795 | .skills .skills-icons li { 796 | transition: 0.3s; 797 | display: flex; 798 | flex-direction: column; 799 | justify-content: center; 800 | align-items: center; 801 | color: white; 802 | font-size: 1rem; 803 | margin: 1rem; 804 | } 805 | @media (max-width: 420px) { 806 | .skills .skills-icons li { 807 | margin: 1rem 0.75rem; 808 | } 809 | } 810 | .skills .skills-icons li .aws-logo { 811 | background: white; 812 | padding: 10px; 813 | border-radius: 3px; 814 | } 815 | .skills .skills-icons li:hover { 816 | transform: scale(1.3); 817 | } 818 | .skills .seperator-skew-top { 819 | position: absolute; 820 | top: -1px; 821 | left: 0; 822 | right: 0; 823 | height: 150px; 824 | width: 120%; 825 | overflow: hidden; 826 | } 827 | .skills .seperator-skew-top svg { 828 | position: absolute; 829 | top: 0; 830 | transform: scaleY(-1) scaleX(-1); 831 | } 832 | .skills .seperator-skew-top svg .fill-white { 833 | fill: white; 834 | } 835 | .skills .seperator-skew-bottom { 836 | position: absolute; 837 | bottom: -0.5px; 838 | left: 0; 839 | right: 0; 840 | height: 150px; 841 | width: 120%; 842 | overflow: hidden; 843 | } 844 | .skills .seperator-skew-bottom svg { 845 | position: absolute; 846 | bottom: 0; 847 | } 848 | .skills .seperator-skew-bottom svg .fill-white { 849 | fill: white; 850 | } 851 | 852 | .contact { 853 | background: white; 854 | padding: 3rem 0; 855 | } 856 | .contact .section-title { 857 | margin-bottom: 2rem; 858 | text-align: center; 859 | } 860 | .contact .card-container { 861 | display: flex; 862 | justify-content: space-around; 863 | margin-bottom: 3rem; 864 | flex-wrap: wrap; 865 | } 866 | .contact .card-container .card { 867 | background: #fff; 868 | width: 260px; 869 | margin: 20px; 870 | padding: 30px; 871 | display: flex; 872 | justify-content: center; 873 | align-items: center; 874 | flex-direction: column; 875 | box-shadow: 0 0.15rem 0.6rem rgba(43, 52, 56, 0.15); 876 | border-radius: 3px; 877 | } 878 | .contact .card-container .card i { 879 | font-size: 3.5rem; 880 | color: #3b82f6; 881 | margin-bottom: 1rem; 882 | transition: 0.4s; 883 | } 884 | .contact .card-container .card i:hover { 885 | transform: translateY(-20%); 886 | } 887 | .contact .card-container .card > * { 888 | margin: 0.5rem; 889 | } 890 | .contact form { 891 | max-width: 600px; 892 | margin: 0 auto; 893 | border-radius: 3px; 894 | box-shadow: 0 0.15rem 0.6rem rgba(43, 52, 56, 0.15); 895 | padding: 2rem; 896 | } 897 | .contact form h2 { 898 | text-align: center; 899 | margin: 1.5rem 0; 900 | } 901 | .contact form .form-group input { 902 | margin: 0.75rem 0; 903 | width: 100%; 904 | border-radius: 3px; 905 | border: 1px solid #afafaf; 906 | padding: 0.75rem; 907 | font-size: 1rem; 908 | } 909 | .contact form .form-group input:focus { 910 | outline: none; 911 | } 912 | .contact form .form-group textarea { 913 | width: 100%; 914 | border-radius: 3px; 915 | margin: 0.75rem 0; 916 | border: 1px solid #afafaf; 917 | padding: 0.75rem; 918 | font-size: 1rem; 919 | resize: vertical; 920 | } 921 | .contact form .form-group textarea:focus { 922 | outline: none; 923 | } 924 | .contact form #status { 925 | width: 100%; 926 | text-align: center; 927 | margin: 0 auto; 928 | border-radius: 3px; 929 | color: #00b700; 930 | } 931 | .contact form #status.success { 932 | color: #00b700; 933 | animation: status 4s ease forwards; 934 | } 935 | .contact form #status.error { 936 | color: red; 937 | animation: status 4s ease forwards; 938 | } 939 | @keyframes status { 940 | 0% { 941 | opacity: 1; 942 | pointer-events: all; 943 | } 944 | 90% { 945 | opacity: 1; 946 | pointer-events: all; 947 | } 948 | 100% { 949 | opacity: 0; 950 | pointer-events: none; 951 | } 952 | } 953 | 954 | .footer { 955 | background: #181a1b; 956 | padding: 1.5rem 0; 957 | color: white; 958 | } 959 | .footer canvas { 960 | position: absolute; 961 | top: 0; 962 | left: 0; 963 | bottom: 0; 964 | width: 100%; 965 | height: 100%; 966 | } 967 | .footer .footer-flex { 968 | display: flex; 969 | justify-content: space-between; 970 | } 971 | .footer .footer-flex #logo-footer { 972 | width: 200px; 973 | } 974 | .footer .footer-flex .top-scroll-button { 975 | cursor: pointer; 976 | display: flex; 977 | justify-content: center; 978 | align-items: center; 979 | width: 35px; 980 | height: 35px; 981 | text-align: center; 982 | border: 3px solid white; 983 | border-radius: 50%; 984 | transition: 0.3s; 985 | } 986 | .footer .footer-flex .top-scroll-button:hover { 987 | color: #3b82f6; 988 | border: 3px solid #3b82f6; 989 | } 990 | .footer .footer-flex .footer-icon-links a { 991 | margin-left: 2rem; 992 | transition: 0.3s; 993 | } 994 | .footer .footer-flex .footer-icon-links a:hover { 995 | color: #3b82f6; 996 | } 997 | .footer .footer-flex .footer-icon-links a i { 998 | transition: 0.3s; 999 | } 1000 | .footer .footer-flex .footer-icon-links a i:hover { 1001 | transform: translateY(-20%); 1002 | } 1003 | 1004 | @media screen and (max-width: 500px) { 1005 | .footer .footer-flex { 1006 | flex-direction: column; 1007 | justify-content: center; 1008 | align-items: center; 1009 | } 1010 | .footer .footer-flex .top-scroll-button { 1011 | margin-top: 2rem; 1012 | } 1013 | .footer .footer-flex .footer-icon-links { 1014 | margin-top: 2rem; 1015 | } 1016 | .footer .footer-flex .footer-icon-links a { 1017 | margin: 0 1rem; 1018 | } 1019 | }/*# sourceMappingURL=main.css.map */ -------------------------------------------------------------------------------- /dist/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | 5 | 6 | 7 |120 | I'm currently working as a software developer at The University of Queensland. I spend my day working on projects with TypeScript, React.js, Node.js, PHP, Symfony and AWS. 121 |
122 | 128 |
160 | Made with:
165 |Cryptocurrency sentiment analysis on Twitter posts. Users can see the overall sentiment (positive, negative or neutral) of different Cryptocurrencies based on tweets. Users can also view keywords and an average sentiment score. React frontend and Node.js backend. Stateless application that uses Elasticache and S3 on AWS for persistence. Application was setup with an autoscaling group to scale in and out as needed.
173 | 178 |
184 | Made with:
189 |Laravel web application for companies looking to hire developers in Australia. Filter by experience, location and keywords. Companies can pay a monthly fee to be able to message developers on the site and view their information.
196 |
206 | Made with:
211 |Worked on a team of four to develop a client-server system in Java for trading of virtual assets within departments of a company. Facilitated trades via a marketplace model where users can buy and sell assets. Admins of an organisation can create assets, users and modify details. Uses MariaDB as a database and Swing for the GUI.
215 |
225 | Made with:
230 |React application that uses a REST API that I made which holds country happiness data collected from the World Happiness Report initiative. Users can register, login and view happiness data by country. Users can filter the data by year, country and search limit. AG Grid and Chart.js were used to present the data.
235 |
247 | Made with:
252 |Developed and deployed an Express API to support the front-end of the Euphorus Happiness Data web application. Routes support query parameters and authorization using JWT. Includes endpoints for countries, rankings, factors, registration, login, and profile. Tested software extensively with Jest and created Swagger documentation for the API as well.
260 | 266 |
272 | Made with:
277 |Computer Auction CRUD application built with Flask that allows users to bid, review, login/register, post new listings, manage listings, search by keyword, and keep a watch list. The website is responsive and uses Bootstrap. Internal server errors and page not found errors are also handled appropriately. The project was developed with a team using Git.
282 | 288 |
294 | Made with:
299 |Console app that manages tasks in a project. Users can load projects from a file and generate a seqeuence to complete them in, based on each task's dependencies. Users can also find earliest possible commencement time of each task, add new tasks, update tasks, remove tasks, and save the results to a text file.
302 |Made with:
317 |Python program that implements a breadth-first search algorithm to generate a minimal spanning tree. Problem was to calculate a shortest path from a starting vertex in a graph to each other vertex. The vertices represent people and each person is related to every other person through parent-child relationships. A person can see how they are related to each other person in the tree.
320 | 325 |
331 | Made with:
336 |Binary game written in C that runs on an Arduino Uno using Tinkercad. The game aims to help users learn binary by challenging them to input different integers in their binary form within a time limit.
339 | 344 |
397 | GPA 6.2/7
403 |benrogers1299@outlook.com
424 |