/* FONTS */ @import url('/fonts/source-sans-3.css'); /* GENERAL */ :root{ scroll-behavior: smooth; interpolate-size: allow-keywords; } body{ /* STYLING */ margin: 0; padding: 0; background: var(--background); color: var(--color); font-family: var(--font); /* VARIABLES */ --primary: #3498db; --secondary: #2980b9; --background: #181818; --color: #f8f8f8; --font: "Source Sans 3", Arial, Helvetica, sans-serif; --border: 2px solid var(--color); --borderPrimary: 2px solid var(--primary); --baseRadius: 12px; --baseTransition: all var(--baseDuration); --baseDuration: 250ms; --navSmallHeight: 66px; --animationOffset: 100px; --animationScale: 0.75; --animationCoverValue: 40%; } ::selection{ background: var(--primary); color: var(--color); } /* CONTENT */ .content{ margin: auto; } .inner-width{ margin: auto; width: 100%; max-width: clamp(1100px, 90%, 1250px); } /* LOADER */ /* animation credits: https://uiverse.io/shadowmurphy/yellow-lizard-30 */ .loadingscreen{ width: 100%; height: 100dvh; background: var(--primary); z-index: 1002; position: fixed; display: flex; justify-content: center; align-content: center; align-items: center; transition: var(--baseTransition); } .loadingscreen.hidden{ display: none; } .loader-logo{ width: 45%; max-width: 200px; fill: transparent; stroke: var(--color); stroke-linecap: round; stroke-width: 2.4rem; stroke-dashoffset: var(--dashoffset); stroke-dasharray: 0 var(--dashoffset); animation: loader 3.5s linear infinite; --dashoffset: 1384; } @keyframes loader { 90%, 100%{ stroke-dashoffset: 0; stroke-dasharray: var(--dashoffset) 0; } } /* NAVIGATION */ nav{ width: 100%; height: 96px; background: transparent; position: fixed; top: 0; left: 0; transition: var(--baseTransition); z-index: 1001; } nav.small{ height: var(--navSmallHeight); background: var(--primary); } nav .inner-width{ height: 100%; display: flex; flex-direction: row; justify-content: space-between; align-content: center; align-items: center; } nav img{ width: auto; height: 56px; margin-block: 20px; box-sizing: border-box; } nav.small img{ height: 41px; } .nav-links a{ /* STYLE */ color: var(--color); font-size: 1.2rem; text-decoration: none; margin: 5px 10px; /* HOVER EFFECT */ position: relative; } .nav-links a:hover, .nav-links a:focus{ text-decoration: none; outline: none; } .nav-links a:not(:last-child)::after{ content: ""; position: absolute; top: 100%; left: 0; width: 100%; height: 4px; background: var(--color); border-radius: 4px; transition: var(--baseTransition); transform: scaleX(0); } .nav-links a:not(:last-child):hover::after, .nav-links a:not(:last-child):focus::after{ transform: scaleX(0.5); } .nav-links a:last-child{ padding: 3px 16px; background: var(--primary); color: var(--color); border: 2px solid transparent; border-radius: var(--baseRadius); transition: var(--baseTransition); } nav.small .nav-links a:last-child{ background: var(--color); color: var(--primary); } .nav-links a:last-child:hover, .nav-links a:last-child:focus{ padding: 3px 30px; background: var(--secondary); border: var(--border); } nav.small .nav-links a:last-child:hover, nav.small .nav-links a:last-child:focus{ background: var(--secondary); color: var(--color); } .nav-toggle{ display: none; } @media screen and (max-width:640px){ .nav-toggle{ display: block; } .nav-links{ display: none; } nav .inner-width{ justify-content: space-between; padding: 0 20px; box-sizing: border-box; } nav.open{ height: 100dvh; background: var(--background); } nav.open .inner-width{ flex-direction: column; flex-wrap: wrap; justify-content: space-around; align-content: center; align-items: center; } nav.open .nav-links{ display: flex; flex-direction: column; flex-wrap: wrap; justify-content: center; align-content: center; align-items: center; } nav.open .nav-links a, nav i{ font-size: 2rem; } nav i{ font-size: 3rem; } .nav-links a:hover::after{ display: none; } .nav-links a:last-child, .nav-links a:last-child:hover, .nav-links a:last-child:focus, nav.small .nav-links a:last-child, nav.small .nav-links a:last-child:hover, nav.small .nav-links a:last-child:focus{ background: inherit; padding: inherit; color: inherit; border: none; } } /* HERO */ .hero{ display: flex; flex-direction: column; justify-content: center; align-content: center; align-items: center; height: 100dvh; background-image: url("assets/hero/bg_animated_4.svg"); background-size: cover; background-repeat: repeat-x; background-position: center; } .hero h1{ margin: 60px 20px 0; font-size: 6rem; transition: var(--baseTransition); letter-spacing: -0.6rem; } @media screen and (max-width:310px){ .hero h1{ font-size: 4rem; letter-spacing: -0.4rem; } } @media screen and (max-width:180px){ .hero h1{ font-size: 2.5rem; letter-spacing: -0.3rem; } } .hero h1 span{ display: inline-block; animation: wave 2s ease-in-out infinite; animation-delay: calc(0.1s * (var(--i) - 1)); } .hero h1 span .name-part{ white-space: nowrap; display: block; } .hero h1 span:nth-child(1) { --i: 1; } .hero h1 span:nth-child(2) { --i: 2; } .hero h1 span:nth-child(3) { --i: 3; } .hero h1 span:nth-child(4) { --i: 4; } .hero h1 span:nth-child(5) { --i: 5; } .hero h1 span:nth-child(6) { --i: 6; } .hero h1 span:nth-child(7) { --i: 7; } .hero h1 span:nth-child(8) { --i: 8; } .hero h1 span:nth-child(9) { --i: 9; } .hero h1 span:nth-child(10) { --i: 10; } .hero h1 span:nth-child(11) { --i: 11; } .hero h1 span:nth-child(12) { --i: 12; } .hero h1 span:nth-child(13) { --i: 13; } .hero h1 span:nth-child(14) { --i: 14; } @keyframes wave{ 0%, 100%{ transform: translateY(0); } 50%{ transform: translateY(-20px); } } .hero p{ margin: 0 20px; font-size: 2rem; } .hero a{ margin: 60px 0 0 0; color: var(--color); text-decoration: none; font-size: 3rem; padding: 5px 15px; border-radius: 50%; transition: var(--baseTransition); animation: scrollHint 2000ms infinite; } .hero a:hover, .hero a:focus{ filter: drop-shadow(0 0 1.1rem var(--primary)); } @keyframes scrollHint{ 0%, 100%{ transform: translateY(0%); } 40%{ transform: translateY(10%); } } /* ABOUT */ .about{ display: flex; flex-direction: row; justify-content: space-between; align-content: stretch; align-items: stretch; padding: 20px; scroll-margin-top: var(--navSmallHeight); } @media screen and (max-width:690px){ .about{ flex-direction: column; } } .about-part{ width: calc(100% - 20px); margin: 0 10px; box-sizing: border-box; } .about img{ padding: 10px; width: 100%; box-sizing: border-box; border-radius: 50%; border: var(--baseRadius) solid var(--primary); transition: var(--baseTransition); } @media (pointer: fine){ .about img:hover{ padding: 0px; } } .about a{ color: var(--color); text-decoration: underline; text-decoration-thickness: 2px; text-decoration-color: var(--primary); transition: var(--baseTransition); } .about a:hover, .about a:focus{ background: var(--primary); outline: none; } .about var{ font-style: normal; } /* PROJECTS */ .projects{ margin-top: 30px; text-align: center; scroll-margin-top: calc(var(--navSmallHeight) + 10px); } .projects-intro{ padding: 0 10px; box-sizing: border-box; } .tag-filter{ display: flex; flex-direction: row; justify-content: center; align-content: flex-start; align-items: baseline; flex-wrap: wrap; -webkit-user-select: none; user-select: none; } .tag-filter.hidden{ display: none; } .tag{ background: var(--color); color: var(--primary); margin: 10px 5px; padding: 5px 16px; font-size: 1rem; border-radius: var(--baseRadius); transition: var(--baseTransition); border: 2px solid var(--primary); cursor: pointer; } .tag input{ display: none; } .tag:has(:checked){ background: var(--primary); color: var(--color); } .tag:hover, .tag:focus{ padding: 5px 26px; background: var(--secondary); color: var(--color); border: var(--border); } .project-list{ padding: 10px 0 20px 0; display: flex; flex-direction: row; flex-wrap: wrap; justify-content: center; align-content: stretch; align-items: stretch; } .project-load-btn{ padding: 10px 20px; background: var(--primary); color: var(--color); font-size: 1rem; border: 2px solid transparent; border-radius: var(--baseRadius); transition: var(--baseTransition); opacity: 1; } .project-load-btn.hidden{ opacity: 0; } .project-load-btn:hover, .project-load-btn:focus{ padding: 10px 40px; background: var(--secondary); border: var(--border); cursor: pointer; } .no-projects{ font-size: 1.8rem; font-weight: 600; transition: var(--baseTransition); } .no-projects.hidden{ opacity: 0; scale: 0; height: 0; } .no-projects i{ font-size: 3rem; } /* hide load more btn when no projects are shown */ .project-list:not(:has(.project-card:not(.hidden))) ~ .project-load .project-load-btn{ display: none; } /* Card animation: https://uiverse.io/suleymanlaarabidev/perfect-husky-88 */ .project-card{ width: 30%; min-width: 300px; min-height: 250px; margin: 20px 10px; padding: 0 10px; background: var(--primary); background-size: cover; background-repeat: no-repeat; background-position: center; border: none; outline: none; border-radius: var(--baseRadius); transition: var(--baseTransition); box-shadow: var(--boxShadow); overflow: hidden; position: relative; --boxShadow: 0px 0px 10px 5px rgba(0, 0, 0, 0.705); --backgroundImage: url("assets/projects/sprinkle.svg"); --fontSizeH2: 1.2rem; --fontSizeIcon: 2.5rem; --fontSizeP: 1.1rem; --fontWeightP: 600; } .project-card a{ color: inherit; text-decoration: none; font-style: inherit; } .project-card.hidden{ animation: fade-out var(--baseDuration) ease-in-out; animation-fill-mode: forwards; } .card-first img{ position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); width: auto; height: 100%; } @media (pointer: fine){ .project-card:hover, .project-card:focus{ background: var(--primary); background-image: var(--backgroundImage); background-size: cover; background-repeat: no-repeat; background-position: center; box-shadow: var(--boxShadow); cursor: pointer; overflow: hidden; } .card-first{ width: 100%; height: 100%; display: flex; flex-direction: column; justify-content: center; align-items: center; transition: var(--baseTransition); opacity: 1; } .card-first img{ --buffer: 5px; width: calc(100% + var(--buffer)); height: calc(100% + var(--buffer)); object-fit: cover; } .project-card:hover .card-first, .project-card:focus .card-first{ height: 0; opacity: 0; } .card-second{ width: 100%; height: 0; display: flex; flex-direction: column; justify-content: center; align-items: center; transition: var(--baseTransition); opacity: 0; font-size: 0; transform: rotate(90deg) scale(-1); } .project-card:hover .card-second, .project-card:focus .card-second{ height: 100%; opacity: 1; font-size: 1rem; transform: rotate(0deg); } .project-card:hover .card-second h2, .project-card:focus .card-second h2{ font-size: var(--fontSizeH2); } .project-card:hover .card-second p, .project-card:focus .card-second p{ font-size: var(--fontSizeP);; font-weight: var(--fontWeightP); } .project-card:hover .card-second i, .project-card:focus .card-second i{ font-size: var(--fontSizeIcon);; } } @media (pointer: coarse) or (pointer: none){ .project-card{ background: var(--primary); background-image: var(--backgroundImage); background-size: cover; background-repeat: no-repeat; background-position: center; box-shadow: var(--boxShadow); } .card-first img{ height: calc(100% + 60px); filter: blur(6px) brightness(0.6); } .card-second{ width: 100%; height: 100%; display: flex; flex-direction: column; justify-content: center; align-items: center; transition: var(--baseTransition); height: 100%; opacity: 1; font-size: 1rem; transform: rotate(0deg); } .project-card .card-second h2{ font-size: var(--fontSizeH2); } .project-card .card-second p{ font-size: var(--fontSizeP); font-weight: var(--fontWeightP); } .project-card .card-second i{ font-size: var(--fontSizeIcon); } } /* PROJECTS LOADER */ /* credits: https://uiverse.io/AbanoubMagdy1/evil-bullfrog-30 */ .project-loader-wrapper{ width: 100%; height: calc(var(--size) * 2); margin: 0 0 var(--size) 0; display: flex; justify-content: center; align-content: center; align-items: center; --size: 2.5rem; --factor: 2.5; --duration: 2s; --background: var(--primary); } .project-loader-wrapper.hidden{ display: none; } .project-loader{ width: var(--size); height: var(--size); position: relative; animation: circleLoader var(--duration) linear infinite; transition: var(--baseTransition); } .project-loader:hover{ --size: 3rem; --background: var(--secondary); } .project-loader-circle{ width: calc(var(--size) / var(--factor)); height: calc(var(--size) / var(--factor)); background: var(--background); border-radius: 50%; position: absolute; transition: var(--baseTransition); } .project-loader-circle:nth-child(1){ top: 0; left: 0; } .project-loader-circle:nth-child(2){ top: 0; right: 0; } .project-loader-circle:nth-child(3){ bottom: 0; left: 0; } .project-loader-circle:nth-child(4){ bottom: 0; right: 0; } @keyframes circleLoader{ 0%{ scale: 1; rotate: 0deg; } 20%, 25%{ scale: 1.3; rotate: 90deg; } 45%, 50%{ scale: 1; rotate: 180deg; } 70%, 75%{ scale: 1.3; rotate: 270deg; } 95%, 100%{ scale: 1; rotate: 360deg; } } /* FACTS */ .facts{ margin-top: 30px; padding-bottom: 20px; text-align: center; scroll-margin-top: calc(var(--navSmallHeight) + 10px); } .fact-container{ display: flex; flex-direction: row; justify-content: space-around; } .fact{ display: flex; flex-direction: column; font-size: 1.2rem; font-weight: 600; width: 100%; padding-block: 40px 20px; } .fact p{ margin: 5px 0; padding: 0; } @media screen and (max-width:690px){ .fact-container{ flex-direction: column; } .fact{ padding-block: 10px; } } @property --factCounter{ syntax: ''; initial-value: 0; inherits: false; } .fact-counter{ font-size: 3.8rem; font-weight: 700; color: var(--primary); transition: --factCounter 1s, var(--baseTransition); counter-reset: factCounter var(--factCounter); } @media (pointer: fine){ .fact-counter:hover, .fact-counter:focus{ transform: scale(1.1); transition: var(--baseTransition); filter: drop-shadow(0 0 0.6rem var(--primary)); } } .fact-counter::after{ content: counter(factCounter); } /* FAQ */ .faq{ padding-block: 40px; text-align: center; scroll-margin-top: calc(var(--navSmallHeight) + 20px); } .faq-container{ padding-inline: 30px; display: flex; flex-direction: column; justify-content: center; align-content: center; align-items: stretch; } .faq details{ margin: 14px 0; padding: 10px 20px; background: var(--primary); border: var(--borderPrimary); border-radius: var(--baseRadius); text-align: left; cursor: pointer; overflow: hidden; } .faq details:hover, .faq details:focus-within{ background: var(--secondary); border: var(--border); outline: none; } .faq details::selection{ background: var(--color); color: var(--secondary); } /* animation credits: https://www.youtube.com/watch?v=Vzj3jSUbMtI */ .faq details::details-content{ block-size: 0; transition: block-size var(--baseDuration) linear, content-visibility var(--baseDuration) linear; transition-behavior: allow-discrete; } .faq details[open]::details-content{ block-size: auto; } .faq summary{ position: relative; padding-inline: 2.4rem;; font-size: 1.2rem; font-weight: 600; list-style-position: outside; } .faq summary:focus{ outline: none; } .faq summary::marker{ content: none; } .faq summary::-webkit-details-marker{ display: none; } .faq summary::before{ content: "\f156"; font-family: akar-icons; position: absolute; inset-inline-start: 0.3rem; inset-block-start: 0.25rem; transition: var(--baseTransition); } .faq details[open] summary::before{ rotate: -180deg; } /* CONTACT */ .contact{ display: flex; flex-direction: column; justify-content: center; align-content: center; align-items: center; height: 100dvh; background-image: url("assets/hero/bg_animated_4.svg"); background-size: cover; background-repeat: repeat-x; background-position: center; } .contact h1{ margin: inherit 20px; font-size: clamp(1.5rem, 10vw, 6rem); word-break: break-word; overflow: hidden; border-right: 0.15em solid var(--primary); white-space: nowrap; } @media (prefers-reduced-motion: no-preference){ /* Only runs when user did not disable animations */ .typewriter-animation{ animation: typing 2s steps(32, end), caret .75s step-end infinite; /* Typewriter effect: https://css-tricks.com/snippets/css/typewriter-effect/ */ } } @keyframes typing{ 0%{ width: 0; } 100%{ width: 100%; } } @keyframes caret { 0%, 100%{ border-color: transparent; } 50%{ border-color: var(--primary); } } .contact div{ display: flex; flex-direction: row; justify-content: space-around; align-content: center; align-items: center; } @media screen and (max-width:330px){ .contact div{ flex-direction: column; } } .contact a{ margin: 10px; font-size: 3rem; color: var(--color); text-decoration: none; transition: var(--baseTransition); } .contact a:hover, .contact a:focus{ margin: 10px 20px; color: var(--color); text-decoration: none; transform: scale(1.8); outline: none; } /* SCROLL TOP */ .scroll-top{ width: 40px; height: 40px; margin: 15px; background: var(--primary); color: var(--color); border-radius: var(--baseRadius); position: fixed; bottom: 0; right: 0; display: flex; justify-content: center; font-size: 28px; transition: var(--baseTransition); } .scroll-top a{ text-decoration: none; color: var(--color); margin-top: 0; transition: var(--baseTransition); } .scroll-top a:hover, .scroll-top a:focus{ margin-top: -5px; } .scroll-top i{ stroke-width: 3px; } /* FOOTER */ .footer{ width: 100%; height: auto; padding: 10px 80px 10px 40px; box-sizing: border-box; background: var(--primary); color: var(--color); font-size: 1rem; display: flex; flex-direction: row; justify-content: space-between; align-content: center; align-items: baseline; background-image: url("assets/projects/sprinkle.svg"); background-size: cover; background-repeat: repeat-x; background-position: center; } .footer-part, .sm-icons{ display: flex; flex-direction: row; justify-content: space-around; align-content: center; align-items: center; padding: 0 10px; } @media screen and (max-width:490px){ .footer, .footer-part{ flex-direction: column-reverse; } .footer-part{ width: calc(100% + 20px); } .sm-icons{ flex-direction: row; } .sm-icons i{ font-size: 1.4rem; } } .footer a{ margin: 10px; font-size: 1rem; color: var(--color); text-decoration: none; transition: var(--baseTransition); } .footer a:hover, .footer a:focus{ color: var(--color); text-decoration: none; outline: none; } @media (pointer: fine){ .footer a:hover:has(i), .footer a:focus:has(i){ transform: scale(1.4); } .footer a:hover:not(:has(i)), .footer a:focus:not(:has(i)){ transform: scale(1.1); } } .footer select{ background: var(--color); color: var(--primary); margin: 10px 5px; padding: 5px 16px; border-radius: var(--baseRadius); transition: var(--baseTransition); border: 1px solid var(--primary); outline: none; } /* COPYRIGHT MODAL */ .modal{ --top: calc(var(--navSmallHeight) - 15px); width: calc(100% - 40px); max-width: 700px; height: auto; padding: 10px 30px; box-sizing: border-box; position: fixed; top: var(--top); left: 50%; transform: translate(-50%, calc(100% - (100% - var(--top)))); background: var(--primary); color: var(--color); border-radius: var(--baseRadius); transition: var(--baseTransition); display: flex; flex-direction: column; box-shadow: 0px 8px 24px var(--background); } .modal.hidden{ display: none; } .modal ::selection{ background: var(--color); color: var(--secondary); } .modal-bar{ display: flex; flex-direction: row; justify-content: space-between; align-content: stretch; align-items: center; } .modal-bar h1{ margin-block: 10px; } .modal-bar button{ background: transparent; border: none; outline: none; color: inherit; font-size: 2rem; transition: var(--baseTransition); cursor: pointer; } .modal-bar button:hover, .modal-bar abutton:focus{ rotate: -45deg; filter: drop-shadow(0 0 0.8rem var(--color)); } .modal-content{ margin: 0; } .modal-content a{ color: var(--color); text-decoration: underline; text-decoration-thickness: 2px; text-decoration-color: var(--color); transition: var(--baseTransition); } .modal-content a:hover, .modal-content a:focus{ background: var(--color); color: var(--secondary); outline: none; } /* GENERAL ANIMATIONS */ /* only css on scroll animations: https://www.youtube.com/watch?v=0TnO1GzKWPc */ @media (prefers-reduced-motion: no-preference){ .fade-up{ animation: fade-up linear; animation-timeline: view(); animation-composition: add; animation-range: entry 0 cover var(--animationCoverValue); overflow: hidden; } .fade-down{ animation: fade-down var(--baseDuration) linear; animation-timeline: view(); animation-composition: add; animation-range: entry 0 cover var(--animationCoverValue); overflow: hidden; } .fade-left{ animation: fade-left var(--baseDuration) linear; animation-timeline: view(); animation-composition: add; animation-range: entry 0 cover var(--animationCoverValue); overflow: hidden; } .fade-right{ animation: fade-right var(--baseDuration) linear; animation-timeline: view(); animation-composition: add; animation-range: entry 0 cover var(--animationCoverValue); overflow: hidden; } .fade-in{ animation: fade-in var(--baseDuration) linear; animation-fill-mode: forwards; overflow: hidden; } .fade-in-no-scale-flex{ animation: fade-in-no-scale-flex var(--baseDuration) linear; animation-fill-mode: forwards; overflow: hidden; } .fade-out{ animation: fade-out var(--baseDuration) linear; animation-fill-mode: forwards; overflow: hidden; } .fade-out-no-scale{ animation: fade-out-no-scale var(--baseDuration) linear; animation-fill-mode: forwards; overflow: hidden; } } @keyframes fade-up{ 0%{ opacity: 0; translate: 0px var(--animationOffset); scale: var(--animationScale); } 100%{ opacity: 1; translate: 0px 0px; scale: 1; } } @keyframes fade-down{ 0%{ opacity: 0; translate: 0px calc(var(--animationOffset) * -1); scale: var(--animationScale); } 100%{ opacity: 1; translate: 0px 0px; scale: 1; } } @keyframes fade-left{ 0%{ opacity: 0; translate: calc(var(--animationOffset) * -1) 0px; scale: var(--animationScale); } 100%{ opacity: 1; translate: 0px 0px; scale: 1; } } @keyframes fade-right{ 0%{ opacity: 0; translate: var(--animationOffset) 0px; scale: var(--animationScale); } 100%{ opacity: 1; translate: 0px 0px; scale: 1; } } @keyframes fade-in{ 0%{ opacity: 0; scale: 0; } 100%{ opacity: 1; scale: 1; } } @keyframes fade-in-no-scale-flex{ 0%{ opacity: 0; } 100%{ opacity: 1; display: flex; } } @keyframes fade-out{ 0%{ opacity: 1; scale: 1; } 100%{ opacity: 0; scale: 0; display: none; } } @keyframes fade-out-no-scale{ 0%{ opacity: 1; } 100%{ opacity: 0; display: none; } }