1
0
mirror of https://github.com/kremalicious/blog.git synced 2024-12-22 17:23:50 +01:00

add basic styling

This commit is contained in:
Matthias Kretschmann 2018-07-18 00:24:11 +02:00
parent 1cd59e0a84
commit a293c93f5e
Signed by: m
GPG Key ID: 606EEEF3C479A91F
16 changed files with 368 additions and 23 deletions

View File

@ -9,8 +9,8 @@
# Basics # Basics
# -------------------- # --------------------
name: kremalicious title: kremalicious
description: 'Blog of designer & developer Matthias Kretschmann' tagline: 'Blog of designer & developer Matthias Kretschmann'
url: https://kremalicious.com url: https://kremalicious.com
author: author:
name: Matthias Kretschmann name: Matthias Kretschmann
@ -24,8 +24,4 @@ author:
ether: "0x339dbC44d39bf1961E385ed0Ae88FC6069b87Ea1" ether: "0x339dbC44d39bf1961E385ed0Ae88FC6069b87Ea1"
# Urls typekitID: msu4qap
# --------------------
media_url: "https://res.cloudinary.com/kremalicious"

View File

@ -40,14 +40,14 @@ Just adding feature after feature out of dubious reasons (“Your competitors ha
After finding ezeeps Buddha nature, the next step was to actually create the various elements of our experience and branding, ranging from typography, color, visual style, writing style, interaction models, user flows and more. After finding ezeeps Buddha nature, the next step was to actually create the various elements of our experience and branding, ranging from typography, color, visual style, writing style, interaction models, user flows and more.
<img src="/media/buddha-colorscheme.png" alt="ezeep color scheme"> ![ezeep color scheme](../media/buddha-colorscheme.png)
While being human and friendly sounds like a no-brainer, in the corporate software world, it turns out it isnt. ezeeps vivid color scheme, subtle textures, graphics and icons are a visible manifestation of this, tackling the negative perception of printing for our users. While being human and friendly sounds like a no-brainer, in the corporate software world, it turns out it isnt. ezeeps vivid color scheme, subtle textures, graphics and icons are a visible manifestation of this, tackling the negative perception of printing for our users.
Creating this layer of delight on top of the functional layers is especially crucial in printing. Good design helps making users more forgiving about errors no matter whos responsible for them. Printers the little autistic beings they are just tend to not work from time to time, and a failing device immediately reflects back on our service. If thats the case the least we can do is make the experience beautiful. Creating this layer of delight on top of the functional layers is especially crucial in printing. Good design helps making users more forgiving about errors no matter whos responsible for them. Printers the little autistic beings they are just tend to not work from time to time, and a failing device immediately reflects back on our service. If thats the case the least we can do is make the experience beautiful.
<img src="/media/buddha-printer.png"> ![](../media/buddha-printer.png)
Paired with helpful and to-the-point copy, this creates a friendly and unifying atmosphere across the whole product, ranging from the web to native apps on Mac, Windows, iOS and Android. Paired with helpful and to-the-point copy, this creates a friendly and unifying atmosphere across the whole product, ranging from the web to native apps on Mac, Windows, iOS and Android.
We acknowledge we dont have all the answers yet or, more precisely, we know what we dont know. For us the only way to get those answers is by shipping iteration after iteration and learning from them. Feedback rules. We acknowledge we dont have all the answers yet or, more precisely, we know what we dont know. For us the only way to get those answers is by shipping iteration after iteration and learning from them. Feedback rules.

10
gatsby-browser.js Normal file
View File

@ -0,0 +1,10 @@
exports.onInitialClientRender = () => {
require('./src/styles/base.scss')
}
exports.onClientEntry = () => {
// IntersectionObserver polyfill for gatsby-image (Safari, IE)
if (typeof window.IntersectionObserver === 'undefined') {
require('intersection-observer')
}
}

View File

@ -23,6 +23,13 @@ module.exports = {
path: path.join(__dirname, 'content', 'media') path: path.join(__dirname, 'content', 'media')
} }
}, },
{
resolve: 'gatsby-source-filesystem',
options: {
name: 'posts',
path: path.join(__dirname, 'content')
}
},
{ {
resolve: 'gatsby-transformer-remark', resolve: 'gatsby-transformer-remark',
options: { options: {
@ -33,7 +40,8 @@ module.exports = {
maxWidth: 940, maxWidth: 940,
linkImagesToOriginal: false, linkImagesToOriginal: false,
sizeByPixelDensity: true, sizeByPixelDensity: true,
showCaptions: true showCaptions: true,
backgroundColor: '#e7eef4'
} }
}, },
'gatsby-remark-smartypants', 'gatsby-remark-smartypants',
@ -44,7 +52,7 @@ module.exports = {
{ {
resolve: 'gatsby-plugin-sass', resolve: 'gatsby-plugin-sass',
options: { options: {
includePaths: [`${__dirname}/node_modules`] includePaths: [`${__dirname}/node_modules`, `${__dirname}/src/styles`]
} }
}, },
'gatsby-plugin-react-helmet', 'gatsby-plugin-react-helmet',

View File

@ -39,6 +39,7 @@
"gatsby-transformer-sharp": "^2.1.1-beta.5", "gatsby-transformer-sharp": "^2.1.1-beta.5",
"gatsby-transformer-yaml": "^2.1.1-beta.2", "gatsby-transformer-yaml": "^2.1.1-beta.2",
"graphql": "^0.13.2", "graphql": "^0.13.2",
"intersection-observer": "^0.5.0",
"node-sass": "^4.9.2", "node-sass": "^4.9.2",
"normalize-css": "^2.3.1", "normalize-css": "^2.3.1",
"normalize-opentype.css": "^0.2.4", "normalize-opentype.css": "^0.2.4",

53
src/components/Layout.jsx Normal file
View File

@ -0,0 +1,53 @@
import React, { Fragment } from 'react'
import PropTypes from 'prop-types'
import { StaticQuery, graphql } from 'gatsby'
import Head from './molecules/Head'
import styles from './Layout.module.scss'
const Layout = ({ children, location }) => {
return (
<StaticQuery
query={graphql`
query {
# the content/meta.yml file
contentYaml {
title
tagline
url
author {
name
email
uri
twitter
github
facebook
googleplus
bitcoin
ether
}
}
}
`}
render={data => {
const meta = data.contentYaml
return (
<Fragment>
<Head meta={meta} />
<main className={styles.screen} location={location}>
{children}
</main>
</Fragment>
)
}}
/>
)
}
Layout.propTypes = {
children: PropTypes.any.isRequired,
location: PropTypes.object.isRequired
}
export default Layout

View File

@ -0,0 +1,6 @@
@import 'variables';
.screen {
flex: 1;
padding: $spacer;
}

View File

@ -0,0 +1,46 @@
import React from 'react'
import { StaticQuery, graphql } from 'gatsby'
import Helmet from 'react-helmet'
const TypekitScript = typekitID => (
<script>
{`
(function(d) {
var config = {
kitId: '${typekitID}',
scriptTimeout: 3000,
async: true
},
h=d.documentElement,t=setTimeout(function(){h.className=h.className.replace(/\bwf-loading\b/g,"")+" wf-inactive";},config.scriptTimeout),tk=d.createElement("script"),f=false,s=d.getElementsByTagName("script")[0],a;h.className+=" wf-loading";tk.src='https://use.typekit.net/'+config.kitId+'.js';tk.async=true;tk.onload=tk.onreadystatechange=function(){a=this.readyState;if(f||a&&a!="complete"&&a!="loaded")return;f=true;clearTimeout(t);try{Typekit.load(config)}catch(e){}};s.parentNode.insertBefore(tk,s)
})(document);
`}
</script>
)
const Typekit = () => (
<StaticQuery
query={graphql`
query {
contentYaml {
typekitID
}
}
`}
render={data => {
const { typekitID } = data.contentYaml
return (
typekitID && (
<Helmet>
<link rel="dns-prefetch" href="https://use.typekit.net/" />
<link rel="dns-prefetch" href="https://p.typekit.net/" />
{TypekitScript(typekitID)}
</Helmet>
)
)
}}
/>
)
export default Typekit

View File

@ -0,0 +1,28 @@
import React, { Fragment } from 'react'
import PropTypes from 'prop-types'
import Helmet from 'react-helmet'
import Typekit from '../atoms/Typekit'
const Head = ({ meta }) => {
const { title, tagline } = meta
return (
<Fragment>
<Helmet
defaultTitle={`${title.toLowerCase()} ¦ ${tagline.toLowerCase()}`}
titleTemplate={`%s ¦ ${title.toLowerCase()}`}
>
<meta name="apple-mobile-web-app-title" content={title.toLowerCase()} />
<meta name="theme-color" content="#e7eef4" />
</Helmet>
<Typekit />
</Fragment>
)
}
Head.propTypes = {
meta: PropTypes.object.isRequired
}
export default Head

View File

@ -1,16 +1,17 @@
import React, { Fragment } from 'react' import React from 'react'
import Layout from '../components/Layout'
const NotFound = () => ( const NotFound = () => (
<Fragment> <Layout location={location}>
<div className="hal-9000" /> <div className="hal-9000" />
<p className="srverror-title">I am sorry Dave,</p> <p className="srverror-title">I am sorry Dave,</p>
<p className="srverror-text">I am afraid I can NotFound do that.</p> <p className="srverror-text">I am afraid I can not do that.</p>
<a href="#" className="js-search-init"> <a href="#" className="js-search-init">
How about a nice search? How about a nice search?
</a> </a>
</Fragment> </Layout>
) )
export default NotFound export default NotFound

View File

@ -1,6 +1,7 @@
import React from 'react' import React from 'react'
import PropTypes from 'prop-types' import PropTypes from 'prop-types'
import { Link, graphql } from 'gatsby' import { Link, graphql } from 'gatsby'
import Layout from '../components/Layout'
const IndexPage = ({ data }) => { const IndexPage = ({ data }) => {
const edges = data.allMarkdownRemark.edges const edges = data.allMarkdownRemark.edges
@ -12,7 +13,11 @@ const IndexPage = ({ data }) => {
</li> </li>
)) ))
return <ul>{Posts}</ul> return (
<Layout location={location}>
<ul>{Posts}</ul>
</Layout>
)
} }
IndexPage.propTypes = { IndexPage.propTypes = {

121
src/styles/base.scss Normal file
View File

@ -0,0 +1,121 @@
@import 'variables';
*,
*::before,
*::after {
box-sizing: border-box;
}
html,
body {
margin: 0;
padding: 0;
}
html {
font-size: $font-size-root;
background: $body-background-color;
}
body {
font-family: $font-family-base;
font-weight: $font-weight-base;
font-size: $font-size-base;
line-height: $line-height;
color: $font-color-base;
text-rendering: optimizeLegibility;
font-feature-settings: 'liga', 'kern';
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
min-height: 100vh;
background: $body-background-color;
transition: background .6s $easing;
&.dark {
background-color: $body-background-color--dark;
color: $text-color--dark;
}
}
p,
ul,
ol {
margin: 0 0 $spacer;
}
// Headings
/////////////////////////////////////
h1 {
font-size: $font-size-h1;
}
h2 {
font-size: $font-size-h2;
}
h3 {
font-size: $font-size-h3;
}
h4 {
font-size: $font-size-h4;
}
h5 {
font-size: $font-size-h5;
}
h6 {
font-size: $font-size-h6;
}
h1,
h2,
h3,
h4,
h5,
h6 {
font-family: $font-family-headings;
line-height: $line-height-headings;
color: $color-headings;
font-weight: $font-weight-headings;
margin: 0 0 $spacer;
letter-spacing: -.02em;
.dark & {
color: $color-headings--dark;
}
}
// Links
/////////////////////////////////////
a {
color: $brand-cyan;
text-decoration: none;
transition: .2s ease-out;
&:hover,
&:focus {
color: lighten($brand-cyan, 10%);
transform: translate3d(0, -.1rem, 0);
}
}
// Media
/////////////////////////////////////
img,
video,
svg {
max-width: 100%;
height: auto;
margin: 0;
}
#___gatsby {
display: flex;
min-height: 100vh;
flex-direction: column;
}

69
src/styles/variables.scss Normal file
View File

@ -0,0 +1,69 @@
$imageMaxWidth: 940px;
$easing: cubic-bezier(.75, 0, .08, 1);
// Colors
/////////////////////////////////////
$brand-main: #015565;
$brand-cyan: #43a699;
$brand-main-light: #88bec8;
$brand-light: #e7eef4;
$brand-grey: #6b7f88;
$brand-grey-light: lighten($brand-grey, 15%);
$brand-grey-dimmed: lighten($brand-grey, 50%);
// Backgrounds
/////////////////////////////////////
$body-background-color: $brand-light;
$body-background-color--dark: darken($brand-grey, 30%);
// Text Colors
/////////////////////////////////////
$text-color: $brand-grey;
$text-color-light: $brand-grey-light;
$text-color--dark: $brand-grey-light;
$text-color-light--dark: $brand-grey;
// Typography
/////////////////////////////////////
$font-size-root: 18px;
$font-size-base: 1rem;
$font-size-large: 1.2rem;
$font-size-small: .8rem;
$font-size-mini: .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;
$line-height: 1.5;
$line-height-small: 1.1428571429;
$font-family-base: 'ff-tisa-sans-web-pro', 'Trebuchet MS', 'Helvetica Neue',
Helvetica, Arial, sans-serif;
$font-weight-base: 400;
$font-color-base: $text-color;
$font-family-monospace: Menlo, Monaco, Consolas, 'Courier New', monospace;
$font-family-headings: 'brandon-grotesque', 'Avenir Next', 'Helvetica Neue',
Helvetica, Arial, sans-serif;
$font-weight-headings: 500;
$line-height-headings: 1.1;
$color-headings: $brand-main;
$color-headings--dark: $brand-main-light;
// Components spacing
/////////////////////////////////////
$spacer: ($font-size-base * $line-height);

View File

@ -2,25 +2,26 @@ import React from 'react'
import PropTypes from 'prop-types' import PropTypes from 'prop-types'
import Helmet from 'react-helmet' import Helmet from 'react-helmet'
import { graphql } from 'gatsby' import { graphql } from 'gatsby'
import Image from '../components/Image' import Layout from '../components/Layout'
import Image from '../components/atoms/Image'
const Post = ({ data }) => { const Post = ({ data }) => {
const { markdownRemark: post } = data const { markdownRemark: post } = data
const { title, image } = post.frontmatter const { title, image } = post.frontmatter
return ( return (
<div className="blog-post-container"> <Layout location={location}>
<Helmet title={title} /> <Helmet title={title} />
<div className="blog-post"> <article className="blog-post">
<h1 className="title">{title}</h1> <h1 className="title">{title}</h1>
<Image fluid={image.childImageSharp.fluid} alt={title} /> {image && <Image fluid={image.childImageSharp.fluid} alt={title} />}
<div <div
className="blog-post-content" className="blog-post-content"
dangerouslySetInnerHTML={{ __html: post.html }} dangerouslySetInnerHTML={{ __html: post.html }}
/> />
</div> </article>
</div> </Layout>
) )
} }