Initial public commit

This commit is contained in:
2016-08-15 18:21:55 +02:00
commit f9c5f3db5a
86 changed files with 2024 additions and 0 deletions
@@ -0,0 +1,54 @@
<div class="preview-canvas">
<h1>Color previews</h1>
<ul class="palette">
<li class="palette__color">
<div class="palette__swatch background--pagebg"></div>
<p class="palette__label">pagebg</p>
</li>
<li class="palette__color">
<div class="palette__swatch background--pagepattern"></div>
<p class="palette__label">pagepattern</p>
</li>
<li class="palette__color">
<div class="palette__swatch background--text"></div>
<p class="palette__label">text</p>
</li>
<li class="palette__color">
<div class="palette__swatch background--warn"></div>
<p class="palette__label">warn</p>
</li>
</ul>
<ul class="palette">
<li class="palette__color">
<div class="palette__swatch background--passive-light"></div>
<p class="palette__label">passive-light</p>
</li>
<li class="palette__color">
<div class="palette__swatch background--passive"></div>
<p class="palette__label">passive</p>
</li>
<li class="palette__color">
<div class="palette__swatch background--passive-dark"></div>
<p class="palette__label">passive-dark</p>
</li>
</ul>
<ul class="palette">
<li class="palette__color">
<div class="palette__swatch background--brand-primary"></div>
<p class="palette__label">brand-primary</p>
</li>
<li class="palette__color">
<div class="palette__swatch background--brand-primary-alternate"></div>
<p class="palette__label">brand-primary-alternate</p>
</li>
<li class="palette__color">
<div class="palette__swatch background--brand-secondary"></div>
<p class="palette__label">brand-secondary</p>
</li>
<li class="palette__color">
<div class="palette__swatch background--brand-secondary-alternate"></div>
<p class="palette__label">brand-secondary-alternate</p>
</li>
</ul>
</div>
+4
View File
@@ -0,0 +1,4 @@
$color--brand-primary: #ed8f1b !default;
$color--brand-primary-alternate: lighten($color--brand-primary, 15%) !default;
$color--brand-secondary: #0bb888 !default;
$color--brand-secondary-alternate: lighten($color--brand-secondary, 5%) !default;
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.2 KiB

@@ -0,0 +1,41 @@
<div class="contact">
<div class="contact__main">
<form class="contact__form form" action="" method="post">
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
<img class="contact__stamp" src="<?= url('assets/img/stamp.svg') ?>" alt="">
</form>
<div class="contact__thank-you">
Thank you for your message.
</div>
</div>
<aside class="contact__sidebar">
<div class="contact__detail">
<h2 class="contact__heading">Email</h2>
<div class="contact__email"><?= str::email('lukas@example.com') ?> <a href="<?= url('legal') ?>#contact">?</a></div>
<small><a href="<?= url('pgp.asc') ?>" rel="pgpkey">PGP: 2E2A DD32 FE50 61C1</a></small>
</div>
<div class="contact__detail">
<h2 class="contact__heading">Twitter</h2>
<?= twitter('lukasbestle') ?>
</div>
</aside>
</div>
<script>
// Demonstration of the form animation
setTimeout(function() {
document.querySelector('.form').classList.add('form--sent');
}, 2000);
setTimeout(function() {
document.querySelector('.form').classList.add('form--success');
}, 2750);
</script>
+100
View File
@@ -0,0 +1,100 @@
.contact {
position: relative;
display: flex;
justify-content: space-between;
@media (max-width: 50em) {
flex-direction: column;
}
}
.contact__main {
flex: 1;
}
.contact__form {
position: relative;
}
.contact__stamp {
position: absolute;
bottom: -1.5rem;
right: 1rem;
width: 6rem;
visibility: hidden;
opacity: 0;
filter: blur(2px);
transform: scale(1.3);
transition: visibility 0s linear 0.3s, opacity 0.3s ease, filter 0.3s ease, transform 0.3s ease;
.form--sent & {
visibility: visible;
opacity: 1;
filter: none;
transform: none;
transition-delay: 0s;
}
}
.contact__thank-you {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
z-index: -1;
}
.contact__sidebar {
max-width: 16rem;
margin-left: 2rem;
@media (max-width: 50em) {
max-width: 100%;
margin: 0;
margin-top: 2rem;
display: flex;
flex-wrap: wrap;
}
}
.contact__detail {
@media (min-width: 50em), (max-width: 42em) {
&:not(:last-child) {
margin-bottom: 1.8rem;
}
}
@media (max-width: 50em) {
width: 50%;
}
@media (max-width: 42em) {
width: 100%;
}
}
.contact__heading {
font-size: -cdd-rem(20);
margin-bottom: 0.3em;
}
.contact__email {
display: flex;
margin-bottom: 0.3rem;
> :nth-child(1) {
margin-right: 0.5rem;
padding-right: 0.5rem;
border-right: 1px solid $color--passive;
}
> :nth-child(2) {
align-self: center;
font-size: -cdd-rem(22);
}
}
File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 9.0 KiB

@@ -0,0 +1,14 @@
<?php
return [
'defaults' => [
'illustration' => false,
'text' => '<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Voluptas repellendus modi ea praesentium totam, earum, accusamus pariatur cumque.</p>'
],
'preview' => function() {
// Use the home illustration if we have one
$illustration = page('home')->image('illustration.svg')->url();
return compact('illustration');
}
];
@@ -0,0 +1,21 @@
<article class="home-banner">
<?php if($illustration): ?>
<img class="home-banner__illustration" src="<?= $illustration ?>" alt="">
<?php endif ?>
<div class="home-banner__description">
<div class="home-banner__text text"><?= $text ?></div>
<?php pattern('shared/2-blocks/button', [
'text' => l::get('home-banner.learnmore', 'Learn more'),
'label' => l::get('home-banner.learnmore.label', 'Learn more about my services'),
'link' => url('services'),
'modifiers' => 'novisited'
]) ?>
<?php pattern('shared/2-blocks/button', [
'text' => l::get('home-banner.contact', 'Contact'),
'link' => url('contact'),
'modifiers' => ['novisited', 'secondary']
]) ?>
</div>
</article>
@@ -0,0 +1,36 @@
.home-banner {
display: flex;
align-items: flex-start;
@media (max-width: 44em) {
flex-direction: column;
align-items: center;
}
}
.home-banner__illustration {
width: 25em;
max-width: 100%;
margin-right: 4em;
@media (max-width: 60em) {
width: 45%;
margin-right: 2em;
}
@media (max-width: 44em) {
width: 20em;
margin-right: 0;
margin-bottom: 1em;
}
}
.home-banner__description {
flex: 1;
}
.home-banner__text {
font-size: -cdd-rem(24);
line-height: 1.55;
margin-bottom: 0.5em;
}
+3
View File
@@ -0,0 +1,3 @@
<a href="<?= site()->homepage()->url() ?>" class="logo" title="Homepage">
<?= f::read(__DIR__ . DS . 'logo.svg') ?>
</a>
+50
View File
@@ -0,0 +1,50 @@
.logo__gear {
transition: transform 2s ease-in-out 2.3s;
.logo:hover &, .logo:focus & {
transition-delay: 0.7s;
}
}
.logo__gear--left {
transform-origin: 261px 261px;
.logo:hover &, .logo:focus & {
transform: rotate(-90deg);
}
}
.logo__gear--right {
transform-origin: 1100px 340px;
.logo:hover &, .logo:focus & {
transform: rotate(90deg);
}
}
.logo__esignd, .logo__gears {
opacity: 1;
transition: opacity 1s ease-in-out 1.4s;
.logo:hover &, .logo:focus & {
opacity: 0;
transition-delay: 2.7s;
}
}
.logo__leftd {
transition: transform 1s ease-in-out 0.7s;
.logo:hover &, .logo:focus & {
transform: translateX(-470px);
transition-delay: 3.4s;
}
}
.logo__tilde {
opacity: 0;
transition: opacity 1s ease-in-out;
.logo:hover &, .logo:focus & {
opacity: 1;
transition-delay: 4.3s;
}
}
File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 22 KiB

@@ -0,0 +1,17 @@
<?php
return [
'defaults' => [
'illustration' => false,
'title' => 'Lorem ipsum dolor',
'coloredTitle' => true,
'text' => '<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Voluptas repellendus modi ea praesentium totam, earum, accusamus pariatur cumque.</p>'
],
'preview' => function() {
// Use a random service illustration if we have one
$page = page('services');
$illustration = ($page)? $page->images()->shuffle()->first()->url() : false;
return compact('illustration');
}
];
@@ -0,0 +1,10 @@
<section class="service illustrated-text illustrated-text--decorative text">
<?php if($illustration): ?>
<img class="illustrated-text__sidebar" src="<?= $illustration ?>" alt="">
<?php endif ?>
<div class="service__description illustrated-text__main">
<h2 class="service__title<?php e($coloredTitle, ' service__title--colored') ?>"><?= html($title) ?></h2>
<?= $text ?>
</div>
</section>
+24
View File
@@ -0,0 +1,24 @@
.service {
// Make the illustrations overlap
&:not(:first-of-type) {
margin-top: -0.5em;
@media (max-width: 50em) {
margin-top: -0.25em;
}
}
}
.service__description {
.service:not(:last-of-type) & {
margin-bottom: 2em;
}
:last-child {
margin-bottom: 0;
}
}
.service__title--colored::first-letter {
color: $color--brand-secondary;
}
+7
View File
@@ -0,0 +1,7 @@
(function(app) {
'use strict';
app.on('ajax.after', function(target, data) {
document.querySelector('.nav').innerHTML = data.nav;
});
})(window.app = window.app || {});
+70
View File
@@ -0,0 +1,70 @@
//=require element-closest/closest.js
//=require whatwg-fetch/fetch.js
(function(app) {
'use strict';
// Listen on submit events on body (events from forms will bubble up)
document.body.addEventListener('submit', function(e) {
// Find closest form parent
var form = e.target.closest('.contact__form');
// Only continue if the form was found and if we have Promise support
if(!form || !Promise) return;
e.preventDefault();
// Disable the submit button and display the animated stamp
console.info('Sending form data');
form._submit.disabled = true;
form.classList.add('form--sent');
// Get form data
// Explicitly add value of submit button (browser bug in Chrome/FF?)
var data = new FormData(form);
data.append('_submit', form._submit.value);
// Send the form data via AJAX
var options = {
method: 'POST',
body: data,
credentials: 'same-origin',
headers: {'Accept': 'application/json'}
};
var dataPromise = fetch(form.action, options)
.then(app.validateHttpStatus)
.then(app.parseJsonResponse);
// Wait for the stamp animation
Promise.all([dataPromise, app.timerPromise(750)])
.then(function(values) {
// Get the result of the data promise
var data = values[0];
// Mark the (in)valid fields
for(var field in data.fields) {
// Add the class if value is true, otherwise remove it
form[field].classList.toggle('input--invalid', data.fields[field]);
}
// Check if the form submission was successful
if(data.success) {
form.querySelector('.form__message').innerText = '';
document.querySelector('.contact__thank-you').innerText = data.message;
form.classList.add('form--success');
} else {
// Throw message to catch it below, because apparently our code is a dog
throw data.message;
}
})
.catch(function(err) {
console.error(err);
// Display the error to the user
form.classList.remove('form--sent');
form.querySelector('.form__message').innerText = err;
// Enable the submit button again
form._submit.disabled = false;
});
});
})(window.app = window.app || {});
+11
View File
@@ -0,0 +1,11 @@
// Import site-specific color variables
@import "1-globals/colors/colors";
// Import shared styles
@import "../shared/shared";
// Import blocks in alphabetical order (they are strictly independent)
@import "2-blocks/contact/contact";
@import "2-blocks/home-banner/home-banner";
@import "2-blocks/logo/logo";
@import "2-blocks/service/service";