mirror of
https://github.com/locomotivemtl/locomotive-boilerplate.git
synced 2026-01-15 00:55:08 +08:00
Compare commits
83 Commits
feature/pr
...
feature/11
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
171aa29a12 | ||
|
|
375b54150e | ||
|
|
0a4da30696 | ||
|
|
ec55037dfe | ||
|
|
795be38edb | ||
|
|
f52d2bc61e | ||
|
|
6cef7be291 | ||
|
|
e97cf527b8 | ||
|
|
a1801c8bc8 | ||
|
|
d6abf2b4ca | ||
|
|
09217c17e5 | ||
|
|
a66cb193d0 | ||
|
|
6d37049989 | ||
|
|
bc3fd3a492 | ||
|
|
45d8be5525 | ||
|
|
ea8f98a52d | ||
|
|
56bbd9e3c5 | ||
|
|
dcb7e91b91 | ||
|
|
2b1eb8e0dd | ||
|
|
f4afd9c6b2 | ||
|
|
7578397a8e | ||
|
|
27effb470d | ||
|
|
7a91cbce61 | ||
|
|
65a265c0ea | ||
|
|
afb3a4aa6a | ||
|
|
40521c3f2b | ||
|
|
2d395cf73a | ||
|
|
81d47b88b8 | ||
|
|
c16407c8c1 | ||
|
|
522c9c0bcb | ||
|
|
ddd12ffc38 | ||
|
|
9e6d7ae182 | ||
|
|
d5bff3ab50 | ||
|
|
962ba66b96 | ||
|
|
5b6bca6ce3 | ||
|
|
4ae90a5821 | ||
|
|
31061daf60 | ||
|
|
ceefeb554e | ||
|
|
276b5eebc0 | ||
|
|
8cde150a3a | ||
|
|
a37c5b047a | ||
|
|
0af2be4599 | ||
|
|
98ba8c4972 | ||
|
|
3f7077b488 | ||
|
|
a674a16c4b | ||
|
|
dd2c783938 | ||
|
|
61b6222525 | ||
|
|
5acd27d1b0 | ||
|
|
9a5a91b221 | ||
|
|
7021666c46 | ||
|
|
43c86c3b50 | ||
|
|
0b4c82ceda | ||
|
|
b72fdabe23 | ||
|
|
f1ebc27a69 | ||
|
|
f2898c8c8e | ||
|
|
12d65db09f | ||
|
|
657fd41f70 | ||
|
|
65c486b910 | ||
|
|
3d0e4d26a2 | ||
|
|
df1a3a6f3c | ||
|
|
7f1b6dad2e | ||
|
|
63e46cde26 | ||
|
|
6564fb330a | ||
|
|
b5753148f1 | ||
|
|
7b415af8c2 | ||
|
|
dc0bc2042c | ||
|
|
e9dbb03207 | ||
|
|
95caf9ebb5 | ||
|
|
596ff7a8ee | ||
|
|
70b36052e6 | ||
|
|
f1e2e2270f | ||
|
|
13735c64f9 | ||
|
|
659ef3767b | ||
|
|
e162af17dd | ||
|
|
93559a0c84 | ||
|
|
c1bcf7fb0d | ||
|
|
d0fcfaac86 | ||
|
|
4a958c5fb5 | ||
|
|
5e7e92c7f5 | ||
|
|
380fbd40c3 | ||
|
|
e16ba2ca16 | ||
|
|
43a5eb1ad3 | ||
|
|
99801a2d8b |
14
.gitignore
vendored
14
.gitignore
vendored
@@ -3,4 +3,16 @@ node_modules
|
||||
Thumbs.db
|
||||
loconfig.*.json
|
||||
!loconfig.example.json
|
||||
.prettierrc
|
||||
.prettierrc
|
||||
www/**/*.html
|
||||
|
||||
www/assets/scripts/app.js
|
||||
www/assets/scripts/app.js.map
|
||||
www/assets/scripts/vendors.js
|
||||
|
||||
www/assets/styles/main.css
|
||||
www/assets/styles/main.css.map
|
||||
www/assets/styles/critical.css
|
||||
www/assets/styles/critical.css.map
|
||||
|
||||
assets.json
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
{
|
||||
"version": 1686214653663
|
||||
}
|
||||
@@ -1,48 +1,34 @@
|
||||
import modular from 'modujs';
|
||||
import * as modules from './modules';
|
||||
import globals from './globals';
|
||||
import { debounce } from './utils/tickers'
|
||||
import { debounce } from './utils/tickers';
|
||||
import { $html } from './utils/dom';
|
||||
import { ENV, FONT, CUSTOM_EVENT, CSS_CLASS } from './config'
|
||||
import { isFontLoadingAPIAvailable, loadFonts } from './utils/fonts';
|
||||
|
||||
const app = new modular({
|
||||
modules: modules,
|
||||
modules,
|
||||
});
|
||||
|
||||
window.onload = (event) => {
|
||||
const $style = document.getElementById('main-css');
|
||||
|
||||
if ($style) {
|
||||
if ($style.isLoaded) {
|
||||
init();
|
||||
} else {
|
||||
$style.addEventListener('load', (event) => {
|
||||
init();
|
||||
});
|
||||
}
|
||||
} else {
|
||||
console.warn('The "main-css" stylesheet not found');
|
||||
}
|
||||
};
|
||||
|
||||
function init() {
|
||||
bindEvents();
|
||||
globals();
|
||||
setViewportSizes();
|
||||
|
||||
app.init(app);
|
||||
|
||||
$html.classList.add(CSS_CLASS.LOADED);
|
||||
$html.classList.add(CSS_CLASS.READY);
|
||||
$html.classList.add(CSS_CLASS.LOADED, CSS_CLASS.READY);
|
||||
$html.classList.remove(CSS_CLASS.LOADING);
|
||||
|
||||
// Bind window resize event with default vars
|
||||
const resizeEndEvent = new CustomEvent(CUSTOM_EVENT.RESIZE_END)
|
||||
window.addEventListener('resize', () => {
|
||||
$html.style.setProperty('--vw', `${document.documentElement.clientWidth * 0.01}px`)
|
||||
debounce(() => {
|
||||
window.dispatchEvent(resizeEndEvent)
|
||||
}, 200, false)
|
||||
})
|
||||
/**
|
||||
* Debug focus
|
||||
*/
|
||||
// document.addEventListener(
|
||||
// "focusin",
|
||||
// function () {
|
||||
// console.log('focused: ', document.activeElement)
|
||||
// }, true
|
||||
// );
|
||||
|
||||
/**
|
||||
* Eagerly load the following fonts.
|
||||
@@ -51,15 +37,101 @@ function init() {
|
||||
loadFonts(FONT.EAGER, ENV.IS_DEV).then((eagerFonts) => {
|
||||
$html.classList.add(CSS_CLASS.FONTS_LOADED);
|
||||
|
||||
if (ENV.IS_DEV) {
|
||||
console.group('Eager fonts loaded!', eagerFonts.length, '/', document.fonts.size);
|
||||
console.group('State of eager fonts:')
|
||||
eagerFonts.forEach((font) => console.log(font.family, font.style, font.weight, font.status/*, font*/))
|
||||
console.groupEnd()
|
||||
console.group('State of all fonts:')
|
||||
document.fonts.forEach((font) => console.log(font.family, font.style, font.weight, font.status/*, font*/))
|
||||
console.groupEnd()
|
||||
}
|
||||
/**
|
||||
* Debug fonts loading
|
||||
*/
|
||||
// if (ENV.IS_DEV) {
|
||||
// console.group('Eager fonts loaded!', eagerFonts.length, '/', document.fonts.size);
|
||||
// console.group('State of eager fonts:');
|
||||
// eagerFonts.forEach(font => console.log(font.family, font.style, font.weight, font.status));
|
||||
// console.groupEnd();
|
||||
// console.group('State of all fonts:');
|
||||
// document.fonts.forEach(font => console.log(font.family, font.style, font.weight, font.status));
|
||||
// console.groupEnd();
|
||||
// }
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
////////////////
|
||||
// Global events
|
||||
////////////////
|
||||
function bindEvents() {
|
||||
|
||||
// Resize event
|
||||
const resizeEndEvent = new CustomEvent(CUSTOM_EVENT.RESIZE_END)
|
||||
window.addEventListener(
|
||||
"resize",
|
||||
debounce(() => {
|
||||
window.dispatchEvent(resizeEndEvent)
|
||||
}, 200, false)
|
||||
)
|
||||
window.addEventListener(
|
||||
"resize",
|
||||
onResize
|
||||
)
|
||||
}
|
||||
|
||||
function onResize() {
|
||||
setViewportSizes()
|
||||
}
|
||||
|
||||
function setViewportSizes() {
|
||||
|
||||
// Document styles
|
||||
const documentStyles = document.documentElement.style;
|
||||
|
||||
// Viewport width
|
||||
const vw = document.body.clientWidth * 0.01;
|
||||
documentStyles.setProperty('--vw', `${vw}px`);
|
||||
|
||||
// Return if browser supports vh, svh, dvh, & lvh
|
||||
if (ENV.SUPPORTS_VH) {
|
||||
return
|
||||
}
|
||||
|
||||
// Viewport height
|
||||
const svh = document.documentElement.clientHeight * 0.01;
|
||||
documentStyles.setProperty('--svh', `${svh}px`);
|
||||
|
||||
const dvh = window.innerHeight * 0.01;
|
||||
documentStyles.setProperty('--dvh', `${dvh}px`);
|
||||
|
||||
if (document.body) {
|
||||
const fixed = document.createElement('div');
|
||||
fixed.style.width = '1px';
|
||||
fixed.style.height = '100vh';
|
||||
fixed.style.position = 'fixed';
|
||||
fixed.style.left = '0';
|
||||
fixed.style.top = '0';
|
||||
fixed.style.bottom = '0';
|
||||
fixed.style.visibility = 'hidden';
|
||||
|
||||
document.body.appendChild(fixed);
|
||||
|
||||
var fixedHeight = fixed.clientHeight;
|
||||
|
||||
fixed.remove();
|
||||
|
||||
const lvh = fixedHeight * 0.01;
|
||||
|
||||
documentStyles.setProperty('--lvh', `${lvh}px`);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////
|
||||
// Execute
|
||||
////////////////
|
||||
window.addEventListener('load', () => {
|
||||
const $style = document.getElementById('main-css');
|
||||
|
||||
if ($style) {
|
||||
if ($style.isLoaded) {
|
||||
init();
|
||||
} else {
|
||||
$style.addEventListener('load', init);
|
||||
}
|
||||
} else {
|
||||
console.warn('The "main-css" stylesheet not found');
|
||||
}
|
||||
});
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
*/
|
||||
|
||||
const NODE_ENV = process.env.NODE_ENV
|
||||
const IS_DESKTOP = typeof window.orientation === 'undefined'
|
||||
const IS_MOBILE = window.matchMedia('(any-pointer:coarse)').matches
|
||||
|
||||
// Main environment variables
|
||||
const ENV = Object.freeze({
|
||||
@@ -19,8 +19,17 @@ const ENV = Object.freeze({
|
||||
IS_DEV: NODE_ENV === 'development',
|
||||
|
||||
// Device
|
||||
IS_DESKTOP,
|
||||
IS_MOBILE: !IS_DESKTOP,
|
||||
IS_MOBILE,
|
||||
IS_DESKTOP: !IS_MOBILE,
|
||||
|
||||
// Supports
|
||||
SUPPORTS_VH: (
|
||||
'CSS' in window
|
||||
&& 'supports' in window.CSS
|
||||
&& window.CSS.supports('height: 100svh')
|
||||
&& window.CSS.supports('height: 100dvh')
|
||||
&& window.CSS.supports('height: 100lvh')
|
||||
)
|
||||
})
|
||||
|
||||
// Main CSS classes used within the project
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { module } from 'modujs';
|
||||
import { lazyLoadImage } from '../utils/image';
|
||||
import LocomotiveScroll from 'locomotive-scroll';
|
||||
import { module } from 'modujs'
|
||||
import { lazyLoadImage } from '../utils/image'
|
||||
import LocomotiveScroll from 'locomotive-scroll'
|
||||
|
||||
export default class extends module {
|
||||
constructor(m) {
|
||||
@@ -9,18 +9,14 @@ export default class extends module {
|
||||
|
||||
init() {
|
||||
this.scroll = new LocomotiveScroll({
|
||||
el: this.el,
|
||||
smooth: true
|
||||
});
|
||||
|
||||
this.scroll.on('call', (func, way, obj, id) => {
|
||||
// Using modularJS
|
||||
this.call(func[0], { way, obj }, func[1], func[2]);
|
||||
});
|
||||
|
||||
this.scroll.on('scroll', (args) => {
|
||||
// console.log(args.scroll);
|
||||
modularInstance: this,
|
||||
})
|
||||
|
||||
// // Force scroll to top
|
||||
// if (history.scrollRestoration) {
|
||||
// history.scrollRestoration = 'manual'
|
||||
// window.scrollTo(0, 0)
|
||||
// }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -41,11 +37,22 @@ export default class extends module {
|
||||
* @param {LocomotiveScroll} args - The Locomotive Scroll instance.
|
||||
*/
|
||||
lazyLoad(args) {
|
||||
lazyLoadImage(args.obj.el, null, () => {
|
||||
lazyLoadImage(args.target, null, () => {
|
||||
//callback
|
||||
})
|
||||
}
|
||||
|
||||
scrollTo(params) {
|
||||
let { target, ...options } = params
|
||||
|
||||
options = Object.assign({
|
||||
// Defaults
|
||||
duration: 1,
|
||||
}, options)
|
||||
|
||||
this.scroll?.scrollTo(target, options)
|
||||
}
|
||||
|
||||
destroy() {
|
||||
this.scroll.destroy();
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ const lerp = (x, y, a) => x * (1 - a) + y * a
|
||||
* @return {number} inverted lerp value
|
||||
*/
|
||||
|
||||
const invlerp = (x, y, a) => clamp((v - x)/(a - x))
|
||||
const invlerp = (x, y, a) => clamp((a - x)/(y - x))
|
||||
|
||||
|
||||
/**
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
width: 11px;
|
||||
height: 100vh;
|
||||
transform-origin: center right;
|
||||
transition: transform 0.3s, opacity 0.3s;
|
||||
transition: transform t(normal), opacity t(normal);
|
||||
opacity: 0;
|
||||
|
||||
&:hover {
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
//
|
||||
// Simple page-level setup.
|
||||
//
|
||||
// 1. Include web fonts
|
||||
// 1. Includes fonts
|
||||
// 2. Ensure the page always fills at least the entire height of the viewport.
|
||||
// 3. Set the default `font-size` and `line-height` for the entire project,
|
||||
// sourced from our default variables.
|
||||
@@ -20,56 +20,32 @@ html {
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
|
||||
@media (max-width: $to-small) {
|
||||
@media (max-width: $to-sm) {
|
||||
font-size: $font-size - 2px;
|
||||
}
|
||||
|
||||
@media (min-width: $from-small) and (max-width: $to-medium) {
|
||||
font-size: $font-size - 2px;
|
||||
}
|
||||
|
||||
@media (min-width: $from-medium) and (max-width: $to-large) {
|
||||
@media (min-width: $from-sm) and (max-width: $to-lg) {
|
||||
font-size: $font-size - 1px;
|
||||
}
|
||||
|
||||
@media (min-width: $from-large) and (max-width: $to-huge) {
|
||||
font-size: $font-size; // [1]
|
||||
@media (min-width: $from-lg) and (max-width: $to-2xl) {
|
||||
font-size: $font-size;
|
||||
}
|
||||
|
||||
@media (min-width: $from-huge) and (max-width: $to-gigantic) {
|
||||
@media (min-width: $from-2xl) and (max-width: $to-3xl) {
|
||||
font-size: $font-size + 1px;
|
||||
}
|
||||
|
||||
@media (min-width: $from-gigantic) and (max-width: $to-colossal) {
|
||||
@media (min-width: $from-3xl) {
|
||||
font-size: $font-size + 2px;
|
||||
}
|
||||
|
||||
@media (min-width: $from-colossal) {
|
||||
font-size: $font-size + 4px;
|
||||
}
|
||||
|
||||
&.is-loading {
|
||||
cursor: wait;
|
||||
}
|
||||
|
||||
&.has-scroll-smooth {
|
||||
overflow: hidden;
|
||||
position: fixed;
|
||||
left: 0;
|
||||
top: 0;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
&.has-scroll-dragging {
|
||||
user-select: none;
|
||||
}
|
||||
}
|
||||
|
||||
body {
|
||||
.has-scroll-smooth & {
|
||||
overflow: hidden;
|
||||
}
|
||||
}
|
||||
|
||||
::selection {
|
||||
|
||||
124
assets/styles/elements/_normalize.scss
Normal file
124
assets/styles/elements/_normalize.scss
Normal file
@@ -0,0 +1,124 @@
|
||||
// ==========================================================================
|
||||
// Elements / Normalize
|
||||
// ==========================================================================
|
||||
|
||||
// Modern CSS Normalize
|
||||
// Based on the reset by Andy.set with some tweaks.
|
||||
// Original by Andy.set: https://piccalil.li/blog/a-more-modern-css-reset/
|
||||
// Review by Chris collier: https://chriscoyier.net/2023/10/03/being-picky-about-a-css-reset-for-fun-pleasure/
|
||||
|
||||
|
||||
// Box sizing rules
|
||||
*,
|
||||
*:after,
|
||||
*:before {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
// Prevent font size inflation
|
||||
html {
|
||||
-moz-text-size-adjust: none;
|
||||
-webkit-text-size-adjust: none;
|
||||
text-size-adjust: none;
|
||||
}
|
||||
|
||||
// Remove default margin in favour of better control in authored CSS
|
||||
p,
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
h5,
|
||||
h6,
|
||||
dl,
|
||||
dd,
|
||||
figure,
|
||||
blockquote {
|
||||
margin-block: unset;
|
||||
}
|
||||
|
||||
// Remove list styles on ul, ol elements with a class, which suggests default styling will be removed
|
||||
ul[class],
|
||||
ol[class] {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
// Set core defaults
|
||||
html {
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: unset;
|
||||
}
|
||||
|
||||
// Set shorter line heights on headings and interactive elements
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
h5,
|
||||
h6,
|
||||
input,
|
||||
label,
|
||||
button {
|
||||
line-height: 1.1;
|
||||
}
|
||||
|
||||
// Balance text wrapping on headings
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
h5,
|
||||
h6 {
|
||||
text-wrap: balance;
|
||||
}
|
||||
|
||||
// Remove a elements default styles if they have a class
|
||||
a[class] {
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
// Make assets easier to work with
|
||||
img,
|
||||
svg,
|
||||
canvas,
|
||||
picture {
|
||||
display: block;
|
||||
max-inline-size: 100%;
|
||||
block-size: auto;
|
||||
}
|
||||
|
||||
// Inherit fonts for inputs and buttons
|
||||
input,
|
||||
button,
|
||||
select,
|
||||
textarea {
|
||||
font: inherit;
|
||||
}
|
||||
|
||||
// Make sure textareas without a rows attribute are not tiny
|
||||
textarea:not([rows]) {
|
||||
min-height: 10em;
|
||||
}
|
||||
|
||||
// Anything that has been anchored to should have extra scroll margin
|
||||
:target {
|
||||
scroll-margin-block: 1rlh;
|
||||
}
|
||||
|
||||
// Reduced mootion preference
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
*,
|
||||
*:after,
|
||||
*:before {
|
||||
animation-duration: 0.01ms !important;
|
||||
animation-iteration-count: 1 !important;
|
||||
transition-duration: 0.01ms !important;
|
||||
scroll-behavior: auto !important;
|
||||
}
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
// ==========================================================================
|
||||
// Generic / Buttons
|
||||
// ==========================================================================
|
||||
|
||||
// 1. Allow us to style box model properties.
|
||||
// 2. Fixes odd inner spacing in IE7.
|
||||
// 3. Reset/normalize some styles.
|
||||
// 4. Line different sized buttons up a little nicer.
|
||||
// 5. Make buttons inherit font styles (often necessary when styling `input`s as buttons).
|
||||
// 6. Force all button-styled elements to appear clickable.
|
||||
|
||||
button,
|
||||
.c-button {
|
||||
@include u-hocus {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
display: inline-block; // [1]
|
||||
overflow: visible; // [2]
|
||||
margin: 0; // [3]
|
||||
padding: 0;
|
||||
outline: 0;
|
||||
border: 0;
|
||||
background: none transparent;
|
||||
color: inherit;
|
||||
vertical-align: middle; // [4]
|
||||
text-align: center; // [3]
|
||||
text-decoration: none;
|
||||
text-transform: none;
|
||||
font: inherit; // [5]
|
||||
line-height: normal;
|
||||
cursor: pointer; // [6]
|
||||
user-select: none;
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
// ==========================================================================
|
||||
// Generic / Forms
|
||||
// ==========================================================================
|
||||
|
||||
input,
|
||||
select,
|
||||
textarea {
|
||||
display: block;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
width: 100%;
|
||||
outline: 0;
|
||||
border: 0;
|
||||
border-radius: 0;
|
||||
background: none transparent;
|
||||
color: inherit;
|
||||
font: inherit;
|
||||
line-height: normal;
|
||||
appearance: none;
|
||||
}
|
||||
|
||||
select {
|
||||
text-transform: none;
|
||||
|
||||
&::-ms-expand {
|
||||
display: none;
|
||||
}
|
||||
|
||||
&::-ms-value {
|
||||
background: none;
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
// // Remove Firefox :focus dotted outline, breaks color inherit
|
||||
// // &:-moz-focusring {
|
||||
// // color: transparent;
|
||||
// // text-shadow: 0 0 0 #000000; // Text :focus color
|
||||
// // }
|
||||
}
|
||||
|
||||
textarea {
|
||||
overflow: auto;
|
||||
resize: vertical;
|
||||
}
|
||||
@@ -1,87 +0,0 @@
|
||||
// ==========================================================================
|
||||
// Generic
|
||||
// ==========================================================================
|
||||
|
||||
html {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
// Add the correct display in IE 10-.
|
||||
// 1. Add the correct display in IE.
|
||||
|
||||
template, // [1]
|
||||
[hidden] {
|
||||
display: none;
|
||||
}
|
||||
|
||||
*,
|
||||
:before,
|
||||
:after {
|
||||
box-sizing: inherit;
|
||||
}
|
||||
|
||||
address {
|
||||
font-style: inherit;
|
||||
}
|
||||
|
||||
dfn,
|
||||
cite,
|
||||
em,
|
||||
i {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
b,
|
||||
strong {
|
||||
font-weight: $font-weight-bold;
|
||||
}
|
||||
|
||||
a {
|
||||
text-decoration: none;
|
||||
|
||||
svg {
|
||||
pointer-events: none;
|
||||
}
|
||||
}
|
||||
|
||||
ul,
|
||||
ol {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
p,
|
||||
figure {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
// 1. Single taps should be dispatched immediately on clickable elements
|
||||
|
||||
a, area, button, input, label, select, textarea, [tabindex] {
|
||||
-ms-touch-action: manipulation; // [1]
|
||||
touch-action: manipulation;
|
||||
}
|
||||
|
||||
[hreflang] > abbr[title] {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
table {
|
||||
border-spacing: 0;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
hr {
|
||||
display: block;
|
||||
margin: 1em 0;
|
||||
padding: 0;
|
||||
height: 1px;
|
||||
border: 0;
|
||||
border-top: 1px solid #CCCCCC;
|
||||
}
|
||||
@@ -1,52 +0,0 @@
|
||||
// ==========================================================================
|
||||
// Generic / Media
|
||||
// ==========================================================================
|
||||
|
||||
// 1. Setting `vertical-align` removes the whitespace that appears under `img`
|
||||
// elements when they are dropped into a page as-is. Safer alternative to
|
||||
// using `display: block;`.
|
||||
|
||||
audio,
|
||||
canvas,
|
||||
iframe,
|
||||
img,
|
||||
svg,
|
||||
video {
|
||||
vertical-align: middle; // [1]
|
||||
}
|
||||
|
||||
// Add the correct display in iOS 4-7.
|
||||
|
||||
audio:not([controls]) {
|
||||
display: none;
|
||||
height: 0;
|
||||
}
|
||||
|
||||
// 2. Fluid media for responsive purposes.
|
||||
|
||||
img,
|
||||
svg {
|
||||
max-width: 100%; // [2]
|
||||
height: auto;
|
||||
|
||||
// 4. If a `width` and/or `height` attribute have been explicitly defined,
|
||||
// let’s not make the image fluid.
|
||||
|
||||
&[width], // [4]
|
||||
&[height] {
|
||||
// [4]
|
||||
max-width: none;
|
||||
}
|
||||
}
|
||||
|
||||
// 4. Offset `alt` text from surrounding copy.
|
||||
|
||||
img {
|
||||
font-style: italic; // [4]
|
||||
}
|
||||
|
||||
// 5. SVG elements should fallback to their surrounding text color.
|
||||
|
||||
svg {
|
||||
fill: currentColor; // [5]
|
||||
}
|
||||
@@ -1,16 +1,18 @@
|
||||
// ==========================================================================
|
||||
// Main
|
||||
// ==========================================================================
|
||||
|
||||
// Modules
|
||||
// ==========================================================================
|
||||
|
||||
@use "sass:math";
|
||||
|
||||
// ==========================================================================
|
||||
// Tools
|
||||
// ==========================================================================
|
||||
|
||||
@import "tools/maths";
|
||||
@import "tools/functions";
|
||||
@import "tools/mixins";
|
||||
@import "tools/fonts";
|
||||
// @import "tools/layout";
|
||||
// @import "tools/widths";
|
||||
// @import "tools/family";
|
||||
@@ -18,29 +20,29 @@
|
||||
// Settings
|
||||
// ==========================================================================
|
||||
|
||||
@import "settings/config.eases";
|
||||
@import "settings/config.colors";
|
||||
@import "settings/config";
|
||||
@import "settings/config.breakpoints";
|
||||
@import "settings/config.colors";
|
||||
@import "settings/config.eases";
|
||||
@import "settings/config.fonts";
|
||||
@import "settings/config.spacings";
|
||||
@import "settings/config.speeds";
|
||||
@import "settings/config.zindexes";
|
||||
@import "settings/config.variables";
|
||||
|
||||
// Generic
|
||||
// Vendors
|
||||
// ==========================================================================
|
||||
|
||||
@import "node_modules/normalize.css/normalize";
|
||||
@import "generic/generic";
|
||||
@import "generic/media";
|
||||
@import "generic/form";
|
||||
@import "generic/button";
|
||||
@import "node_modules/locomotive-scroll/dist/locomotive-scroll";
|
||||
|
||||
// Elements
|
||||
// ==========================================================================
|
||||
|
||||
@import "elements/normalize";
|
||||
@import "elements/document";
|
||||
|
||||
// Objects
|
||||
// ==========================================================================
|
||||
|
||||
@import "objects/scroll";
|
||||
@import "objects/container";
|
||||
@import "objects/ratio";
|
||||
@import "objects/icons";
|
||||
@@ -48,14 +50,9 @@
|
||||
// @import "objects/layout";
|
||||
// @import "objects/table";
|
||||
|
||||
// Vendors
|
||||
// ==========================================================================
|
||||
// @import "vendors/vendor";
|
||||
|
||||
// Components
|
||||
// ==========================================================================
|
||||
|
||||
@import "components/scrollbar";
|
||||
@import "components/heading";
|
||||
@import "components/button";
|
||||
@import "components/form";
|
||||
@@ -69,5 +66,5 @@
|
||||
// @import "utilities/align";
|
||||
// @import "utilities/helpers";
|
||||
// @import "utilities/states";
|
||||
// @import "utilities/spacing";
|
||||
@import "utilities/spacing";
|
||||
// @import "utilities/print";
|
||||
|
||||
@@ -45,8 +45,8 @@
|
||||
grid-template-columns: repeat(4, 1fr);
|
||||
}
|
||||
|
||||
&.-col-#{$base-column-nb}\@from-medium {
|
||||
@media (min-width: $from-medium) {
|
||||
&.-col-#{$base-column-nb}\@from-md {
|
||||
@media (min-width: $from-md) {
|
||||
grid-template-columns: repeat(#{$base-column-nb}, 1fr);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@
|
||||
// // Logo
|
||||
// .svg-logo {
|
||||
// --icon-width: #{rem(100px)};
|
||||
// --icon-ratio: 20/30; // width/height based on svg viewBox
|
||||
// --icon-ratio: math.div(20, 30); // width/height based on svg viewBox
|
||||
|
||||
// // Sizes
|
||||
// .o-icon.-big & {
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
// ==========================================================================
|
||||
// Objects / Scroll
|
||||
// ==========================================================================
|
||||
|
||||
.o-scroll {
|
||||
min-height: 100vh;
|
||||
}
|
||||
92
assets/styles/settings/_config.breakpoints.scss
Normal file
92
assets/styles/settings/_config.breakpoints.scss
Normal file
@@ -0,0 +1,92 @@
|
||||
// ==========================================================================
|
||||
// Settings / Config / Breakpoints
|
||||
// ==========================================================================
|
||||
|
||||
// Breakpoints
|
||||
// ==========================================================================
|
||||
|
||||
$breakpoints: (
|
||||
"2xs": 340px,
|
||||
"xs": 500px,
|
||||
"sm": 700px,
|
||||
"md": 1000px,
|
||||
"lg": 1200px,
|
||||
"xl": 1400px,
|
||||
"2xl": 1600px,
|
||||
"3xl": 1800px,
|
||||
"4xl": 2000px,
|
||||
"5xl": 2400px
|
||||
);
|
||||
|
||||
// Functions
|
||||
// ==========================================================================
|
||||
|
||||
// Creates a min-width or max-width media query expression.
|
||||
//
|
||||
// @param {string} $breakpoint The breakpoint.
|
||||
// @param {string} $type Either "min" or "max".
|
||||
// @return {string}
|
||||
|
||||
@function mq($breakpoint, $type: "min") {
|
||||
@if not map-has-key($breakpoints, $breakpoint) {
|
||||
@warn "Unknown media query breakpoint: `#{$breakpoint}`";
|
||||
}
|
||||
|
||||
$value: map-get($breakpoints, $breakpoint);
|
||||
|
||||
@if ($type == "min") {
|
||||
@return "(min-width: #{$value})";
|
||||
}
|
||||
@if ($type == "max") {
|
||||
@return "(max-width: #{$value - 1px})";
|
||||
}
|
||||
|
||||
@error "Unknown media query type: #{$type}";
|
||||
}
|
||||
|
||||
// Creates a min-width media query expression.
|
||||
//
|
||||
// @param {string} $breakpoint The breakpoint.
|
||||
// @return {string}
|
||||
|
||||
@function mq-min($breakpoint) {
|
||||
@return mq($breakpoint, "min");
|
||||
}
|
||||
|
||||
// Creates a max-width media query expression.
|
||||
//
|
||||
// @param {string} $breakpoint The breakpoint.
|
||||
// @return {string}
|
||||
|
||||
@function mq-max($breakpoint) {
|
||||
@return mq($breakpoint, "max");
|
||||
}
|
||||
|
||||
// Creates a min-width and max-width media query expression.
|
||||
//
|
||||
// @param {string} $from The min-width breakpoint.
|
||||
// @param {string} $until The max-width breakpoint.
|
||||
// @return {string}
|
||||
|
||||
@function mq-between($breakpointMin, $breakpointMax) {
|
||||
@return "#{mq-min($breakpointMin)} and #{mq-max($breakpointMax)}";
|
||||
}
|
||||
|
||||
|
||||
// Legacy
|
||||
// ==========================================================================
|
||||
|
||||
$from-xs: map-get($breakpoints, "xs") !default;
|
||||
$to-xs: map-get($breakpoints, "xs") - 1 !default;
|
||||
$from-sm: map-get($breakpoints, "sm") !default;
|
||||
$to-sm: map-get($breakpoints, "sm") - 1 !default;
|
||||
$from-md: map-get($breakpoints, "md") !default;
|
||||
$to-md: map-get($breakpoints, "md") - 1 !default;
|
||||
$from-lg: map-get($breakpoints, "lg") !default;
|
||||
$to-lg: map-get($breakpoints, "lg") - 1 !default;
|
||||
$from-xl: map-get($breakpoints, "xl") !default;
|
||||
$to-xl: map-get($breakpoints, "xl") - 1 !default;
|
||||
$from-2xl: map-get($breakpoints, "2xl") !default;
|
||||
$to-2xl: map-get($breakpoints, "2xl") - 1 !default;
|
||||
$from-3xl: map-get($breakpoints, "3xl") !default;
|
||||
$to-3xl: map-get($breakpoints, "3xl") - 1 !default;
|
||||
@@ -3,7 +3,7 @@
|
||||
// ==========================================================================
|
||||
|
||||
// Palette
|
||||
// =============================================================================
|
||||
// ==========================================================================
|
||||
|
||||
$colors: (
|
||||
primary: #3297FD,
|
||||
@@ -11,9 +11,37 @@ $colors: (
|
||||
darkest: #000000,
|
||||
);
|
||||
|
||||
// Function
|
||||
// ==========================================================================
|
||||
|
||||
// Returns color code.
|
||||
//
|
||||
// ```scss
|
||||
// .c-box {
|
||||
// color: color(primary);
|
||||
// }
|
||||
// ```
|
||||
//
|
||||
// @param {string} $key - The color key in $colors.
|
||||
// @param {number} $alpha - The alpha for the color value.
|
||||
// @return {color}
|
||||
|
||||
@function color($key, $alpha: 1) {
|
||||
@if not map-has-key($colors, $key) {
|
||||
@error "Unknown '#{$key}' in $colors.";
|
||||
}
|
||||
|
||||
@if($alpha < 0 or $alpha > 1) {
|
||||
@error "Alpha '#{$alpha}' must be in range [0, 1].";
|
||||
}
|
||||
|
||||
$color: map-get($colors, $key);
|
||||
|
||||
@return rgba($color, $alpha);
|
||||
}
|
||||
|
||||
// Specifics
|
||||
// =============================================================================
|
||||
// ==========================================================================
|
||||
|
||||
// Link
|
||||
$color-link: color(primary);
|
||||
|
||||
@@ -2,47 +2,77 @@
|
||||
// Settings / Config / Eases
|
||||
// ==========================================================================
|
||||
|
||||
// Power 1
|
||||
$ease-power1-in: cubic-bezier(0.550, 0.085, 0.680, 0.530);
|
||||
$ease-power1-out: cubic-bezier(0.250, 0.460, 0.450, 0.940);
|
||||
$ease-power1-in-out: cubic-bezier(0.455, 0.030, 0.515, 0.955);
|
||||
// Eases
|
||||
// ==========================================================================
|
||||
|
||||
// Power 2
|
||||
$ease-power2-in: cubic-bezier(0.550, 0.055, 0.675, 0.190);
|
||||
$ease-power2-out: cubic-bezier(0.215, 0.610, 0.355, 1.000);
|
||||
$ease-power2-in-out: cubic-bezier(0.645, 0.045, 0.355, 1.000);
|
||||
$eases: (
|
||||
// Power 1
|
||||
"power1.in": cubic-bezier(0.550, 0.085, 0.680, 0.530),
|
||||
"power1.out": cubic-bezier(0.250, 0.460, 0.450, 0.940),
|
||||
"power1.inOut": cubic-bezier(0.455, 0.030, 0.515, 0.955),
|
||||
|
||||
// Power 3
|
||||
$ease-power3-in: cubic-bezier(0.895, 0.030, 0.685, 0.220);
|
||||
$ease-power3-out: cubic-bezier(0.165, 0.840, 0.440, 1.000);
|
||||
$ease-power3-in-out: cubic-bezier(0.770, 0.000, 0.175, 1.000);
|
||||
// Power 2
|
||||
"power2.in": cubic-bezier(0.550, 0.055, 0.675, 0.190),
|
||||
"power2.out": cubic-bezier(0.215, 0.610, 0.355, 1.000),
|
||||
"power2.inOut": cubic-bezier(0.645, 0.045, 0.355, 1.000),
|
||||
|
||||
// Power 3
|
||||
$ease-power4-in: cubic-bezier(0.755, 0.050, 0.855, 0.060);
|
||||
$ease-power4-out: cubic-bezier(0.230, 1.000, 0.320, 1.000);
|
||||
$ease-power4-in-out: cubic-bezier(0.860, 0.000, 0.070, 1.000);
|
||||
// Power 3
|
||||
"power3.in": cubic-bezier(0.895, 0.030, 0.685, 0.220),
|
||||
"power3.out": cubic-bezier(0.165, 0.840, 0.440, 1.000),
|
||||
"power3.inOut": cubic-bezier(0.770, 0.000, 0.175, 1.000),
|
||||
|
||||
// Expo
|
||||
$ease-expo-in: cubic-bezier(0.950, 0.050, 0.795, 0.035);
|
||||
$ease-expo-out: cubic-bezier(0.190, 1.000, 0.220, 1.000);
|
||||
$ease-expo-in-out: cubic-bezier(1.000, 0.000, 0.000, 1.000);
|
||||
// Power 4
|
||||
"power4.in": cubic-bezier(0.755, 0.050, 0.855, 0.060),
|
||||
"power4.out": cubic-bezier(0.230, 1.000, 0.320, 1.000),
|
||||
"power4.inOut": cubic-bezier(0.860, 0.000, 0.070, 1.000),
|
||||
|
||||
// Back
|
||||
$ease-back-in: cubic-bezier(0.600, -0.280, 0.735, 0.045);
|
||||
$ease-back-out: cubic-bezier(0.175, 00.885, 0.320, 1.275);
|
||||
$ease-back-in-out: cubic-bezier(0.680, -0.550, 0.265, 1.550);
|
||||
// Expo
|
||||
"expo.in": cubic-bezier(0.950, 0.050, 0.795, 0.035),
|
||||
"expo.out": cubic-bezier(0.190, 1.000, 0.220, 1.000),
|
||||
"expo.inOut": cubic-bezier(1.000, 0.000, 0.000, 1.000),
|
||||
|
||||
// Sine
|
||||
$ease-sine-in: cubic-bezier(0.470, 0.000, 0.745, 0.715);
|
||||
$ease-sine-out: cubic-bezier(0.390, 0.575, 0.565, 1.000);
|
||||
$ease-sine-in-out: cubic-bezier(0.445, 0.050, 0.550, 0.950);
|
||||
// Back
|
||||
"back.in": cubic-bezier(0.600, -0.280, 0.735, 0.045),
|
||||
"back.out": cubic-bezier(0.175, 00.885, 0.320, 1.275),
|
||||
"back.inOut": cubic-bezier(0.680, -0.550, 0.265, 1.550),
|
||||
|
||||
// Circ
|
||||
$ease-circ-in: cubic-bezier(0.600, 0.040, 0.980, 0.335);
|
||||
$ease-circ-out: cubic-bezier(0.075, 0.820, 0.165, 1.000);
|
||||
$ease-circ-in-out: cubic-bezier(0.785, 0.135, 0.150, 0.860);
|
||||
// Sine
|
||||
"sine.in": cubic-bezier(0.470, 0.000, 0.745, 0.715),
|
||||
"sine.out": cubic-bezier(0.390, 0.575, 0.565, 1.000),
|
||||
"sine.inOut": cubic-bezier(0.445, 0.050, 0.550, 0.950),
|
||||
|
||||
// Misc
|
||||
$ease-bounce: cubic-bezier(0.17, 0.67, 0.3, 1.33);
|
||||
$ease-slow-out: cubic-bezier(.04,1.15,0.4,.99);
|
||||
$ease-smooth: cubic-bezier(0.380, 0.005, 0.215, 1);
|
||||
// Circ
|
||||
"circ.in": cubic-bezier(0.600, 0.040, 0.980, 0.335),
|
||||
"circ.out": cubic-bezier(0.075, 0.820, 0.165, 1.000),
|
||||
"circ.inOut": cubic-bezier(0.785, 0.135, 0.150, 0.860),
|
||||
|
||||
// Misc
|
||||
"bounce": cubic-bezier(0.17, 0.67, 0.3, 1.33),
|
||||
"slow.out": cubic-bezier(.04,1.15,0.4,.99),
|
||||
"smooth": cubic-bezier(0.380, 0.005, 0.215, 1),
|
||||
);
|
||||
|
||||
// Default value for ease()
|
||||
$ease-default: "power2.out" !default;
|
||||
|
||||
// Function
|
||||
// ==========================================================================
|
||||
|
||||
// Returns ease curve.
|
||||
//
|
||||
// ```scss
|
||||
// .c-box {
|
||||
// transition-timing-function: ease("power2.out");
|
||||
// }
|
||||
// ```
|
||||
//
|
||||
// @param {string} $key - The ease key in $eases.
|
||||
// @return {easing-function}
|
||||
|
||||
@function ease($key: $ease-default) {
|
||||
@if not map-has-key($eases, $key) {
|
||||
@error "Unknown '#{$key}' in $eases.";
|
||||
}
|
||||
|
||||
@return map-get($eases, $key);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,42 @@
|
||||
// ==========================================================================
|
||||
// Tools / Font Faces
|
||||
// Settings / Config / Breakpoints
|
||||
// ==========================================================================
|
||||
|
||||
// Font fallbacks (retrieved from systemfontstack.com on 2022-05-31)
|
||||
// ==========================================================================
|
||||
|
||||
$font-fallback-sans: -apple-system, BlinkMacSystemFont, avenir next, avenir, segoe ui, helvetica neue, helvetica, Cantarell, Ubuntu, roboto, noto, arial, sans-serif;
|
||||
$font-fallback-serif: Iowan Old Style, Apple Garamond, Baskerville, Times New Roman, Droid Serif, Times, Source Serif Pro, serif, Apple Color Emoji, Segoe UI Emoji, Segoe UI Symbol;
|
||||
$font-fallback-mono: Menlo, Consolas, Monaco, Liberation Mono, Lucida Console, monospace;
|
||||
|
||||
// Typefaces
|
||||
// ==========================================================================
|
||||
|
||||
// List of custom font faces as tuples.
|
||||
//
|
||||
// ```
|
||||
// <font-name> <font-file-basename> <font-weight> <font-style>
|
||||
// ```
|
||||
$font-faces: (
|
||||
("Source Sans", "SourceSans3-Bold", 700, normal),
|
||||
("Source Sans", "SourceSans3-BoldIt", 700, italic),
|
||||
("Source Sans", "SourceSans3-Regular", 400, normal),
|
||||
("Source Sans", "SourceSans3-RegularIt", 400, italic),
|
||||
);
|
||||
|
||||
// Map of font families.
|
||||
//
|
||||
// ```
|
||||
// <font-id>: (<font-name>, <font-fallbacks>)
|
||||
// ```
|
||||
$font-families: (
|
||||
sans: join("Source Sans", $font-fallback-sans, $separator: comma),
|
||||
);
|
||||
|
||||
// Font directory
|
||||
$font-dir: "../fonts/";
|
||||
|
||||
// Functions
|
||||
// ==========================================================================
|
||||
|
||||
// Imports the custom font.
|
||||
@@ -11,43 +11,11 @@ $context: frontend !default;
|
||||
// Path is relative to the stylesheets directory.
|
||||
$assets-path: "../" !default;
|
||||
|
||||
// Typefaces
|
||||
// =============================================================================
|
||||
|
||||
// Font directory
|
||||
$font-dir: "../fonts/";
|
||||
|
||||
// Font fallbacks (retrieved from systemfontstack.com on 2022-05-31)
|
||||
$font-fallback-sans: -apple-system, BlinkMacSystemFont, avenir next, avenir, segoe ui, helvetica neue, helvetica, Cantarell, Ubuntu, roboto, noto, arial, sans-serif;
|
||||
$font-fallback-serif: Iowan Old Style, Apple Garamond, Baskerville, Times New Roman, Droid Serif, Times, Source Serif Pro, serif, Apple Color Emoji, Segoe UI Emoji, Segoe UI Symbol;
|
||||
$font-fallback-mono: Menlo, Consolas, Monaco, Liberation Mono, Lucida Console, monospace;
|
||||
|
||||
// Map of font families.
|
||||
//
|
||||
// ```
|
||||
// <font-id>: (<font-name>, <font-fallbacks>)
|
||||
// ```
|
||||
$font-families: (
|
||||
sans: join("Source Sans", $font-fallback-sans, $separator: comma),
|
||||
);
|
||||
|
||||
// List of custom font faces as tuples.
|
||||
//
|
||||
// ```
|
||||
// <font-name> <font-file-basename> <font-weight> <font-style>
|
||||
// ```
|
||||
$font-faces: (
|
||||
("Source Sans", "SourceSans3-Bold", 700, normal),
|
||||
("Source Sans", "SourceSans3-BoldIt", 700, italic),
|
||||
("Source Sans", "SourceSans3-Regular", 400, normal),
|
||||
("Source Sans", "SourceSans3-RegularIt", 400, italic),
|
||||
);
|
||||
|
||||
// Typography
|
||||
// =============================================================================
|
||||
|
||||
// Base
|
||||
$font-size: 16px;
|
||||
$font-size: 16px;
|
||||
$line-height: math.div(24px, $font-size);
|
||||
$font-color: color(darkest);
|
||||
|
||||
@@ -57,52 +25,21 @@ $font-weight-normal: 400;
|
||||
$font-weight-medium: 500;
|
||||
$font-weight-bold: 700;
|
||||
|
||||
// Transitions
|
||||
// Transition defaults
|
||||
// =============================================================================
|
||||
|
||||
$speed: 0.3s;
|
||||
$easing: $ease-power2-out;
|
||||
$speed: t(normal);
|
||||
$easing: ease("power2.out");
|
||||
|
||||
// Spacing Units
|
||||
// =============================================================================
|
||||
$unit: 60px;
|
||||
$unit-small: 20px;
|
||||
$unit: 60px;
|
||||
$unit-small: 20px;
|
||||
$vw-viewport: 1440;
|
||||
|
||||
// Container
|
||||
// ==========================================================================
|
||||
$padding: $unit;
|
||||
$padding: $unit;
|
||||
|
||||
// Grid
|
||||
// ==========================================================================
|
||||
$base-column-nb: 12;
|
||||
|
||||
// Breakpoints
|
||||
// =============================================================================
|
||||
|
||||
$from-tiny: 500px !default;
|
||||
$to-tiny: $from-tiny - 1 !default;
|
||||
$from-small: 700px !default;
|
||||
$to-small: $from-small - 1 !default;
|
||||
$from-medium: 1000px !default;
|
||||
$to-medium: $from-medium - 1 !default;
|
||||
$from-large: 1200px !default;
|
||||
$to-large: $from-large - 1 !default;
|
||||
$from-big: 1400px !default;
|
||||
$to-big: $from-big - 1 !default;
|
||||
$from-huge: 1600px !default;
|
||||
$to-huge: $from-huge - 1 !default;
|
||||
$from-enormous: 1800px !default;
|
||||
$to-enormous: $from-enormous - 1 !default;
|
||||
$from-gigantic: 2000px !default;
|
||||
$to-gigantic: $from-gigantic - 1 !default;
|
||||
$from-colossal: 2400px !default;
|
||||
$to-colossal: $from-colossal - 1 !default;
|
||||
|
||||
// Master z-indexe
|
||||
// =============================================================================
|
||||
|
||||
$z-indexes: (
|
||||
"header": 200,
|
||||
"above": 1,
|
||||
"below": -1
|
||||
);
|
||||
|
||||
69
assets/styles/settings/_config.spacings.scss
Normal file
69
assets/styles/settings/_config.spacings.scss
Normal file
@@ -0,0 +1,69 @@
|
||||
// ==========================================================================
|
||||
// Settings / Config / Spacings
|
||||
// ==========================================================================
|
||||
|
||||
:root {
|
||||
--spacing-2xs-mobile: 6;
|
||||
--spacing-2xs-desktop: 10;
|
||||
|
||||
--spacing-xs-mobile: 12;
|
||||
--spacing-xs-desktop: 16;
|
||||
|
||||
--spacing-sm-mobile: 22;
|
||||
--spacing-sm-desktop: 32;
|
||||
|
||||
--spacing-md-mobile: 32;
|
||||
--spacing-md-desktop: 56;
|
||||
|
||||
--spacing-lg-mobile: 48;
|
||||
--spacing-lg-desktop: 96;
|
||||
|
||||
--spacing-xl-mobile: 64;
|
||||
--spacing-xl-desktop: 128;
|
||||
|
||||
--spacing-2xl-mobile: 88;
|
||||
--spacing-2xl-desktop: 176;
|
||||
|
||||
--spacing-3xl-mobile: 122;
|
||||
--spacing-3xl-desktop: 224;
|
||||
}
|
||||
|
||||
// Spacings
|
||||
// ==========================================================================
|
||||
|
||||
$spacings: (
|
||||
'gutter': var(--grid-gutter),
|
||||
'2xs': #{size-clamp('2xs')},
|
||||
'xs': #{size-clamp('xs')},
|
||||
'sm': #{size-clamp('sm')},
|
||||
'md': #{size-clamp('md')},
|
||||
'lg': #{size-clamp('lg')},
|
||||
'xl': #{size-clamp('xl')},
|
||||
'2xl': #{size-clamp('2xl')},
|
||||
'3xl': #{size-clamp('3xl')},
|
||||
);
|
||||
|
||||
// Function
|
||||
// ==========================================================================
|
||||
|
||||
// Returns spacing.
|
||||
//
|
||||
// ```scss
|
||||
// .c-box {
|
||||
// margin-top: spacing(gutter);
|
||||
// }
|
||||
// ```
|
||||
//
|
||||
// @param {string} $key - The spacing key in $spacings.
|
||||
// @param {number} $multiplier - The multiplier of the spacing value.
|
||||
// @return {size}
|
||||
|
||||
@function spacing($spacing: 'sm', $multiplier: 1) {
|
||||
@if not map-has-key($spacings, $spacing) {
|
||||
@error "Unknown master spacing: #{$spacing}";
|
||||
}
|
||||
|
||||
$index: map-get($spacings, $spacing);
|
||||
|
||||
@return calc(#{$index} * #{$multiplier});
|
||||
}
|
||||
38
assets/styles/settings/_config.speeds.scss
Normal file
38
assets/styles/settings/_config.speeds.scss
Normal file
@@ -0,0 +1,38 @@
|
||||
// ==========================================================================
|
||||
// Settings / Config / Speeds
|
||||
// ==========================================================================
|
||||
|
||||
// Speeds
|
||||
// ==========================================================================
|
||||
|
||||
$speeds: (
|
||||
fastest: 0.1s,
|
||||
faster: 0.15s,
|
||||
fast: 0.25s,
|
||||
normal: 0.3s,
|
||||
slow: 0.5s,
|
||||
slower: 0.75s,
|
||||
slowest: 1s,
|
||||
);
|
||||
|
||||
// Function
|
||||
// ==========================================================================
|
||||
|
||||
// Returns timing.
|
||||
//
|
||||
// ```scss
|
||||
// .c-box {
|
||||
// transition-duration: speed(slow);
|
||||
// }
|
||||
// ```
|
||||
//
|
||||
// @param {string} $key - The speed key in $speeds.
|
||||
// @return {duration}
|
||||
|
||||
@function speed($key: "normal") {
|
||||
@if not map-has-key($speeds, $key) {
|
||||
@error "Unknown '#{$key}' in $speeds.";
|
||||
}
|
||||
|
||||
@return map-get($speeds, $key);
|
||||
}
|
||||
@@ -7,7 +7,6 @@
|
||||
// Grid
|
||||
--grid-columns: 4;
|
||||
--grid-gutter: #{rem(10px)};
|
||||
--grid-gutter-half: calc(0.5 * var(--grid-gutter));
|
||||
--grid-margin: #{rem(10px)};
|
||||
|
||||
// Container
|
||||
@@ -26,7 +25,7 @@
|
||||
// --color-#{"" + $color}: #{$value};
|
||||
// }
|
||||
|
||||
@media (min-width: $from-small) {
|
||||
@media (min-width: $from-sm) {
|
||||
--grid-columns: #{$base-column-nb};
|
||||
--grid-gutter: #{rem(16px)};
|
||||
--grid-margin: #{rem(20px)};
|
||||
|
||||
44
assets/styles/settings/_config.zindexes.scss
Normal file
44
assets/styles/settings/_config.zindexes.scss
Normal file
@@ -0,0 +1,44 @@
|
||||
// ==========================================================================
|
||||
// Settings / Config / Z-indexes
|
||||
// ==========================================================================
|
||||
|
||||
// Timings
|
||||
// ==========================================================================
|
||||
|
||||
$z-indexes: (
|
||||
"header": 200,
|
||||
"above": 1,
|
||||
"default": 0,
|
||||
"below": -1
|
||||
);
|
||||
|
||||
// Default z-index for z()
|
||||
$z-index-default: "above" !default;
|
||||
|
||||
// Function
|
||||
// ==========================================================================
|
||||
|
||||
// Retrieves the z-index from the {@see $layers master list}.
|
||||
//
|
||||
// @link on http://css-tricks.com/handling-z-index/
|
||||
//
|
||||
// @param {string} $layer The name of the z-index.
|
||||
// @param {number} $modifier A positive or negative modifier to apply
|
||||
// to the returned z-index value.
|
||||
// @throw Error if the $layer does not exist.
|
||||
// @throw Warning if the $modifier might overlap another master z-index.
|
||||
// @return {number} The computed z-index of $layer and $modifier.
|
||||
|
||||
@function z($layer: $z-index-default, $modifier: 0) {
|
||||
@if not map-has-key($z-indexes, $layer) {
|
||||
@error "Unknown master z-index layer: #{$layer}";
|
||||
}
|
||||
|
||||
@if ($modifier >= 50 or $modifier <= -50) {
|
||||
@warn "Modifier may overlap the another master z-index layer: #{$modifier}";
|
||||
}
|
||||
|
||||
$index: map-get($z-indexes, $layer);
|
||||
|
||||
@return $index + $modifier;
|
||||
}
|
||||
@@ -48,42 +48,6 @@
|
||||
@return math.div($size, $base) * 1rem;
|
||||
}
|
||||
|
||||
// Retrieves the z-index from the {@see $layers master list}.
|
||||
//
|
||||
// @link on http://css-tricks.com/handling-z-index/
|
||||
//
|
||||
// @param {string} $layer The name of the z-index.
|
||||
// @param {number} $modifier A positive or negative modifier to apply
|
||||
// to the returned z-index value.
|
||||
// @throw Error if the $layer does not exist.
|
||||
// @throw Warning if the $modifier might overlap another master z-index.
|
||||
// @return {number} The computed z-index of $layer and $modifier.
|
||||
|
||||
@function z($layer, $modifier: 0) {
|
||||
@if not map-has-key($z-indexes, $layer) {
|
||||
@error "Unknown master z-index layer: #{$layer}";
|
||||
}
|
||||
|
||||
@if ($modifier >= 50 or $modifier <= -50) {
|
||||
@warn "Modifier may overlap the another master z-index layer: #{$modifier}";
|
||||
}
|
||||
|
||||
$index: map-get($z-indexes, $layer);
|
||||
|
||||
@return $index + $modifier;
|
||||
}
|
||||
|
||||
// Converts a number to a percentage.
|
||||
//
|
||||
// @alias percentage()
|
||||
// @link http://sassdoc.com/annotations/#alias
|
||||
// @param {Number} $number - The value to convert.
|
||||
// @return {Number} A percentage.
|
||||
|
||||
@function span($number) {
|
||||
@return percentage($number);
|
||||
}
|
||||
|
||||
// Checks if a list contains a value(s).
|
||||
//
|
||||
// @link https://github.com/thoughtbot/bourbon/blob/master/core/bourbon/validators/_contains.scss
|
||||
@@ -150,25 +114,53 @@ $context: 'frontend' !default;
|
||||
// }
|
||||
// ```
|
||||
//
|
||||
// @param {number} $number - The percentage spacer
|
||||
// @param {number} $inset - The grid gutter inset
|
||||
// @param {number} $percentage - The percentage spacer
|
||||
// @param {number} $inset - The grid gutter inset
|
||||
// @return {function<number>}
|
||||
@function grid-space($percentage, $inset: 0) {
|
||||
@return calc(#{$percentage} * (100vw - 2 * var(--grid-margin, 0px)) - (1 - #{$percentage}) * var(--grid-gutter, 0px) + #{$inset} * var(--grid-gutter, 0px));
|
||||
@return calc(#{$percentage} * (#{vw(100)} - 2 * var(--grid-margin, 0px)) - (1 - #{$percentage}) * var(--grid-gutter, 0px) + #{$inset} * var(--grid-gutter, 0px));
|
||||
}
|
||||
|
||||
// Returns calculation of a percentage of the viewport height.
|
||||
// Returns calculation of a percentage of the viewport small height.
|
||||
//
|
||||
// ```scss
|
||||
// .c-box {
|
||||
// height: vh(100);
|
||||
// height: svh(100);
|
||||
// }
|
||||
// ```
|
||||
//
|
||||
// @param {number} $number - The percentage number
|
||||
// @return {function<number>} in vh
|
||||
@function vh($number) {
|
||||
@return calc(#{$number} * var(--vh, 1vh));
|
||||
// @return {function<number>} in svh
|
||||
@function svh($number) {
|
||||
@return calc(#{$number} * var(--svh, 1svh));
|
||||
}
|
||||
|
||||
// Returns calculation of a percentage of the viewport large height.
|
||||
//
|
||||
// ```scss
|
||||
// .c-box {
|
||||
// height: lvh(100);
|
||||
// }
|
||||
// ```
|
||||
//
|
||||
// @param {number} $number - The percentage number
|
||||
// @return {function<number>} in lvh
|
||||
@function lvh($number) {
|
||||
@return calc(#{$number} * var(--lvh, 1lvh));
|
||||
}
|
||||
|
||||
// Returns calculation of a percentage of the viewport dynamic height.
|
||||
//
|
||||
// ```scss
|
||||
// .c-box {
|
||||
// height: dvh(100);
|
||||
// }
|
||||
// ```
|
||||
//
|
||||
// @param {number} $number - The percentage number
|
||||
// @return {function<number>} in dvh
|
||||
@function dvh($number) {
|
||||
@return calc(#{$number} * var(--dvh, 1dvh));
|
||||
}
|
||||
|
||||
// Returns calculation of a percentage of the viewport width.
|
||||
@@ -186,6 +178,19 @@ $context: 'frontend' !default;
|
||||
@return calc(#{$number} * var(--vw, 1vw));
|
||||
}
|
||||
|
||||
@function clamp-with-max($min, $size, $max) {
|
||||
$vw-context: $vw-viewport * 0.01;
|
||||
@return clamp(#{$min}, calc(#{$size} / #{$vw-context} * 1vw), #{$max});
|
||||
}
|
||||
|
||||
@function size-clamp($size) {
|
||||
@return clamp-with-max(
|
||||
calc(#{rem(1px)} * var(--spacing-#{$size}-mobile)),
|
||||
var(--spacing-#{$size}-desktop),
|
||||
calc(#{rem(1px)} * var(--spacing-#{$size}-desktop))
|
||||
);
|
||||
}
|
||||
|
||||
// Returns clamp of calculated preferred responsive font size
|
||||
// within a font size and breakpoint range.
|
||||
//
|
||||
@@ -195,7 +200,7 @@ $context: 'frontend' !default;
|
||||
// }
|
||||
//
|
||||
// .c-heading.-h2 {
|
||||
// font-size: responsive-type(20px, 40px, $from-big);
|
||||
// font-size: responsive-type(20px, 40px, $from-xl);
|
||||
// }
|
||||
// ```
|
||||
//
|
||||
@@ -207,21 +212,3 @@ $context: 'frontend' !default;
|
||||
$delta: math.div($max-size, $breakpoint);
|
||||
@return clamp($min-size, calc(#{strip-unit($delta)} * #{vw(100)}), $max-size);
|
||||
}
|
||||
|
||||
// Returns color code.
|
||||
//
|
||||
// ```scss
|
||||
// .c-box {
|
||||
// width: color(primary);
|
||||
// }
|
||||
// ```
|
||||
//
|
||||
// @param {string} $key - The color key in $colors.
|
||||
// @return {color}
|
||||
|
||||
@function color($key) {
|
||||
@if not map-has-key($colors, $key) {
|
||||
@error "Unknown '#{$key}' in $colors.";
|
||||
}
|
||||
@return map-get($colors, $key);
|
||||
}
|
||||
|
||||
@@ -193,3 +193,32 @@
|
||||
display: $display $important;
|
||||
visibility: visible $important;
|
||||
}
|
||||
|
||||
// Aspect-ratio polyfill
|
||||
//
|
||||
// @param {Number} $ratio [19/6] - The ratio of the element.
|
||||
// @param {Number} $width [100%] - The fallback width of element.
|
||||
// @param {Boolean} $children [false] - Whether the element contains children for the fallback properties.
|
||||
// @output Properties for maintaining aspect-ratio
|
||||
|
||||
@mixin aspect-ratio($ratio: math.div(16, 9), $width: 100%, $children: false) {
|
||||
|
||||
@supports (aspect-ratio: 1) {
|
||||
aspect-ratio: $ratio;
|
||||
}
|
||||
|
||||
@supports not (aspect-ratio: 1) {
|
||||
height: 0;
|
||||
padding-top: calc(#{$width} * #{math.div(1, $ratio)});
|
||||
|
||||
@if ($children == true) {
|
||||
position: relative;
|
||||
|
||||
> * {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,29 +11,31 @@
|
||||
|
||||
$colsMax: $base-column-nb + 1;
|
||||
|
||||
$breakpoints: (
|
||||
"null" null,
|
||||
"from-tiny" $from-tiny,
|
||||
"from-small" $from-small,
|
||||
"from-medium" $from-medium,
|
||||
"from-large" $from-large,
|
||||
"from-big" $from-big
|
||||
) !default;
|
||||
|
||||
@each $breakpoint, $mediaquery in $breakpoints {
|
||||
@for $fromIndex from 1 through $colsMax {
|
||||
@for $toIndex from 1 through $colsMax {
|
||||
@if $mediaquery == null {
|
||||
|
||||
// Columns without media query
|
||||
@if $breakpoint == "tiny" {
|
||||
.u-gc-#{$fromIndex}\/#{$toIndex} {
|
||||
--gc-start: #{$fromIndex};
|
||||
--gc-end: #{$toIndex};
|
||||
}
|
||||
} @else {
|
||||
.u-gc-#{$fromIndex}\/#{$toIndex}\@#{$breakpoint} {
|
||||
@media (min-width: #{$mediaquery}) {
|
||||
--gc-start: #{$fromIndex};
|
||||
--gc-end: #{$toIndex};
|
||||
}
|
||||
}
|
||||
|
||||
// Columns min-width breakpoints `@from-*`
|
||||
.u-gc-#{$fromIndex}\/#{$toIndex}\@from-#{$breakpoint} {
|
||||
@media #{mq-min($breakpoint)} {
|
||||
--gc-start: #{$fromIndex};
|
||||
--gc-end: #{$toIndex};
|
||||
}
|
||||
}
|
||||
|
||||
// Columns max-width breakpoints @to-*`
|
||||
.u-gc-#{$fromIndex}\/#{$toIndex}\@to-#{$breakpoint} {
|
||||
@media #{mq-max($breakpoint)} {
|
||||
--gc-start: #{$fromIndex};
|
||||
--gc-end: #{$toIndex};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,12 +8,11 @@
|
||||
///
|
||||
/// @example
|
||||
/// .u-margin-top {}
|
||||
/// .u-padding-left-large {}
|
||||
/// .u-margin-right-small {}
|
||||
/// .u-margin-top-xs {}
|
||||
/// .u-padding-left-lg {}
|
||||
/// .u-margin-right-sm {}
|
||||
/// .u-padding {}
|
||||
/// .u-padding-right-none {}
|
||||
/// .u-padding-horizontal {}
|
||||
/// .u-padding-vertical-small {}
|
||||
///
|
||||
/// @link https://github.com/inuitcss/inuitcss/blob/512977a/utilities/_utilities.spacing.scss
|
||||
////
|
||||
@@ -26,8 +25,8 @@ $spacing-directions: (
|
||||
'-right': '-right',
|
||||
'-bottom': '-bottom',
|
||||
'-left': '-left',
|
||||
'-horizontal': '-left' '-right',
|
||||
'-vertical': '-top' '-bottom',
|
||||
'-x': '-left' '-right',
|
||||
'-y': '-top' '-bottom',
|
||||
) !default;
|
||||
|
||||
$spacing-properties: (
|
||||
@@ -35,19 +34,47 @@ $spacing-properties: (
|
||||
'margin': 'margin',
|
||||
) !default;
|
||||
|
||||
$spacing-sizes: (
|
||||
null: $unit,
|
||||
'-double': $unit * 2,
|
||||
'-small': $unit-small,
|
||||
'-none': 0px
|
||||
) !default;
|
||||
$spacing-sizes: join($spacings, (
|
||||
null: var(--grid-gutter),
|
||||
'none': 0
|
||||
));
|
||||
|
||||
@each $property-namespace, $property in $spacing-properties {
|
||||
@each $direction-namespace, $direction-rules in $spacing-directions {
|
||||
@each $size-namespace, $size in $spacing-sizes {
|
||||
.u-#{$property-namespace}#{$direction-namespace}#{$size-namespace} {
|
||||
@each $direction in $direction-rules {
|
||||
#{$property}#{$direction}: rem($size) !important;
|
||||
@each $breakpoint, $mediaquery in $breakpoints {
|
||||
@each $property-namespace, $property in $spacing-properties {
|
||||
@each $direction-namespace, $directions in $spacing-directions {
|
||||
@each $size-namespace, $size in $spacing-sizes {
|
||||
|
||||
// Prepend "-" to spacing sizes if not null
|
||||
$size-namespace: if($size-namespace != null, "-" + $size-namespace, $size-namespace);
|
||||
|
||||
// Base class
|
||||
$base-class: ".u-" + #{$property-namespace}#{$direction-namespace}#{$size-namespace};
|
||||
|
||||
// Spacing without media query
|
||||
@if $breakpoint == "xs" {
|
||||
#{$base-class} {
|
||||
@each $direction in $directions {
|
||||
#{$property}#{$direction}: $size !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Spacing min-width breakpoints `@from-*`
|
||||
#{$base-class}\@from-#{$breakpoint} {
|
||||
@media #{mq-min($breakpoint)} {
|
||||
@each $direction in $directions {
|
||||
#{$property}#{$direction}: $size !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Spacing max-width breakpoints @to-*`
|
||||
#{$base-class}\@to-#{$breakpoint} {
|
||||
@media #{mq-max($breakpoint)} {
|
||||
@each $direction in $directions {
|
||||
#{$property}#{$direction}: $size !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,14 +46,14 @@
|
||||
}
|
||||
}
|
||||
|
||||
// .is-hidden\@to-large {
|
||||
// @media (max-width: $to-large) {
|
||||
// .is-hidden\@to-lg {
|
||||
// @media (max-width: $to-lg) {
|
||||
// display: none;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// .is-hidden\@from-large {
|
||||
// @media (min-width: $from-large) {
|
||||
// .is-hidden\@from-lg {
|
||||
// @media (min-width: $from-lg) {
|
||||
// display: none;
|
||||
// }
|
||||
// }
|
||||
|
||||
@@ -21,8 +21,8 @@ $widths-fractions: 1 2 3 4 5 !default;
|
||||
|
||||
@include widths($widths-fractions);
|
||||
|
||||
.u-1\/2\@from-small {
|
||||
@media (min-width: $from-small) {
|
||||
width: span(1/2);
|
||||
.u-1\/2\@from-sm {
|
||||
@media (min-width: $from-sm) {
|
||||
width: 50%;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
import buildEleventy from './tasks/eleventy.js';
|
||||
import concatFiles from './tasks/concats.js';
|
||||
import compileScripts from './tasks/scripts.js';
|
||||
import compileStyles from './tasks/styles.js';
|
||||
import compileSVGs from './tasks/svgs.js';
|
||||
import bumpVersions from './tasks/versions.js';
|
||||
|
||||
buildEleventy();
|
||||
concatFiles();
|
||||
compileScripts();
|
||||
compileStyles();
|
||||
|
||||
@@ -95,7 +95,7 @@ export default async function concatFiles(globOptions = null, concatOptions = nu
|
||||
* Defaults to the outfile name.
|
||||
* @return {Promise}
|
||||
*/
|
||||
loconfig.tasks.concats.forEach(async ({
|
||||
loconfig.tasks.concats?.forEach(async ({
|
||||
includes,
|
||||
outfile,
|
||||
label = null
|
||||
|
||||
50
build/tasks/eleventy.js
Normal file
50
build/tasks/eleventy.js
Normal file
@@ -0,0 +1,50 @@
|
||||
import message from '../helpers/message.js';
|
||||
import { merge } from '../utils/index.js';
|
||||
import Eleventy from "@11ty/eleventy";
|
||||
|
||||
export const defaultEleventyOptions = {
|
||||
production: true
|
||||
}
|
||||
|
||||
export const developmentEleventyOptions = {
|
||||
production: false
|
||||
}
|
||||
|
||||
export const productionEleventyOptions = {
|
||||
production: true
|
||||
}
|
||||
|
||||
let elev;
|
||||
export default async function buildEleventy(eleventyOptions = null) {
|
||||
if (eleventyOptions == null) {
|
||||
eleventyOptions = productionEleventyOptions;
|
||||
} else if (
|
||||
eleventyOptions !== developmentEleventyOptions &&
|
||||
eleventyOptions !== productionEleventyOptions
|
||||
) {
|
||||
eleventyOptions = merge({}, defaultEleventyOptions, eleventyOptions);
|
||||
}
|
||||
|
||||
const { production } = eleventyOptions;
|
||||
const timeLabel = `11ty compiled in`;
|
||||
console.time(timeLabel);
|
||||
|
||||
try {
|
||||
|
||||
if(!elev) {
|
||||
elev = new Eleventy();
|
||||
|
||||
if(!production) {
|
||||
await elev.watch();
|
||||
}
|
||||
}
|
||||
|
||||
// Disable caching to ensure a fresh build each time
|
||||
await elev.write();
|
||||
|
||||
message(`11ty compiled`, 'success', timeLabel);
|
||||
} catch(err) {
|
||||
console.error(err)
|
||||
message(err, 'error', timeLabel);
|
||||
}
|
||||
}
|
||||
@@ -65,7 +65,7 @@ export default async function compileScripts(esBuildOptions = null) {
|
||||
* @throws {TypeError} If outdir and outfile are missing.
|
||||
* @return {Promise}
|
||||
*/
|
||||
loconfig.tasks.scripts.forEach(async ({
|
||||
loconfig.tasks.scripts?.forEach(async ({
|
||||
includes,
|
||||
outdir = '',
|
||||
outfile = '',
|
||||
|
||||
@@ -11,7 +11,7 @@ import { merge } from '../utils/index.js';
|
||||
import { writeFile } from 'node:fs/promises';
|
||||
import { basename } from 'node:path';
|
||||
import { promisify } from 'node:util';
|
||||
import sass from 'sass';
|
||||
import * as sass from 'sass';
|
||||
import { PurgeCSS } from 'purgecss';
|
||||
|
||||
const sassRender = promisify(sass.render);
|
||||
@@ -60,10 +60,12 @@ export const productionPostCSSOptions = Object.assign({}, defaultPostCSSOptions
|
||||
export const developmentStylesArgs = [
|
||||
developmentSassOptions,
|
||||
developmentPostCSSOptions,
|
||||
false
|
||||
];
|
||||
export const productionStylesArgs = [
|
||||
productionSassOptions,
|
||||
productionPostCSSOptions,
|
||||
true
|
||||
];
|
||||
|
||||
/**
|
||||
@@ -80,7 +82,7 @@ export const productionStylesArgs = [
|
||||
* If `false`, PostCSS processing will be ignored.
|
||||
* @return {Promise}
|
||||
*/
|
||||
export default async function compileStyles(sassOptions = null, postcssOptions = null) {
|
||||
export default async function compileStyles(sassOptions = null, postcssOptions = null, purge = true) {
|
||||
if (sassOptions == null) {
|
||||
sassOptions = productionSassOptions;
|
||||
} else if (
|
||||
@@ -111,7 +113,7 @@ export default async function compileStyles(sassOptions = null, postcssOptions =
|
||||
* Defaults to the outfile name.
|
||||
* @return {Promise}
|
||||
*/
|
||||
loconfig.tasks.styles.forEach(async ({
|
||||
loconfig.tasks.styles?.forEach(async ({
|
||||
infile,
|
||||
outfile,
|
||||
label = null
|
||||
@@ -160,7 +162,7 @@ export default async function compileStyles(sassOptions = null, postcssOptions =
|
||||
try {
|
||||
await writeFile(outfile, result.css).then(() => {
|
||||
// Purge CSS once file exists.
|
||||
if (outfile) {
|
||||
if (outfile && purge) {
|
||||
purgeUnusedCSS(outfile, `${label || `${filestem}.css`}`);
|
||||
}
|
||||
});
|
||||
@@ -216,21 +218,27 @@ export default async function compileStyles(sassOptions = null, postcssOptions =
|
||||
* @return {Promise}
|
||||
*/
|
||||
async function purgeUnusedCSS(outfile, label) {
|
||||
const contentFiles = loconfig.tasks.purgeCSS?.content;
|
||||
if (!Array.isArray(contentFiles) || !contentFiles.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
label = label ?? basename(outfile);
|
||||
|
||||
const timeLabel = `${label} purged in`;
|
||||
console.time(timeLabel);
|
||||
|
||||
const purgeCSSContentFiles = Array.from(loconfig.tasks.purgeCSS.content);
|
||||
|
||||
const purgeCSSResults = await (new PurgeCSS()).purge({
|
||||
content: purgeCSSContentFiles,
|
||||
content: contentFiles,
|
||||
css: [ outfile ],
|
||||
rejected: true,
|
||||
defaultExtractor: (content) => content.match(/[a-z0-9_\-\\\/\@]+/gi) || [],
|
||||
defaultExtractor: content => content.match(/[a-z0-9_\-\\\/\@]+/gi) || [],
|
||||
fontFaces: true,
|
||||
keyframes: true,
|
||||
safelist: {
|
||||
standard: [ /^((?!\bu-gc-).)*$/ ]
|
||||
}
|
||||
// Keep all except .u-gc-* | .u-margin-* | .u-padding-*
|
||||
standard: [ /^(?!.*\b(u-gc-|u-margin|u-padding)).*$/ ]
|
||||
},
|
||||
variables: true,
|
||||
})
|
||||
|
||||
for (let result of purgeCSSResults) {
|
||||
|
||||
@@ -57,7 +57,7 @@ export default async function compileSVGs(mixerOptions = null) {
|
||||
* Defaults to the outfile name.
|
||||
* @return {Promise}
|
||||
*/
|
||||
loconfig.tasks.svgs.forEach(async ({
|
||||
loconfig.tasks.svgs?.forEach(async ({
|
||||
includes,
|
||||
outfile,
|
||||
label = null
|
||||
|
||||
@@ -21,6 +21,8 @@ import {
|
||||
} from 'node:path';
|
||||
import readline from 'node:readline';
|
||||
|
||||
export const REGEXP_SEMVER = /^(?<major>0|[1-9]\d*)\.(?<minor>0|[1-9]\d*)\.(?<patch>0|[1-9]\d*)(?:-(?<prerelease>(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+(?<buildmetadata>[0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$/;
|
||||
|
||||
/**
|
||||
* @typedef {object} VersionOptions
|
||||
* @property {string|number|null} prettyPrint - A string or number to insert
|
||||
@@ -111,7 +113,7 @@ export default async function bumpVersions(versionOptions = null) {
|
||||
* @param {?string|number} [entry.pretty] - The white space to use to format the JSON file.
|
||||
* @return {Promise}
|
||||
*/
|
||||
loconfig.tasks.versions.forEach(({
|
||||
loconfig.tasks.versions?.forEach(({
|
||||
outfile,
|
||||
label = null,
|
||||
...options
|
||||
@@ -135,32 +137,64 @@ export default async function bumpVersions(versionOptions = null) {
|
||||
/**
|
||||
* Creates a formatted version number or string.
|
||||
*
|
||||
* @param {string} format - The version format.
|
||||
* @param {string} format - The version format.
|
||||
* @param {?string} [oldValue] - The old version value.
|
||||
* @return {string|number}
|
||||
* @throws TypeError If the format or value are invalid.
|
||||
*/
|
||||
function createVersionNumber(format) {
|
||||
function createVersionNumber(format, oldValue = null) {
|
||||
let [ type, modifier ] = format.split(':', 2);
|
||||
|
||||
switch (type) {
|
||||
case 'hex':
|
||||
case 'hexadecimal':
|
||||
modifier = Number.parseInt(modifier);
|
||||
try {
|
||||
modifier = Number.parseInt(modifier);
|
||||
|
||||
if (Number.isNaN(modifier)) {
|
||||
modifier = 6;
|
||||
if (Number.isNaN(modifier)) {
|
||||
modifier = 6;
|
||||
}
|
||||
|
||||
return randomBytes(modifier).toString('hex');
|
||||
} catch (err) {
|
||||
throw new TypeError(
|
||||
`${err.message} for \'format\' type "hexadecimal"`,
|
||||
{ cause: err }
|
||||
);
|
||||
}
|
||||
|
||||
return randomBytes(modifier).toString('hex');
|
||||
case 'inc':
|
||||
case 'increment':
|
||||
try {
|
||||
if (modifier === 'semver') {
|
||||
return incrementSemVer(oldValue, [ 'buildmetadata', 'patch' ]);
|
||||
}
|
||||
|
||||
return incrementNumber(oldValue, modifier);
|
||||
} catch (err) {
|
||||
throw new TypeError(
|
||||
`${err.message} for \'format\' type "increment"`,
|
||||
{ cause: err }
|
||||
);
|
||||
}
|
||||
|
||||
case 'regex':
|
||||
return new RegExp(modifier);
|
||||
case 'regexp':
|
||||
try {
|
||||
return new RegExp(modifier);
|
||||
} catch (err) {
|
||||
throw new TypeError(
|
||||
`${err.message} for \'format\' type "regexp"`,
|
||||
{ cause: err }
|
||||
);
|
||||
}
|
||||
|
||||
case 'timestamp':
|
||||
return Date.now().valueOf();
|
||||
}
|
||||
|
||||
throw new TypeError(
|
||||
'Expected \'format\' to be either "timestamp" or "hexadecimal"'
|
||||
'Expected \'format\' to be either "timestamp", "increment", or "hexadecimal"'
|
||||
);
|
||||
}
|
||||
|
||||
@@ -221,9 +255,7 @@ async function handleBumpVersionInJson(outfile, label, options) {
|
||||
await mkdir(dirname(outfile), { recursive: true });
|
||||
}
|
||||
|
||||
const version = createVersionNumber(options.format);
|
||||
|
||||
json[options.key] = version;
|
||||
json[options.key] = createVersionNumber(options.format, json?.[options.key]);
|
||||
|
||||
return await writeFile(
|
||||
outfile,
|
||||
@@ -254,7 +286,7 @@ async function handleBumpVersionWithRegExp(outfile, label, options) {
|
||||
input: createReadStream(bckfile),
|
||||
});
|
||||
|
||||
const version = createVersionNumber(options.format);
|
||||
let newVersion = null;
|
||||
|
||||
const writeStream = createWriteStream(outfile, { encoding: 'utf8' });
|
||||
|
||||
@@ -262,12 +294,12 @@ async function handleBumpVersionWithRegExp(outfile, label, options) {
|
||||
const found = line.match(options.key);
|
||||
|
||||
if (found) {
|
||||
const groups = (found.groups ?? {});
|
||||
const replace = found[0].replace(
|
||||
(groups.build ?? groups.version ?? found[1] ?? found[0]),
|
||||
version
|
||||
);
|
||||
line = line.replace(found[0], replace);
|
||||
const groups = (found.groups ?? {});
|
||||
const oldVersion = (groups.build ?? groups.version ?? found[1] ?? found[0]);
|
||||
const newVersion = createVersionNumber(options.format, oldVersion);
|
||||
const replacement = found[0].replace(oldVersion, newVersion);
|
||||
|
||||
line = line.replace(found[0], replacement);
|
||||
}
|
||||
|
||||
writeStream.write(line + "\n");
|
||||
@@ -285,6 +317,88 @@ async function handleBumpVersionWithRegExp(outfile, label, options) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Increments the given integer.
|
||||
*
|
||||
* @param {string|int} value - The number to increment.
|
||||
* @param {string|int} [increment=1] - The amount to increment by.
|
||||
* @return {int}
|
||||
* @throws TypeError If the version number is invalid.
|
||||
*/
|
||||
function incrementNumber(value, increment = 1) {
|
||||
const version = Number.parseInt(value);
|
||||
if (Number.isNaN(version)) {
|
||||
throw new TypeError(
|
||||
`Expected an integer version number, received [${value}]`
|
||||
);
|
||||
}
|
||||
|
||||
increment = Number.parseInt(increment);
|
||||
if (Number.isNaN(increment)) {
|
||||
throw new TypeError(
|
||||
'Expected an integer increment number'
|
||||
);
|
||||
}
|
||||
|
||||
return (version + increment);
|
||||
}
|
||||
|
||||
/**
|
||||
* Increments the given SemVer version number.
|
||||
*
|
||||
* @param {string} value - The version to mutate.
|
||||
* @param {string|string[]} [target] - The segment to increment, one of:
|
||||
* 'major', 'minor', 'patch', ~~'prerelease'~~, 'buildmetadata'.
|
||||
* @param {string|int} [increment=1] - The amount to increment by.
|
||||
* @return {string}
|
||||
* @throws TypeError If the version or target are invalid.
|
||||
*/
|
||||
function incrementSemVer(value, target = 'patch', increment = 1) {
|
||||
const found = value.match(REGEXP_SEMVER);
|
||||
if (!found) {
|
||||
throw new TypeError(
|
||||
`Expected a SemVer version number, received [${value}]`
|
||||
);
|
||||
}
|
||||
|
||||
if (Array.isArray(target)) {
|
||||
for (const group of target) {
|
||||
if (found.groups[group] != null) {
|
||||
target = group;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!target || !found.groups[target]) {
|
||||
throw new TypeError(
|
||||
`Expected a supported SemVer segment, received [${target}]`
|
||||
);
|
||||
}
|
||||
|
||||
const segments = {
|
||||
'major': '',
|
||||
'minor': '.',
|
||||
'patch': '.',
|
||||
'prerelease': '-',
|
||||
'buildmetadata': '+',
|
||||
};
|
||||
|
||||
let replacement = '';
|
||||
|
||||
for (const [ segment, delimiter ] of Object.entries(segments)) {
|
||||
if (found.groups?.[segment] != null) {
|
||||
const newVersion = (segment === target)
|
||||
? incrementNumber(found.groups[segment], increment)
|
||||
: found.groups[segment];
|
||||
|
||||
replacement += `${delimiter}${newVersion}`;
|
||||
}
|
||||
}
|
||||
|
||||
return value.replace(found[0], replacement);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the version key.
|
||||
*
|
||||
|
||||
@@ -2,6 +2,7 @@ import concatFiles, { developmentConcatFilesArgs } from './tasks/concats.js';
|
||||
import compileScripts, { developmentScriptsArgs } from './tasks/scripts.js';
|
||||
import compileStyles, { developmentStylesArgs } from './tasks/styles.js' ;
|
||||
import compileSVGs, { developmentSVGsArgs } from './tasks/svgs.js';
|
||||
import buildEleventy, { developmentEleventyOptions } from './tasks/eleventy.js';
|
||||
import loconfig from './helpers/config.js';
|
||||
import message from './helpers/message.js';
|
||||
import notification from './helpers/notification.js';
|
||||
@@ -19,6 +20,7 @@ concatFiles(...developmentConcatFilesArgs);
|
||||
compileScripts(...developmentScriptsArgs);
|
||||
compileStyles(...developmentStylesArgs);
|
||||
compileSVGs(...developmentSVGsArgs);
|
||||
await buildEleventy(developmentEleventyOptions);
|
||||
|
||||
// Create a new BrowserSync instance
|
||||
const server = browserSync.create();
|
||||
@@ -53,10 +55,7 @@ function configureServer(server, { paths, tasks }) {
|
||||
// Reload on any changes to views or processed files
|
||||
server.watch(
|
||||
[
|
||||
...views,
|
||||
join(paths.scripts.dest, '*.js'),
|
||||
join(paths.styles.dest, '*.css'),
|
||||
join(paths.svgs.dest, '*.svg'),
|
||||
join(paths.dest, '**/*')
|
||||
]
|
||||
).on('change', server.reload);
|
||||
|
||||
@@ -70,16 +69,18 @@ function configureServer(server, { paths, tasks }) {
|
||||
});
|
||||
|
||||
// Watch source concats
|
||||
server.watch(
|
||||
resolve(
|
||||
tasks.concats.reduce(
|
||||
(patterns, { includes }) => patterns.concat(includes),
|
||||
[]
|
||||
if (tasks.concats?.length) {
|
||||
server.watch(
|
||||
resolve(
|
||||
tasks.concats.reduce(
|
||||
(patterns, { includes }) => patterns.concat(includes),
|
||||
[]
|
||||
)
|
||||
)
|
||||
)
|
||||
).on('change', () => {
|
||||
concatFiles(...developmentConcatFilesArgs);
|
||||
});
|
||||
).on('change', () => {
|
||||
concatFiles(...developmentConcatFilesArgs);
|
||||
});
|
||||
}
|
||||
|
||||
// Watch source styles
|
||||
server.watch(
|
||||
|
||||
4
data/metadata.json
Normal file
4
data/metadata.json
Normal file
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"title": "Locomotive Boilerplate",
|
||||
"description": "Front-end boilerplate for projects by Locomotive."
|
||||
}
|
||||
34
data/projects.json
Normal file
34
data/projects.json
Normal file
@@ -0,0 +1,34 @@
|
||||
[
|
||||
{
|
||||
"title": "Lusail Stadium",
|
||||
"desc": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Scelerisque viverra mauris in aliquam sem fringilla ut morbi tincidunt. In dictum non consectetur a erat nam at lectus urna. Ullamcorper dignissim cras tincidunt lobortis feugiat vivamus at augue."
|
||||
},
|
||||
{
|
||||
"title": "Tottenham Hotspur Stadium",
|
||||
"desc": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Interdum posuere lorem ipsum dolor sit amet consectetur adipiscing. Eget mi proin sed libero enim sed. Tincidunt id aliquet risus feugiat in ante metus."
|
||||
},
|
||||
{
|
||||
"title": "Narendra Modi Stadium",
|
||||
"desc": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Vitae tempus quam pellentesque nec nam aliquam. Velit laoreet id donec ultrices tincidunt. Tincidunt lobortis feugiat vivamus at augue eget arcu."
|
||||
},
|
||||
{
|
||||
"title": "Texas A&M Kyle Field",
|
||||
"desc": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Adipiscing diam donec adipiscing tristique risus nec feugiat in fermentum. Integer malesuada nunc vel risus commodo viverra maecenas accumsan. Dui faucibus in ornare quam viverra orci sagittis."
|
||||
},
|
||||
{
|
||||
"title": "The Cathedral — A New Icon for Milan",
|
||||
"desc": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Scelerisque viverra mauris in aliquam sem fringilla ut morbi tincidunt. In dictum non consectetur a erat nam at lectus urna. Ullamcorper dignissim cras tincidunt lobortis feugiat vivamus at augue."
|
||||
},
|
||||
{
|
||||
"title": "Allianz Field",
|
||||
"desc": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Interdum posuere lorem ipsum dolor sit amet consectetur adipiscing. Eget mi proin sed libero enim sed. Tincidunt id aliquet risus feugiat in ante metus."
|
||||
},
|
||||
{
|
||||
"title": "TQL Stadium",
|
||||
"desc": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Vitae tempus quam pellentesque nec nam aliquam. Velit laoreet id donec ultrices tincidunt. Tincidunt lobortis feugiat vivamus at augue eget arcu."
|
||||
},
|
||||
{
|
||||
"title": "Groupama Stadium and Training Centre",
|
||||
"desc": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Adipiscing diam donec adipiscing tristique risus nec feugiat in fermentum. Integer malesuada nunc vel risus commodo viverra maecenas accumsan. Dui faucibus in ornare quam viverra orci sagittis."
|
||||
}
|
||||
]
|
||||
@@ -338,8 +338,8 @@ See [`svgs.js`](../build/tasks/svgs.js) for details.
|
||||
|
||||
A task to create and update values for use in versioning assets.
|
||||
|
||||
Can generate a hexadecimal value (using random bytes) or
|
||||
use the current timestamp.
|
||||
Can generate a hexadecimal value (using random bytes), use the current timestamp,
|
||||
or increment a number.
|
||||
|
||||
Example:
|
||||
|
||||
@@ -355,6 +355,11 @@ Example:
|
||||
"format": "hex:8",
|
||||
"key": "hex",
|
||||
"outfile": "./assets.json"
|
||||
},
|
||||
{
|
||||
"format": "inc:semver",
|
||||
"key": "inc",
|
||||
"outfile": "./assets.json"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -363,7 +368,8 @@ Example:
|
||||
```json
|
||||
{
|
||||
"now": 1665071717350,
|
||||
"hex": "6ef54181c4ba"
|
||||
"hex": "6ef54181c4ba",
|
||||
"hex": "1.0.2"
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
@@ -70,8 +70,8 @@ The first step is to set intial SCSS values in the following files :
|
||||
grid-template-columns: repeat(4, 1fr);
|
||||
}
|
||||
|
||||
&.-col-#{$base-column-nb}\@from-medium {
|
||||
@media (min-width: $from-medium) {
|
||||
&.-col-#{$base-column-nb}\@from-md {
|
||||
@media (min-width: $from-md) {
|
||||
grid-template-columns: repeat(#{$base-column-nb}, 1fr);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -80,10 +80,10 @@ Learn about [namespacing](https://csswizardry.com/2015/03/more-transparent-ui-co
|
||||
}
|
||||
|
||||
.c-block_heading {
|
||||
@media (max-width: $to-medium) {
|
||||
@media (max-width: $to-md) {
|
||||
.c-block.-large & {
|
||||
margin-bottom: rem(40px);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
@@ -181,10 +181,7 @@ detection and smooth scrolling with parallax.
|
||||
```js
|
||||
import LocomotiveScroll from 'locomotive-scroll';
|
||||
|
||||
this.scroll = new LocomotiveScroll({
|
||||
el: this.el,
|
||||
smooth: true
|
||||
});
|
||||
this.scroll = new LocomotiveScroll({})
|
||||
````
|
||||
|
||||
Learn more about [Locomotive Scroll][locomotive-scroll].
|
||||
|
||||
71
eleventy.config.cjs
Normal file
71
eleventy.config.cjs
Normal file
@@ -0,0 +1,71 @@
|
||||
// Import required modules
|
||||
const twig = require("twig");
|
||||
const fs = require('fs')
|
||||
const eleventyPluginTwig = require("@factorial/eleventy-plugin-twig");
|
||||
|
||||
// Export Eleventy configuration
|
||||
module.exports = function(eleventyConfig) {
|
||||
// Function to generate a version identifier
|
||||
function generateVersion() {
|
||||
// You can use a timestamp, a hash of asset files, or any other method you prefer
|
||||
return Date.now();
|
||||
}
|
||||
|
||||
eleventyConfig.setServerOptions({
|
||||
enabled: false,
|
||||
});
|
||||
|
||||
eleventyConfig.addWatchTarget("views/**/*");
|
||||
|
||||
// Use twig
|
||||
eleventyConfig.addPlugin(eleventyPluginTwig, {
|
||||
twig: {
|
||||
namespaces: {
|
||||
layouts: "views/layouts",
|
||||
partials: "views/partials",
|
||||
snippets: "views/snippets"
|
||||
}
|
||||
},
|
||||
dir: {
|
||||
input: 'views/templates',
|
||||
output: 'www'
|
||||
}
|
||||
});
|
||||
|
||||
twig.extendFilter("log", function(value) {
|
||||
return '<pre>'+JSON.stringify(value)+'</pre>';
|
||||
});
|
||||
|
||||
twig.extendFilter("slug", function(str) {
|
||||
return str
|
||||
.toLowerCase() // Convert the string to lowercase
|
||||
.replace(/\s+/g, '-') // Replace spaces with dashes
|
||||
.replace(/[^\w-]/g, '') // Remove non-word characters
|
||||
.replace(/--+/g, '-') // Replace consecutive dashes with a single dash
|
||||
.trim(); // Trim any leading or trailing dashes
|
||||
})
|
||||
|
||||
// // Add a filter to append the version to asset URLs
|
||||
twig.extendFilter('version', function(url) {
|
||||
const version = generateVersion();
|
||||
return `${url}?v=${version}`;
|
||||
});
|
||||
|
||||
twig.extendFunction("critical_css", function() {
|
||||
try {
|
||||
return fs.readFileSync('./www/assets/styles/critical.css', 'utf-8')
|
||||
} catch(error) {
|
||||
return '';
|
||||
}
|
||||
});
|
||||
|
||||
// Configure and return Eleventy settings
|
||||
return {
|
||||
templateFormats: ['twig'],
|
||||
dir: {
|
||||
input: 'views/templates',
|
||||
output: 'www',
|
||||
data: '../../data'
|
||||
}
|
||||
};
|
||||
};
|
||||
@@ -15,11 +15,14 @@
|
||||
"dest": "./www/assets/scripts"
|
||||
},
|
||||
"svgs": {
|
||||
"src": "./assets/images/sprite",
|
||||
"src": "./assets/svgs",
|
||||
"dest": "./www/assets/images"
|
||||
},
|
||||
"views": {
|
||||
"src": "./www/"
|
||||
"src": "./views/"
|
||||
},
|
||||
"data": {
|
||||
"src": "./data/"
|
||||
}
|
||||
},
|
||||
"tasks": {
|
||||
|
||||
10235
package-lock.json
generated
10235
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
19
package.json
19
package.json
@@ -6,7 +6,7 @@
|
||||
"author": "Locomotive <info@locomotive.ca>",
|
||||
"type": "module",
|
||||
"engines": {
|
||||
"node": ">=17.9",
|
||||
"node": "20.x",
|
||||
"npm": ">=8.0"
|
||||
},
|
||||
"scripts": {
|
||||
@@ -14,24 +14,27 @@
|
||||
"build": "node --experimental-json-modules --no-warnings build/build.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"locomotive-scroll": "^4.1.4",
|
||||
"locomotive-scroll": "^5.0.0-beta.11",
|
||||
"modujs": "^1.4.2",
|
||||
"modularload": "^1.2.6",
|
||||
"normalize.css": "^8.0.1",
|
||||
"svg4everybody": "^2.1.9"
|
||||
},
|
||||
"devDependencies": {
|
||||
"autoprefixer": "^10.4.13",
|
||||
"browser-sync": "^2.27.11",
|
||||
"@11ty/eleventy": "^2.0.1",
|
||||
"@11ty/eleventy-img": "^3.1.8",
|
||||
"@factorial/eleventy-plugin-twig": "^0.1.2",
|
||||
"autoprefixer": "^10.4.17",
|
||||
"browser-sync": "^3.0.2",
|
||||
"concat": "^1.0.3",
|
||||
"esbuild": "^0.17.6",
|
||||
"esbuild": "^0.20.0",
|
||||
"kleur": "^4.1.5",
|
||||
"node-notifier": "^10.0.1",
|
||||
"postcss": "^8.4.21",
|
||||
"purgecss": "^5.0.0",
|
||||
"sass": "^1.57.1",
|
||||
"sass": "^1.70.0",
|
||||
"svg-mixer": "~2.3.14",
|
||||
"tiny-glob": "^0.2.9"
|
||||
"tiny-glob": "^0.2.9",
|
||||
"twig": "^1.17.1"
|
||||
},
|
||||
"overrides": {
|
||||
"browser-sync": {
|
||||
|
||||
48
views/layouts/base.twig
Normal file
48
views/layouts/base.twig
Normal file
@@ -0,0 +1,48 @@
|
||||
<!doctype html>
|
||||
<html class="is-loading" lang="en" data-page="images">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
|
||||
<base href="/">
|
||||
|
||||
<title>{% if title %}{{ title }} | {% endif %}{{ metadata.title }}</title>
|
||||
<meta name="description" content="{% if description %}{{description}}{% else %}{{ metadata.description }}{% endif %}">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
|
||||
<meta name="theme-color" content="#ffffff">
|
||||
<meta name="msapplication-TileColor" content="#ffffff">
|
||||
<link rel="manifest" href="site.webmanifest">
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="assets/images/favicons/apple-touch-icon.png">
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="assets/images/favicons/favicon-32x32.png">
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="assets/images/favicons/favicon-16x16.png">
|
||||
<link rel="mask-icon" href="assets/images/favicons/safari-pinned-tab.svg" color="#000000">
|
||||
|
||||
<link id="main-css" rel="stylesheet" href="assets/styles/main.css" media="print" onload="this.media='all'; this.onload=null; this.isLoaded=true">
|
||||
</head>
|
||||
<body data-module-load>
|
||||
<div data-load-container>
|
||||
{% block beforeMain %}
|
||||
<div data-module-scroll="main">
|
||||
{% include "@partials/header.twig" %}
|
||||
{% endblock %}
|
||||
|
||||
<main>
|
||||
{% block content %}{% endblock %}
|
||||
|
||||
{% block afterContent %}
|
||||
{% include "@partials/footer.twig" %}
|
||||
{% endblock %}
|
||||
</main>
|
||||
|
||||
{% block afterMain %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
</div>
|
||||
|
||||
<script nomodule src="https://cdnjs.cloudflare.com/ajax/libs/babel-polyfill/7.6.0/polyfill.min.js" crossorigin="anonymous"></script>
|
||||
<script nomodule src="https://polyfill.io/v3/polyfill.min.js?features=Element.prototype.remove%2CElement.prototype.append%2Cfetch%2CCustomEvent%2CElement.prototype.matches%2CNodeList.prototype.forEach%2CAbortController" crossorigin="anonymous"></script>
|
||||
|
||||
<script src="assets/scripts/vendors.js" defer></script>
|
||||
<script src="assets/scripts/app.js" defer></script>
|
||||
</body>
|
||||
</html>
|
||||
5
views/partials/footer.twig
Normal file
5
views/partials/footer.twig
Normal file
@@ -0,0 +1,5 @@
|
||||
<footer class="o-container">
|
||||
<p>Made by Locomotive<br>
|
||||
<a href="https://github.com/locomotivemtl/locomotive-boilerplate" title="Locomotive Boilerplate" target="_blank" rel="noopener">Github</a>
|
||||
</p>
|
||||
</footer>
|
||||
11
views/partials/header.twig
Normal file
11
views/partials/header.twig
Normal file
@@ -0,0 +1,11 @@
|
||||
<header class="o-container">
|
||||
<h1><a href="/">Locomotive Boilerplate</a></h1>
|
||||
<nav>
|
||||
<ul>
|
||||
<li><a href="/grid">Grid</a></li>
|
||||
<li><a href="/form" data-load="customTransition">Form</a></li>
|
||||
<li><a href="/wysiwyg">Wysiwyg</a></li>
|
||||
<li><a href="/projects">Projects</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
</header>
|
||||
51
views/snippets/button.twig
Normal file
51
views/snippets/button.twig
Normal file
@@ -0,0 +1,51 @@
|
||||
{# --- Parameters ------------------------- #}
|
||||
|
||||
{% set _tag = tag | default('button') %}
|
||||
{% set _href = href | default(null) %}
|
||||
{% set _external = external ?? false %}
|
||||
{% set _classes = classes | default(null) %}
|
||||
{% set _modifiers = modifiers | default(null) %}
|
||||
{% set _label = label | default(null) %}
|
||||
{% set _icon = icon | default(null) %}
|
||||
{% set _attr = attr | default(null) %}
|
||||
|
||||
{# --- Computed --------------------------- #}
|
||||
|
||||
{% if _href != null %}
|
||||
{% set _tag = 'a' %}
|
||||
{% elseif _tag == 'a' %}
|
||||
{% set _tag = 'span' %}
|
||||
{% endif %}
|
||||
|
||||
{% if _classes != null %}
|
||||
{% set _classes = ' ' ~ _classes %}
|
||||
{% endif %}
|
||||
|
||||
{% if _modifiers != null %}
|
||||
{% set _classes = ' ' ~ _modifiers ~ ' ' ~ _classes %}
|
||||
{% endif %}
|
||||
|
||||
{# ---------------------------------------- #}
|
||||
|
||||
<{{ _tag }}
|
||||
class="c-button{{ _classes }}"
|
||||
{% if _href %}href="{{ _href }}"{% endif %}
|
||||
{% if _external %}target="_blank" rel="noopener noreferrer" data-load="false"{% endif %}
|
||||
{% if _attr %}{{ _attr | raw }}{% endif %}
|
||||
>
|
||||
{% block inner %}
|
||||
<span class="c-button_inner">
|
||||
{% if _label %}
|
||||
<span class="c-button_label">
|
||||
{{ _label }}
|
||||
</span>
|
||||
{% endif %}
|
||||
{% if _icon %}
|
||||
{% include "@snippets/icon.twig" with {
|
||||
icon: _icon,
|
||||
classes: 'c-button_icon',
|
||||
} only %}
|
||||
{% endif %}
|
||||
</span>
|
||||
{% endblock %}
|
||||
</{{ _tag }}>
|
||||
15
views/snippets/icon.twig
Normal file
15
views/snippets/icon.twig
Normal file
@@ -0,0 +1,15 @@
|
||||
{# --- Parameters ------------------------- #}
|
||||
|
||||
{% set _icon = icon %}
|
||||
{% set _classes = classes | default(null) %}
|
||||
{% set _modifiers = modifiers | default(null) %}
|
||||
|
||||
{# ---------------------------------------- #}
|
||||
|
||||
{% if _icon %}
|
||||
<span class="o-icon {{ _classes }} {{ _modifiers }}">
|
||||
<svg class="svg-{{ _icon }}" focusable="false" aria-hidden="true">
|
||||
<use xlink:href="#{{ _icon }}"></use>
|
||||
</svg>
|
||||
</span>
|
||||
{% endif %}
|
||||
95
views/snippets/image.twig
Normal file
95
views/snippets/image.twig
Normal file
@@ -0,0 +1,95 @@
|
||||
{#
|
||||
Image snippet
|
||||
|
||||
The `img` parameter was made to receive formatted data from a CMS.
|
||||
The use case would be to output an image without overriding is dimensions or other properties.
|
||||
|
||||
It needs to be an object with the following keys :
|
||||
-src: String,
|
||||
-width: Int,
|
||||
-height: Int,
|
||||
-alt?: String,
|
||||
-caption?: String
|
||||
|
||||
```twig
|
||||
{% include '@snippets/image.twig' with
|
||||
img: project.featured_image
|
||||
%}
|
||||
```
|
||||
#}
|
||||
|
||||
{# Defaults #}
|
||||
{% set _width = img.width | default(1) %}
|
||||
{% set _height = img.height | default(1) %}
|
||||
{% set _src = img.src | default(null) %}
|
||||
{% set _alt = img.alt | default(null) %}
|
||||
{% set _caption = img.caption | default(null) %}
|
||||
{% set _attr = attr | default(null) %}
|
||||
{% set _has_parallax = has_parallax | default(null) %}
|
||||
{% set _parallax_speed = parallax_speed | default('-0.1') %}
|
||||
|
||||
{# Override properties #}
|
||||
{% set _width = width | default(_width) %}
|
||||
{% set _height = height | default(_height) %}
|
||||
{% set _src = src | default(_src) %}
|
||||
{% set _alt = alt | default(_alt) %}
|
||||
{% set _caption = caption | default(_caption) %}
|
||||
|
||||
{# Misc. #}
|
||||
{% set _is_figure = is_figure | default(false) %}
|
||||
{% set _is_lazy_load = is_lazy_load | default(true) %}
|
||||
{% set _tag = _is_figure ? 'figure' : 'div' %}
|
||||
|
||||
{# Classes & modifiers #}
|
||||
{% set _classes = classes | default(null) %}
|
||||
{% set _modifiers = modifiers | default(null) %}
|
||||
|
||||
{% if _has_parallax %}
|
||||
{% set _modifiers = _modifiers ~ ' -parallax' %}
|
||||
{% endif %}
|
||||
|
||||
{% if _is_lazy_load %}
|
||||
{% set _modifiers = _modifiers ~ ' -lazy-load' %}
|
||||
{% set _loading = 'lazy' %}
|
||||
{% else %}
|
||||
{% set _loading = 'eager' %}
|
||||
{% endif %}
|
||||
|
||||
{% if _classes != null %}
|
||||
{% set _classes = ' ' ~ _classes %}
|
||||
{% endif %}
|
||||
|
||||
{% if _modifiers != null %}
|
||||
{% set _classes = ' ' ~ _modifiers ~ ' ' ~ _classes %}
|
||||
{% endif %}
|
||||
|
||||
{# ---------------------------------------- #}
|
||||
|
||||
<{{_tag}} class="c-image{{ _classes }}" {{_attr}}>
|
||||
<div
|
||||
class="c-image_inner"
|
||||
{% if has_parallax %}
|
||||
data-scroll
|
||||
data-scroll-speed="{{ _parallax_speed }}"
|
||||
{% endif %}
|
||||
>
|
||||
<img
|
||||
class="c-image_img"
|
||||
src="{{ _src }}"
|
||||
alt="{{ _alt }}"
|
||||
width="{{ _width }}"
|
||||
height="{{ _height }}"
|
||||
loading="{{ _loading }}"
|
||||
onload="this.closest('.c-image')?.classList?.add('is-loaded');"
|
||||
>
|
||||
</div>
|
||||
|
||||
{% if _caption %}
|
||||
{% if _is_figure %}
|
||||
<figcaption class="c-image_description">{{ _caption }}</figcaption>
|
||||
{% else %}
|
||||
<div class="c-image_description"><span>{{ _caption }}</span></div>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
</{{ _tag }}>
|
||||
61
views/templates/form.twig
Normal file
61
views/templates/form.twig
Normal file
@@ -0,0 +1,61 @@
|
||||
{% extends "@layouts/base.twig" %}
|
||||
|
||||
{% block content %}
|
||||
<div class="o-container">
|
||||
<h1 class="c-heading -h1">Page</h1>
|
||||
|
||||
<div class="o-layout">
|
||||
<div class="o-layout_item u-1/2@from-small">
|
||||
|
||||
<form class="c-form">
|
||||
<div class="c-form_item">
|
||||
<label class="c-form_label" for="input">Input</label>
|
||||
<input class="c-form_input" type="text" id="input">
|
||||
</div>
|
||||
<div class="c-form_item">
|
||||
<div class="o-layout -gutter">
|
||||
<div class="o-layout_item u-1/2">
|
||||
<input class="c-form_checkbox" type="checkbox" id="checkbox">
|
||||
<label class="c-form_checkboxLabel" for="checkbox">Checkbox</label>
|
||||
</div>
|
||||
<div class="o-layout_item u-1/2">
|
||||
<input class="c-form_checkbox" type="checkbox" id="checkbox2">
|
||||
<label class="c-form_checkboxLabel" for="checkbox2">Checkbox 2</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="c-form_item">
|
||||
<div class="o-layout -gutter">
|
||||
<div class="o-layout_item u-1/2">
|
||||
<input class="c-form_radio" type="radio" name="radio" id="radio">
|
||||
<label class="c-form_radioLabel" for="radio">Radio</label>
|
||||
</div>
|
||||
<div class="o-layout_item u-1/2">
|
||||
<input class="c-form_radio" type="radio" name="radio" id="radio2">
|
||||
<label class="c-form_radioLabel" for="radio2">Radio 2</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="c-form_item">
|
||||
<label class="c-form_label" for="select">Select</label>
|
||||
<div class="c-form_select">
|
||||
<select class="c-form_select_input" id="select">
|
||||
<option value="option">Option</option>
|
||||
<option value="option2">Option 2</option>
|
||||
<option value="option3">Option 3</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="c-form_item">
|
||||
<label class="c-form_label" for="textarea">Textarea</label>
|
||||
<textarea class="c-form_textarea" id="textarea"></textarea>
|
||||
</div>
|
||||
<button class="c-button" type="submit">
|
||||
Submit
|
||||
</button>
|
||||
</form>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
29
views/templates/grid.twig
Normal file
29
views/templates/grid.twig
Normal file
@@ -0,0 +1,29 @@
|
||||
{% extends "@layouts/base.twig" %}
|
||||
|
||||
{% block content %}
|
||||
<div class="o-container">
|
||||
<h1 class="c-heading -h1">Hello</h1>
|
||||
|
||||
<div class="o-grid -col-4 -col-12@from-md -gutters">
|
||||
<div class="o-grid_item u-gc-1/8@from-md" style="background-color: gray;">
|
||||
<h2 class="c-heading -h2">This grid has 4 columns and 12 columns from `md` MQ</h2>
|
||||
</div>
|
||||
|
||||
<div class="o-grid_item u-gc-1/5@from-md" style="background-color: yellow;">
|
||||
<p>Lorem, ipsum dolor sit amet consectetur adipisicing elit. Expedita provident distinctio deleniti eaque cumque doloremque aut quo dicta porro commodi, temporibus totam dolor autem tempore quasi ullam sed suscipit vero?</p>
|
||||
</div>
|
||||
|
||||
<div class="o-grid_item u-gc-5/9@from-md" style="background-color: red;">
|
||||
<p>Lorem, ipsum dolor sit amet consectetur adipisicing elit. Expedita provident distinctio deleniti eaque cumque doloremque aut quo dicta porro commodi, temporibus totam dolor autem tempore quasi ullam sed suscipit vero?</p>
|
||||
</div>
|
||||
|
||||
<div class="o-grid_item u-gc-9/13@from-md" style="background-color: blue;">
|
||||
<p>Lorem, ipsum dolor sit amet consectetur adipisicing elit. Expedita provident distinctio deleniti eaque cumque doloremque aut quo dicta porro commodi, temporibus totam dolor autem tempore quasi ullam sed suscipit vero?</p>
|
||||
</div>
|
||||
|
||||
<div class="o-grid_item u-gc-1/3 u-gc-5/13@from-md" style="background-color: pink;">
|
||||
<p>Lorem, ipsum dolor sit amet consectetur adipisicing elit. Expedita provident distinctio deleniti eaque cumque doloremque aut quo dicta porro commodi, temporibus totam dolor autem tempore quasi ullam sed suscipit vero?</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
89
views/templates/images.twig
Normal file
89
views/templates/images.twig
Normal file
@@ -0,0 +1,89 @@
|
||||
{% extends "@layouts/base.twig" %}
|
||||
|
||||
{% block content %}
|
||||
<div data-module-scroll="main">
|
||||
<div class="o-container">
|
||||
<h1 class="c-heading -h1">Images</h1>
|
||||
|
||||
<section>
|
||||
<h2 class="c-heading -h2">Lazy load demo</h2>
|
||||
|
||||
<h3 class="c-heading -h3">Basic</h3>
|
||||
|
||||
<div style="width: 640px; max-width: 100%;">
|
||||
<div class="o-ratio u-4:3"><img data-load-src="http://picsum.photos/800/600?v=1" alt="" src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" /></div>
|
||||
<div class="o-ratio u-4:3"><img data-load-src="http://picsum.photos/800/600?v=2" alt="" src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" /></div>
|
||||
</div>
|
||||
|
||||
<h4 class="c-heading -h3">Using o-ratio & background-image</h3>
|
||||
|
||||
<div style="width: 480px; max-width: 100%;">
|
||||
<div class="o-ratio u-16:9" data-load-style="background-size: cover; background-position: center; background-image: url(http://picsum.photos/640/480?v=1);"></div>
|
||||
<div class="o-ratio u-16:9" data-load-style="background-size: cover; background-position: center; background-image: url(http://picsum.photos/640/480?v=2);"></div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h3 class="c-heading -h3">Relative to scroll</h3>
|
||||
|
||||
<h4 class="c-heading -h3">Using o-ratio & img</h3>
|
||||
|
||||
<div style="width: 640px; max-width: 100%;">
|
||||
<div class="o-ratio u-4:3">
|
||||
<img data-scroll data-scroll-call="lazyLoad, Scroll, main" data-src="http://picsum.photos/800/600?v=1" alt="" src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" />
|
||||
</div>
|
||||
<div class="o-ratio u-4:3">
|
||||
<img data-scroll data-scroll-call="lazyLoad, Scroll, main" data-src="http://picsum.photos/800/600?v=2" alt="" src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" />
|
||||
</div>
|
||||
<div class="o-ratio u-4:3">
|
||||
<img data-scroll data-scroll-call="lazyLoad, Scroll, main" data-src="http://picsum.photos/800/600?v=3" alt="" src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" />
|
||||
</div>
|
||||
<div class="o-ratio u-4:3">
|
||||
<img data-scroll data-scroll-call="lazyLoad, Scroll, main" data-src="http://picsum.photos/800/600?v=4" alt="" src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" />
|
||||
</div>
|
||||
<div class="o-ratio u-4:3">
|
||||
<img data-scroll data-scroll-call="lazyLoad, Scroll, main" data-src="http://picsum.photos/800/600?v=5" alt="" src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h4 class="c-heading -h3">Using o-ratio & background-image</h3>
|
||||
|
||||
<div style="width: 480px; max-width: 100%;">
|
||||
<div style="background-size: cover; background-position: center;" class="o-ratio u-16:9" data-scroll data-scroll-call="lazyLoad, Scroll, main" data-src="http://picsum.photos/1280/720?v=1"></div>
|
||||
<div style="background-size: cover; background-position: center;" class="o-ratio u-16:9" data-scroll data-scroll-call="lazyLoad, Scroll, main" data-src="http://picsum.photos/1280/720?v=2"></div>
|
||||
<div style="background-size: cover; background-position: center;" class="o-ratio u-16:9" data-scroll data-scroll-call="lazyLoad, Scroll, main" data-src="http://picsum.photos/1280/720?v=3"></div>
|
||||
<div style="background-size: cover; background-position: center;" class="o-ratio u-16:9" data-scroll data-scroll-call="lazyLoad, Scroll, main" data-src="http://picsum.photos/1280/720?v=4"></div>
|
||||
<div style="background-size: cover; background-position: center;" class="o-ratio u-16:9" data-scroll data-scroll-call="lazyLoad, Scroll, main" data-src="http://picsum.photos/1280/720?v=5"></div>
|
||||
</div>
|
||||
|
||||
<h4 class="c-heading -h3">Using SVG viewport for ratio</h3>
|
||||
|
||||
<div style="width: 480px; max-width: 100%;">
|
||||
<img
|
||||
data-scroll
|
||||
data-scroll-call="lazyLoad, Scroll, main"
|
||||
data-src="http://picsum.photos/640/480?v=6"
|
||||
alt=""
|
||||
src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 640 480'%3E%3C/svg%3E"
|
||||
/>
|
||||
|
||||
<img
|
||||
data-scroll
|
||||
data-scroll-call="lazyLoad, Scroll, main"
|
||||
data-src="http://picsum.photos/640/480?v=7"
|
||||
alt=""
|
||||
src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 640 480'%3E%3C/svg%3E"
|
||||
/>
|
||||
|
||||
<img
|
||||
data-scroll
|
||||
data-scroll-call="lazyLoad, Scroll, main"
|
||||
data-src="http://picsum.photos/640/480?v=8"
|
||||
alt=""
|
||||
src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 640 480'%3E%3C/svg%3E"
|
||||
/>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
54
views/templates/index.twig
Normal file
54
views/templates/index.twig
Normal file
@@ -0,0 +1,54 @@
|
||||
---
|
||||
title: Home
|
||||
---
|
||||
|
||||
{% extends "@layouts/base.twig" %}
|
||||
|
||||
{% block content %}
|
||||
<div class="o-container">
|
||||
|
||||
{# ====================== #}
|
||||
{# ====== Headings ====== #}
|
||||
{# ====================== #}
|
||||
|
||||
<h1 class="c-heading -h1">Heading 1</h1>
|
||||
<h1 class="c-heading -h2">Heading 2</h1>
|
||||
<h1 class="c-heading -h3">Heading 3</h1>
|
||||
<h1 class="c-heading -h4">Heading 4</h1>
|
||||
<h1 class="c-heading -h5">Heading 5</h1>
|
||||
<h1 class="c-heading -h6">Heading 6</h1>
|
||||
|
||||
<hr>
|
||||
|
||||
{# ======================= #}
|
||||
{# ======== Texts ======== #}
|
||||
{# ======================= #}
|
||||
|
||||
<p class="c-text -body-regular" style="max-width: 500px">
|
||||
Lorem ipsum dolor sit amet consectetur adipisicing elit. Totam libero, sit pariatur voluptatum amet magni odio ducimus! Saepe facere iste porro voluptatem. Tenetur perferendis ea a quasi vitae! Ullam, blanditiis.
|
||||
</p>
|
||||
|
||||
<hr>
|
||||
|
||||
{# ======================= #}
|
||||
{# ======= Buttons ======= #}
|
||||
{# ======================= #}
|
||||
|
||||
{% include "@snippets/button.twig" with {
|
||||
label: 'Button'
|
||||
} %}
|
||||
|
||||
<hr>
|
||||
|
||||
{# ====================== #}
|
||||
{# ======= Images ======= #}
|
||||
{# ====================== #}
|
||||
|
||||
{% include "@snippets/image.twig" with {
|
||||
src: 'http://picsum.photos/800/600?v=1',
|
||||
width: 800,
|
||||
height: 600
|
||||
} %}
|
||||
|
||||
</div>
|
||||
{% endblock %}
|
||||
16
views/templates/project.twig
Normal file
16
views/templates/project.twig
Normal file
@@ -0,0 +1,16 @@
|
||||
---
|
||||
pagination:
|
||||
data: projects
|
||||
size: 1
|
||||
alias: project
|
||||
permalink: "project/{{ project.title | slug }}/index.html"
|
||||
---
|
||||
|
||||
{% extends "@layouts/base.twig" %}
|
||||
|
||||
{% block content %}
|
||||
<div data-module-scroll="main">
|
||||
<h1 class="c-heading -h1">{{project.title}}</h1>
|
||||
<p>{{project.desc}}</p>
|
||||
</div>
|
||||
{% endblock %}
|
||||
30
views/templates/projects.twig
Normal file
30
views/templates/projects.twig
Normal file
@@ -0,0 +1,30 @@
|
||||
---
|
||||
pagination:
|
||||
data: projects
|
||||
size: 4
|
||||
---
|
||||
|
||||
{% extends "@layouts/base.twig" %}
|
||||
|
||||
{% block content %}
|
||||
<div data-module-scroll="main">
|
||||
|
||||
<h1 class="c-heading -h1">Projects</h1>
|
||||
|
||||
<ul>
|
||||
{% for item in pagination.items %}
|
||||
<li><a href="/project/{{item.title|slug}}">{{ item.title }}</a></li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
|
||||
<ol>
|
||||
{% for pageEntry in pagination.pages %}
|
||||
{% if page.url == pagination.hrefs[ loop.index0 ] %}
|
||||
<span aria-current="page">{{ loop.index }}</span>
|
||||
{% else %}
|
||||
<a href="{{ pagination.hrefs[ loop.index0 ] }}">{{ loop.index }}</a>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</ol>
|
||||
</div>
|
||||
{% endblock %}
|
||||
78
views/templates/wysiwyg.twig
Normal file
78
views/templates/wysiwyg.twig
Normal file
@@ -0,0 +1,78 @@
|
||||
{% extends "@layouts/base.twig" %}
|
||||
|
||||
{% block content %}
|
||||
<div data-module-scroll="main">
|
||||
<div class="o-container || c-wysiwyg">
|
||||
<h1>Heading 1</h1>
|
||||
<h2>Heading 2</h2>
|
||||
<h3>Heading 3</h3>
|
||||
<h4>Heading 4</h4>
|
||||
<h5>Heading 5</h5>
|
||||
<h6>Heading 6</h6>
|
||||
<h1>Heading 1</h1>
|
||||
<p>Lorem ipsum dolor sit amet, consectetur adipiscing 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.</p>
|
||||
<h2>Heading 2</h2>
|
||||
<p>Lorem ipsum dolor sit amet, consectetur adipiscing 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.</p>
|
||||
<h3>Heading 3</h3>
|
||||
<p>Lorem ipsum dolor sit amet, consectetur adipiscing 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.</p>
|
||||
<h4>Heading 4</h4>
|
||||
<p>Lorem ipsum dolor sit amet, consectetur adipiscing 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.</p>
|
||||
<h5>Heading 5</h5>
|
||||
<p>Lorem ipsum dolor sit amet, consectetur adipiscing 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.</p>
|
||||
<h6>Heading 6</h6>
|
||||
<p>Lorem ipsum dolor sit amet, consectetur adipiscing 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.</p>
|
||||
<p>Lorem ipsum dolor sit amet, consectetur adipiscing 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.</p><p><strong>Lorem ipsum dolor sit amet, consectetur</strong> adipiscing elit, sed do eiusmod tempor incididunt u<strong>t labore et dolore magna aliqua</strong>. Ut enim ad minim <em>veniam, quis nostrud exercitation</em> ullamco laboris <em>nisi ut aliquip ex ea</em> commodo consequat. <span style="text-decoration: underline;">Duis aute irure dolor in reprehenderit in voluptate velit</span> esse cillum dolore eu fugiat nulla pariatur. <span style="text-decoration: underline;">Excepteur sint occaecat cupidatat</span> non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
|
||||
<blockquote>
|
||||
<p>Lorem ipsum dolor sit amet, consectetur adipiscing 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.</p>
|
||||
</blockquote>
|
||||
<p>Je suis un <a href="https://www.lipsum.com/" target="_blank" title="Un super lien" rel="noopener noreferrer">super lien.</a> Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor <a href="https://www.lipsum.com/" title="Lorem Ipsum">incididunt ut labore et dolore magna aliqua</a>. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex.</p>
|
||||
<p>
|
||||
<a href="mailto:example@example.com" title="Test mail">Lien mail.</a><br/>
|
||||
<a href="tel:+0-123-456-7890" title="Test tel">Lien téléphone.</a>
|
||||
</p>
|
||||
<ul>
|
||||
<li>Item 1</li>
|
||||
<li><strong>Item 2</strong></li>
|
||||
<li><em><strong>Item 3</strong></em></li>
|
||||
<li><span style="text-decoration: underline;">Item 4</span></li>
|
||||
<li><a href="https://www.lipsum.com/" title="Lorem ipsum">Item 5</a></li>
|
||||
</ul>
|
||||
<ol>
|
||||
<li>Item 1</li>
|
||||
<li>Item 2</li>
|
||||
<li>Item 3</li>
|
||||
</ol>
|
||||
<p style="padding-left: 60px;">"Lorem ipsum dolor sit amet, consectetur adipiscing 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. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. <br/>Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex."</p>
|
||||
<p style="text-align: left;">Lorem ipsum dolor sit amet, consectetur adipiscing 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.</p>
|
||||
<p style="text-align: center;">Lorem ipsum dolor sit amet, consectetur adipiscing 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.</p>
|
||||
<p style="text-align: right;">Lorem ipsum dolor sit amet, consectetur adipiscing 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.</p>
|
||||
<table width="539" height="90">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td style="width: 126.55px;"><strong>Last name</strong></td>
|
||||
<td style="width: 261.417px;"><span style="text-decoration: underline;">First name</span></td>
|
||||
<td style="width: 126.533px;"><em>City</em></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="width: 126.55px;">Lorem</td>
|
||||
<td style="width: 261.417px;">Ipsum</td>
|
||||
<td style="width: 126.533px;">Montréal</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="width: 126.55px;">Dolor</td>
|
||||
<td style="width: 261.417px;">Sit</td>
|
||||
<td style="width: 126.533px;">Paris</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<p>Lorem ipsum dolor sit amet, consectetur adipiscing 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.</p>
|
||||
<p><img src="https://www.airinuit.com/uploads/destinations/XGR/Mathias_Laroque_MWL.pilot_website_fall_2021_HD.jpg" alt=""/></p>
|
||||
<p>Lorem ipsum dolor sit amet, consectetur adipiscing 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.</p>
|
||||
<p><img src="https://www.airinuit.com/uploads/destinations/XGR/Mathias_Laroque_MWL.pilot_website_fall_2021_HD.jpg" alt=""/></p>
|
||||
<p>Lorem ipsum dolor sit amet, consectetur adipiscing 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.</p>
|
||||
<p><iframe width="560" height="315" src="https://www.youtube.com/embed/qt7jSw55N1A" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe></p>
|
||||
<p>Lorem ipsum dolor sit amet, consectetur adipiscing 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.</p>
|
||||
<p><img src="https://www.airinuit.com/uploads/destinations/XGR/Mathias_Laroque_MWL.pilot_website_fall_2021_HD.jpg" alt=""/></p>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1 +0,0 @@
|
||||
{"version":3,"sources":[],"names":[],"mappings":"","file":"critical.css"}
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
105
www/form.html
105
www/form.html
@@ -1,105 +0,0 @@
|
||||
<!doctype html>
|
||||
<html class="is-loading" lang="en" data-page="page">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Form | Locomotive Boilerplate</title>
|
||||
<meta name="description" content="">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
|
||||
<meta name="theme-color" content="#ffffff">
|
||||
<meta name="msapplication-TileColor" content="#ffffff">
|
||||
<link rel="manifest" href="site.webmanifest">
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="assets/images/favicons/apple-touch-icon.png">
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="assets/images/favicons/favicon-32x32.png">
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="assets/images/favicons/favicon-16x16.png">
|
||||
<link rel="mask-icon" href="assets/images/favicons/safari-pinned-tab.svg" color="#000000">
|
||||
|
||||
<link id="main-css" rel="stylesheet" href="assets/styles/main.css" media="print" onload="this.media='all'; this.onload=null; this.isLoaded=true">
|
||||
</head>
|
||||
<body data-module-load>
|
||||
<div data-load-container>
|
||||
<div class="o-scroll" data-module-scroll="main">
|
||||
<header data-scroll-section>
|
||||
<a href="/"><h1>Locomotive Boilerplate</h1></a>
|
||||
<nav>
|
||||
<ul>
|
||||
<li><a href="images.html">Images</a></li>
|
||||
<li><a href="form.html" data-load="customTransition">Form</a></li>
|
||||
<li><a href="grid.html">Grid</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
</header>
|
||||
|
||||
<main data-scroll-section>
|
||||
<div class="o-container">
|
||||
<h1 class="c-heading -h1">Page</h1>
|
||||
|
||||
<div class="o-layout">
|
||||
<div class="o-layout_item u-1/2@from-small">
|
||||
|
||||
<form class="c-form">
|
||||
<div class="c-form_item">
|
||||
<label class="c-form_label" for="input">Input</label>
|
||||
<input class="c-form_input" type="text" id="input">
|
||||
</div>
|
||||
<div class="c-form_item">
|
||||
<div class="o-layout -gutter">
|
||||
<div class="o-layout_item u-1/2">
|
||||
<input class="c-form_checkbox" type="checkbox" id="checkbox">
|
||||
<label class="c-form_checkboxLabel" for="checkbox">Checkbox</label>
|
||||
</div>
|
||||
<div class="o-layout_item u-1/2">
|
||||
<input class="c-form_checkbox" type="checkbox" id="checkbox2">
|
||||
<label class="c-form_checkboxLabel" for="checkbox2">Checkbox 2</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="c-form_item">
|
||||
<div class="o-layout -gutter">
|
||||
<div class="o-layout_item u-1/2">
|
||||
<input class="c-form_radio" type="radio" name="radio" id="radio">
|
||||
<label class="c-form_radioLabel" for="radio">Radio</label>
|
||||
</div>
|
||||
<div class="o-layout_item u-1/2">
|
||||
<input class="c-form_radio" type="radio" name="radio" id="radio2">
|
||||
<label class="c-form_radioLabel" for="radio2">Radio 2</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="c-form_item">
|
||||
<label class="c-form_label" for="select">Select</label>
|
||||
<div class="c-form_select">
|
||||
<select class="c-form_select_input" id="select">
|
||||
<option value="option">Option</option>
|
||||
<option value="option2">Option 2</option>
|
||||
<option value="option3">Option 3</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="c-form_item">
|
||||
<label class="c-form_label" for="textarea">Textarea</label>
|
||||
<textarea class="c-form_textarea" id="textarea"></textarea>
|
||||
</div>
|
||||
<button class="c-button" type="submit">
|
||||
Submit
|
||||
</button>
|
||||
</form>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<footer data-scroll-section>
|
||||
<p>Made with <a href="https://github.com/locomotivemtl/locomotive-boilerplate" title="Locomotive Boilerplate" target="_blank" rel="noopener">🚂</a></p>
|
||||
</footer>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script nomodule src="https://cdnjs.cloudflare.com/ajax/libs/babel-polyfill/7.6.0/polyfill.min.js" crossorigin="anonymous"></script>
|
||||
<script nomodule src="https://polyfill.io/v3/polyfill.min.js?features=Element.prototype.remove%2CElement.prototype.append%2Cfetch%2CCustomEvent%2CElement.prototype.matches%2CNodeList.prototype.forEach%2CAbortController" crossorigin="anonymous"></script>
|
||||
|
||||
<script src="assets/scripts/vendors.js" defer></script>
|
||||
<script src="assets/scripts/app.js" defer></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,96 +0,0 @@
|
||||
<!doctype html>
|
||||
<html class="is-loading" lang="en" data-page="grid">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Locomotive Boilerplate</title>
|
||||
<meta name="description" content="">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
|
||||
<meta name="theme-color" content="#ffffff">
|
||||
<meta name="msapplication-TileColor" content="#ffffff">
|
||||
<link rel="manifest" href="site.webmanifest">
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="assets/images/favicons/apple-touch-icon.png">
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="assets/images/favicons/favicon-32x32.png">
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="assets/images/favicons/favicon-16x16.png">
|
||||
<link rel="mask-icon" href="assets/images/favicons/safari-pinned-tab.svg" color="#000000">
|
||||
<!-- For a dark mode managment and svg favicon add this in your favicon.svg -->
|
||||
<!--
|
||||
<style>
|
||||
path {
|
||||
fill: #000;
|
||||
}
|
||||
@media (prefers-color-scheme: dark) {
|
||||
path {
|
||||
fill: #fff;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
-->
|
||||
<!-- <link rel="icon" href="assets/images/favicons/favicon.svg"> -->
|
||||
|
||||
<link id="main-css" rel="stylesheet" href="assets/styles/main.css" media="print"
|
||||
onload="this.media='all'; this.onload=null; this.isLoaded=true">
|
||||
</head>
|
||||
|
||||
<body data-module-load>
|
||||
<div data-load-container>
|
||||
<div class="o-scroll" data-module-scroll="main">
|
||||
<header data-scroll-section>
|
||||
<a href="/">
|
||||
<h1>Locomotive Boilerplate</h1>
|
||||
</a>
|
||||
<nav>
|
||||
<ul>
|
||||
<li><a href="images.html">Images</a></li>
|
||||
<li><a href="form.html" data-load="customTransition">Form</a></li>
|
||||
<li><a href="grid.html">Grid</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
</header>
|
||||
|
||||
<main data-scroll-section>
|
||||
<div class="o-container">
|
||||
<h1 class="c-heading -h1">Hello</h1>
|
||||
|
||||
<div class="o-grid -col-4 -col-12@from-medium -gutters">
|
||||
<div class="o-grid_item u-gc-1/8@from-medium" style="background-color: gray;">
|
||||
<h2 class="c-heading -h2">This grid has 4 columns and 12 columns from `medium` MQ</h2>
|
||||
</div>
|
||||
|
||||
<div class="o-grid_item u-gc-1/5@from-medium" style="background-color: yellow;">
|
||||
<p>Lorem, ipsum dolor sit amet consectetur adipisicing elit. Expedita provident distinctio deleniti eaque cumque doloremque aut quo dicta porro commodi, temporibus totam dolor autem tempore quasi ullam sed suscipit vero?</p>
|
||||
</div>
|
||||
|
||||
<div class="o-grid_item u-gc-5/9@from-medium" style="background-color: red;">
|
||||
<p>Lorem, ipsum dolor sit amet consectetur adipisicing elit. Expedita provident distinctio deleniti eaque cumque doloremque aut quo dicta porro commodi, temporibus totam dolor autem tempore quasi ullam sed suscipit vero?</p>
|
||||
</div>
|
||||
|
||||
<div class="o-grid_item u-gc-9/13@from-medium" style="background-color: blue;">
|
||||
<p>Lorem, ipsum dolor sit amet consectetur adipisicing elit. Expedita provident distinctio deleniti eaque cumque doloremque aut quo dicta porro commodi, temporibus totam dolor autem tempore quasi ullam sed suscipit vero?</p>
|
||||
</div>
|
||||
|
||||
<div class="o-grid_item u-gc-1/3 u-gc-5/13@from-medium" style="background-color: pink;">
|
||||
<p>Lorem, ipsum dolor sit amet consectetur adipisicing elit. Expedita provident distinctio deleniti eaque cumque doloremque aut quo dicta porro commodi, temporibus totam dolor autem tempore quasi ullam sed suscipit vero?</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<footer data-scroll-section>
|
||||
<p>Made with <a href="https://github.com/locomotivemtl/locomotive-boilerplate"
|
||||
title="Locomotive Boilerplate" target="_blank" rel="noopener">🚂</a></p>
|
||||
</footer>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script nomodule src="https://cdnjs.cloudflare.com/ajax/libs/babel-polyfill/7.6.0/polyfill.min.js"
|
||||
crossorigin="anonymous"></script>
|
||||
<script nomodule
|
||||
src="https://polyfill.io/v3/polyfill.min.js?features=Element.prototype.remove%2CElement.prototype.append%2Cfetch%2CCustomEvent%2CElement.prototype.matches%2CNodeList.prototype.forEach%2CAbortController"
|
||||
crossorigin="anonymous"></script>
|
||||
|
||||
<script src="assets/scripts/vendors.js" defer></script>
|
||||
<script src="assets/scripts/app.js" defer></script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
131
www/images.html
131
www/images.html
@@ -1,131 +0,0 @@
|
||||
<!doctype html>
|
||||
<html class="is-loading" lang="en" data-page="images">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Images | Locomotive Boilerplate</title>
|
||||
<meta name="description" content="">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
|
||||
<meta name="theme-color" content="#ffffff">
|
||||
<meta name="msapplication-TileColor" content="#ffffff">
|
||||
<link rel="manifest" href="site.webmanifest">
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="assets/images/favicons/apple-touch-icon.png">
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="assets/images/favicons/favicon-32x32.png">
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="assets/images/favicons/favicon-16x16.png">
|
||||
<link rel="mask-icon" href="assets/images/favicons/safari-pinned-tab.svg" color="#000000">
|
||||
|
||||
<link id="main-css" rel="stylesheet" href="assets/styles/main.css" media="print" onload="this.media='all'; this.onload=null; this.isLoaded=true">
|
||||
</head>
|
||||
<body data-module-load>
|
||||
<div data-load-container>
|
||||
<div class="o-scroll" data-module-scroll="main">
|
||||
<header data-scroll-section>
|
||||
<a href="/"><h1>Locomotive Boilerplate</h1></a>
|
||||
<nav>
|
||||
<ul>
|
||||
<li><a href="images.html">Images</a></li>
|
||||
<li><a href="form.html" data-load="customTransition">Form</a></li>
|
||||
<li><a href="grid.html">Grid</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
</header>
|
||||
|
||||
<main data-scroll-section>
|
||||
<div class="o-container">
|
||||
<h1 class="c-heading -h1">Images</h1>
|
||||
|
||||
<section>
|
||||
<h2 class="c-heading -h2">Lazy load demo</h2>
|
||||
|
||||
<h3 class="c-heading -h3">Basic</h3>
|
||||
|
||||
<div style="width: 640px; max-width: 100%;">
|
||||
<div class="o-ratio u-4:3"><img data-load-src="http://picsum.photos/800/600?v=1" alt="" src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" /></div>
|
||||
<div class="o-ratio u-4:3"><img data-load-src="http://picsum.photos/800/600?v=2" alt="" src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" /></div>
|
||||
</div>
|
||||
|
||||
<h4 class="c-heading -h3">Using o-ratio & background-image</h3>
|
||||
|
||||
<div style="width: 480px; max-width: 100%;">
|
||||
<div class="o-ratio u-16:9" data-load-style="background-size: cover; background-position: center; background-image: url(http://picsum.photos/640/480?v=1);"></div>
|
||||
<div class="o-ratio u-16:9" data-load-style="background-size: cover; background-position: center; background-image: url(http://picsum.photos/640/480?v=2);"></div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h3 class="c-heading -h3">Relative to scroll</h3>
|
||||
|
||||
<h4 class="c-heading -h3">Using o-ratio & img</h3>
|
||||
|
||||
<div style="width: 640px; max-width: 100%;">
|
||||
<div class="o-ratio u-4:3">
|
||||
<img data-scroll data-scroll-call="lazyLoad, Scroll, main" data-src="http://picsum.photos/800/600?v=1" alt="" src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" />
|
||||
</div>
|
||||
<div class="o-ratio u-4:3">
|
||||
<img data-scroll data-scroll-call="lazyLoad, Scroll, main" data-src="http://picsum.photos/800/600?v=2" alt="" src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" />
|
||||
</div>
|
||||
<div class="o-ratio u-4:3">
|
||||
<img data-scroll data-scroll-call="lazyLoad, Scroll, main" data-src="http://picsum.photos/800/600?v=3" alt="" src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" />
|
||||
</div>
|
||||
<div class="o-ratio u-4:3">
|
||||
<img data-scroll data-scroll-call="lazyLoad, Scroll, main" data-src="http://picsum.photos/800/600?v=4" alt="" src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" />
|
||||
</div>
|
||||
<div class="o-ratio u-4:3">
|
||||
<img data-scroll data-scroll-call="lazyLoad, Scroll, main" data-src="http://picsum.photos/800/600?v=5" alt="" src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h4 class="c-heading -h3">Using o-ratio & background-image</h3>
|
||||
|
||||
<div style="width: 480px; max-width: 100%;">
|
||||
<div style="background-size: cover; background-position: center;" class="o-ratio u-16:9" data-scroll data-scroll-call="lazyLoad, Scroll, main" data-src="http://picsum.photos/1280/720?v=1"></div>
|
||||
<div style="background-size: cover; background-position: center;" class="o-ratio u-16:9" data-scroll data-scroll-call="lazyLoad, Scroll, main" data-src="http://picsum.photos/1280/720?v=2"></div>
|
||||
<div style="background-size: cover; background-position: center;" class="o-ratio u-16:9" data-scroll data-scroll-call="lazyLoad, Scroll, main" data-src="http://picsum.photos/1280/720?v=3"></div>
|
||||
<div style="background-size: cover; background-position: center;" class="o-ratio u-16:9" data-scroll data-scroll-call="lazyLoad, Scroll, main" data-src="http://picsum.photos/1280/720?v=4"></div>
|
||||
<div style="background-size: cover; background-position: center;" class="o-ratio u-16:9" data-scroll data-scroll-call="lazyLoad, Scroll, main" data-src="http://picsum.photos/1280/720?v=5"></div>
|
||||
</div>
|
||||
|
||||
<h4 class="c-heading -h3">Using SVG viewport for ratio</h3>
|
||||
|
||||
<div style="width: 480px; max-width: 100%;">
|
||||
<img
|
||||
data-scroll
|
||||
data-scroll-call="lazyLoad, Scroll, main"
|
||||
data-src="http://picsum.photos/640/480?v=6"
|
||||
alt=""
|
||||
src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 640 480'%3E%3C/svg%3E"
|
||||
/>
|
||||
|
||||
<img
|
||||
data-scroll
|
||||
data-scroll-call="lazyLoad, Scroll, main"
|
||||
data-src="http://picsum.photos/640/480?v=7"
|
||||
alt=""
|
||||
src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 640 480'%3E%3C/svg%3E"
|
||||
/>
|
||||
|
||||
<img
|
||||
data-scroll
|
||||
data-scroll-call="lazyLoad, Scroll, main"
|
||||
data-src="http://picsum.photos/640/480?v=8"
|
||||
alt=""
|
||||
src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 640 480'%3E%3C/svg%3E"
|
||||
/>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<footer data-scroll-section>
|
||||
<p>Made with <a href="https://github.com/locomotivemtl/locomotive-boilerplate" title="Locomotive Boilerplate" target="_blank" rel="noopener">🚂</a></p>
|
||||
</footer>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script nomodule src="https://cdnjs.cloudflare.com/ajax/libs/babel-polyfill/7.6.0/polyfill.min.js" crossorigin="anonymous"></script>
|
||||
<script nomodule src="https://polyfill.io/v3/polyfill.min.js?features=Element.prototype.remove%2CElement.prototype.append%2Cfetch%2CCustomEvent%2CElement.prototype.matches%2CNodeList.prototype.forEach%2CAbortController" crossorigin="anonymous"></script>
|
||||
|
||||
<script src="assets/scripts/vendors.js" defer></script>
|
||||
<script src="assets/scripts/app.js" defer></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,82 +0,0 @@
|
||||
<!doctype html>
|
||||
<html class="is-loading" lang="en" data-page="home">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Locomotive Boilerplate</title>
|
||||
<meta name="description" content="">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
|
||||
<meta name="theme-color" content="#ffffff">
|
||||
<meta name="msapplication-TileColor" content="#ffffff">
|
||||
<link rel="manifest" href="site.webmanifest">
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="assets/images/favicons/apple-touch-icon.png">
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="assets/images/favicons/favicon-32x32.png">
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="assets/images/favicons/favicon-16x16.png">
|
||||
<link rel="mask-icon" href="assets/images/favicons/safari-pinned-tab.svg" color="#000000">
|
||||
<!-- For a dark mode managment and svg favicon add this in your favicon.svg -->
|
||||
<!--
|
||||
<style>
|
||||
path {
|
||||
fill: #000;
|
||||
}
|
||||
@media (prefers-color-scheme: dark) {
|
||||
path {
|
||||
fill: #fff;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
-->
|
||||
<!-- <link rel="icon" href="assets/images/favicons/favicon.svg"> -->
|
||||
|
||||
<!-- Preload Fonts -->
|
||||
<link rel="preload" href="assets/fonts/SourceSans3-Bold.woff2" as="font" type="font/woff2" crossorigin>
|
||||
<link rel="preload" href="assets/fonts/SourceSans3-BoldIt.woff2" as="font" type="font/woff2" crossorigin>
|
||||
<link rel="preload" href="assets/fonts/SourceSans3-Regular.woff2" as="font" type="font/woff2" crossorigin>
|
||||
<link rel="preload" href="assets/fonts/SourceSans3-RegularIt.woff2" as="font" type="font/woff2" crossorigin>
|
||||
|
||||
<link id="main-css" rel="stylesheet" href="assets/styles/main.css" media="print"
|
||||
onload="this.media='all'; this.onload=null; this.isLoaded=true">
|
||||
</head>
|
||||
|
||||
<body data-module-load>
|
||||
|
||||
<div data-load-container>
|
||||
<div class="o-scroll" data-module-scroll="main">
|
||||
<header data-scroll-section>
|
||||
<a href="/">
|
||||
<h1>Locomotive Boilerplate</h1>
|
||||
</a>
|
||||
<nav>
|
||||
<ul>
|
||||
<li><a href="images.html">Images</a></li>
|
||||
<li><a href="form.html" data-load="customTransition">Form</a></li>
|
||||
<li><a href="grid.html">Grid</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
</header>
|
||||
|
||||
<main data-module-example data-scroll-section>
|
||||
<div class="o-container">
|
||||
<h1 class="c-heading -h1">Hello</h1>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<footer data-scroll-section>
|
||||
<p>Made with <a href="https://github.com/locomotivemtl/locomotive-boilerplate"
|
||||
title="Locomotive Boilerplate" target="_blank" rel="noopener">🚂</a></p>
|
||||
</footer>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script nomodule src="https://cdnjs.cloudflare.com/ajax/libs/babel-polyfill/7.6.0/polyfill.min.js"
|
||||
crossorigin="anonymous"></script>
|
||||
<script nomodule
|
||||
src="https://polyfill.io/v3/polyfill.min.js?features=Element.prototype.remove%2CElement.prototype.append%2Cfetch%2CCustomEvent%2CElement.prototype.matches%2CNodeList.prototype.forEach%2CAbortController"
|
||||
crossorigin="anonymous"></script>
|
||||
|
||||
<script src="assets/scripts/vendors.js" defer></script>
|
||||
<script src="assets/scripts/app.js" defer></script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
Reference in New Issue
Block a user