After 7 months of programming everyday and more than 30 projects built, this is last project I made for the FreeCodeCamp curriculum.
It's been a great journey and I learnt A LOT of new stuff!
A Pen by Yago Estévez on CodePen.
#app |
After 7 months of programming everyday and more than 30 projects built, this is last project I made for the FreeCodeCamp curriculum.
It's been a great journey and I learnt A LOT of new stuff!
A Pen by Yago Estévez on CodePen.
// Made by Yago Estévez (Twitter: @yagoestevez.com) | |
/*********************** | |
Menu Component | |
***********************/ | |
const Menu = props => { | |
return ( | |
<div className={`menu-container ${props.showMenu}`}> | |
<div className="overlay" /> | |
<div className="menu-items"> | |
<ul> | |
<li> | |
<a href="#welcome-section" onClick={props.toggleMenu}> | |
HOME | |
</a> | |
</li> | |
<li> | |
<a href="#about" onClick={props.toggleMenu}> | |
ABOUT | |
</a> | |
</li> | |
<li> | |
<a href="#projects" onClick={props.toggleMenu}> | |
PORTFOLIO | |
</a> | |
</li> | |
<li> | |
<a href="#contact" onClick={props.toggleMenu}> | |
CONTACT | |
</a> | |
</li> | |
</ul> | |
<SocialLinks /> | |
</div> | |
</div> | |
); | |
}; | |
/*********************** | |
Nav Component | |
***********************/ | |
const Nav = props => { | |
return ( | |
<React.Fragment> | |
<nav id="navbar"> | |
<div className="nav-wrapper"> | |
<p className="brand"> | |
yago | |
<strong>estévez</strong> | |
</p> | |
<a | |
onClick={props.toggleMenu} | |
className={props.showMenu === 'active' ? 'menu-button active' : 'menu-button'} | |
> | |
<span /> | |
</a> | |
</div> | |
</nav> | |
</React.Fragment> | |
); | |
}; | |
/*********************** | |
Header Component | |
***********************/ | |
const Header = props => { | |
return ( | |
<header id="welcome-section"> | |
<div className="forest" /> | |
<div className="silhouette" /> | |
<div className="moon" /> | |
<div className="container"> | |
<h1> | |
<span className="line">I do</span> | |
<span className="line">graphic design</span> | |
<span className="line"> | |
<span className="color">&</span> code. | |
</span> | |
</h1> | |
<div className="buttons"> | |
<a href="#projects">my portfolio</a> | |
<a href="#contact" className="cta"> | |
get in touch | |
</a> | |
</div> | |
</div> | |
</header> | |
); | |
}; | |
/*********************** | |
About Component | |
***********************/ | |
const About = props => { | |
return ( | |
<section id="about"> | |
<div className="wrapper"> | |
<article> | |
<div className="title"> | |
<h3>Who's this guy?</h3> | |
<p className="separator" /> | |
</div> | |
<div className="desc full"> | |
<h4 className="subtitle">My name is Yago.</h4> | |
<p> | |
I am a web developer and UX designer based in the beautiful west coast of Spain, | |
Galicia. | |
</p> | |
<p> | |
I really enjoy solving problems as well as making things pretty and easy to use. I | |
can't stop learning new things; the more, the better. I also love photography, a hobby | |
I'm taking along since the good old film cameras. Oh, and rice with milk; I have a | |
passion for rice with milk! | |
</p> | |
</div> | |
<div className="title"> | |
<h3>What does he do?</h3> | |
<p className="separator" /> | |
</div> | |
<div className="desc"> | |
<h4 className="subtitle">I'm a programmer.</h4> | |
<p> | |
For the front-end I usually work with Javascript, either standalone or including | |
popular frameworks like ReactJS and VueJS. I also make the web pretty by using Sass, | |
CSS and, whenever needed, any of their friends: Bootstrap, Bulma, etc. | |
</p> | |
<p> | |
For the back-end I also work with Javascript (NodeJS, Express, MongoDB, etc). But, of | |
course, whenever the project requires PHP, I do PHP as well (Wordpress, Laravel, etc). | |
</p> | |
</div> | |
<div className="desc"> | |
<h4 className="subtitle">Also a designer.</h4> | |
<p> | |
I feel comfortable working with many Adobe products. Photoshop, Illustrator, InDesign, | |
Lightroom or Xd are some kind of industry standards and I love working with them. I'm | |
not limited to them, though: Gimp, Inkscape or Figma are also very valid applications | |
that I've been working with. | |
</p> | |
<p> | |
User interfaces, brochures, books, branding... You name it! As I mentioned, creating | |
pretty things is particularly important for me. | |
</p> | |
</div> | |
</article> | |
</div> | |
</section> | |
); | |
}; | |
/*********************** | |
Project Component | |
***********************/ | |
const Project = props => { | |
const tech = { | |
sass: 'fab fa-sass', | |
css: 'fab fa-css3-alt', | |
js: 'fab fa-js-square', | |
react: 'fab fa-react', | |
vue: 'fab fa-vuejs', | |
d3: 'far fa-chart-bar', | |
node: 'fab fa-node' | |
}; | |
const link = props.link || 'http://'; | |
const repo = props.repo || 'http://'; | |
return ( | |
<div className="project"> | |
<a className="project-link" href={link} target="_blank" rel="noopener noreferrer"> | |
<img className="project-image" src={props.img} alt={'Screenshot of ' + props.title} /> | |
</a> | |
<div className="project-details"> | |
<div className="project-tile"> | |
<p className="icons"> | |
{props.tech.split(' ').map(t => ( | |
<i className={tech[t]} key={t} /> | |
))} | |
</p> | |
{props.title}{' '} | |
</div> | |
{props.children} | |
<div className="buttons"> | |
<a href={repo} target="_blank" rel="noopener noreferrer"> | |
View source <i className="fas fa-external-link-alt" /> | |
</a> | |
<a href={link} target="_blank" rel="noopener noreferrer"> | |
Try it Live <i className="fas fa-external-link-alt" /> | |
</a> | |
</div> | |
</div> | |
</div> | |
); | |
}; | |
/*********************** | |
Projects Component | |
***********************/ | |
const Projects = props => { | |
return ( | |
<section id="projects"> | |
<div className="projects-container"> | |
<div className="heading"> | |
<h3 className="title">My Works</h3> | |
<p className="separator" /> | |
<p className="subtitle"> | |
Here's a list of <u>most</u> of the projects I've been working on lately. All of these | |
were built during my coding camp adventure on{' '} | |
<a href="https://www.freecodecamp.org/" target="_blank" rel="noopener noreferrer"> | |
freeCodeCamp | |
</a> | |
, where I've been coding for almost 7 months non-stop until I completed all the projects | |
required to get my Full-Stack Developer certification. | |
</p> | |
</div> | |
<div className="projects-wrapper"> | |
<Project | |
title="Anonymous Message Board." | |
img={'https://raw.githubusercontent.com/yagoestevez/fcc-portfolio/master/src/Components/Projects/Images/AnonMsgBoard.jpg'} | |
tech="js css react node" | |
link="https://yagoestevez-anon-msg-board.glitch.me/" | |
repo="https://github.com/yagoestevez/anonymous-message-board" | |
> | |
<small> | |
Built using Node, Express, MongoDB, CSS + Bulma, React.js and React Router. | |
</small> | |
<p> | |
This is a full-stack website that I made which lets the users read and post anonymous | |
messages and replies. | |
</p> | |
</Project> | |
<Project | |
title="Stock Price Checker." | |
img={'https://raw.githubusercontent.com/yagoestevez/fcc-portfolio/master/src/Components/Projects/Images/StockPriceChecker.jpg'} | |
tech="js node css" | |
link="https://yagoestevez-stock-price-checker.glitch.me/" | |
repo="https://github.com/yagoestevez/fcc-stock-price-checker" | |
> | |
<small> | |
Built using Node, Express, MongoDB, JS + jQuery + Axios, CSS + Bootstrap and Pug. | |
</small> | |
<p> | |
Another full-stack website to check the current value of any requested stock in the | |
market. | |
</p> | |
</Project> | |
<Project | |
title="Personal Library." | |
img={'https://raw.githubusercontent.com/yagoestevez/fcc-portfolio/master/src/Components/Projects/Images/PersonalLibrary.jpg'} | |
tech="js node css" | |
link="https://yagoestevez-personal-library.glitch.me/" | |
repo="https://github.com/yagoestevez/fcc-personal-library" | |
> | |
<small>Built using Node, Express, MongoDB, JS + jQuery, CSS + Bootstrap and Pug.</small> | |
<p> | |
A full-stack website to store book titles and comments to each book into a remote | |
database. | |
</p> | |
</Project> | |
<Project | |
title="Issue Tracker." | |
img={'https://raw.githubusercontent.com/yagoestevez/fcc-portfolio/master/src/Components/Projects/Images/IssueTracker.jpg'} | |
tech="js node css" | |
link="https://yagoestevez-issue-tracker.glitch.me/" | |
repo="https://github.com/yagoestevez/fcc-issue-tracker" | |
> | |
<small>Built using Node, Express, MongoDB, JS + jQuery, CSS + Bootstrap and Pug.</small> | |
<p>Yet another full-stack app to save and manage technical issues to be fixed.</p> | |
</Project> | |
<Project | |
title="Metric-Imperial Converter." | |
img={'https://raw.githubusercontent.com/yagoestevez/fcc-portfolio/master/src/Components/Projects/Images/MetricImperialConverter.jpg'} | |
tech="js node css" | |
link="https://yagoestevez-metric-imperial-converter.glitch.me/" | |
repo="https://github.com/yagoestevez/fcc-metric-imperial-converter/" | |
> | |
<small>Built using Node, Express, JS + jQuery, CSS + Bootstrap and Pug.</small> | |
<p> | |
Another full-stack for converting values from the Internation System of Units (Metric) | |
into the imperial units. | |
</p> | |
</Project> | |
<Project | |
title="URL Shortener Microservice." | |
img={'https://raw.githubusercontent.com/yagoestevez/fcc-portfolio/master/src/Components/Projects/Images/Cortala.jpg'} | |
tech="js node css" | |
link="https://cortala.glitch.me/example" | |
repo="https://github.com/yagoestevez/cortala" | |
> | |
<small>Built using Node, Express, CSS + Bootstrap and Pug.</small> | |
<p> | |
A microservice which takes a raw URL and makes it a short link to make it easy to sent | |
it through the Internet. | |
</p> | |
</Project> | |
<Project | |
title="Exercise Tracker." | |
img={'https://raw.githubusercontent.com/yagoestevez/fcc-portfolio/master/src/Components/Projects/Images/ExerciseTracker.jpg'} | |
tech="js vue node css" | |
link="https://yagoestevez-exercise-tracker.glitch.me" | |
repo="https://github.com/yagoestevez/exercise-tracker" | |
> | |
<small>Built using Node, Express, VueJS + Vue Router and CSS + Bootstrap.</small> | |
<p> | |
A service which lets the users save their daily exercise (or anything) into a log for | |
them to check it later. | |
</p> | |
</Project> | |
<Project | |
title="Bar Chart." | |
img={'https://raw.githubusercontent.com/yagoestevez/fcc-portfolio/master/src/Components/Projects/Images/BarChart.jpg'} | |
tech="js d3 css" | |
link="https://codepen.io/yagoestevez/full/wxjmrB/" | |
repo="https://github.com/yagoestevez/fcc-barchart" | |
> | |
<small>Built using CSS, JS and D3.js.</small> | |
<p>A bar chart representing the evolution of the US GDP.</p> | |
</Project> | |
<Project | |
title="Treemap Diagram." | |
img={'https://raw.githubusercontent.com/yagoestevez/fcc-portfolio/master/src/Components/Projects/Images/TreemapDiagram.jpg'} | |
tech="js d3 css" | |
link="https://codepen.io/yagoestevez/full/bjZygz/" | |
repo="https://github.com/yagoestevez/fcc-treemap-diagram" | |
> | |
<small>Built using CSS, JS and D3.js.</small> | |
<p> | |
A treemap diagram representing groups of pledges and sales from a particular category. | |
</p> | |
</Project> | |
<Project | |
title="Choropleth Map." | |
img={'https://raw.githubusercontent.com/yagoestevez/fcc-portfolio/master/src/Components/Projects/Images/ChoroplethMap.jpg'} | |
tech="js d3 css" | |
link="https://codepen.io/yagoestevez/full/NBeaWK/" | |
repo="https://github.com/yagoestevez/fcc-choropleth-map" | |
> | |
<small>Built using CSS, JS and D3.js.</small> | |
<p>A choropleth map representing the educational attainment by county in the U.S.</p> | |
</Project> | |
<Project | |
title="Random Quoting Machine." | |
img={'https://raw.githubusercontent.com/yagoestevez/fcc-portfolio/master/src/Components/Projects/Images/QuotingMachine.jpg'} | |
tech="js vue css" | |
link="https://codepen.io/yagoestevez/full/bxgEyd/" | |
repo="https://github.com/yagoestevez/random-quoting-machine" | |
> | |
<small>Built using VueJS, Axios and CSS + Bootstrap.</small> | |
<p>A random quoting app which retrieves pictures and quotes from two different APIs.</p> | |
</Project> | |
<Project | |
title="Calculator." | |
img={'https://raw.githubusercontent.com/yagoestevez/fcc-portfolio/master/src/Components/Projects/Images/Calculator.jpg'} | |
tech="js react css" | |
link="https://codepen.io/yagoestevez/full/ERVONM/" | |
repo="https://github.com/yagoestevez/the-calcoolator" | |
> | |
<small>Built using React and CSS.</small> | |
<p>A project on which I built a virtual calculator with its usual features.</p> | |
</Project> | |
<Project | |
title="Pomodoro Timer." | |
img={'https://raw.githubusercontent.com/yagoestevez/fcc-portfolio/master/src/Components/Projects/Images/TomateTimer.jpg'} | |
tech="js react css" | |
link="https://codepen.io/yagoestevez/full/dqJGVa" | |
repo="https://github.com/yagoestevez/tomate-time" | |
> | |
<small>Built using React, CSS and lots of SVG.</small> | |
<p>A cute and animated Pomodoro clock to help the users improve their productivity.</p> | |
</Project> | |
<Project | |
title="TicTacToe Game." | |
img={'https://raw.githubusercontent.com/yagoestevez/fcc-portfolio/master/src/Components/Projects/Images/TicTacToe.jpg'} | |
tech="js react css" | |
link="https://codepen.io/yagoestevez/full/KRevzB/" | |
repo="https://github.com/yagoestevez/TicTacToe" | |
> | |
<small>Built using React, CSS and SVG.</small> | |
<p> | |
A TicTacToe game with a basic AI algorithm made for the legacy front-end projects on | |
FreeCodeCamp. | |
</p> | |
</Project> | |
<Project | |
title="Twitch Clone." | |
img={'https://raw.githubusercontent.com/yagoestevez/fcc-portfolio/master/src/Components/Projects/Images/Twitch.jpg'} | |
tech="js vue sass" | |
link="https://codepen.io/yagoestevez/full/xjwVPq/" | |
> | |
{/* repo="https://github.com/yagoestevez/TicTacToe"> */} | |
<small>Built using VueJS, Axios and Scss.</small> | |
<p> | |
Simple Twitch clone using the new Twitch Helix API and made for the legacy front-end | |
projects on FreeCodeCamp. | |
</p> | |
</Project> | |
<Project | |
title="Weather App." | |
img={'https://raw.githubusercontent.com/yagoestevez/fcc-portfolio/master/src/Components/Projects/Images/WeatherApp.jpg'} | |
tech="js vue css" | |
link="https://codepen.io/yagoestevez/full/zWbGmZ/" | |
> | |
{/* repo="https://github.com/yagoestevez/TicTacToe"> */} | |
<small>Built using VueJS, Axios and CSS.</small> | |
<p>App that present the users with the current local weather for their location.</p> | |
</Project> | |
<Project | |
title="Tribute." | |
img={'https://raw.githubusercontent.com/yagoestevez/fcc-portfolio/master/src/Components/Projects/Images/Tribute.jpg'} | |
tech="js sass" | |
link="https://codepen.io/yagoestevez/full/aaaOxL/" | |
repo="https://github.com/yagoestevez/tribute-to-aaron-swartz" | |
> | |
<small>Built using vanilla Javascript and Scss.</small> | |
<p> | |
Tribute page to Aaron Swartz, a static website built with SCSS and plain Javascript. | |
</p> | |
</Project> | |
<Project | |
title="Survey Form." | |
img={'https://raw.githubusercontent.com/yagoestevez/fcc-portfolio/master/src/Components/Projects/Images/SurveyForm.jpg'} | |
tech="js sass" | |
link="https://codepen.io/yagoestevez/full/bjVgjX/" | |
repo="https://github.com/yagoestevez/membership-form" | |
> | |
<small>Built using vanilla Javascript and Scss.</small> | |
<p>An animated survey form.</p> | |
</Project> | |
<Project | |
title="Landing Page Example." | |
img={'https://raw.githubusercontent.com/yagoestevez/fcc-portfolio/master/src/Components/Projects/Images/LandingPage.jpg'} | |
tech="js sass" | |
link="https://codepen.io/yagoestevez/full/pOBLeK/" | |
repo="https://github.com/yagoestevez/tomate-timer-landing-page" | |
> | |
<small>Built using vanilla Javascript and Scss.</small> | |
<p>A landing page for the Pomodoro Timer I made (shown previously in this section).</p> | |
</Project> | |
<Project | |
title="Technical Documentation Page." | |
img={'https://raw.githubusercontent.com/yagoestevez/fcc-portfolio/master/src/Components/Projects/Images/Documentify.jpg'} | |
tech="js react css" | |
link="https://codepen.io/yagoestevez/full/QxOLKX/" | |
repo="https://github.com/yagoestevez/documentify" | |
> | |
<small>Built using React and CSS.</small> | |
<p> | |
A technical documentation page made for a little React library I published on NPM. | |
</p> | |
</Project> | |
</div> | |
</div> | |
</section> | |
); | |
}; | |
/*********************** | |
Contact Component | |
***********************/ | |
const Contact = props => { | |
return ( | |
<section id="contact"> | |
<div className="container"> | |
<div className="heading-wrapper"> | |
<div className="heading"> | |
<p className="title"> | |
Want to <br /> | |
contact me? | |
</p> | |
<p className="separator" /> | |
<p className="subtitle"> | |
Please, use the form below or send an email to {''} | |
<span className="mail"> | |
web | |
<i className="fas fa-at at" /> | |
yagoestevez | |
<i className="fas fa-circle dot" /> | |
com | |
</span> | |
: | |
</p> | |
</div> | |
<SocialLinks /> | |
</div> | |
<form id="contact-form" action="#"> | |
<input placeholder="Name" name="name" type="text" required /> | |
<input placeholder="Email" name="email" type="email" required /> | |
<textarea placeholder="Message" type="text" name="message" /> | |
<input className="button" id="submit" value="Submit" type="submit" /> | |
</form> | |
</div> | |
</section> | |
); | |
}; | |
/*********************** | |
Footer Component | |
***********************/ | |
const Footer = props => { | |
return ( | |
<footer> | |
<div className="wrapper"> | |
<h3>THANKS FOR VISITING</h3> | |
<p>© {new Date().getFullYear()} Yago Estévez.</p> | |
<SocialLinks /> | |
</div> | |
</footer> | |
); | |
}; | |
/*********************** | |
Social Links Component | |
***********************/ | |
const SocialLinks = props => { | |
return ( | |
<div className="social"> | |
<a | |
href="https://twitter.com/yagoestevez" | |
target="_blank" | |
rel="noopener noreferrer" | |
title="Link to author's Twitter profile" | |
> | |
{' '} | |
<i className="fab fa-twitter" /> | |
</a> | |
<a | |
id="profile-link" | |
href="https://github.com/yagoestevez" | |
target="_blank" | |
rel="noopener noreferrer" | |
title="Link to author's GitHub Profile" | |
> | |
{' '} | |
<i className="fab fa-github" /> | |
</a> | |
<a | |
href="https://codepen.io/yagoestevez" | |
target="_blank" | |
rel="noopener noreferrer" | |
title="Link to author's Codepen Profile" | |
> | |
{' '} | |
<i className="fab fa-codepen" /> | |
</a> | |
</div> | |
); | |
}; | |
/*********************** | |
Main Component | |
***********************/ | |
class App extends React.Component { | |
state = { | |
menuState: false | |
}; | |
toggleMenu = () => { | |
this.setState(state => ({ | |
menuState: !state.menuState | |
? 'active' | |
: state.menuState === 'deactive' | |
? 'active' | |
: 'deactive' | |
})); | |
}; | |
render() { | |
return ( | |
<React.Fragment> | |
<Menu toggleMenu={this.toggleMenu} showMenu={this.state.menuState} /> | |
<Nav toggleMenu={this.toggleMenu} showMenu={this.state.menuState} /> | |
<Header /> | |
<About /> | |
<Projects /> | |
<Contact /> | |
<Footer /> | |
</React.Fragment> | |
); | |
} | |
componentDidMount() { | |
const navbar = document.querySelector('#navbar'); | |
const header = document.querySelector('#welcome-section'); | |
const forest = document.querySelector('.forest'); | |
const silhouette = document.querySelector('.silhouette'); | |
let forestInitPos = -300; | |
window.onscroll = () => { | |
let scrollPos = document.documentElement.scrollTop || document.body.scrollTop; | |
if (scrollPos <= window.innerHeight) { | |
silhouette.style.bottom = `${parseInt(scrollPos / 6)}px`; | |
forest.style.bottom = `${parseInt(forestInitPos + scrollPos / 6)}px`; | |
} | |
if (scrollPos - 100 <= window.innerHeight) | |
header.style.visibility = header.style.visibility === 'hidden' && 'visible'; | |
else header.style.visibility = 'hidden'; | |
if (scrollPos + 100 >= window.innerHeight) navbar.classList.add('bg-active'); | |
else navbar.classList.remove('bg-active'); | |
}; | |
(function navSmoothScrolling() { | |
const internalLinks = document.querySelectorAll('a[href^="#"]'); | |
for (let i in internalLinks) { | |
if (internalLinks.hasOwnProperty(i)) { | |
internalLinks[i].addEventListener('click', e => { | |
e.preventDefault(); | |
document.querySelector(internalLinks[i].hash).scrollIntoView({ | |
block: 'start', | |
behavior: 'smooth' | |
}); | |
}); | |
} | |
} | |
})(); | |
} | |
} | |
ReactDOM.render(<App />, document.getElementById('app')); |
<script src="https://unpkg.com/react@16/umd/react.production.min.js"></script> | |
<script src="https://unpkg.com/react-dom@16/umd/react-dom.production.min.js"></script> |
/* Made by Yago Estévez (Twitter: @yagoestevez.com) */ | |
*, | |
*::before, | |
*::after, | |
:root { | |
margin: 0; | |
padding: 0; | |
box-sizing: border-box; | |
} | |
@import 'https://fonts.googleapis.com/css?family=Overlock:400,400i,700|Oleo+Script'; | |
html, body { | |
height: 100%; | |
} | |
body { | |
color: #252934; | |
background: #fafafa; | |
font-size: 62.5%; | |
font-family: 'Overlock', Arial, Helvetica, sans-serif; | |
overflow-x: hidden; | |
} | |
a, | |
a:visited { | |
color: #252934; | |
font-size: 1.4rem; | |
text-decoration: none; | |
transition: 200ms; | |
} | |
a:hover, | |
a:active { | |
color: #f300b4; | |
} | |
/***************** | |
***************** | |
MENU STYLES | |
***************** | |
*****************/ | |
/***** Overlay Layer *****/ | |
.menu-container > .overlay, | |
.menu-container.active > .overlay { | |
position: absolute; | |
right: 0; | |
height: calc( 100vh - 120px ); | |
width: calc( 100vw - 120px ); | |
background: #fafafa; | |
} | |
.menu-container.active > .overlay { | |
animation: overlay-slide-in 300ms forwards 300ms; | |
} | |
@keyframes overlay-slide-in { | |
from { | |
width: calc( 100vw - 120px ); | |
} | |
to { | |
width: 0; | |
} | |
} | |
.menu-container > .overlay { | |
animation: overlay-slide-out 300ms forwards; | |
} | |
@keyframes overlay-slide-out { | |
from { | |
left: 0; | |
width: 0; | |
} | |
to { | |
left: 0; | |
width: calc( 100vw - 120px ); | |
} | |
} | |
/***** Menu Layer *****/ | |
.menu-container { | |
position: fixed; | |
height: 100vh; | |
width: 100vw; | |
background: #202934; | |
border: 60px solid #181d23; | |
display: flex; | |
flex-direction: column; | |
justify-content: center; | |
align-items: center; | |
overflow: hidden; | |
} | |
.menu-container::before, | |
.menu-container::after { | |
content: ''; | |
position: absolute; | |
width: 100%; | |
min-height: 100vh; | |
z-index: -1; | |
} | |
.menu-container::before { | |
background: url(https://raw.githubusercontent.com/yagoestevez/fcc-portfolio/master/src/Images/Stars.svg?sanitize=true); | |
} | |
.menu-container::after { | |
background: url(https://raw.githubusercontent.com/yagoestevez/fcc-portfolio/master/src/Images/Trees.svg?sanitize=true) bottom repeat-x; | |
} | |
.menu-container.deactive { | |
animation: fade-out 600ms forwards; | |
} | |
@keyframes fade-out { | |
0% { | |
opacity: 1; | |
z-index: 999; | |
} | |
50% { | |
opacity: 1; | |
z-index: 999; | |
} | |
100% { | |
opacity: 0; | |
z-index: -1; | |
} | |
} | |
.menu-container.active { | |
animation: fade-in 300ms forwards; | |
} | |
@keyframes fade-in { | |
from { | |
opacity: 0; | |
z-index: -1; | |
} | |
to { | |
opacity: 1; | |
z-index: 999; | |
} | |
} | |
/***** Menu Items: Animation *****/ | |
.menu-container ul, | |
.menu-container .social { | |
margin-left: -80px; | |
opacity: 0; | |
animation: slide-out 200ms forwards; | |
} | |
.menu-container ul { | |
list-style-type: none !important; | |
font-size: 3rem; | |
} | |
@keyframes slide-out { | |
from { | |
opacity: 1; | |
margin-left: 0px; | |
} | |
to { | |
opacity: 0; | |
margin-left: -80px; | |
} | |
} | |
.menu-container.active ul, | |
.menu-container.active .social { | |
animation: slide-in 300ms forwards 600ms; | |
} | |
@keyframes slide-in { | |
from { | |
opacity: 0; | |
margin-left: -80px; | |
} | |
to { | |
opacity: 1; | |
margin-left: 0; | |
} | |
} | |
/***** Menu Items: Hover Animation *****/ | |
.menu-container ul li { | |
border-left: .2rem solid transparent; | |
transition: border-left 200ms; | |
} | |
.menu-container ul li a { | |
font-size: 3rem; | |
padding-left: .5rem; | |
} | |
.menu-container ul li a::after { | |
content: ' »'; | |
font-size: 2.5rem; | |
color: transparent; | |
transition: color 200ms; | |
} | |
.menu-container ul li a:hover::after { | |
content: ' »'; | |
color: #f300b4; | |
} | |
.social { | |
padding: 1rem 0 0 .5rem; | |
} | |
.social a { | |
font-size: 1.5rem; | |
padding: .2rem; | |
} | |
.menu-container a, | |
.menu-container a:visited { | |
color: #fafafa; | |
} | |
.menu-container a:hover, | |
.menu-container a:active { | |
color: #f300b4; | |
} | |
@media only screen and (max-width: 649px) { | |
.menu-container { | |
border: none; | |
} | |
.menu-container > .overlay, | |
.menu-container.active > .overlay { | |
height: 100vh; | |
width: 100vw; | |
} | |
.menu-container.active > .overlay { | |
animation: overlay-slide-in 300ms forwards 300ms; | |
} | |
@keyframes overlay-slide-in { | |
from { | |
width: 100vw; | |
} | |
to { | |
width: 0; | |
} | |
} | |
.menu-container > .overlay { | |
animation: overlay-slide-out 300ms forwards; | |
} | |
@keyframes overlay-slide-out { | |
from { | |
left: 0; | |
width: 0; | |
} | |
to { | |
left: 0; | |
width: 100vw; | |
} | |
} | |
} | |
/***************** | |
***************** | |
NAV STYLES | |
***************** | |
*****************/ | |
#navbar { | |
position: fixed; | |
z-index: 9999; | |
width: 100%; | |
padding: 1rem; | |
display: flex; | |
justify-content: center; | |
} | |
#navbar.bg-active { | |
background: #181d23; | |
} | |
#navbar .nav-wrapper { | |
width: 100%; | |
display: flex; | |
justify-content: space-between; | |
align-items: center; | |
max-width: 1400px; | |
padding: 0 2rem; | |
} | |
#navbar .brand { | |
font-size: 1.6rem; | |
color: #fafafa; | |
cursor: default; | |
} | |
/***** Menu Button *****/ | |
.menu-button { | |
position: relative; | |
height: 22px; | |
width: 30px; | |
outline: none; | |
} | |
.menu-button span, | |
.menu-button span::before, | |
.menu-button span::after { | |
position: absolute; | |
content: ''; | |
width: 30px; | |
height: 3px; | |
background: #fafafa; | |
transition: 500ms cubic-bezier(0.77, 0, 0.175, 1); | |
} | |
.menu-button span { | |
position: relative; | |
display: block; | |
top: 50%; | |
transform: translate(0,-50%); | |
} | |
.menu-button span::before { | |
top: -8px; | |
} | |
.menu-button span::after { | |
top: 8px; | |
} | |
.menu-button:hover > span, | |
.menu-button:hover > span::before, | |
.menu-button:hover > span::after { | |
background: #f300b4; | |
} | |
.menu-button.active > span { | |
background: transparent; | |
} | |
.menu-button.active > span::before { | |
transform: rotate(-225deg); | |
top: 0px; | |
} | |
.menu-button.active > span::after { | |
transform: rotate(225deg); | |
top: 0px; | |
} | |
@media only screen and (max-width: 849px) { | |
#navbar { | |
background: #181d23aa; | |
} | |
} | |
/***************** | |
***************** | |
HEADER STYLES | |
***************** | |
*****************/ | |
#welcome-section { | |
background: #202736; | |
background: linear-gradient(to bottom, #181d23 0%, #202736 80%); | |
background-attachment: fixed; | |
background-size: cover; | |
position: relative; | |
min-height: 100vh; | |
margin: 0 auto; | |
z-index: 1; | |
} | |
#welcome-section::before { | |
content: ''; | |
position: fixed; | |
background: url(https://raw.githubusercontent.com/yagoestevez/fcc-portfolio/master/src/Images/Stars.svg?sanitize=true); | |
background-attachment: fixed; | |
width: 100%; | |
min-height: 100vh; | |
z-index: -1; | |
opacity: 0; | |
animation: stars-move-in 1000ms 300ms forwards; | |
} | |
@keyframes stars-move-in { | |
from { | |
background-position-y: -100px; | |
} | |
to { | |
opacity: 1; | |
background-position-y: 0; | |
} | |
} | |
.forest { | |
position: absolute; | |
bottom: -300px; | |
left: 0; | |
background: url(https://raw.githubusercontent.com/yagoestevez/fcc-portfolio/master/src/Images/Trees.svg?sanitize=true) bottom left repeat-x; | |
background-size: cover; | |
width: 100%; | |
height: 80%; | |
opacity: 0; | |
animation: forest-move-in 1000ms 500ms forwards; | |
border-bottom: 300px solid #181d23; | |
} | |
@keyframes forest-move-in { | |
from { | |
background-position-y: 150%; | |
} | |
to { | |
opacity: 1; | |
background-position-y: 100%; | |
} | |
} | |
.silhouette { | |
position: absolute; | |
bottom: 0; | |
left: 0; | |
background: url(https://raw.githubusercontent.com/yagoestevez/fcc-portfolio/master/src/Images/Silhouette.svg?sanitize=true) bottom left no-repeat; | |
width: 50%; | |
height: 50%; | |
opacity: 0; | |
animation: silhouette-move-in 1000ms 800ms forwards; | |
} | |
@keyframes silhouette-move-in { | |
from { | |
background-position-x: 0; | |
} | |
to { | |
opacity: 1; | |
background-position-x: 50%; | |
} | |
} | |
.moon { | |
position: absolute; | |
top: 0; | |
right: 0; | |
position: fixed; | |
background: url(https://raw.githubusercontent.com/yagoestevez/fcc-portfolio/master/src/Images/Moon.svg?sanitize=true) right 150% no-repeat; | |
background-size: 40% 40%; | |
background-attachment: fixed; | |
width: 100%; | |
height: 100%; | |
z-index: -1; | |
opacity: 0; | |
animation: moon-move-in 1.2s 1s forwards; | |
} | |
@keyframes moon-move-in { | |
from { | |
opacity: 0; | |
background-position: right 150%; | |
} | |
to { | |
opacity: 1; | |
background-position: top right; | |
} | |
} | |
/* Copy and CTA */ | |
#welcome-section .container { | |
width: fit-content; | |
position: absolute; | |
right: 0; | |
top: 50%; | |
right: 25%; | |
opacity: 0; | |
transform: translate(0, -50%); | |
animation: text-fade-in 1000ms 800ms forwards; | |
} | |
@keyframes text-fade-in { | |
from { | |
right: 0; | |
} | |
to { | |
opacity: 1; | |
right: 25%; | |
} | |
} | |
#welcome-section .container h1 { | |
font-size: 4rem; | |
font-weight: normal; | |
font-style: italic; | |
color: #fafafa; | |
line-height: 3rem; | |
} | |
#welcome-section .container h1 .line:first-child { | |
margin-left: 1rem; | |
} | |
#welcome-section .container h1 .line:last-child { | |
margin-left: 2rem; | |
} | |
#welcome-section .container .buttons { | |
display: flex; | |
margin-top: 1rem; | |
} | |
#welcome-section .container .buttons a, | |
#welcome-section .container .buttons a:visited { | |
width: 100%; | |
padding: 1rem; | |
border: 1px solid #fafafa; | |
color: #fafafa; | |
text-align: center; | |
text-transform: uppercase; | |
font-size: 1rem; | |
} | |
#welcome-section .container .buttons a:hover, | |
#welcome-section .container .buttons a:active { | |
border: 1px solid #f300b4; | |
transform: translateY(-2px); | |
box-shadow: 0 10px 100px -20px #f300b4; | |
} | |
#welcome-section .container .buttons a.cta, | |
#welcome-section .container .buttons a.cta:visited { | |
background: #f300b4; | |
border: 1px solid transparent; | |
color: #fafafa; | |
font-weight: bold; | |
} | |
#welcome-section .container .buttons a.cta:hover, | |
#welcome-section .container .buttons a.cta:active { | |
background: transparent; | |
border: 1px solid #f300b4; | |
} | |
#welcome-section .container .buttons a:first-child { | |
margin-right: 1rem; | |
} | |
.line { | |
display: block; | |
} | |
.color { | |
color: #f300b4; | |
font-style: italic; | |
} | |
@media only screen and (max-width: 649px) { | |
#welcome-section .container { | |
right: 50%; | |
top: 10%; | |
width: 80%; | |
transform: translate(50%, 0); | |
animation: text-fade-in 1000ms 800ms forwards; | |
} | |
@keyframes text-fade-in { | |
from { | |
right: 0; | |
} | |
to { | |
opacity: 1; | |
right: 50%; | |
} | |
} | |
.silhouette { | |
width: 100%; | |
} | |
} | |
/***************** | |
***************** | |
ABOUT STYLES | |
***************** | |
*****************/ | |
#about { | |
height: 100%; | |
min-height: 100vh; | |
font-size: 1.4rem; | |
position: relative; | |
background: #fafafa; | |
clip-path: polygon(0 0, 20% 5%, 100% 0, 100% 100%, 80% 95%, 0 100%); | |
z-index: 5; | |
background: #fafafa url(https://raw.githubusercontent.com/yagoestevez/fcc-portfolio/master/src/Images/Author_BG.jpg) center right no-repeat; | |
background-attachment: fixed; | |
} | |
#about .wrapper { | |
padding: 15rem 10rem 12rem; | |
height: 100%; | |
min-height: 100vh; | |
max-width: 1400px; | |
margin: 0 auto; | |
} | |
#about article { | |
display: grid; | |
grid-template-columns: repeat(4, 1fr); | |
grid-gap: 1rem; | |
padding: 3rem 0; | |
} | |
#about .title { | |
grid-column-end: span 4; | |
display: flex; | |
flex-direction: column; | |
align-items: center; | |
} | |
#about .title h3 { | |
font-size: 2.4rem; | |
} | |
#about .separator { | |
background: #f300b4; | |
width: 150px; | |
height: 2px; | |
margin: 1rem 0; | |
padding: 0; | |
} | |
#about .subtitle { | |
font-size: 1.6rem; | |
text-align: center; | |
color: inherit; | |
padding-bottom: 1.5rem; | |
} | |
#about p { | |
padding-bottom: 1.5rem; | |
color: #555; | |
line-height: 1.9rem; | |
} | |
#about .desc.full { | |
grid-column-end: span 4; | |
margin-bottom: 2rem; | |
} | |
#about .desc { | |
grid-column-end: span 2; | |
background: #ffffffaa; | |
padding: 2rem; | |
text-align: justify; | |
} | |
@media only screen and (max-width: 1149px) { | |
#about article { | |
grid-template-columns: 1fr; | |
grid-gap: 0; | |
} | |
#about .desc.full { | |
grid-column-end: -1; | |
} | |
#about .desc { | |
grid-column-end: -1; | |
} | |
} | |
@media only screen and (max-width: 949px) { | |
#about { | |
clip-path: polygon(0 0, 20% 2%, 100% 0, 100% 100%, 80% 98%, 0 100%); | |
background-position: top left; | |
background-size: cover; | |
} | |
} | |
@media only screen and (max-width: 649px) { | |
#about .wrapper { | |
padding: 10rem 2rem 8rem; | |
} | |
} | |
/***************** | |
***************** | |
PROJECTS STYLES | |
***************** | |
*****************/ | |
#projects { | |
min-height: 100vh; | |
font-size: 1.4rem; | |
position: relative; | |
background: #f0f0f0; | |
background: linear-gradient(215deg, #f0f0f0 0%,#fafafa 100%); | |
margin-top: -10rem; | |
z-index: 1; | |
} | |
#projects a, | |
#projects a:visited { | |
color: #f300b4; | |
} | |
#projects a:hover, | |
#projects a:active { | |
color: #252934; | |
} | |
/* Container */ | |
#projects .projects-container { | |
max-width: 1400px; | |
margin: 0 auto; | |
width: 100%; | |
padding: 12rem 5rem 8rem; | |
} | |
/* Heading */ | |
#projects .heading .title { | |
text-align: center; | |
font-size: 2.4rem; | |
line-height: 2.4rem; | |
} | |
#projects .heading .separator { | |
background: #f300b4; | |
width: 150px; | |
height: 2px; | |
margin: 1rem auto; | |
} | |
#projects .heading .subtitle { | |
font-size: 1.4rem; | |
text-align: center; | |
width: 70%; | |
margin: 0 auto; | |
text-align: justify; | |
} | |
/* Single Project */ | |
#projects .project { | |
margin: 1rem auto; | |
width: 70%; | |
padding: 2rem; | |
display: grid; | |
grid-template-columns: 1fr 1fr; | |
grid-template-rows: 1fr; | |
grid-gap: 2rem; | |
} | |
/* Project Image */ | |
#projects .project .project-link { | |
display: block; | |
margin: auto 0; | |
color: #252934; | |
overflow: hidden; | |
text-align: center; | |
border-radius: 50%; | |
border: 1px solid #fafafa; | |
box-shadow: 0 20px 10px -10px #25293450; | |
transition: 300ms; | |
} | |
#projects .project .project-link:hover { | |
box-shadow: 0 50px 15px -30px #25293450; | |
} | |
#projects .project .project-link:hover > img { | |
filter: saturate(1); | |
transform: scale(1.05); | |
} | |
#projects .project .project-image { | |
width: 100%; | |
transform: scale(1.2); | |
filter: saturate(0); | |
transition: all 300ms; | |
} | |
/* Project Details */ | |
#projects .project .project-details { | |
margin: auto 0; | |
} | |
#projects .project-details .project-tile { | |
font-size: 2rem; | |
text-transform: uppercase; | |
font-weight: bold; | |
margin-bottom: 0; | |
color: #f300b4; | |
} | |
/* Icons */ | |
#projects .project-details .icons { | |
margin: 0; | |
color: #252934; | |
} | |
#projects .project-details .icons i { | |
margin-right: .4rem; | |
font-weight: normal; | |
font-size: 1.4rem; | |
} | |
/* Text */ | |
#projects .project-details small { | |
font-style: italic; | |
} | |
#projects .project-details p { | |
margin: 1rem 0; | |
} | |
/* Buttons */ | |
#projects .project-details .buttons { | |
display: flex; | |
justify-content: space-between; | |
} | |
#projects .project-details .buttons a { | |
width: 49%; | |
padding: .5rem; | |
border: none; | |
border-bottom: 1px solid #f300b4; | |
color: #252934; | |
background: #fafafa; | |
font-size: 1.2rem; | |
text-align: center; | |
} | |
#projects .project-details .buttons a:hover { | |
background: #f300b4; | |
color: #fafafa; | |
} | |
#projects .project-details .buttons i { | |
font-size: .8rem; | |
vertical-align: middle; | |
margin-left: .5rem;; | |
} | |
@media only screen and (max-width: 1149px) { | |
#projects .project { | |
grid-template-columns: 1fr 2fr; | |
} | |
} | |
@media only screen and (max-width: 949px) { | |
#projects .project { | |
grid-template-columns: 1fr; | |
} | |
} | |
@media only screen and (max-width: 649px) { | |
#projects { | |
background: #f0f0f0; | |
} | |
#projects .projects-container { | |
padding: 12rem 0 8rem; | |
} | |
#projects .project { | |
padding: 2rem 0; | |
} | |
} | |
/***************** | |
***************** | |
CONTACT STYLES | |
***************** | |
*****************/ | |
#contact { | |
background: #181d23 url(https://raw.githubusercontent.com/yagoestevez/fcc-portfolio/master/src/Images/envelope.svg?sanitize=true) no-repeat right; | |
clip-path: polygon(0 0, 20% 100px, 100% 0, 100% 100%, 0 100%); | |
color: #fafafa; | |
min-height: 100vh; | |
width: 100%; | |
padding: 5rem 3rem; | |
display: flex; | |
justify-content: center; | |
align-items: center; | |
position: relative; | |
margin: -100px 0 140px; | |
z-index: 1; | |
} | |
#contact .container { | |
width: 70%; | |
max-width: 1200px; | |
padding: 25vh 0; | |
} | |
#contact .container .heading-wrapper { | |
display: flex; | |
justify-content: space-between; | |
} | |
#contact .heading-wrapper .social a { | |
color: #fafafa; | |
} | |
#contact .heading-wrapper .social a:hover { | |
color: #f300b4; | |
} | |
.heading-wrapper .heading .title { | |
font-size: 3rem; | |
line-height: 2.4rem; | |
} | |
.heading-wrapper .heading .separator { | |
background: #f300b4; | |
width: 150px; | |
height: 2px; | |
margin: 1rem 0; | |
} | |
.heading-wrapper .heading .subtitle { | |
font-size: 1.4rem; | |
} | |
#contact-form { | |
margin-top: 1rem; | |
} | |
input, textarea { | |
border: none; | |
padding: 1rem; | |
font-family: 'Overlock', Arial, Helvetica, sans-serif; | |
width: 100%; | |
height: 40%; | |
transition: 200ms; | |
} | |
input[type="text"], | |
input[type="email"], | |
input[type="text"]:not(output):not(:focus), | |
input[type="email"]:not(output):not(:focus), | |
textarea { | |
border-bottom: 1px solid #fafafa; | |
background: transparent; | |
color: #fafafa; | |
font-size: 1.8rem; | |
box-shadow: none; | |
outline: none; | |
} | |
input[type="text"]:focus, | |
input[type="email"]:focus, | |
input[type="text"]:not(output):focus, | |
input[type="email"]:not(output):focus, | |
textarea:focus { | |
border-bottom: 1px solid #f300b4; | |
} | |
input[type="submit"] { | |
background: #f300b4; | |
color: #fafafa; | |
margin-top: 1rem; | |
width: auto; | |
float: right; | |
} | |
input[type="submit"]:hover, | |
input[type="submit"]:focus { | |
cursor: pointer; | |
color: #333; | |
background: #fafafa; | |
} | |
::placeholder { | |
color: #fafafa; | |
} | |
/** Email to avoid spam **/ | |
.mail { | |
display: inline-block; | |
font-style: italic; | |
} | |
.mail .at, .mail .dot { | |
font-size: .9rem; | |
margin: 0 .1rem; | |
color: #f300b4; | |
} | |
@media only screen and (max-width: 1149px) { | |
#contact .social a { | |
display: block; | |
} | |
} | |
@media only screen and (max-width: 649px) { | |
#contact { | |
clip-path: polygon(0 0, 20% 5%, 100% 0, 100% 100%, 0 100%); | |
padding: 0; | |
} | |
} | |
/***************** | |
***************** | |
FOOTER STYLES | |
***************** | |
*****************/ | |
footer { | |
font-size: 1rem; | |
display: flex; | |
justify-content: center; | |
position: fixed; | |
bottom: 0; | |
left: 0; | |
width: 100%; | |
height: 150px; | |
background: #fafafa; | |
z-index: 0; | |
} | |
footer .wrapper { | |
display: flex; | |
width: 100%; | |
padding: 2rem; | |
max-width: 1400px; | |
align-items: center; | |
justify-content: space-between; | |
} | |
@media only screen and (max-width: 649px) { | |
footer .wrapper { | |
flex-direction: column; | |
} | |
footer .wrapper h3 { | |
padding-bottom: .8rem; | |
} | |
} |
<link href="https://use.fontawesome.com/releases/v5.3.1/css/all.css" rel="stylesheet" /> |