add resume

This commit is contained in:
Matthias Kretschmann 2019-08-11 21:47:22 +02:00
parent 13bdde4686
commit f44e0557ed
Signed by: m
GPG Key ID: 606EEEF3C479A91F
20 changed files with 640 additions and 95 deletions

View File

@ -19,6 +19,7 @@
- [💍 One data file to rule all pages](#-one-data-file-to-rule-all-pages)
- [🐱 GitHub repositories](#-github-repositories)
- [💅 Theme switcher](#-theme-switcher)
- [🗂 Resume](#-resume)
- [🏆 SEO component](#-seo-component)
- [📇 Client-side vCard creation](#-client-side-vcard-creation)
- [💫 Page transitions](#-page-transitions)
@ -76,6 +77,16 @@ If you want to know how, have a look at the respective components:
- [`src/components/molecules/ThemeSwitch.jsx`](src/components/molecules/ThemeSwitch.jsx)
- [`src/hooks/use-dark-mode.jsx`](src/hooks/use-dark-mode.jsx)
### 🗂 Resume
Resume page based on [JSON Resume](https://jsonresume.org) standard.
If you want to know how, have a look at the respective components:
- [`src/pages/resume.jsx`](src/pages/resume.jsx)
- [`content/resume.json`](content/resume.json)
- [`src/hooks/use-resume.js`](src/hooks/use-resume.js)
### 🏆 SEO component
Includes a SEO component which automatically switches all required `meta` tags for search engines, Twitter Cards, and Facebook OpenGraph tags based on the browsed route/page.

View File

@ -1,19 +1,11 @@
# more personal metadata can be found in ./resume.json
- title: Matthias Kretschmann
tagline: Designer & Developer
description: Portfolio of web & ui designer/developer hybrid Matthias Kretschmann.
url: https://matthiaskretschmann.com
email: m@kretschmann.io
avatar: ../src/images/avatar.jpg
img: ../src/images/twitter-card.png
social:
Mail: mailto:m@kretschmann.io
Blog: https://kremalicious.com
Twitter: https://twitter.com/kremalicious
GitHub: https://github.com/kremalicious
Dribbble: https://dribbble.com/kremalicious
Keybase: https://keybase.io/kremalicious
availability:
status: false
available: '👔 Available for new projects. <a href="mailto:m@kretschmann.io">Lets talk</a>!'

237
content/resume.json Normal file
View File

@ -0,0 +1,237 @@
{
"basics": {
"name": "Matthias Kretschmann",
"label": "Designer & Developer",
"picture": "../src/images/avatar.jpg",
"email": "m@kretschmann.io",
"website": "https://matthiaskretschmann.com",
"summary": "",
"profiles": [
{
"network": "Blog",
"url": "https://kremalicious.com"
},
{
"network": "Twitter",
"username": "kremalicious",
"url": "https://twitter.com/kremalicious"
},
{
"network": "GitHub",
"username": "kremalicious",
"url": "https://github.com/kremalicious"
},
{
"network": "Dribbble",
"username": "kremalicious",
"url": "https://dribbble.com/kremalicious"
},
{
"network": "Keybase",
"username": "kremalicious",
"url": "https://keybase.io/kremalicious"
}
],
"location": {
"city": "Berlin",
"country": "Germany",
"countryCode": "DE"
}
},
"work": [
{
"company": "Ocean Protocol Foundation",
"position": "Lead UI Designer & Developer",
"website": "https://oceanprotocol.com",
"startDate": "2017-01-01",
"summary": "Leading the UI design & development of Ocean Protocol, iterating on a components-based UI design system spanning all of Ocean Protocol's web properties. Additionally, I conceptualize, execute and iterate on the creative and visual direction of the Ocean Protocol brand.",
"highlights": ["Started the company"]
},
{
"company": "BigchainDB GmbH",
"position": "Lead UI Designer & Developer",
"website": "https://bigchaindb.com",
"startDate": "2016-12-01",
"endDate": "2018-12-31",
"summary": "Leading the UI design & development of all BigchainDB web properties. I created the initial BigchainDB brand and further conceptualized, executed and iterated on the creative and visual direction of BigchainDB. This included creating and iterating on a components-based UI design system for all of BigchainDB's web properties.",
"highlights": ["Started the company"]
},
{
"company": "ascribe GmbH",
"position": "UI Designer & Developer",
"website": "https://ascribe.io",
"startDate": "2016-01-01",
"endDate": "2017-12-31",
"summary": "Description...",
"highlights": ["Started the company"]
},
{
"company": "ChartMogul Ltd.",
"position": "Lead UI Engineer",
"website": "https://chartmogul.com",
"startDate": "2015-07-15",
"endDate": "2017-02-01",
"summary": "Co-designing and leading the UI design & development of various ChartMogul web properties. This included the creation of a components-based UI design system and implementing it across all web touch points. Besides designing and implementing new features, I maintained the front-end of the ChartMogul application and implemented the UI design system by refactoring most of its front-end codebase.",
"highlights": ["Started the company"]
},
{
"company": "UN World Food Programme/ShareTheMeal",
"position": "UI Engineer",
"website": "https://sharethemeal.org",
"startDate": "2014-10-01",
"endDate": "2015-06-01",
"summary": "...",
"highlights": ["Started the company"]
},
{
"company": "ezeep GmbH",
"position": "Lead Designer & Front End Developer",
"website": "https://ezeep.com",
"startDate": "2012-01-01",
"endDate": "2014-09-01",
"summary": "Creating an unprecedented, market-leading & award-winning user experience around printing based on the principles of emotional design way ahead of all competitors. This included defining the product based on user & market research in an iterative process and designing & building ezeeps numerous touch points, like the web app, web site, desktop apps for Windows & Mac OS X and apps for iOS & Android. On top of that I created the corporate identity and a consistent visual branding including the logo."
},
{
"company": "Martin Luther University Halle-Wittenberg",
"position": "UI/UX Designer & Front End Developer",
"startDate": "2009-02-01",
"endDate": "2012-01-01",
"summary": "Conceptualizing & implementing numerous in-house and public facing interfaces for thousands of students and staff. Additionally, conceptualizing, creating and maintaining the blog network & community for all students & staff."
},
{
"company": "Harz University of Applied Sciences",
"position": "Consultant & Teacher",
"startDate": "2011-02-01",
"endDate": "2011-05-01",
"summary": "Conceptualizing a web design & development university seminar and building a responsive & fluid grid framework with a basic HTML/CSS template for students of Media Informatics at the Harz University of Applied Sciences to learn and use."
},
{
"company": "Martin Luther University Halle-Wittenberg",
"position": "Consultant & Teacher",
"startDate": "2011-02-01",
"endDate": "2011-05-01",
"summary": "Conceptualizing a WordPress-based web design university seminar and building a minimal starting theme for students of media & communication science at the MLU Halle-Wittenberg to learn and use."
},
{
"company": "Shortmoves",
"position": "Web Designer & Developer",
"startDate": "2009-01-01",
"endDate": "2010-01-01",
"summary": "Creating & managing the web presence and marketing material of the International Shortfilm Festival Shortmoves in Halle (Saale), Germany."
},
{
"company": "Agentur Ahron",
"position": "Co-Founder & Photojournalist & Photographer",
"startDate": "2005-01-01",
"endDate": "2008-12-31",
"summary": "Co-founded and built up a photo agency from the ground up and worked as a photographer ranging from journalistic works for news agencies & newspapers to photographic work for private clients."
},
{
"company": "Freelance",
"position": "Designer & Developer",
"startDate": "2004-01-01",
"summary": "Numerous projects and clients as a UI/UX Designer, Front End Developer, Icon Designer & Photographer."
}
],
"education": [
{
"institution": "Self-taught",
"area": "UI Design & Web Development",
"studyType": "Autodidactic",
"startDate": "1999-01-01",
"endDate": "2004-01-01"
},
{
"institution": "Martin Luther University Halle-Wittenberg",
"area": "Media/Communication Science & Art History",
"studyType": "Bachelor",
"startDate": "2008-01-01",
"endDate": "2012-01-01"
},
{
"institution": "Martin Luther University Halle-Wittenberg",
"area": "Political Science & Sociology",
"studyType": "Magister Artium",
"startDate": "2006-01-01",
"endDate": "2008-01-01"
}
],
"awards": [
{
"title": "German Design Award",
"date": "2015-11-01",
"awarder": "ezeep GmbH"
},
{
"title": "CeBIT Preview Award",
"date": "2013-11-01",
"awarder": "ezeep GmbH"
}
],
"skills": [
{
"name": "Design",
"level": "Master",
"keywords": [
"Product Design",
"Service Design",
"Interface Design",
"User Experience Design",
"Communication Design",
"Interaction Design",
"Information Architecture",
"Icon Design",
"Web Design",
"Typography",
"Design management"
]
},
{
"name": "Web Development",
"level": "Master",
"keywords": [
"HTML",
"CSS",
"Javascript",
"Node.js",
"npm ecosystem",
"SASS/SCSS",
"Less",
"Stylus",
"Gulp",
"Gatsby",
"React",
"Styled Components",
"JAMstack"
]
},
{
"name": "General Software Development",
"level": "Master",
"keywords": [
"Git",
"GitHub",
"Bash",
"UNIX",
"Agile: Kanban & Scrum",
"Prototyping",
"Incremental"
]
},
{
"name": "DevOps",
"level": "Intermediate",
"keywords": ["AWS", "Now", "Serverless", "Cloudflare", "NGINX", "Apache"]
}
],
"languages": [
{
"language": "German",
"fluency": "Native speaker"
},
{
"language": "English",
"fluency": "Advanced speaker"
}
]
}

View File

@ -11,38 +11,20 @@ module.exports = {
siteUrl: `${url}`
},
plugins: [
'gatsby-transformer-yaml',
'gatsby-transformer-json',
{
resolve: 'gatsby-transformer-yaml',
resolve: 'gatsby-source-filesystem',
options: {
plugins: [
{
resolve: 'gatsby-source-filesystem',
options: {
name: 'content',
path: path.join(__dirname, 'content')
}
}
]
name: 'content',
path: path.join(__dirname, 'content')
}
},
{
resolve: 'gatsby-transformer-json',
resolve: 'gatsby-source-filesystem',
options: {
plugins: [
{
resolve: 'gatsby-source-filesystem',
options: {
name: 'pkg',
path: path.join(__dirname, 'package.json')
}
}
]
}
},
{
resolve: 'gatsby-plugin-sass',
options: {
includePaths: [`${__dirname}/node_modules`, `${__dirname}/src/styles`]
name: 'pkg',
path: path.join(__dirname, 'package.json')
}
},
{
@ -52,6 +34,12 @@ module.exports = {
path: path.join(__dirname, 'src', 'images')
}
},
{
resolve: 'gatsby-plugin-sass',
options: {
includePaths: [`${__dirname}/node_modules`, `${__dirname}/src/styles`]
}
},
{
resolve: 'gatsby-plugin-svgr',
options: {

View File

@ -4,32 +4,6 @@
"tagline": "Designer & Developer",
"description": "Portfolio of web &amp; ui designer/developer hybrid Matthias Kretschmann.",
"url": "https://matthiaskretschmann.com",
"email": "m@kretschmann.io",
"avatar": {
"childImageSharp": {
"fluid": {
"src": "/static/b45f45aa8d98d4e4019a242d38f2f248/bc3a8/avatar.jpg"
},
"resize": {
"src": "/static/b45f45aa8d98d4e4019a242d38f2f248/bc3a8/avatar.jpg"
}
}
},
"img": {
"childImageSharp": {
"resize": {
"src": "/static/5ecbb5694b0b2152aa71398164af38b2/da1a7/twitter-card.png"
}
}
},
"social": {
"Email": "mailto:m@kretschmann.io",
"Blog": "https://kremalicious.com",
"Twitter": "https://twitter.com/kremalicious",
"GitHub": "https://github.com/kremalicious",
"Dribbble": "https://dribbble.com/kremalicious",
"Keybase": "https://keybase.io/kremalicious"
},
"availability": {
"status": false,
"available": "👔 Available for new projects. <a href=\"mailto:m@kretschmann.io\">Lets talk</a>!",

View File

@ -28,6 +28,7 @@ export default function Layout({ children, location }) {
const isHomepage =
location.pathname === '/' ||
location.pathname === '/offline-plugin-app-shell-fallback/'
const isResume = location.pathname === '/resume'
return (
<>
@ -40,7 +41,7 @@ export default function Layout({ children, location }) {
delay={timeout}
delayChildren={timeout}
>
<Header minimal={!isHomepage} />
<Header minimal={!isHomepage} isResume={isResume} />
<main className={styles.screen}>{children}</main>
</RoutesContainer>
</PoseGroup>

View File

@ -1,7 +1,14 @@
import React from 'react'
import Helmet from 'react-helmet'
import PropTypes from 'prop-types'
import { useMeta } from '../../hooks/use-meta'
import { useMeta } from '../../hooks/use-meta'`
import { useResume } from '../../hooks/use-resume'
const MetaTags = ({ title, description, url, image, meta }) => {
const resume = useResume()
const twitterHandle = resume.basics.profiles.filter(
({ network }) => network === 'Twitter'
)[0].username
const MetaTags = ({ title, description, url, image, meta }) => (
<Helmet
@ -24,7 +31,7 @@ const MetaTags = ({ title, description, url, image, meta }) => (
{/* Twitter Card tags */}
<meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:creator" content={meta.social.Twitter} />
<meta name="twitter:creator" content={twitterHandle} />
<meta name="twitter:title" content={title} />
<meta name="twitter:description" content={description} />
<meta name="twitter:image" content={`${meta.url}${image}`} />

View File

@ -2,20 +2,34 @@ import React from 'react'
import saveAs from 'file-saver'
import vCard from 'vcf'
import { useMeta } from '../../hooks/use-meta'
import { useResume } from '../../hooks/use-resume'
export default function Vcard() {
const metaYaml = useMeta()
const { basics } = useResume()
const data = useStaticQuery(query)
const photoSrc = basics.picture.childImageSharp.fixed.src
const { name, label, email, profiles } = basics
const meta = {
...metaYaml,
photoSrc,
name,
label,
email,
profiles
}
const handleAddressbookClick = e => {
e.preventDefault()
init(metaYaml)
init(meta)
}
return (
<a
// href is kinda fake, only there for usability
// so user knows what to expect when hovering the link before clicking
href={metaYaml.addressbook}
href={meta.addressbook}
onClick={handleAddressbookClick}
>
Add to addressbook
@ -24,10 +38,8 @@ export default function Vcard() {
}
export const init = async meta => {
const photoSrc = meta.avatar.childImageSharp.resize.src
// first, convert the avatar to base64, then construct all vCard elements
const dataUrl = await toDataURL(photoSrc, 'image/jpeg')
const dataUrl = await toDataURL(meta.photoSrc, 'image/jpeg')
const vcard = await constructVcard(dataUrl, meta)
downloadVcard(vcard, meta)
@ -49,12 +61,12 @@ export const constructVcard = async (dataUrl, meta) => {
// for vcard to actually display the image for whatever reason
// const dataUrlCleaned = dataUrl.split('data:image/jpeg;base64,').join('')
// contact.set('photo', dataUrlCleaned, { encoding: 'b', type: 'JPEG' })
contact.set('fn', meta.title)
contact.set('title', meta.tagline)
contact.set('fn', meta.name)
contact.set('title', meta.label)
contact.set('email', meta.email)
contact.set('nickname', 'kremalicious')
contact.set('url', meta.url, { type: 'Portfolio' })
contact.add('url', meta.social.Blog, { type: 'Blog' })
contact.set('nickname', 'kremalicious')
contact.add('x-socialprofile', meta.social.Twitter, { type: 'twitter' })
contact.add('x-socialprofile', meta.social.GitHub, { type: 'GitHub' })

View File

@ -8,7 +8,8 @@ import { ReactComponent as Logo } from '../../images/logo.svg'
import styles from './LogoUnit.module.scss'
LogoUnit.propTypes = {
minimal: PropTypes.bool
minimal: PropTypes.bool,
isResume: PropTypes.bool
}
export default function LogoUnit({ minimal }) {

View File

@ -4,8 +4,25 @@ import posed from 'react-pose'
import { moveInTop } from '../atoms/Transitions'
import Icon from '../atoms/Icon'
import { useMeta } from '../../hooks/use-meta'
import { useResume } from '../../hooks/use-resume'
import styles from './Networks.module.scss'
const NetworkLink = ({ name, url }) => (
<a
className={linkClasses(name)}
href={url}
data-testid={`network-${name.toLowerCase()}`}
>
<Icon name={name} />
<span className={styles.title}>{name}</span>
</a>
)
NetworkLink.propTypes = {
name: PropTypes.string.isRequired,
url: PropTypes.string.isRequired
}
export default function Networks({ small, hide }) {
const { social } = useMeta()
if (hide) return null
@ -17,17 +34,15 @@ export default function Networks({ small, hide }) {
return (
<Animation className={small ? styles.small : styles.networks}>
{Object.keys(social).map((key, i) => (
<a
className={linkClasses(key)}
href={social[key]}
key={i}
data-testid={`network-${key.toLowerCase()}`}
>
<Icon name={key} />
<span className={styles.title}>{key}</span>
</a>
))}
<NetworkLink name={'Email'} url={`mailto:${basics.email}`} />
{profiles.map(profile => (
<NetworkLink
key={profile.network}
name={profile.network}
url={profile.url}
/>
))}
</Animation>
)
}

View File

@ -21,11 +21,11 @@
}
.link {
margin-left: $spacer / 2;
margin-right: $spacer / 2;
margin-left: $spacer / $line-height;
margin-right: $spacer / $line-height;
margin-bottom: $spacer / 2;
text-align: center;
display: block;
display: inline-block;
flex: 0 1;
min-width: 2.5rem;

View File

@ -8,16 +8,17 @@ import styles from './Header.module.scss'
import { useMeta } from '../../hooks/use-meta'
Header.propTypes = {
minimal: PropTypes.bool
minimal: PropTypes.bool,
isResume: PropTypes.bool
}
export default function Header({ minimal }) {
export default function Header({ minimal, isResume }) {
const { availability } = useMeta()
return (
<header className={minimal ? styles.minimal : styles.header}>
<ThemeSwitch />
<LogoUnit minimal={minimal} />
<LogoUnit minimal={minimal} isResume={isResume} />
<Networks hide={minimal} />
<Availability hide={minimal && !availability.status} />
</header>

62
src/hooks/use-resume.js Normal file
View File

@ -0,0 +1,62 @@
import { useStaticQuery, graphql } from 'gatsby'
const query = graphql`
query Resume {
contentJson {
basics {
name
label
picture {
childImageSharp {
fixed(width: 256, height: 256) {
...GatsbyImageSharpFixed_withWebp_noBase64
}
}
}
email
website
summary
profiles {
network
url
username
}
location {
city
country
countryCode
}
}
education {
institution
area
studyType
startDate
endDate
}
languages {
language
fluency
}
skills {
name
level
keywords
}
work {
company
position
website
startDate
endDate
summary
highlights
}
}
}
`
export const useResume = () => {
const { contentJson } = useStaticQuery(query)
return contentJson
}

View File

@ -0,0 +1,10 @@
import React from 'react'
import { render } from '@testing-library/react'
import Resume from '../resume'
describe('Resume', () => {
it('renders correctly from data file values', () => {
const { container } = render(<Resume />)
expect(container.firstChild).toBeInTheDocument()
})
})

View File

@ -0,0 +1,45 @@
import React from 'react'
import PropTypes from 'prop-types'
import styles from './ResumeItem.module.scss'
export default function ResumeItem({ workPlace, eduPlace }) {
const title = workPlace ? workPlace.company : eduPlace.institution
const subTitle = workPlace ? workPlace.position : eduPlace.area
const text = workPlace ? workPlace.summary : eduPlace.studyType
const { startDate, endDate } = workPlace || eduPlace
const dateStart = new Date(startDate).getFullYear()
const dateEnd = endDate && new Date(endDate).getFullYear()
const isSameYear = dateStart === dateEnd
return (
<div className={styles.resumeItem}>
<span className={styles.time}>
{dateStart}
{dateEnd ? !isSameYear && `${dateEnd}` : 'present'}{' '}
</span>
<h4 className={styles.title}>{title}</h4>
<h5 className={styles.subTitle}>{subTitle}</h5>
<p>
<em>{text}</em>
</p>
</div>
)
}
ResumeItem.propTypes = {
workPlace: PropTypes.shape({
startDate: PropTypes.string.isRequired,
endDate: PropTypes.string,
company: PropTypes.string.isRequired,
position: PropTypes.string.isRequired,
summary: PropTypes.string
}),
eduPlace: PropTypes.shape({
startDate: PropTypes.string.isRequired,
endDate: PropTypes.string,
institution: PropTypes.string.isRequired,
area: PropTypes.string.isRequired,
studyType: PropTypes.string
})
}

View File

@ -0,0 +1,52 @@
@import 'variables';
.resumeItem {
padding-bottom: $spacer * 3;
padding-left: $spacer;
position: relative;
border-left: 1px solid $brand-grey-light;
&::before {
content: '';
display: block;
width: 1rem;
height: 1rem;
border-radius: 50%;
background: $brand-grey-light;
position: absolute;
left: -0.5rem;
}
p:last-child {
margin-bottom: 0;
}
}
.title {
margin-bottom: $spacer / 3;
font-size: $font-size-h4;
position: relative;
top: -($spacer / 6);
}
.subTitle {
color: $brand-grey-light;
font-size: $font-size-h5;
:global(.dark) & {
color: $brand-grey-dimmed;
}
}
.time {
display: block;
margin-bottom: $spacer / 2;
white-space: nowrap;
@media (min-width: $screen-md) {
text-align: right;
position: absolute;
top: -0.3rem;
right: 105%;
}
}

View File

@ -0,0 +1,70 @@
import React from 'react'
import shortid from 'shortid'
import SEO from '../../components/atoms/SEO'
import LinkIcon from '../../components/atoms/LinkIcon'
import { useResume } from '../../hooks/use-resume'
import styles from './index.module.scss'
import ResumeItem from './ResumeItem'
export default function Resume() {
const { basics, education, languages, work } = useResume()
return (
<>
<SEO />
<div className={styles.resume}>
<header>
<p>Résumé</p>
<h1 className={styles.title}>{basics.name}</h1>
<h2 className={styles.label}>{basics.label}</h2>
</header>
<div>
<ul className={styles.contact}>
<li>
<a href={basics.website}>
<LinkIcon type="website" />
{basics.website.replace('https://', '')}
</a>
</li>
<li>
<LinkIcon type="Email" />
{basics.email}
</li>
<li>
<LinkIcon type="Info" />
{basics.location.city}
</li>
<li>
<LinkIcon type="Info" />
{languages.map(item => (
<span
key={item.language}
>{`${item.language} (${item.fluency})`}</span>
))}
</li>
</ul>
</div>
<div>
<h3 className={styles.subTitle}>Work</h3>
</div>
<div>
{work.map(workPlace => (
<ResumeItem key={shortid.generate()} workPlace={workPlace} />
))}
</div>
<div>
<h3 className={styles.subTitle}>Education</h3>
</div>
<div>
{education.map(eduPlace => (
<ResumeItem key={shortid.generate()} eduPlace={eduPlace} />
))}
</div>
</div>
</>
)
}

View File

@ -0,0 +1,66 @@
@import 'variables';
.resume {
padding: $spacer;
display: grid;
grid-gap: $spacer * 4;
grid-template-columns: 1fr;
@media (min-width: $screen-md) {
grid-template-columns: 1fr 2fr;
max-width: calc(#{$projectImageMaxWidth} + #{$spacer * 2});
margin: 0 auto;
padding: $spacer $spacer * 3;
}
}
.title {
font-size: $font-size-h2;
margin-bottom: $spacer / 4;
}
.label {
font-size: $font-size-h3;
color: $brand-grey-light;
margin-bottom: 0;
:global(.dark) & {
color: $brand-grey-dimmed;
}
}
.contact {
list-style: none;
padding: 0;
svg {
fill: $brand-grey-light;
width: $font-size-small;
height: $font-size-small;
opacity: 0.5;
margin-right: $spacer / 4;
:global(.dark) & {
fill: $brand-grey;
}
}
@media (min-width: $screen-md) {
margin-top: $spacer * 2;
}
}
.subTitle {
font-size: $font-size-h3;
margin-bottom: 0;
}
@media print {
.resume {
grid-template-columns: 1fr;
}
:global(html) {
font-size: 10pt;
}
}

View File

@ -40,10 +40,10 @@ $font-size-mini: 0.7rem;
$font-size-h1: 2.5rem;
$font-size-h2: 2rem;
$font-size-h3: 1.75rem;
$font-size-h4: $font-size-large;
$font-size-h5: $font-size-base;
$font-size-h6: $font-size-small;
$font-size-h3: 1.65rem;
$font-size-h4: 1.45rem;
$font-size-h5: $font-size-large;
$font-size-h6: $font-size-base;
$line-height: 1.5;
$line-height-small: 1.1428571429;

View File

@ -2,3 +2,4 @@
# www.google.com/support/webmasters/bin/answer.py?hl=en&answer=156449
User-agent: *
Disallow: /resume