Initial public commit
This commit is contained in:
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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;
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
<a href="<?= site()->homepage()->url() ?>" class="logo" title="Homepage">
|
||||
<?= f::read(__DIR__ . DS . 'logo.svg') ?>
|
||||
</a>
|
||||
@@ -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>
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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 || {});
|
||||
@@ -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 || {});
|
||||
@@ -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";
|
||||
Reference in New Issue
Block a user